%====================================================================== % 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