Files
laoyang 3906bb49a4 清理代码库中的开发过程内容
- 删除 WORKFLOW.md(开发流程文档,已移入记忆库)
- build.sh 去掉 WSL 相关说明
- 33 个源文件的注释:去掉踩坑记录、实测推导、原文件对比、工单号引用
- 保留技术参数、约束说明、命令含义

净删 399 行。全库 16/16 编译通过。
2026-11-01 09:29:00 +08:00

352 lines
17 KiB
TeX
Raw Permalink 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.
%======================================================================
% oucal.sty —— 中国海洋大学 课程教学日历(理论课程)版式包
%
% 依据:学校下发的《附件3:中国海洋大学课程教学日历(理论课程)》.doc
%
% 这是**学校下发的通用空白表**,与课程无关。本包只复刻版式,
% 不携带任何具体课程的数据。
%
% 所有尺寸都由 Word 内部数值换算:
% pt → mm : mm = pt / 72 * 25.4
% twips → mm : mm = twips / 1440 * 25.4
% w:sz : 半磅值,÷ 2 即 pt
%
% 用法见同目录 课程教学日历.tex,说明见 README.md
%======================================================================
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{oucal}[2026/10/27 v1.0 OUC course teaching calendar]
\RequirePackage{geometry}
\RequirePackage{fontspec}
\RequirePackage{xeCJK}
\RequirePackage{tabularray}
%======================================================================
% 1. 页面与版心
%
% sectPr:
% pgSz w:w=11906 h:h=16838 → A4(210.01 × 297.00 mm)
% pgMar top/bottom = 1440 twips = 25.40 mm
% left/right = 1800 twips = 31.75 mm
% header 851 / footer 992 twips
%
% 表格参数(注意这两条,是本文档最关键的两个数):
% tblW 9900 twips = 174.625 mm ← 表宽
% tblInd −792 twips = −13.97 mm ← **负缩进**,表格比版心更靠左
%
% 版心宽 = 210 − 2×31.75 = 146.50 mm,而表宽 174.625 mm,
% 表格比版心宽 28.125 mm。加上 tblInd 为负,表格实际位置是:
%
% 表格左边界 = 31.75 + (−13.97) − cellMar(1.905) = 15.875 mm
% 表格右边界 = 15.875 + 174.625 = 190.50 mm
%
% PDF 8 条竖线的 x 正是 15.875 / 31.75 / 57.309 / … / 190.5 mm,
% 与上式一致(见 README)。
%
% ⚠️ 但按 left=15.875mm 排出来,竖线在 15.963mm,整体右偏 0.088mm。
% 这是 tabularray 把左竖线画在"版心左边界 + 半线宽"处的取整结果。
% 故 left 取 15.875 − 0.088 = 15.787mm,竖线回到 15.875mm。
%
% ⇒ 本包处理(与前两个归档模板同一套办法):
% 把版心直接设成表格的可见范围 15.875 ~ 190.50 mm,
% 即 left = 15.875mm、totalwidth = 174.625mm。
% 这样表格与版心同宽、居中摆放,编译不刷 Overfull \hbox,
% 且表格在纸面上的绝对位置与完全一致。
%
% 表格【外】的内容(标题、课程信息、签字栏)原本是相对 31.75mm
% 的版心排的,故用 §7 的 \caloutside 把它们放回原位:
% \leftskip = 31.75 − 15.875 = 15.875 mm
% \rightskip = 190.50 − 178.25 = 12.25 mm
% ⇒ 行宽 = 174.625 − 15.875 − 12.25 = 146.50 mm(正是原版心宽)
%======================================================================
\geometry{
paperwidth = 210mm,
paperheight = 297mm,
left = 15.787mm, % = 表格左边界 15.875 − 取整补偿 0.088(见下)
totalwidth = 174.80mm, % = 表宽 + tabularray 取整余量(见 §4)
top = 25.40mm,
bottom = 25.40mm,
headheight = 0pt,
headsep = 0pt,
footskip = 17.50mm,
}
\setlength{\parindent}{0pt}
\setlength{\parskip}{0pt}
\pagestyle{empty} % 无页眉页脚,故不排页码
%======================================================================
% 2. 字体
%
% :全文中文「宋体」,西文/数字 Times New Roman
% (docDefaults: ascii=Times New Roman, eastAsia=宋体)
% 换成 OUC Serif(思源宋体 SC 子集,OFL 1.1)与 TeX Gyre Termes
% (Times 的度量兼容替代,字宽逐字相同)。
%======================================================================
\input{../fonts.tex}
%----------------------------------------------------------------------
% ⚠️⚠️⚠️【必须关掉 xeCJK 的全角标点压缩】
%
% 本表内容大量用全角标点(,、。:()),落在**居中**的单元格里。
% xeCJK 默认 PunctStyle=quanjiao 会对全角标点做字宽挤压,
% 省下的空间记在行内盒子起点,导致整行相对盒子偏移 —— 居中的格子
%
% Word 不做这个挤压,关掉反而与原件一致。
%----------------------------------------------------------------------
\xeCJKsetup{PunctStyle=plain}
%======================================================================
% 3. 字号与行距
%
% 各档字号(w:sz 是半磅):
% 「附件3:」行 28/2 = 14pt 粗
% 标题 28/2 = 14pt 粗
% 「学年 学期」行 24/2 = 12pt 粗
% 课程信息两行 Normal 样式 sz=21 ⇒ 21/2 = 10.5pt
% 表格正文 同上 10.5pt
% 签字栏 10.5pt
%
% 行距(表格外两行信息段落):w:line=460 lineRule=exact
% ⇒ 460 twips = 460/20 = 23.00 pt 固定行距
% 表格内未单独设 spacing,Word 按同一 docGrid 排,行距也是 23.00pt。
%
% ⚠️ 所有字号必须用 bp,不能用默认 pt:Word 的 pt 是 PostScript point
% (1/72 英寸),TeX 默认 pt 是 TeX point(1/72.27 英寸),大 0.36%。
% 写 10.5 会排出 10.45(= 10.5 × 72/72.27),。
%======================================================================
\newcommand{\cal@ls}{\linespread{1}\relax}
\newcommand{\calfontA}{\cal@ls\fontsize{14bp}{23bp}\selectfont} % 附件号/标题
\newcommand{\calfontB}{\cal@ls\fontsize{12bp}{23bp}\selectfont} % 学年学期
\newcommand{\calfontC}{\cal@ls\fontsize{10.5bp}{23bp}\selectfont} % 正文/表格
%======================================================================
% 4. 列的宽度模型
%
% tblGrid 七列(twips → mm):
% c1 周次 900 = 15.8750 mm
% c2 日期 1449 = 25.5587 mm
% c3 学时 1029 = 18.1504 mm
% c4 教学内容 2669 = 47.0782 mm
% c5 教学方式 1366 = 24.0947 mm
% c6 课堂讨论… 1224 = 21.5900 mm
% c7 课下作业… 1263 = 22.2779 mm
% ─────────────────────────────
% 合计 9900 twips = 174.6250 mm
%
% cellMar:left/right = 108 twips = 1.9050 mm,top/bottom = 0
% 边框 :w:sz = 4 ⇒ 0.5 pt = 0.1764 mm
%
% ⚠️⚠️ 列宽 = gridCol − 2×colsep − 线宽,不是"按竖线根数分摊"。
% tabularray 把边框线宽算进列宽里(相邻竖线中心距 = wd + 2×colsep
% + 线宽)。按分摊算每列会窄 0.154mm,整表窄 0.47mm —— 这在
% 试卷归档目录/ 里实际验证过,本包直接沿用正确式。
%
% c1: 15.8750 − 3.8100 − 0.1764 = 11.8886 mm
% c2: 25.5587 − 3.8100 − 0.1764 = 21.5723 mm
% c3: 18.1504 − 3.8100 − 0.1764 = 14.1640 mm
% c4: 47.0782 − 3.8100 − 0.1764 = 43.0918 mm
% c5: 24.0947 − 3.8100 − 0.1764 = 20.1083 mm
% c6: 21.5900 − 3.8100 − 0.1764 = 17.6036 mm
% c7: 22.2779 − 3.8100 − 0.1764 = 18.2915 mm
% ───────────────────────────────────────
% Σwd = 146.7201 mm
% + 7×2×1.9050 = 26.6700(内边距)
% + 8×0.1764 = 1.4112(8 条竖线)
% ───────────────────────────────────────
% = 174.8013 mm
%
% ⇒ totalwidth 取 174.80mm(§1 已设)。若取 174.625 会报
% "Table width is too small",因为 tabularray 的盒子还要多占
% 约 0.4945pt(左竖线画在边界内侧、右竖线外缘又占半个线宽)。
%======================================================================
\newcommand{\calrule}{0.5pt} % 边框粗细(w:sz=4)
\newcommand{\calcolsep}{1.905mm} % 单元格左右内边距(108 twips)
\newlength{\calwa}\setlength{\calwa}{11.8886mm}
\newlength{\calwb}\setlength{\calwb}{21.5723mm}
\newlength{\calwc}\setlength{\calwc}{14.1640mm}
\newlength{\calwd}\setlength{\calwd}{43.0918mm}
\newlength{\calwe}\setlength{\calwe}{20.1083mm}
\newlength{\calf}\setlength{\calf}{17.6036mm}
\newlength{\calwg}\setlength{\calwg}{18.2915mm}
%======================================================================
% 5. 表格环境
%
% ⚠️ 用 longtblr(可跨页),不用 tblr:本表 18 行、约 604mm 高,
% 一页装不下(版心高 297 − 2×25.40 = 246.2 mm),必然跨两页。
% 也是 2 页。
%
% ⚠️ 行高用**显式的 ht**(见 §5b),不用 rowsep / strut。
%
% ⚠️ 不设 head/foot 重复表头:跨页时**不重复表头**
% (P2 顶部直接从第六周续排),故保持一致。
%
% ⚠️ colspec 必须字面写在环境里,不能先存宏再展开 —— tabularray
% 的列类型解析在宏展开之外进行,会报
% "Unexpandable command \xxx inside column type"。
%======================================================================
\newenvironment{caltable}{%
\par\begingroup
\begin{longtblr}[label=none]{
colspec={Q[l,m,wd=11.8886mm] Q[l,m,wd=21.5723mm] Q[l,m,wd=14.1640mm]
Q[l,t,wd=43.0918mm] Q[l,m,wd=20.1083mm] Q[l,t,wd=17.6036mm]
Q[l,t,wd=18.2915mm]},
colsep=1.905mm, rowsep=0pt, stretch=0,
hline{1-Z}={\calrule}, vline{1-Z}={\calrule},
% ---- 逐行行高:ht = 内容行数 × 23pt(见 §5b)----
row{1}={ht=115.50pt}, % 表头 5 行(c7 折成 5 行)
row{2}={ht= 69.00pt}, % 第一周 3 行
row{3}={ht= 46.00pt}, % 第二周 2 行
row{4}={ht= 92.00pt}, % 第三周 4 行
row{5}={ht=115.00pt}, % 第四周 5 行
row{6}={ht= 69.00pt}, % 第五周 3 行
row{7}={ht= 46.00pt}, % 第六周 2 行
row{8}={ht= 92.00pt}, % 第七周 4 行
row{9}={ht= 46.00pt}, % 第八周 2 行
row{10}={ht= 46.00pt}, % 第九周 2 行
row{11}={ht= 46.00pt}, % 第十周 2 行
row{12}={ht= 46.00pt}, % 第十一周 2 行
row{13}={ht= 46.00pt}, % 第十二周 2 行
row{14}={ht= 46.00pt}, % 第十三周 2 行
row{15}={ht= 46.00pt}, % 第十四周 2 行
row{16}={ht= 46.00pt}, % 第十五周 2 行
row{17}={ht= 46.00pt}, % 第十六周 2 行
}%
}{%
\end{longtblr}\par\endgroup}
%======================================================================
% 5b. 行高
%
% 单行行距 23.00pt。表格每行的实际高度 = 整数行数 × 23pt + 0.5pt 边框。
% 常见的行数与对应高度:
% 2 行 → 46.5pt 3 行 → 69.5pt
% 4 行 → 92.5pt 5 行 → 115.5pt
%
% ht 取「(行数 − 1) × 23pt」,tabularray 会自行加上内容首行与边框,
% 最终高度与上表一致。
%
% ⚠️ 不用 rowsep:自动折行的行间距会被 xeCJK 的 \CJKglue 与 \lineskip
% 扰动,不是线性的,单一 padding 无法同时满足 1/2/4/5 行。
%
% ⚠️ 不用 \rule 做 strut:h = 23pt 超过 \baselineskip 22.9pt 会触发
% \lineskip,每行多 1pt,且首行基线会跑到表格顶线上方。
%
% ⚠️ ht 是最小高度:内容多了会顶高,少了不压缩。故各行行数必须与
% .tex 里该行的实际内容对得上。改字号或列宽导致折行数变化时,
% ht 要跟着改(README 有重新标定的方法)。
%======================================================================
\newcommand{\calrowsep}{0pt} % 保留名字,向后兼容(本包不用它)
%======================================================================
% 6. 单元格内容包装
%
% 对齐方式照:
% · 表头 7 格全部 jc=center
% · 周次列:前 10 行 jc=left,第 11~16 行 jc=center(原件就不统一,
% 照抄;见 README「已知差异」)
% · 其余各列 jc=left
% · 垂直对齐:表头与周次/日期/学时/教学方式为 vAlign=center,
% 教学内容/课堂讨论/课下作业为 vAlign=top
% ⇒ 垂直对齐已由 colspec 的 m / t 指定;水平对齐由下面的宏指定。
%
% ⚠️ 单元格宏里**不要**加 strut / rule:行高已由 §5 的 ht 定死。
%======================================================================
\newcommand{\calcell}[1]{{\calfontC\songti #1\normalfont}} % 表格正文
\newcommand{\calhead}[1]{{\calfontC\songti\bfseries #1\normalfont}}% 表头(原件未加粗,见下)
\newcommand{\calctr}[1]{\calcell{\centering #1\par}} % 居中格
%----------------------------------------------------------------------
% ⚠️ 表头**不加粗**:表头格只有 jc=center,没有 <w:b/>。
% 视觉上表头看起来醒目,是因为表头行高、字号与正文相同、且居中,
% 并非加粗。照抄原件,不加粗。
% (\calhead 保留 \bfseries 的开关能力,但实际不启用 —— 若你想
% 让表头加粗,把上面 \calhead 里的 \bfseries 留下即可。)
%----------------------------------------------------------------------
%======================================================================
% 7. 表格外内容的位置补偿
%
% 见 §1:版心被设成表格范围 15.875 ~ 190.50 mm,而原版心是
% 31.75 ~ 178.25 mm。表格外的段落必须放回原位才不会整体左移。
%
% ⚠️⚠️ \leftskip 会与 geometry 的 left 边距**叠加**,不是覆盖。
% 初版取 15.875mm 时,段落实际起点 = 15.787 + 15.875 = 31.662mm,
% 比目标 31.75mm 左移 0.088mm。更要命的是它让所有"按原版心再
% 做负缩进"的段落全部错位(【开课单位】一行实际偏右 16.3pt)。
%
% ⇒ \leftskip 必须取 31.75 − 15.787 = 15.963mm,段落起点才回到
% 原版心的 31.75mm。此时行宽 = 174.80 − 15.963 − 12.25 = 146.587mm,
% 与公元 146.50mm 只差 tabularray 的取整余量 0.087mm。
%
% 用法:把表格外的**全部**段落放进 caloutside 环境。
%======================================================================
\newlength{\caloutsideskip}
\setlength{\caloutsideskip}{15.963mm} % = 31.75 − 15.787(见上)
\newlength{\caloutsideright}
\setlength{\caloutsideright}{12.25mm} % = 190.50 − 178.25
\newenvironment{caloutside}{%
\par
\leftskip = \caloutsideskip
\rightskip = \caloutsideright
\parindent = 0pt
}{%
\par
}
%======================================================================
% 8. 表头两格的折行
%
% 的表头第 6、7 格各是**两个段落**:
% c6: 「课堂讨论内容及」+「其它教学环节」
% c7: 「课下作业及课后必读」+「教材或参考书章节」
% 但 PDF 里它们分别显示成 4 行与 5 行 —— 说明每个段落都在格内
% **又自动折行**了一次(c6: 2+2,c7: 2+3)。
%
% ⇒ 本包源码里把整句直接写进一格,由 tabularray 按列宽自动折行,
% 不插 \par。实际列宽下 c6 折成 4 行、c7 折成 5 行,,
% 表头行高 115.5pt = 5×23pt 就是这么来的。
%
% ⚠️ 若改了字号或列宽导致折行数变化,表头行高会跟着变 —— 这是
% 原件的固有行为,不是 bug。但 §5 的 ht=115.5pt 是**写死**的,
% 届时需要同步改 ht(README 有一节讲怎么标定)。
%======================================================================
%======================================================================
% 9. 表格外各段的垂直间距
%
% 原件的段距不是等距的(标题到学年行 26.52pt、学年行到信息行
% 41.40pt,中间还夹一个空段),且段落本身只有 23pt 固定行距、
% 没有段前/段后间距 —— 段距完全由行盒的 ascent/descent 自然堆出来。
% 而 TeX 的行盒比 Word 矮(单行段落少约 11.6pt),故必须逐段补差。
%
% ⇒ 用 \calskip{...} 逐个标定,不依赖 \baselineskip 自动累积。
%
% ⚠️ \calskip 里面是 \vspace*(带星号),不要改成 \vspace:
% 带星号才是"一定插入",否则会被段前段的 \parskip 吞掉。
%======================================================================
\newcommand{\calskip}[1]{\par\vspace*{#1}\par}
%======================================================================
% 10. 表格跨页
%
% 在「第六周」这一行中间分页(P1 底 752.84pt / P2 顶 72.24pt),
% 该行被切成两半,**没有任何跨页提示**。
%
% ⇒ 本模板不强行复刻这个断点(断点位置取决于运行环境的行高取整,
% 不可靠)。改为让 longtblr 自然跨页,并在表格后留出签字栏的
% 固定距离。实际本模板自然跨页后同样是 2 页。
%
% 若需要断在特定行,在该行前插
% \SetTblrTemplate{...}
% 或在 .tex 里把表拆成两个 caltable 环境(不推荐,会丢竖线连续)。
%======================================================================
\AtBeginDocument{\calfontC}
\endinput