源文件:微信收到的 会议预算表.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 ## 说明 空表,金额/卡号/日期/人名一律留空。不含任何真实数据。
82 lines
3.1 KiB
Bash
Executable File
82 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"
|
||
"会议预算表|会议预算表.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 |