Files
ouc-slide-latex-template/theme/beamerinnerthemeOUCSlide.sty
T
laoyang 3ded53b6c4 新增三个深色颜色(苍松绿 / 暮山紫 / 琥珀橙)并同步要点框自动排布
一、新增颜色(放在 beamercolorthemeOUCSlide.sty)
  oucpine   苍松绿  RGB(30, 86, 64)    白字对比度 8.54
  oucdusk   暮山紫  RGB(92, 58, 118)   白字对比度 9.04
  oucamber  琥珀橙  RGB(196, 82, 16)   白字对比度 4.60
三个都是较深的颜色,与白色文字有足够对比度(WCAG >= 4.5),
可直接作色块底色;各自同样带 10 个色阶(如 oucpine10 ~ oucpine90)。
命名取自中文传统色:「苍松」「暮山紫」「琥珀」。
琥珀橙是高饱和深橘,与低饱和的暗褐「文脉棕」在饱和度上明显区分(0.98 vs 0.61)。

二、要点框自动排布 pointboxgrid(此前仅在 main 上,现同步到本分支)
每行最多 4 个,超过则均匀分成多行(5→3+2;6→3+3;7→4+3;8→4+4;9→3+3+3…),
用法见 README 的「要点框自动排布」一节。

三、验证
本分支已用 TeX Live 2022 重新编译验证:0 错误、0 溢出;
颜色样例页与要点框排布页均正常,三个新颜色在 PDF 中实际生效。
2026-10-13 08:43:43 +08:00

326 lines
10 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%% 版本:1.0
%% 作者:杨永全
%% 本文件的主要目的,是为了定义列表等内部元素的样式
%% 完成时间:2022-05-09
\RequirePackage{listings,verbatim}%引入代码包
\RequirePackage{caption}
\usepackage{tcolorbox} %引入彩色框
\tcbuselibrary{most} %引入所有包
%列表样式,使用了fontawesome图标
\setbeamertemplate{itemize item}{\faBookmark}
\setbeamertemplate{itemize subitem}{\faHandORight}
\setbeamertemplate{itemize subsubitem}{\faSquare}
%超链接的颜色等信息
\hypersetup{
%colorlinks=true, %超链接颜色,全部使用海大红。
linkcolor=oucred,
urlcolor=oucred,
citecolor=oucred,
anchorcolor=oucred,
}
%代码块的一些设定,原模板代码
\renewcommand{\ttdefault}{pcr}
\lstset{
frame=shadowbox,
numbers=left,
numberstyle=\small,
basicstyle=\ttfamily\upshape\small,
breaklines=true,
backgroundcolor=\color{oucsilver10},
xleftmargin=0.8cm,
framexleftmargin=0em,
keywordstyle=\bfseries\color{oucblue},
stringstyle=\color{oucblue},
commentstyle=\color{mygreen},
rulesepcolor= \color{oucsilver40},
rulecolor=\color{oucblue},
deletekeywords={compile},
escapechar=\&,
escapeinside={<@}{@>}
}
%% 代码块标题设定
\DeclareCaptionFormat{codecaptionformat}{%
\parbox{\textwidth}{\hspace{2em}\textcolor{violet}\faCode~\textcolor{violet}{#1#2}\hspace{.5em}#3}%代码块caption的设置
}
\captionsetup[lstlisting]{format=codecaptionformat}
%设置信息框titlebox
\newtcolorbox{titlebox}[2][]
{
title=#1, %标题
colback = white, %标题背景是白色
colframe = #2, %边框颜色
coltitle = #2, %标题颜色
boxrule=.5pt,%边框的粗细,细一点感觉更精致
boxed title style={size=normal,colframe=white,boxrule=0pt},%标题栏没有背景色和边框,只有文字
left=5pt, right=5pt, top=5pt, bottom=0pt,%内部文字边距
boxsep=5pt,
colbacktitle = white, enhanced,%标题的背景,白色
attach boxed title to top center={yshift=-4mm},%把标题放在中间
opacityupper={100}, %上面边框透明度
}
%设置笔记提示框
\newtcolorbox{notebox}[1][]
{
enhanced,
arc=2pt,%圆角
boxrule=.5pt,%边框
left=5pt, right=5pt, top=0pt, bottom=0pt,%文字边距
boxsep=5pt,
colframe=oucblue,
colback=oucblue10,
colbacktitle=oucblue10,
coltext=oucblue,
title={\textcolor{oucblue}{\faStickyNoteO\hspace{.5em}\bfseries{\textbf{#1}}}},
halign=left,
}
%设置重要提示框
\newtcolorbox{importantbox}[1][]
{
enhanced,
arc=2pt,
boxrule=.5pt,
left=5pt, right=5pt, top=0pt, bottom=0pt,
boxsep=5pt,
colframe=oucred,
colback=oucred10,
colbacktitle=oucred10,
coltext=oucred,
title={\textcolor{oucred}{\faExclamationCircle\hspace{.5em}\bfseries{\textbf{#1}}}},
halign=left,
}
%列表框
\newtcolorbox{vcolorbox}[2][]
{
boxrule=0.5pt,%边框,很细
arc=0pt,outer arc=0pt,%不要圆角
left=5pt, right=5pt, top=0pt, bottom=0pt,
leftrule=5pt, %左侧边框的宽度
colframe=#2,%边框的颜色
colback=white,
colbacktitle=white,
coltext=black,%内部文字的颜色,如果要和标题保持一致,可改为#2
title={\textcolor{#2}{\bfseries{\textbf{#1}}}},%标题样式
halign=left,
}
%要点框
\newtcolorbox{pointbox}[3][]
{
colback = white, %背景是白色
boxrule=0.5pt,%边框的粗细,细一点感觉更精致
colframe = #2, %边框颜色
fonttitle = \bfseries,%标题加粗
colbacktitle = #2, enhanced,
left=2pt, right=2pt, top=5pt, bottom=0pt,%内部文字边距
attach boxed title to top center={yshift=-2mm},
width=\textwidth,
height=#3,
title=#1
}
%% ======================================================================
%% 要点框自动排布:pointboxgrid
%% ----------------------------------------------------------------------
%% 把任意多个要点自动排成「每行最多 4 个」的网格:
%% \begin{pointboxgrid}{高度}
%% \pointitem{标题}{颜色}{内容}
%% ...
%% \end{pointboxgrid}
%%
%% 排布规则(行数尽可能少,并尽量均匀):
%% 1~4 个 → 一行
%% 5 个 → 上行 3 + 下行 2
%% 6 个 → 3 + 3
%% 7 个 → 4 + 3
%% 8 个 → 4 + 4
%% 9 个 → 3 + 3 + 3
%% 10 个 → 4 + 3 + 3
%% 11 个 → 4 + 4 + 3
%% 12 个 → 4 + 4 + 4
%% 一般地:行数 = ceil(N/4),前 N mod 行数 行每行多放 1 个。
%%
%% 说明:
%% - 高度参数与 pointbox 的 height 含义相同(固定高度,内容别超出)。
%% - 较多行时请自行减小高度,避免总高超出页面(建议行数 ≤ 4)。
%% - 「每行最多几个」由 \ouc_pbg_max 控制;间距由 \ouc_pbg_gap /
%% \ouc_pbg_vgap 控制,需要时在导言区改这两个长度。
%% ======================================================================
\ExplSyntaxOn
\int_new:N \l_ouc_pbg_cnt
\int_new:N \l_ouc_pbg_n
\int_new:N \l_ouc_pbg_rows
\int_new:N \l_ouc_pbg_base
\int_new:N \l_ouc_pbg_rem
\int_new:N \l_ouc_pbg_k
\int_new:N \l_ouc_pbg_km
\int_new:N \l_ouc_pbg_i
\int_new:N \l_ouc_pbg_max
\dim_new:N \l_ouc_pbg_est
\dim_new:N \l_ouc_pbg_colw
\dim_new:N \l_ouc_pbg_gap
\dim_new:N \l_ouc_pbg_vgap
\dim_new:N \l_ouc_pbg_h
\int_set:Nn \l_ouc_pbg_max { 4 }
\dim_new:N \l_ouc_pbg_avail
\dim_set:Nn \l_ouc_pbg_avail { 243pt }
\dim_set:Nn \l_ouc_pbg_gap { 8pt }
\dim_set:Nn \l_ouc_pbg_vgap { 6pt }
%% 收集一个要点:内容按原样存进带索引的宏,不做任何展开
\NewDocumentCommand \pointitem { m m m }
{
\int_incr:N \l_ouc_pbg_cnt
\tl_set:cn { l_ouc_pbg_t_ \int_use:N \l_ouc_pbg_cnt } {#1}
\tl_set:cn { l_ouc_pbg_c_ \int_use:N \l_ouc_pbg_cnt } {#2}
\tl_set:cn { l_ouc_pbg_b_ \int_use:N \l_ouc_pbg_cnt } {#3}
}
%% 画一个要点框:按序号直接取用存好的宏
\cs_new_protected:Npn \ouc_pbg_emit:n #1
{
\begin{pointbox}
[ \tl_use:c { l_ouc_pbg_t_#1 } ]
{ \tl_use:c { l_ouc_pbg_c_#1 } }
{ \dim_use:N \l_ouc_pbg_h }
\tl_use:c { l_ouc_pbg_b_#1 }
\end{pointbox}
}
%% 列宽 = (正文宽 - (k-1)*间距) / k
%% 注:某些 TeX Live 下 expl3 的维度乘法(*)会静默算出 0,
%% 因此走 fp_eval + dim_to_fp 的浮点路径,稳妥。
\cs_new_protected:Nn \ouc_pbg_setcolw:
{
\int_set:Nn \l_ouc_pbg_km { \int_use:N \l_ouc_pbg_k - 1 }
\dim_set:Nn \l_ouc_pbg_colw
{
\fp_eval:n
{
( \dim_to_fp:n { \textwidth }
- \int_use:N \l_ouc_pbg_km * \dim_to_fp:n { \l_ouc_pbg_gap } )
/ \int_use:N \l_ouc_pbg_k
}
pt
}
}
\cs_new_protected:Nn \ouc_pbg_typeset:
{
\int_set:Nn \l_ouc_pbg_n { \int_use:N \l_ouc_pbg_cnt }
\int_compare:nNnT { \int_use:N \l_ouc_pbg_n } > { 0 }
{
%% 行数 = ceil(N / max)
\int_set:Nn \l_ouc_pbg_rows
{
\int_div_truncate:nn
{ \int_use:N \l_ouc_pbg_n + \int_use:N \l_ouc_pbg_max - 1 }
{ \int_use:N \l_ouc_pbg_max }
}
%% 均匀分配:前 rem 行每行多 1 个(上行不少于下行)
\int_set:Nn \l_ouc_pbg_base
{
\int_div_truncate:nn
{ \int_use:N \l_ouc_pbg_n } { \int_use:N \l_ouc_pbg_rows }
}
\int_set:Nn \l_ouc_pbg_rem
{
\int_use:N \l_ouc_pbg_n
- \int_use:N \l_ouc_pbg_base * \int_use:N \l_ouc_pbg_rows
}
%% 预估总高度并与正文可用高度比较(公式按实测校准):
%% 总高 ≈ 69pt(首行含标题条) + 行数*高度 + (行数-1)*25pt(行间距)
\dim_set:Nn \l_ouc_pbg_est
{
\fp_eval:n
{
69
+ \int_use:N \l_ouc_pbg_rows * \dim_to_fp:n { \l_ouc_pbg_h }
+ ( \int_use:N \l_ouc_pbg_rows - 1 ) * 25
}
pt
}
\ifdim \l_ouc_pbg_est > \l_ouc_pbg_avail
\PackageWarning{oucslide}
{
要点框共 \int_use:N \l_ouc_pbg_n\space 个,排成
\int_use:N \l_ouc_pbg_rows\space 行、每框高 \dim_use:N \l_ouc_pbg_h,
预估总高 \dim_use:N \l_ouc_pbg_est\space 已超过正文可用高度
\dim_use:N \l_ouc_pbg_avail,可能超出页面底部。
请把高度改小(4 行时建议不超过 24pt)或减少要点个数
}
\fi
\int_zero:N \l_ouc_pbg_i
\int_step_inline:nn { \int_use:N \l_ouc_pbg_rows }
{
\int_set:Nn \l_ouc_pbg_k { \int_use:N \l_ouc_pbg_base }
%% 注意:此处的比较必须用 \ifnum。
%% expl3 的 \int_compare:nNnT 在这套 TeX Live 下判定有误,
%% 会把所有 ##1 都判成"小于等于",导致行内个数分配失效。
\ifnum ##1 > \int_use:N \l_ouc_pbg_rem \else
\int_incr:N \l_ouc_pbg_k
\fi
\ouc_pbg_setcolw:
%% 必须用 [onlytextwidth],否则默认 columns 会带来
%% 左/右边距,4 列时左右各溢出约 10pt。
\begin{columns}[onlytextwidth]
\int_step_inline:nn { \int_use:N \l_ouc_pbg_k }
{
\int_incr:N \l_ouc_pbg_i
\begin{column}{\dim_use:N \l_ouc_pbg_colw}
\ouc_pbg_emit:n { \int_use:N \l_ouc_pbg_i }
\end{column}
}
\end{columns}
\ifnum ##1 < \int_use:N \l_ouc_pbg_rows
\vspace{\dim_use:N \l_ouc_pbg_vgap}
\fi
}
}
}
%% 友好设置:\pointboxsetup{每行最多几个}{横向间距}{纵向间距}
%% 例如 \pointboxsetup{5}{6pt}{4pt}
\NewDocumentCommand \pointboxsetup { m m m }
{
\int_set:Nn \l_ouc_pbg_max {#1}
\dim_set:Nn \l_ouc_pbg_gap {#2}
\dim_set:Nn \l_ouc_pbg_vgap {#3}
}
\NewDocumentEnvironment { pointboxgrid } { m }
{ \int_zero:N \l_ouc_pbg_cnt \dim_set:Nn \l_ouc_pbg_h {#1} }
{ \ouc_pbg_typeset: }
\ExplSyntaxOff
%文本框textbox
\newtcolorbox{textbox}[1]{
colback=#1!5!white,
colframe=#1,
boxrule=0.5pt,
arc=2pt,
}
%标题框headbox
\newtcolorbox{headbox}[1]{
colback=#1,
colframe=#1,
boxrule=0.5pt,
arc=2pt,
coltext=white,
fontupper= \bfseries,
left=0pt, right=0pt, top=0pt, bottom=0pt,%内部文字边距
}
%一些元素的中文名称
\renewcommand{\figurename}{图}
\renewcommand{\tablename}{表}
\renewcommand{\lstlistingname}{代码}
\renewcommand{\abstractname}{摘要}