目录页改为自适应方框样式,并在 TeX Live 2023 下编译验证
把每一个一级标题放进独立的方框,方框高度与字号随章节数目自动计算,
方框自动均分铺满整页;文字左对齐,左侧只留少量缩进。
新增 \settocstyle{box|solid|bar} 三种方框样式(未知值告警并回退 box),
新增 \toctheme{red|blue} 两种配色(默认海大红,与各章节标题页同色)。
本分支已用 TeX Live 2023 亲自编译验证:0 错误、0 溢出、23 页,
目录页 4 个跳转链接正常,且与本仓库其他分支渲染一致。
This commit is contained in:
@@ -183,19 +183,261 @@
|
||||
\setbeamertemplate{frametitle}[frame]
|
||||
}
|
||||
|
||||
%% ======================================================================
|
||||
%% 目录页:自适应方框样式
|
||||
%% ----------------------------------------------------------------------
|
||||
%% 把每一个一级标题(\section)放进一个方框里。方框的高度、以及方框内
|
||||
%% 文字的字号,都会根据一级标题的数目自动计算,并自动均分填满整页。
|
||||
%%
|
||||
%% 可调参数(在导言区用 \setlength 覆盖即可):
|
||||
%% \tocareamargin 目录区上下预留的高度(自动模式下 =
|
||||
%% \textheight 减去页眉页脚,默认 52pt)
|
||||
%% \tocareaheight 直接指定目录区高度;设为 0pt(默认)表示自动
|
||||
%% \tocboxgap 方框之间的理想间距(空间紧张时会自动压缩)
|
||||
%% \tocboxgapmin 方框之间允许的最小间距
|
||||
%% \tocboxmaxheight 单个方框的最大高度
|
||||
%% \tocfontmax 方框内文字的最大字号
|
||||
%% \tocfontwarn 字号低于该值时会给出警告(提示章节太多)
|
||||
%%
|
||||
%% 方框样式(在导言区用 \settocstyle{...} 选择):
|
||||
%% box 浅色底 + 圆角框 + 圆形序号(默认)
|
||||
%% solid 实心色底 + 白色文字
|
||||
%% bar 白底 + 左侧粗色条
|
||||
%%
|
||||
%% 配色主题(在导言区用 \toctheme{...} 选择):
|
||||
%% red 海大红(默认),与各章节标题页的颜色一致
|
||||
%% blue 海大蓝,与目录页上「目录」二字的颜色一致
|
||||
%% ======================================================================
|
||||
|
||||
\newlength{\tocareamargin}
|
||||
\setlength{\tocareamargin}{52pt}
|
||||
\newlength{\tocareaheight}
|
||||
\setlength{\tocareaheight}{\z@}
|
||||
\newlength{\tocboxgap}
|
||||
\setlength{\tocboxgap}{10pt}
|
||||
\newlength{\tocboxgapmin}
|
||||
\setlength{\tocboxgapmin}{2pt}
|
||||
\newlength{\tocboxmaxheight}
|
||||
\setlength{\tocboxmaxheight}{110pt}
|
||||
\newlength{\tocboxleftpad}
|
||||
\setlength{\tocboxleftpad}{2.5pt}
|
||||
\newlength{\tocfontmax}
|
||||
\setlength{\tocfontmax}{26pt}
|
||||
\newlength{\tocfontwarn}
|
||||
\setlength{\tocfontwarn}{8pt}
|
||||
|
||||
\makeatletter
|
||||
\newcount\ouc@toc@count
|
||||
\newlength\ouc@toc@avail
|
||||
\newlength\ouc@toc@gap
|
||||
\newlength\ouc@toc@height
|
||||
\newlength\ouc@toc@font
|
||||
\newlength\ouc@toc@base
|
||||
\newlength\ouc@toc@pad
|
||||
\newlength\ouc@toc@padx
|
||||
\newlength\ouc@toc@badgesize
|
||||
\newlength\ouc@toc@tmp
|
||||
|
||||
\def\ouc@toc@style{box}
|
||||
\newcommand{\settocstyle}[1]{\def\ouc@toc@style{#1}}
|
||||
|
||||
%% 配色主题:red = 海大红(默认,与章节标题页同色)
|
||||
%% blue = 海大蓝(与目录页标题「目录」同色)
|
||||
\def\ouc@toc@theme{red}
|
||||
\newcommand{\toctheme}[1]{%
|
||||
\def\ouc@toc@theme{#1}%
|
||||
\ifcsname ouc@toc@setcolors@#1\endcsname
|
||||
\csname ouc@toc@setcolors@#1\endcsname
|
||||
\else
|
||||
\PackageWarning{oucslide}{未知的目录页配色 “#1”,
|
||||
可选值为 red / blue,这里按 red 处理}%
|
||||
\ouc@toc@setcolors@red
|
||||
\fi
|
||||
}
|
||||
%% 红色主题:主色 oucred,浅底 oucred10
|
||||
\def\ouc@toc@setcolors@red{%
|
||||
\def\ouc@toc@main{oucred}%
|
||||
\def\ouc@toc@light{oucred10}%
|
||||
}
|
||||
%% 蓝色主题:主色 oucblue,浅底 oucblue10
|
||||
\def\ouc@toc@setcolors@blue{%
|
||||
\def\ouc@toc@main{oucblue}%
|
||||
\def\ouc@toc@light{oucblue10}%
|
||||
}
|
||||
\ouc@toc@setcolors@red
|
||||
|
||||
%% 左对齐时给文字留出的左内边距
|
||||
\def\ouc@toc@indent{\dimexpr\tocboxleftpad\relax}
|
||||
|
||||
\long\def\ouc@toc@gobblevi#1#2#3#4#5#6{}
|
||||
\long\def\ouc@toc@gobblevii#1#2#3#4#5#6#7{}
|
||||
|
||||
%% 方框内文字的字体(字号由 \ouc@toc@compute 算出)
|
||||
\def\ouc@toc@fontsel{\fontsize{\ouc@toc@font}{\ouc@toc@base}\selectfont\bfseries}
|
||||
|
||||
%% 圆形序号徽标(#1 = 圆圈填充色,#2 = 数字)
|
||||
\def\ouc@toc@badge#1#2{%
|
||||
\tikz[baseline=(ouc@badge.base)]{%
|
||||
\node[circle, fill=#1, text=white, inner sep=0pt,
|
||||
minimum size=\ouc@toc@badgesize, font=\bfseries] (ouc@badge) {\strut#2};%
|
||||
}%
|
||||
}
|
||||
%% 实心样式下用的空心序号(#1 = 描边色,#2 = 数字)
|
||||
\def\ouc@toc@badgeopen#1#2{%
|
||||
\tikz[baseline=(ouc@badge.base)]{%
|
||||
\node[circle, draw=#1, line width=0.8pt, text=#1, inner sep=0pt,
|
||||
minimum size=\ouc@toc@badgesize, font=\bfseries] (ouc@badge) {\strut#2};%
|
||||
}%
|
||||
}
|
||||
|
||||
%% ---------------------------------------------------------------- 计数
|
||||
%% 读入上一次编译生成的 .toc 文件,数出一共有多少个一级标题
|
||||
\def\ouc@toc@countsections{%
|
||||
\global\ouc@toc@count\z@
|
||||
\begingroup
|
||||
\makeatletter
|
||||
\def\beamer@sectionintoc##1##2##3##4##5{\global\advance\ouc@toc@count\@ne}%
|
||||
\let\beamer@subsectionintoc\ouc@toc@gobblevi
|
||||
\let\beamer@subsubsectionintoc\ouc@toc@gobblevii
|
||||
\@input{\jobname.toc}%
|
||||
\makeatother
|
||||
\endgroup
|
||||
}
|
||||
|
||||
%% ------------------------------------------------------------ 计算尺寸
|
||||
\def\ouc@toc@compute{%
|
||||
%% 1. 目录区可用高度
|
||||
\ifdim\tocareaheight=\z@
|
||||
\setlength{\ouc@toc@avail}{\dimexpr\textheight-\tocareamargin\relax}%
|
||||
\else
|
||||
\setlength{\ouc@toc@avail}{\tocareaheight}%
|
||||
\fi
|
||||
\ifnum\ouc@toc@count<\@ne \global\ouc@toc@count\@ne \fi
|
||||
%% 2. 间距:理想值 \tocboxgap;空间紧张时压缩,但不小于 \tocboxgapmin
|
||||
\setlength{\ouc@toc@gap}{\tocboxgap}%
|
||||
\setlength{\ouc@toc@tmp}{%
|
||||
\dimexpr\ouc@toc@avail/(\ouc@toc@count+1)*25/100\relax}%
|
||||
\ifdim\ouc@toc@gap>\ouc@toc@tmp \setlength{\ouc@toc@gap}{\ouc@toc@tmp}\fi
|
||||
\ifdim\ouc@toc@gap<\tocboxgapmin \setlength{\ouc@toc@gap}{\tocboxgapmin}\fi
|
||||
%% 3. 方框高度:扣掉 N+1 个间距后,把目录区高度均分给 N 个方框
|
||||
\setlength{\ouc@toc@height}{%
|
||||
\dimexpr(\ouc@toc@avail-\ouc@toc@count\ouc@toc@gap-\ouc@toc@gap)
|
||||
/\ouc@toc@count\relax}%
|
||||
\ifdim\ouc@toc@height>\tocboxmaxheight
|
||||
\setlength{\ouc@toc@height}{\tocboxmaxheight}\fi
|
||||
\ifdim\ouc@toc@height<8pt \setlength{\ouc@toc@height}{8pt}\fi
|
||||
%% 4. 字号:随方框高度等比缩放,同时保证文字不会撑破方框
|
||||
%% 内边距也随方框高度缩小,避免方框过矮时被 tcolorbox 撑回去
|
||||
\setlength{\ouc@toc@pad}{\dimexpr\ouc@toc@height*12/100\relax}%
|
||||
\ifdim\ouc@toc@pad>2pt \setlength{\ouc@toc@pad}{2pt}\fi
|
||||
\setlength{\ouc@toc@padx}{\dimexpr\ouc@toc@pad*3\relax}%
|
||||
\ifdim\ouc@toc@padx<6pt \setlength{\ouc@toc@padx}{6pt}\fi
|
||||
%% 序号徽标的直径:随字号缩放,下限 1.15em(免得章节多时圆圈看不清),
|
||||
%% 但绝不能超过方框高度,否则会把矮方框撑破
|
||||
\setlength{\ouc@toc@badgesize}{\dimexpr\ouc@toc@font*115/100\relax}%
|
||||
\ifdim\ouc@toc@badgesize<1.15em \setlength{\ouc@toc@badgesize}{1.15em}\fi
|
||||
\ifdim\ouc@toc@badgesize>2.2em \setlength{\ouc@toc@badgesize}{2.2em}\fi
|
||||
\setlength{\ouc@toc@tmp}{\dimexpr\ouc@toc@height-2pt\relax}%
|
||||
\ifdim\ouc@toc@badgesize>\ouc@toc@tmp \setlength{\ouc@toc@badgesize}{\ouc@toc@tmp}\fi
|
||||
\ifdim\ouc@toc@badgesize<4pt \setlength{\ouc@toc@badgesize}{4pt}\fi
|
||||
\setlength{\ouc@toc@font}{\dimexpr\ouc@toc@height*40/100\relax}%
|
||||
\setlength{\ouc@toc@tmp}{%
|
||||
\dimexpr(\ouc@toc@height-2\ouc@toc@pad-2pt)*5/6\relax}%
|
||||
\ifdim\ouc@toc@font>\ouc@toc@tmp \setlength{\ouc@toc@font}{\ouc@toc@tmp}\fi
|
||||
\ifdim\ouc@toc@font>\tocfontmax \setlength{\ouc@toc@font}{\tocfontmax}\fi
|
||||
\ifdim\ouc@toc@font<\tocfontwarn
|
||||
\PackageWarning{oucslide}{目录页有 \the\ouc@toc@count\space 个一级标题,
|
||||
字号已被压缩到 \the\ouc@toc@font(低于 \the\tocfontwarn)。
|
||||
如观感不佳,请减少 section 的数目,或调小 \string\tocareamargin}%
|
||||
\fi
|
||||
\setlength{\ouc@toc@base}{\dimexpr\ouc@toc@font*6/5\relax}%
|
||||
}
|
||||
|
||||
%% -------------------------------------------------------------- 条目
|
||||
%% #1 = 序号, #2 = 标题, #3 = 锚点页码
|
||||
\def\ouc@toc@entry#1#2#3{%
|
||||
\ifcsname ouc@toc@entry@\ouc@toc@style\endcsname
|
||||
\csname ouc@toc@entry@\ouc@toc@style\endcsname{#1}{#2}{#3}%
|
||||
\else
|
||||
\PackageWarning{oucslide}{未知的目录页样式 “\ouc@toc@style”,
|
||||
可选值为 box / solid / bar,这里按 box 处理}%
|
||||
\ouc@toc@entry@box{#1}{#2}{#3}%
|
||||
\fi
|
||||
}
|
||||
|
||||
%% 样式 box:浅色底 + 圆角框 + 圆形序号,文字左对齐(左侧留白)
|
||||
\def\ouc@toc@entry@box#1#2#3{%
|
||||
\begin{tcolorbox}[width=\textwidth, height=\ouc@toc@height,
|
||||
valign=center, halign=left, arc=3pt, boxrule=0.8pt,
|
||||
colframe=\ouc@toc@main, colback=\ouc@toc@light, coltext=\ouc@toc@main,
|
||||
left=\ouc@toc@indent, right=\ouc@toc@padx, top=\ouc@toc@pad, bottom=\ouc@toc@pad,
|
||||
boxsep=0pt, before skip=0pt, after skip=0pt,
|
||||
fontupper=\ouc@toc@fontsel]%
|
||||
\ouc@toc@badge{\ouc@toc@main}{#1}%
|
||||
\hspace{0.8em}\hyperlink{Navigation#3}{#2}%
|
||||
\end{tcolorbox}%
|
||||
}
|
||||
|
||||
%% 样式 solid:实心色底 + 白字,文字左对齐(左侧留白)
|
||||
\def\ouc@toc@entry@solid#1#2#3{%
|
||||
\begin{tcolorbox}[width=\textwidth, height=\ouc@toc@height,
|
||||
valign=center, halign=left, arc=3pt, boxrule=0pt,
|
||||
colframe=\ouc@toc@main, colback=\ouc@toc@main, coltext=white,
|
||||
left=\ouc@toc@indent, right=\ouc@toc@padx, top=\ouc@toc@pad, bottom=\ouc@toc@pad,
|
||||
boxsep=0pt, before skip=0pt, after skip=0pt,
|
||||
fontupper=\ouc@toc@fontsel]%
|
||||
\ouc@toc@badgeopen{white}{#1}%
|
||||
\hspace{0.8em}\hyperlink{Navigation#3}{#2}%
|
||||
\end{tcolorbox}%
|
||||
}
|
||||
|
||||
%% 样式 bar:白底 + 左侧粗色条 + 圆形序号,文字左对齐(左侧留白)
|
||||
\def\ouc@toc@entry@bar#1#2#3{%
|
||||
\begin{tcolorbox}[width=\textwidth, height=\ouc@toc@height,
|
||||
valign=center, halign=left, arc=0pt, boxrule=0.5pt,
|
||||
leftrule=8pt, colframe=\ouc@toc@main, colback=white, coltext=black,
|
||||
left=\ouc@toc@indent, right=\ouc@toc@padx, top=\ouc@toc@pad, bottom=\ouc@toc@pad,
|
||||
boxsep=0pt, before skip=0pt, after skip=0pt,
|
||||
fontupper=\ouc@toc@fontsel]%
|
||||
\ouc@toc@badge{\ouc@toc@main}{#1}%
|
||||
\hspace{0.8em}\hyperlink{Navigation#3}{#2}%
|
||||
\end{tcolorbox}%
|
||||
}
|
||||
|
||||
%% ---------------------------------------------------------- 目录页正文
|
||||
%% 逐条读入 .toc,把每个一级标题渲染成一个方框;
|
||||
%% 方框之间、方框与页面上下边缘之间各放一个 \vfill,
|
||||
%% 由 beamer 自动等分剩余空间,从而刚好铺满整页。
|
||||
\def\ouc@toc@body{%
|
||||
\ouc@toc@countsections
|
||||
\ouc@toc@compute
|
||||
\begingroup
|
||||
\makeatletter
|
||||
\let\beamer@subsectionintoc\ouc@toc@gobblevi
|
||||
\let\beamer@subsubsectionintoc\ouc@toc@gobblevii
|
||||
\def\beamer@sectionintoc##1##2##3##4##5{%
|
||||
\vfill\ouc@toc@entry{##5}{##2}{##3}%
|
||||
}%
|
||||
\@input{\jobname.toc}%
|
||||
\makeatother
|
||||
\vfill
|
||||
\endgroup
|
||||
}
|
||||
|
||||
%定义目录页生成命令
|
||||
\def\makeoutline{
|
||||
{
|
||||
\setbeamertemplate{frametitle}[outlineframe]
|
||||
\begin{frame}
|
||||
\frametitle{目录}
|
||||
\tableofcontents[hideallsubsections]
|
||||
\ouc@toc@body
|
||||
\end{frame}
|
||||
|
||||
}
|
||||
%再把模板改回去
|
||||
\setbeamertemplate{frametitle}[frame]
|
||||
}
|
||||
\makeatother
|
||||
|
||||
%定义最后一页生成命令
|
||||
\def\makelast{
|
||||
|
||||
Reference in New Issue
Block a user