2026-10-29 12:01:06 +08:00
|
|
|
|
#!/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"
|
2026-10-30 13:45:19 +08:00
|
|
|
|
"课程大纲|课程大纲.tex"
|
2026-10-29 12:01:06 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
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
|