源文件: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 限制)。
## 脱敏
责任教师等真实姓名换成虚构的「张远航」,与仓库其他模板一致。
81 lines
3.1 KiB
Bash
Executable File
81 lines
3.1 KiB
Bash
Executable File
#!/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 |