Files
ouc_latex_template/verify_all.sh
T
laoyang 1c67b7ded1 新增《会议预算表》LaTeX 模板 #24
源文件:微信收到的 会议预算表.doc(51712 字节,**OLE2 老式 .doc**,
D0CF11E0 签名)。python-docx 读不了,处理链路:
.doc --(LibreOffice headless)--> .docx --(python-docx)--> 结构

## 新增文件

   会议预算表/oucmeeting.sty   版式包(含全部 28 行合并规则)
   会议预算表/会议预算表.tex   空表正文(只有内容,无 \SetCell)
   会议预算表/README.md        用法 + 踩坑记录

## 版式(实测)

   页面    A4 210×297mm
   边距    top 38.01 / bottom 35.01 / left 28.01 / right 26.00 mm
   版心    155.99 × 223.98 mm
   字号    标题 22pt,表格与说明 9pt
   表格    28 行 × 7 列,边框 0.5pt,行高 5.6mm

四个边距都不常见,是原表为把 28 行塞进一页压出来的。照抄不"优化"。

⚠️ 原表宽 169.12mm(tblGrid 9588 twips),**比分宽出版心 13.12mm**,
原 docx 靠 fixed 布局硬撑、实际压进页边距。本模板等比缩到版心内。

## 三个踩了很久的坑(全部写进代码注释 + README)

### 1. 合并必须用矩阵式语法,不能写 \SetCell

在这套 7 列 Q[c,m,wd=…] + colsep=1.0mm 配置下,内容里一写
\SetCell[c=n] 就报:

   ! Missing number, treated as zero.
   ! Illegal unit of measure (pt inserted.)
   \__dim_eval_end:

**所有错误都定位到 \end{tblr}**,完全看不出是哪个格。
最小复现(已验证):
   \begin{tblr}{colspec={Q[c,m,wd=21mm]...7列..., colsep=0.8mm}}
     \SetCell[c=2]{c} A & \SetCell[c=5]{l} B \\
   \end{tblr}   % 必崩

✅ 正解:在 tblr 选项里用 cell{行}{列}={c=n}{对齐},被合并格留空。

这个坑吃掉最多时间 —— 因为报错行号指向 \end{tblr},
试过 \shortstack、\rotatebox、\newline 各种改,全都不对,
最后靠「同一合并规则换成 cell{} 语法就 0 错」的最小复现才定位到。

### 2. \SetCell[r=n] 与 \SetCell[c=m] 不能同现

纵向合并和横向合并放同一行,报同样那串错。
本表完全不用纵向合并 —— 「其他费用」改成 \rotatebox{90} 竖排,
第 1 列下面 4 行留空,视觉等价。

### 3. colspec / hline / vline / ht 参数不能用宏

tabularray 用自带展开器解析这些选项,遇到用户宏直接
`! Undefined control sequence.`。全部写字面值。

## 页高预算(关键,别乱改行高)

   28 × 5.6mm = 156.8mm
   标题区(附件1 + 22pt 标题 + 日期行)≈ 30mm
   说明 3 条(第 2 条占两行)≈ 35mm
   合计 ≈ 222mm  ≤ 223.98mm  ✅ 刚好一页

⚠️ 行高 5.6mm 已在下限附近。改回 6.0mm 会让 28 行多出 11.2mm,
第 3 条说明立刻被挤到第 2 页(实测过)。

## 验证

   1 页   error 0   Overfull 0   Underfull 0
   表格 155.52mm / 版心 155.99mm  → 界内
   内容 50 项逐项核对,全部存在
   (唯一"缺失"项是「不得坐支现金」因跨行被 \n 断开,
     去空白后匹配通过 —— 不是真缺失)

全库 bash build.sh all → **15/15 通过**(新增第 15 项,已加入 verify_all.sh)

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

## 说明

空表,金额/卡号/日期/人名一律留空。不含任何真实数据。
2026-10-30 16:50:32 +08:00

82 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"
"会议预算表|会议预算表.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