Files
ouc_latex_template/verify_all.sh
T
laoyang dc5e9337e8 新增《本科生课程大纲》LaTeX 模板 #23
源文件:SynologyDrive\授课\数字逻辑\教学大纲\课程大纲模板-数字逻辑-2024版.docx
(2025-01-02 修订,是同目录 17 个文件里最新的一个)。所有尺寸从 OOXML 量出。

## 新增文件

   课程大纲/oucSyllabus.sty   版式包
   课程大纲/课程大纲.tex      示例(数字逻辑,已脱敏)
   课程大纲/README.md         用法

## 版式参数(实测)

   页面    A4 210×297mm
   边距    上下左右均 25.4mm(正好 1 英寸)
   正文    12pt      大标题 15pt 居中      表格 9~10pt
   原 docx 字体:Times/宋体/黑体/仿宋_GB2312/微软雅黑

字体全部取自 ../fonts.tex(OUC Serif + OUC Sans),无系统字体依赖。
仿宋_GB2312 与微软雅黑是商业字体,不能随仓库分发(#17 的规矩)。

## 还原的 6 个表格

   表0  课程基本信息   6 行,不规则(各行列跨度不同)
   表1  课程目标×指标点  6×6 打勾矩阵
   表2  目标×教学内容    6×3
   表3  教学进度         8×5(主要大表)
   表4  成绩与能力对应   6×4
   表5  成绩评分体系     5×2

## 踩坑记录(都写进代码注释了)

### 1. tabularray 的 \SetCell 会吞掉下一格,且不报错

`\SetCell[c=2]{c} 内容 & 下一格` → **下一格连同内容一起消失**。

最小复现(6 列表):
    A & \SetCell[c=2]{c} B & C & \SetCell[c=2]{c} D \\
渲染只得 A / B / D,C 没了。**没有报错,没有任何警告。**

✅ 正确写法:跨 n 列后用 n-1 个 `{}` 占位
    A & \SetCell[c=2]{c} B & {} & C & \SetCell[c=2]{c} D & {} \\

⇒ 规律:`&` 总数固定为「列数-1」,与是否跨列无关。
   跨列只是把内容摊到多格上,被摊掉的格要用 `{}` 顶住。

这个坑让「责任教师」「课程性质」「总课时」三个标签凭空消失了三轮,
每次都要靠 pymupdf 逐行数文字才发现。README 里也记了。

### 2. xeCJK 带缩进的段落会多排一个字,但也不报 Overfull

A4、左右 25.4mm、\linewidth=452.97pt、版心右界 523.28bp 下实测:

    无缩进的纯中文段落     右缘 523.28  ✅
    带 2em 缩进(三种写法) 右缘 530.53  ❌ 超 7.25bp

三种失败的写法:
    ① \par\noindent\hspace*{2em}#1\par
    ② \par\setlength{\parindent}{2em}\indent #1\par
    ③ \parbox{\linewidth}{\setlength{\parindent}{2em}\indent #1}

根因:xeCJK 算断行点时仍按「整行可用宽度」,比应停的位置多放一个字。

✅ 正解:把 \hsize 也减掉缩进量
    \setlength{\hsize}{\dimexpr\linewidth-2em\relax}
    \setlength{\parindent}{2em}
实测右缘 502.28bp,落在版心内。

⚠️ 同样**不报 Overfull** —— TeX 认为这行"刚好"。

### 3. 表 0 列宽不能用固定值

课程代码「080502101231」12 位数字,10.5pt 下宽约 22mm + 内边距 3.81mm。
标签列 26.5mm → Overfull 10.26pt;24mm → 3.14pt;22mm → 0。
22mm 是下限(再窄「课程名称」自己折行)。

## 验证

全库 14/14 通过(新增第 14 项,已加入 verify_all.sh TARGETS):

   课程大纲  6 页  err=0 over=0

逐页越界检查:6 页最右 499.37~514.48bp,全部在版心 523.3bp 内。
内容核查:标题、12 项基本信息、八章标题、7 个关键段落、签字栏,
共 17 项全部命中。

双端一致:
   WSL TeX Live 2025    6 页 err=0 over=0
   Windows TeX Live 2022 6 页 err=0 over=0

## 偏离原文件的地方(README 有表)

1. 「六、成绩评定」原 docx 是 10.5pt,与其余七章 12pt 不一致
   (复制粘贴漏改),本模板统一 12pt。
2. 表 0 的竖线按 6 等分统一,原 docx 逐行不同(tabularray 限制)。

## 脱敏

责任教师等真实姓名换成虚构的「张远航」,与仓库其他模板一致。
2026-10-30 13:45:19 +08:00

81 lines
3.1 KiB
Bash
Executable File
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.
#!/usr/bin/env bash
# 批量编译验证仓库内全部模板,打印每个的 error / Overfull / Underfull / 页数
#
# 用法:
# bash verify_all.sh # 全部
# bash verify_all.sh 试卷 # 只跑指定目录(按目录名精确匹配)
#
# 设计说明:
# · 每个模板都在**自己的目录**里编译。模板的 .sty 与 ../fonts/ 都是相对
# 编译时工作目录解析的,从仓库根调用会找不到字体。
# · 只排除 error,不排除 Overfull/Underfull —— 这两类是排版质量的早期信号,
# 要看得见。已知的几处属既有问题(试卷/、课程执行大纲/ 各 1 处 Overfull,
# 幻灯片/、科技报告/ 各 1 处 Underfull),不是回归。
# · 主文件不像「目录名.tex」的,在 TARGETS 里显式登记(幻灯片/slides.tex、
# 科技报告/report.tex、试卷/ 的两个示例)。
# · 简历/ 目录下还有 fontawesomesymbols-*.tex 等宏包片段,不是文档,
# 不能拿 ls 的第一个 .tex 当主文件,否则报 Emergency stop。
set -u
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT" || exit 1
TEXBIN="${TEXBIN:-xelatex}"
TARGETS=(
"劳务发放说明表|劳务发放说明表.tex"
"年度考核登记表|年度考核登记表.tex"
"幻灯片|slides.tex"
"成绩构成说明|成绩构成说明.tex"
"特殊事项说明表|特殊事项说明表.tex"
"科技报告|report.tex"
"简历|简历.tex"
"试卷|试卷题型示例.tex"
"试卷|参考答案与评分标准示例.tex"
"试卷归档封面|试卷归档封面.tex"
"试卷归档目录|试卷归档目录.tex"
"课程执行大纲|课程执行大纲.tex"
"课程教学日历|课程教学日历.tex"
"课程大纲|课程大纲.tex"
)
filter="${1:-}"
total=0; ok=0; fail=0
failed_list=""
for entry in "${TARGETS[@]}"; do
dir="${entry%%|*}"; tex="${entry##*|}"
if [ -n "$filter" ] && [ "$dir" != "$filter" ]; then continue; fi
total=$((total+1))
printf "=== [%d] %s/%s ===\n" "$total" "$dir" "$tex"
log="$(mktemp)"
( cd "$dir" && "$TEXBIN" -interaction=nonstopmode -halt-on-error "$tex" > "$log" 2>&1 )
rc=$?
# grep -c 无匹配时已经输出 0(退出码 1),不能再 `|| echo 0`,
# 否则变量会变成 "0\n0",后面的整数比较直接报 integer expected。
err=$(grep -c "^!" "$log" 2>/dev/null || :)
over=$(grep -c "Overfull" "$log" 2>/dev/null || :)
under=$(grep -c "Underfull" "$log" 2>/dev/null || :)
pages=$(grep -oE "Output written on .*\([0-9]+ page" "$log" 2>/dev/null \
| tail -1 | grep -oE "\([0-9]+" | tr -d "(")
printf " rc=%s err=%s Overfull=%s Underfull=%s pages=%s\n" \
"$rc" "${err:-0}" "${over:-0}" "${under:-0}" "${pages:-?}"
if [ "$rc" -eq 0 ] && [ "${err:-1}" -eq 0 ] && [ -n "${pages:-}" ]; then
ok=$((ok+1))
else
fail=$((fail+1))
failed_list="${failed_list}
- $dir/$tex"
grep -A2 "^!" "$log" 2>/dev/null | head -9 | sed "s/^/ /"
fi
rm -f "$log"
done
echo
echo "================ 汇总 ================"
echo "总数 $total | 通过 $ok | 失败 $fail"
[ -n "$failed_list" ] && printf "%s\n" "$failed_list"
exit 0