Files
ouc_latex_template/verify_all.sh
T
laoyang ef1bc72603 加入 WSL 编译取回脚本与换行符策略 #18
build.sh      在 WSL 内编译(默认 xelatex),成功后用 scp 把 PDF 取回
              Windows 侧同路径。支持单模板与 all 全库。路径全部走环境
              变量覆盖,默认值可用,不硬编码某个人的目录。

verify_all.sh 批量编译验证全库主文件,打印 error / Overfull / Underfull
              与页数。每个模板都在自己目录下编译 —— 模板的 .sty 与
              ../fonts/ 是相对编译工作目录解析的,从仓库根调用找不到字体。

.gitattributes 把所有 .sh 钉成 eol=lf。Windows 侧 core.autocrlf=true 会把
              脚本存成 CRLF,到 Linux 上执行就报
                  /bin/bash^M: bad interpreter: No such file or directory
              这个错误容易误判成"没装 bash",所以在仓库层面固定规则,
              不依赖各人本机的 autocrlf 设置。.tex/.sty/.cls 同样钉 lf,
              避免中文注释行尾残留 CR 被 XeTeX 当字符排出来。

关于脚本为什么要写成「编译-取回」而不是纯编译:
WSL2 会按空闲把整个虚拟机 poweroff,届时 xelatex 连同 PID 1 一起消失,
/tmp 也一并清空(后台日志丢失)。脚本的 ssh 会话在编译期间保持不断,
顺带起了保活作用,所以不要把它改成后台运行。
2026-10-29 12:01:06 +08:00

80 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"
)
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