Files
ouc_latex_template/课程执行大纲/README.md
T
laoyang 69da5b41a6 简历排版修正:项目经验整块右移、西文换 Cochineal、课程执行大纲漏网 × #12
一、项目经验整块右移(简历/awesome-source-cv.cls)
  \rightcolumnlength 算早了:geometry 的 1.5cm 边距要到导言区结束才生效,
  cls 里那句 \setlength 读到 article 默认 \textwidth=345pt,算出 249.87pt,
  比应有的 417.02pt 少 167.15pt。longtable 把窄表居中排,整块右移 83.6pt。
  修法:计算挪进 \AtBeginDocument 并减去 | 竖线的 \arrayrulewidth;
  R 列由 >{\hfill}m{2.5cm} 改为 >{\raggedright\arraybackslash}p{2.5cm}。
  日期左边缘 145.1 -> 48.5pt,与其余章节严格对齐。
  这类错误零 error 零 warning,只能量 PDF 坐标才能发现。

二、西文换 Cochineal(fonts/cochineal/ + fonts.tex + 简历 cls)
  中文思源宋体配 Termes 时西文笔画偏细,中英混排会「陷进去」。
  Cochineal 宽 225.42pt vs Termes 229.68pt,只窄 1.9%,断行位置基本不动;
  Pagella/XCharter 宽 7~11%,会把全库断行推着变,故不选。
  字体 920KB 入 fonts/cochineal/(SIL OFL 1.1,附 OFL.txt),
  fonts.tex 新增 \oucUseCochineal 开关,只简历调用,其余 10 个模板不受影响。

三、换字体后暴露的真实缺陷
  西文窄 1.9% 让断点整体前移,ICIEA 那条论文冲出 88.49pt(文字顶到纸边)。
  根因是中文紧跟英文的位置不是断开点,整串被当长单词。
  加 \emergencystretch=3em 解决。

四、课程执行大纲漏网占位符(ouccourse.sty)
  ××学部××学院 硬编码在 \ccschool 里,#11 只扫了 .tex 没扫 .sty 所以漏了。
  拆成 \ccdepartment / \cccollege 两个名称宏,默认「信息科学与工程学部 /
  计算机科学与技术学院」。重编后全文 × 归零。

「代码库 PDF 没更新」经核实不成立:本地/远程 HEAD 均为 8984b93,
从服务器下载 8 个 PDF 逐字节比对全部一致,简历.pdf 3 页 0 个 ×。

验证:简历 3 页 0 error/0 Overfull/0 Underfull;全库 12 项编译回归与基线一致。
2026-10-27 13:13:54 +08:00

292 lines
12 KiB
Markdown
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.
# `课程执行大纲` —— 本科课程教学执行大纲、教学日历(LaTeX 模板)
中国海洋大学下发的《本科课程教学执行大纲》Word 模板的 XeLaTeX 复刻版。
内容全部**虚构**(课程名、课程代码、开课号、教师、教材、思政案例),只复刻版式。
> 样张是一份**填完整的虚构大纲**:《信号与系统基础》2026 秋、电子信息工程专业、
> 56 课时 3.0 学分(含 18 实践学时)、开课号 `99663311`、任课教师「陈立群」、
> 教材用吴大正《信号与线性系统分析》(高等教育出版社)、参考书用郑君里那本。
>
> 注意**本模板刻意不套用其他模板的「数字逻辑 / 张远航」那套设定** ——
> 这份大纲原作就是《信号与线性系统分析》的课,强行改成数字逻辑,
> 大纲里的章节体系、学时分配、思政案例就全对不上了。虚构也要虚构得自洽。
| 文件 | 说明 |
|---|---|
| `课程执行大纲.tex` | 主文件。虚构课程的一份完整示例 |
| `ouccourse.sty` | 版式宏包。尺寸全部从原 docx 的 OOXML 量出 |
| `课程执行大纲.pdf` | 编译产物,5 页(与原 docx 一致) |
## 编译
```bash
xelatex 课程执行大纲.tex # 单次即可,无交叉引用
```
需要 `ctex` + `geometry` + `fontspec` + `xeCJK` + `tabularray`。
实测环境:TeX Live 2022 / tabularray 2022A。
## 换成一门真实的课
**只改 `课程执行大纲.tex` 顶部的宏定义,不要动 `ouccourse.sty`。**
```latex
\newcommand{\cfcourse}{信号与系统基础} % 课程名
\newcommand{\cfyear}{2026} % 学年
\newcommand{\cfseason}{秋} % 季学期
\newcommand{\cfmode}{考试} % 考核方式:考试/考查/论文
\newcommand{\cfcode}{081203304517} % 课程代码
\newcommand{\cfhour}{56} % 总课时
\newcommand{\cfcredit}{3.0} % 学分
\newcommand{\cfprac}{18} % 实践学时
\newcommand{\cfteacher}{陈立群} % 任课教师
\newcommand{\cfteachno}{99663311} % 开课号
\newcommand{\cfmajor}{电子信息工程} % 面向专业
\newcommand{\cfattr}{专业核心必修课} % 课程属性
```
正文各节直接用 `\ccsec{}`(一级标题)、`\ccp{}`(带 2 字首行缩进的正文)。
### 表 0 —— 成绩综合评分体系
```latex
\begin{ccscoretable}
成绩综合评分体系 & 比例\% \\ % 表头
1.课下作业、课堂讨论及平常表现 & 24 \\
2.实验成绩 & 20 \\
3.期末考试成绩 & 56 \\
总计 & 100 \\
\end{ccscoretable}
```
行数可以增减,行高自动(每行 7.834mm)。
### 表 1 —— 教学日历
```latex
\begin{cctable}
{\ccfang\ccszxi\bfseries 周次} & ... & {\ccszix 内容} & 2 & {\ccszix ...} & {\ccszix ...} \\
\end{cctable}
```
- 6 列,顺序固定:周次 / 内容顺序 / 主题 / 计划课时 / 教学内容及教学方式 / 思政点及支撑指标点情况
- 纵向合并周次段用 `\SetCell[r=2]{c}`(跨 2 行,`r=N` 即跨 N 行)
- 表尾「合计」行后有两个 `\SetCell[c=6]{c}` 的整行合并(任课老师签字 / 审核意见)
- 表内默认 9pt;表头用 `\ccszxi`(11pt)加粗;审核意见格内部钉死 10.5pt/12.6pt
## 版式数据来源(twips → mm)
原 docx 的 `sectPr`:
| 属性 | twips | mm | 说明 |
|---|---|---|---|
| `pgSz w` | 11910 | 210.08 | WPS 存的"非标准 A4",本包用标准 210 |
| `pgSz h` | 16840 | 297.04 | 同上,用 297 |
| `pgMar top` | 1420 | 25.05 | 上边距 |
| `pgMar bottom` | 280 | **4.94** | 下边距极小,原文件为塞进 5 页压出来的 |
| `pgMar left` | 1560 | 27.52 | 左边距 |
| `pgMar right` | 1300 | 22.93 | 右边距(左右不对称,照抄) |
| `pgMar header/footer` | 720 | 12.70 | 无页眉页脚内容,仅占位 |
换算:`mm = twips / 1440 × 25.4`,`pt = twips / 20`。
### 表 0(成绩综合评分体系)
| 项目 | twips | mm |
|---|---|---|
| `gridCol` | 7479 + 1418 | 131.921 + 25.012 |
| 表宽 | 8897 | **156.93** |
| `tblCellMar left/right` | 108 | 1.905 |
| `trHeight`(exact) | 454 | 8.01(本包用 7.834,见坑 3) |
| 边框 `sz` | 4 | 0.5pt |
`tblLayout fixed`、`jc center`、`tblW 0 auto`。全表 12pt 仿宋(朱雀仿宋)。
### 表 1(教学日历)
| 项目 | twips | mm |
|---|---|---|
| `gridCol` | 846,1134,1877,850,2835,1843 | 14.922, 20.002, 33.108, 14.993, 50.006, 32.508 |
| 表宽 | 9385 | **165.54**(超版心 5.91) |
| `trHeight` R0(atLeast) | 917 | 16.17 |
| `trHeight` R14(atLeast) | 1825 | 32.19 |
| `trHeight` R15(atLeast) | 1073 | 18.93(只是下限,实际被撑到 56mm) |
**16 行**。R1~R13 无 `trHeight`,行高由内容决定。纵向合并 5 组(R1-R2、R3-R4、
R5-R6、R7-R8、R9-R10);R14/R15 是 `gridSpan=6` 的整行合并。
## 六个必须知道的坑
### 1. 表宽 > 版心时,不要缩放列宽
docx 里表 1 是 165.54mm,版心只有 159.55mm。Word 允许表格超出、居中后压进左右页边距。
**不要按 159.55/165.54 按比例缩列宽。** 缩了之后长文字会提前折行,行高、页数全变。
正确做法:列宽照抄 `gridCol`,用 `\leftskip` 把整块左移。
```latex
\hsize=\cctblw \linewidth=\cctblw % 让表内得下,不报 Overfull
\leftskip=-\cctblshift \rightskip=0pt % 整块左移 5.29mm,落到 22.23mm
```
`\hspace*` 对 `longtblr` 生成的 `\halign` 盒子**无效**,会被吞掉,必须用 `\leftskip`。
### 2. `wd=` 是内容宽,不含竖线自身的宽度
tabularray 的 `Q[...,wd=X]` 里 X 是**内容宽**。每条 `vline` 自身还占 0.5pt = 0.17639mm。
```
表 1:6 列 7 条线,每列承担 7/6 条 ⇒ wd = gridCol − 2×colsep − 0.2058
表 0:2 列 3 条线,每列承担 1.5 条 ⇒ wd = gridCol − 2×colsep − 0.2646
```
漏算的后果很隐蔽:表看起来对,但总宽每列多 0.18mm,6 列就差出 1mm。
### 3. `ht=` 也含横线宽度预算
`row{1-Z}={ht=8.01mm}` 画出来是 **8.19mm**(每行多一条 0.5pt 横线)。
要得到 8.01mm 的真实行高,`ht` 要给 **7.834mm**。
### 4. `presep/postsep/headsep/footsep` 是 outer 键
写进 `\begin{longtblr}[...]` 的**方括号**里;写进花括号(inner spec)不会生效,
反而会把 `0pt` 当表内容印在表格第一行 —— 表头上会出现一串
`0pt0pt0pt0pt` 的垃圾文字,而且**不报错**。
同理,表级默认字号必须写 `cells={font=\ccszix}`,单独写 `font=` 会被静默忽略。
### 5. 跨页续页提示要清两组模板
`longtblr` 跨页时默认印 `( Continued )`、表尾印 `Continued on next page`,
有 caption 时还印 `表0:`。清干净要动两组:
```latex
% (a) 内容模板 *-text —— 不能设成 empty!会报
% "LaTeX3 Error: Erroneous variable \l__tblr_template_conthead_text_tl"
\DefTblrTemplate{conthead-text}{normal}{}
\DefTblrTemplate{contfoot-text}{normal}{}
\SetTblrTemplate{conthead-text}{normal}
\SetTblrTemplate{contfoot-text}{normal}
% (b) 模板实例
\SetTblrTemplate{caption-tag}{empty}
\SetTblrTemplate{caption-sep}{empty}
\SetTblrTemplate{caption-text}{empty}
\SetTblrTemplate{caption}{empty}
\SetTblrTemplate{conthead}{empty}
\SetTblrTemplate{contfoot}{empty}
```
只做 (b) 时第 5 页仍会出现「表0:」与「(Continued)」,因为模板实例里调的是
`\UseTblrTemplate{...}{default}`,会回退到 `normal` 内容。
### 6. `\linespread` 是乘在基准字号上的
ctex 默认 `\linespread ≈ 1.3`,会把 `\fontsize{12}{18}` 的行距放大到 23.4pt。
给字号设行距时**必须**先归 1:
```latex
\newcommand{\ccfont}[2]{\linespread{1}\relax\fontsize{#1}{#2}\selectfont}
```
反过来,在已经缩小过字号的上下文里,**不能**用 `\linespread{1.2}` 当"1.2 倍行距"
(它乘的是外层的 9pt,不是当前的 10.5pt),要直接钉 `\fontsize{10.5}{12.6}`。
## 字体
原 docx 用了 4 个字体,其中 3 个是**方正商业字体**,嵌在 docx 里但本机没装。
旧版做法是降级到 Windows 自带字体(宋体/黑体/仿宋 + `AutoFakeBold` 伪粗),
但这既依赖本机装了什么字体(换台机器就可能编不出),而且 SimSun / SimHei /
FangSong 也都不允许随仓库分发。
现在全部改用仓库公共字体包 `../fonts.tex`:
| docx 原字体 | 用在哪 | 本包替代 | 命令 |
|---|---|---|---|
| 方正小标宋简体 | 校名、副标题、大标题、教学日历 | OUC Serif **真粗体** | `\ccbiaosong` |
| 方正仿宋_GB2312 | 正文、表 0、签字栏 | 朱雀仿宋 | `\ccfang` |
| 黑体 | 各级标题 | OUC Sans(思源黑体) | `\cchei` |
| 宋体 | 教学日历表 9pt | OUC Serif(思源宋体) | `\ccsong` |
比原来的伪粗更好:小标宋本来就是宋体的标题变体,用思源宋体自带的真粗体,
笔画不会像 `AutoFakeBold=3.2` 那样糊在一起。
> ⚠️ **朱雀仿宋只有常规一档**,`\ccfang` 下 `\bfseries` 不会真的变粗。
> 教学日历表头(`课程执行大纲.tex` 里的 `{\ccfang\ccszxi\bfseries 周次}` 等 6 处)
> 原来靠 `AutoFakeBold=2.5` 伪粗,现在给 `ccfang` 单独开了 `FakeBold=0.8`
> 保住层次(见 `ouccourse.sty` 的注释)。若要更实在的粗体,把那几处
> `\ccfang` 换成 `\cchei` —— 黑体本身就是标题用的重字面。
同时 `\xeCJKsetup{CJKecglue={}}` 关掉了西文与汉字之间的自动空隙 —— 原 docx 没有这种空隙,
不关会在中英交界处多出一个空格(原 docx 里紧挨着的「2026 学年」「56/3.0」都会松开)。
## 院名可改(原先是硬编码的 ×× 占位)
首页抬头第二行原本在 `ouccourse.sty` 里**写死**成「××学部××学院」,PDF 里
能直接看到 4 个叉号。现在拆成两个名称宏,改院名只动导言区:
```latex
\renewcommand{\ccdepartment}{海洋地球科学学院} % 默认「信息科学与工程学部」
\renewcommand{\cccollege}{地质学系} % 默认「计算机科学与技术学院」
```
默认值取自本模板的虚构设定(陈立群 / 电子信息工程 / 2025 秋),与课程教学日历、
成绩构成说明、试卷等模板保持一致。校名「中国海洋大学」是真实的,不虚构。
> ⚠️ 为什么不写成 `\ccschool[学部][学院]`:LaTeX 的 `\newcommand` 只支持
> **一个**可选参数,第二个方括号会被当成正文印出来。
## 与 docx 的已知差异
| 项目 | docx | 本模板 | 原因 |
|---|---|---|---|
| 纸张 | 210.08 × 297.04 | 210 × 297 | 标准 A4,肉眼不可辨 |
| 表格是否跨页 | 表 1 跨第 4/5 页 | 同 | 表高 334mm > 版心 267mm |
| 跨页处表头 | 不重复(无 `tblHeader`) | 不重复 | 一致 |
| 行内是否允许断开 | 允许(无 `cantSplit`) | 允许 | 一致 |
| 表 0 每行高 | 8.01 | 8.01 | 一致 |
| 表 1 表宽 | 165.54 | 165.36(−0.18) | 竖线宽度舍入 |
| 字体 | 方正小标宋/仿宋 | 思源宋体粗/朱雀仿宋 | 商业字体不可分发,已换开源替代 |
| 修订标记 | 46 处 `w:ins` | 不保留 | 已接受全部插入修订 |
| 46 处 `w:ins` 中的红字 | `color=C00000` | 黑色 | 那是修订高亮,非正式版式 |
## 校验方法
不靠肉眼,靠量。
```bash
pdftocairo -svg -f 4 -l 4 课程执行大纲.pdf /tmp/p4.svg # 矢量线条
pdftotext -bbox 课程执行大纲.pdf /tmp/bbox.html # 字坐标
```
或用 `pymupdf` 直接读(推荐,能同时拿到线段与 span 的 bbox):
```python
import pymupdf
d = pymupdf.open('课程执行大纲.pdf')
for dr in d[3].get_drawings(): # 表格横竖线
for it in dr['items']:
if it[0] == 'l':
print(it[1], it[2]) # 两端点,单位 pt
```
**注意**:同一条竖线会被重复计入多次(每个单元格一段),做列宽计算前必须
`sorted(set(round(x,2) ...))` 去重,否则 `xs[1]-xs[0]` 算出来是 0。
### 验收结果(实测,26/26 项达标)
```
表 0 宽 156.753 目标 156.930 差 −0.177
左 27.608 目标 27.520
高 40.040 目标 40.050
列 131.830 / 24.924 目标 131.921 / 25.012
表 1 宽 165.358 目标 165.540 差 −0.182
左 22.320 目标 22.270
列 14.894 / 19.971 / 33.076 / 14.965 / 49.975 / 32.477
目标 14.922 / 20.002 / 33.108 / 14.993 / 50.006 / 32.508
R0 16.334(目标 16.170) R14 32.385(目标 32.190)
R15 56.339(atLeast 下限 18.930,被 12 段内容撑高)
页数 5(与原 docx 一致)
编译 零错误、零 Overfull、零 Underfull
各页最低点均 ≤ 292.06mm 版心下沿,无越界
```