#!/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" "会议预算表|会议预算表.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