Files
ouc_latex_template/教材/ouctextbook.sty
T

225 lines
10 KiB
TeX
Raw Normal View History

%======================================================================
% ouctextbook.sty —— 中国海洋大学 教材 版式包
%
% 从《软件需求工程导论》(sre 仓库) 的版式抽取而来,
% 底层是 elegantbook 文档类,保留其全部排版特性。
%
% 编译: xelatex 教材.tex (单次即可;有参考文献时 xelatex→bibtex→xelatex×2)
%
% ------------------------------------------------------------------
% ⚠️⚠️ 本模板与其他模板最大的不同:它是**文档类**不是宏包
%
% elegantbook 是 \documentclass 级别的类,不能 \usepackage。
% 所以本文件只提供**配置命令**,正文首行必须自己写
% \documentclass[...]{elegantbook},再 \usepackage{ouctextbook}。
%
% 顺序不能反:\documentclass 必须第一行。
% ------------------------------------------------------------------
%======================================================================
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ouctextbook}[2026/11/01 v1.0 OUC textbook style]
%======================================================================
% 一、公共字体(本模板的核心约束)
%
% ⚠️⚠️ 为什么必须在 \documentclass 里写 chinesefont=nofont
%
% elegantbook 的 chinesefont 只有三档,全都不通用:
%
% founder(默认) 方正四大字体 FZShuSong-Z01 / FZHei-B01 /
% FZKai-Z03 / FZFangSong-Z02
% ⇒ **商业字体,不能随仓库分发**,换机器就废
% ctexfont ctex 按**系统**字体配(Windows=SimSun/SimHei,
% macOS=PingFang,Linux 视装了什么而定)
% ⇒ 同一份源码在三个平台排出三种样子
% nofont 不设字体,完全交给用户
% ⇒ 不额外配置就直接报错
%
% ⇒ 本模板用 nofont,然后在正文 \input{../fonts.tex} 接入仓库字体。
%
% ⚠️⚠️ 但只写 nofont 还不够 —— elegantbook.cls 自身还硬编码了两处字体:
%
% \setmainfont{TeXGyreTermesX}[...] % 西文衬线
% \setsansfont{texgyreheros}[...] % 西文无衬线
%
% 这两款在精简版 TeX Live 和很多机器上**都没有**,会直接报
% ! Package fontspec Error: The font "texgyreheros-regular"
% cannot be found
% 而且是 9 个错误连发,因为在类的每个字体档位上都会失败。
%
% 实测:在 \documentclass 之后用 \setsansfont 覆盖**无效** ——
% 类加载时该字体族已经注册失败,后面的重新指定救不回来。
%
% ⇒ 唯一可靠的做法是**本地化 cls 本身**:模板目录里带一份
% elegantbook.cls 副本,把那两处改成仓库字体:
% \setmainfont{texgyretermes}[Path=../fonts/tex-gyre-termes/]
% \setsansfont{OUCSans}[Path=../fonts/ouc-sans/]
% 改动处有 "本地化" 注释,便于将来对比上游版本。
%
% ⇒ 这也是本模板与仓库其他模板的**唯一结构性差异**:
% 别的模板只需要 \input{../fonts.tex},
% 本模板还需要那份改过字体的 cls 副本。
%
% ⚠️ fonts.tex 已用 \def 定义 \songti / \heiti / \kaiti / \fangsong,
% elegantbook 内部依赖 \heiti(用于 \cbfseries、章节标题),
% 所以这层依赖是通的。若哪天 fonts.tex 改了这几个命令的名字,
% 本模板的章节标题会立刻失去中文字体。
%======================================================================
\RequirePackage{etoolbox}
% 检查是否已加载 elegantbook 且用了 nofont。
% 若用户忘了写 nofont,给出明确提示而不是让方正字体报一堆乱码错误。
\AtBeginDocument{%
\ifcsname ELEGANT@chinesefont\endcsname
\ifdefstring{\ELEGANT@chinesefont}{nofont}{}{%
\PackageWarning{ouctextbook}{%
检测到 chinesefont 不是 nofont。请把文档类选项改为
\string\documentclass[lang=cn,newtx,10pt,black,chinesefont=nofont]{elegantbook}%
\MessageBreak
否则会加载方正商业字体或系统字体,失去跨平台一致性}%
}%
\fi
}
%======================================================================
% 二、标题编号层级
%
% 原教材主文件里的自定义,很有用,保留:
% 编号最多到第 4 级 章(1) → 节(1.1) → 小节(1.1.1) → 小小节(1.1.1.1)
% 第 5 级(\paragraph)不再进编号体系,改用「(1)(2)(3)」形式,
% 避免出现 3.1.1.1.1 这种过长编号。
%
% ⚠️ 这段必须在 \begin{document} 之前执行,用 \AtBeginDocument 会太晚
% (编号层级在导言区就被读取)。
%======================================================================
\setcounter{secnumdepth}{3}
\setcounter{tocdepth}{3}
\makeatletter
\newcounter{paranum}[subsubsection] % 随小小节自动重置
\renewcommand\paragraph[1]{%
\par\addvspace{0.9ex}%
\stepcounter{paranum}%
\noindent{\bfseries (\arabic{paranum})\,#1}%
\par\nobreak\addvspace{0.1ex}%
\@afterindentfalse\@afterheading}
\makeatother
%======================================================================
% 三、封面色带
%
% 原教材用青绿色 RGB(32,178,170),比 elegantbook 默认的蓝色沉稳,
% 与清华社的封面观感接近。保留。
%
% ⚠️⚠️ 必须在 \begin{document} 之后才能改 coverlinecolor
%
% elegantbook.cls 第 345 行有
% \colorlet{coverlinecolor}{second}
% 这行在**类加载末尾**执行,把 coverlinecolor 绑到 "second" 色上
% (color=black 选项下 second 就是黑色)。
%
% ⇒ 在导言区写 \colorlet{coverlinecolor}{...} 会被它覆盖,
% 实测封面色带仍是纯黑,改了半天没反应。
% 必须用 \AtBeginDocument 排到它后面。
%======================================================================
\definecolor{ouccoverlinecolor}{RGB}{32,178,170}
\AtBeginDocument{%
\colorlet{coverlinecolor}{ouccoverlinecolor}%
}
% 需要临时换别的色时,在正文里调这个(不调则用上面的青绿)
\newcommand{\oucSetCoverColor}[1]{%
\colorlet{coverlinecolor}{#1}%
}
%======================================================================
% 四、图形与表格
%
% 原教材用到的宏包,逐个说明为什么需要:
% array \makecell(表格内换行)
% cprotect \verb 等脆弱命令进表格/标题
% graphicx 插图
% float [H] 强制定位(教材排版要求图跟文字,不能漂走)
% longtable 跨页表格
%======================================================================
\RequirePackage{array}
\RequirePackage{cprotect}
\RequirePackage{graphicx}
\RequirePackage{float}
\RequirePackage{longtable}
% TikZ 绘图库(原教材的流程图/关系图用这些)
\RequirePackage{tikz}
\usetikzlibrary{
shapes.geometric, shapes.misc,
arrows.meta, arrows,
decorations.pathreplacing, decorations.markings,
positioning, calc, fit, backgrounds
}
%======================================================================
% 五、断行宽容度
%
% ⚠️ 教材正文长、中文多、行内夹英文术语和公式,默认 \tolerance
% 会产生大量 Overfull(原教材明确加过这一条)。
% 2em 是原教材实测的值,既消掉大部分告警,又不会排出稀疏的行。
%======================================================================
\setlength{\emergencystretch}{2em}
%======================================================================
% 六、常用排版命令
%======================================================================
% 表格里的色块占位(原教材 \ccr 的用途:图例色块)
\newcommand{\ouccolorcell}[1]{%
\makecell{{\color{#1}\rule{1cm}{1cm}}}}
%======================================================================
% 七、章节末的标准小节
%
% 原教材每章固定以「本章小结」+「习题」收尾。
% 做成命令,避免各章写法不一致。
%======================================================================
\newcommand{\oucsummary}{\section{本章小结}}
\newcommand{\oucexercises}{\section{习题}}
%======================================================================
% 八、封面:无封面图时不插 example-image
%
% ⚠️⚠️ elegantbook 在没写 \cover{} 时会插入 mwe 宏包的 example-image,
% 也就是**一张印着 "Image" 字样的灰底占位图**,铺满首页。
% 源码(cls 第 1288~1300 行):
% \ifcsname @cover\endcsname
% \includegraphics[width=\linewidth]{\@cover}
% \else
% \includegraphics[width=\linewidth]{example-image} ← 就是这个
% \fi
% 交付给别人的模板首页顶着 "Image" 两个大字,不合适。
%
% ⇒ 解法在 cls 里,不在本文件:本地化版本的 elegantbook.cls 已把
% 那两处 example-image 换成了 \ouc@coverblank(一个占位盒子)。
% 这样不写 \cover{} 时封面只有色带和文字,没有占位图。
%
% ⚠️⚠️ 占位盒的宽度**不能是 0**。
%
% 第一版写成 \rule{0pt}{0pt}(0 宽),立刻冒出
% Overfull \hbox (5.00002pt too wide) in paragraph at lines 44--44
% 而且它只出现在 \maketitle 那一行,改 \hspace{2em}、\hspace{2.5em}、
% minipage 的 0.67/0.27\linewidth、tabular 的列间距,**全部无效**,
% 溢出量死钉在 5.00002pt 不动。
%
% 根因:0 宽空盒让 \linewidth 在 titlepage 里的计算与 \textwidth
% 差了 5pt,后续并排的 \parbox{0.8\textwidth} + 两个 minipage
% 就整体超宽。
%
% ✅ 正解:给占位盒一个满宽
% \newcommand{\ouc@coverblank}{%
% \rule{0pt}{0pt}\hspace{\linewidth}\rule{0pt}{0pt}}
% 实测 0 Overfull。
%
% ⚠️ 不要试图在本文件里用 \ifcsname 覆盖 \@cover 来绕开 —— 实测
% \@cover 即使定义成空串也会走 \includegraphics{} 分支报错。
% 改 cls 是唯一干净的办法。
%======================================================================
\endinput