答案卷抬头信息改为一行一项:修复长学院名与右侧字段重叠
用户原话:「试卷里面的答案和评分标准有问题,评分标准最开始不是有个表格吗, 里面有开课学院什么的,如果学院名字太长,就和后面课程名称重合在一起了。 看看怎么解决。我建议一行一个信息,因为这个又不怕长,如果太长, 一行都放不下,就直接换行,这样应该就没有问题了。」
把 dept 改成超长值 计算机科学与技术学院(人工智能与大数据技术方向实验班) 后, pymupdf 提取成品 PDF 的 span 坐标:
dept
计算机科学与技术学院(人工智能与大数据技术方向实验班)
y=139.5 开课学院:(70.87~123.37) 值:(123.37~406.87)
而按 \makebox[0.3333\linewidth] 的布局,第二格「课程名称」本该从 216.0 开始 —— 值一直排到 406.87,重叠 190.87bp, 把「课程名称 / 试卷类型」整个压住了。
\makebox[0.3333\linewidth]
⚠️ 关键:编译不报任何错误,也没有 Overfull 警告(rc=0 over=0)。 \makebox 固定盒宽,内容超出时只是"溢出盒外"继续排, TeX 不认为这是坏行。⇒ 这个 bug 只能靠看渲染结果或量 span 坐标发现, 看日志发现不了。
\makebox
ouckey.sty 第 240 行 \ouckey@inforow:
ouckey.sty
\ouckey@inforow
\newcommand{\ouckey@inforow}[6]{% \par\noindent \makebox[0.3333\linewidth][l]{\ouckey@cell{#1}{#2}}% \makebox[0.3333\linewidth][l]{\ouckey@cell{#3}{#4}}% \makebox[0.3333\linewidth][l]{\ouckey@cell{#5}{#6}}\par}
\makebox[固定宽][l] 是不可断的盒子:
\makebox[固定宽][l]
所以三格布局对"短字段"友好,对"长字段"必然重叠。
\newcommand{\ouckey@inforow}[2]{% \par\noindent\textbf{#1:}#2\par}
即每项独占一行,用普通段落排版 —— 超长自动换行,不再有固定盒宽的假设。
\par
抬头从 3 行变成 9 行(开课学院 / 课程名称 / 试卷类型 / 学生学院 / 年级专业 / 考试方式 / 任课教师 / 命题人 / 满分),多占约 6 行高度。 答案卷是 A4、内容不满页,多 6 行不影响版面。
留空的项仍自动不印(\ouckey@ifempty 逻辑不变),所以实际行数随填写项变化。
\ouckey@ifempty
示例文件已备份到 /tmp/keybase.tex(WSL 内),改完可比对。
/tmp/keybase.tex
42c1394
现在抬头是这样:
课程名称:数字逻辑 开课学院:计算机科学与技术学院 学生学院:信息科学与工程学院 年级专业:计算机科学与技术专业 2023 级 试卷类型:A 卷 考试方式:闭卷、笔试 任课教师:张远航 命题人:张远航 满分:100 分
超长字段自动换行,第二行缩进对齐(从标签后开始,不是顶格)。
\ouckey@inforow 用三个 \makebox[0.3333\linewidth][l] 并排。\makebox 是不可断的盒子:
\makebox[0.3333\linewidth][l]
三格布局对短字段友好,对长字段必然重叠。
⚠️ 这个 bug 编译不报任何错,也没有 Overfull 警告。\makebox 内容溢出 盒外时 TeX 不认为是"坏行"。所以光看日志发现不了,只能量坐标 —— 实测超长时重叠 190.87bp,把「课程名称 / 试卷类型」整个压住。
留空项会印出孤立的「开课学院:」,后面没值。 这是旧版就有的问题, 三格布局下不明显,改成一行一项后暴露。
根因:旧判空宏 \ouckey@ifempty{\ouckey@dept} 里 \detokenize 不展开 参数,看到的是字符串 \ouckey@dept(宏名本身),永远非空 ⇒ 判空永远失败。
\ouckey@ifempty{\ouckey@dept}
\detokenize
\ouckey@dept
修法:在 \define@key 里就规范化空值,13 个 key 全改走 \ouckey@setkey。
\define@key
\ouckey@setkey
⚠️ 中途试过「先 \edef 展开再 \detokenize」,报 ! Incomplete \iffalse —— \if...\else...\fi 被 \expandafter 链打散,TeX 匹配 \fi 错位。 这类宏层展开的修补太脆,放弃了,改用规范化存值的路子。
\edef
! Incomplete \iffalse
\if...\else...\fi
\expandafter
\fi
试卷题型示例 6 页 err=0 over=0 (未受影响) 参考答案与评分标准 4 页 err=0 over=0 全库 13/13 通过
示例文件测试后已还原,git diff 为空。只改 ouckey.sty 一个文件。
git diff
3 页 → 4 页。抬头从 3 行变 9 行,这是「一行一项」的必然代价。 你已确认接受。 第 4 页只有说明文字末尾 2 行 + 签字行。
行距我收紧到了 15bp(正文是 16bp)—— 抬头是查阅信息,不需要正文行距, 9 行省了约 52bp,相当于 3 行正文的空间。
No dependencies set.
The note is not visible to the blocked user.
答案卷抬头信息改为一行一项:修复长学院名与右侧字段重叠
用户诉求
用户原话:「试卷里面的答案和评分标准有问题,评分标准最开始不是有个表格吗,
里面有开课学院什么的,如果学院名字太长,就和后面课程名称重合在一起了。
看看怎么解决。我建议一行一个信息,因为这个又不怕长,如果太长,
一行都放不下,就直接换行,这样应该就没有问题了。」
现象(已复现并量化)
把
dept改成超长值计算机科学与技术学院(人工智能与大数据技术方向实验班)后,pymupdf 提取成品 PDF 的 span 坐标:
而按
\makebox[0.3333\linewidth]的布局,第二格「课程名称」本该从216.0 开始 —— 值一直排到 406.87,重叠 190.87bp,
把「课程名称 / 试卷类型」整个压住了。
⚠️ 关键:编译不报任何错误,也没有 Overfull 警告(rc=0 over=0)。
\makebox固定盒宽,内容超出时只是"溢出盒外"继续排,TeX 不认为这是坏行。⇒ 这个 bug 只能靠看渲染结果或量 span 坐标发现,
看日志发现不了。
根因
ouckey.sty第 240 行\ouckey@inforow:\makebox[固定宽][l]是不可断的盒子:\makebox内部是 LR 模式,不做段落断行)所以三格布局对"短字段"友好,对"长字段"必然重叠。
方案:改为一行一项
即每项独占一行,用普通段落排版 —— 超长自动换行,不再有固定盒宽的假设。
为什么这个方案对
\par模式下中文可在任意汉字间断行。代价(已接受)
抬头从 3 行变成 9 行(开课学院 / 课程名称 / 试卷类型 / 学生学院 /
年级专业 / 考试方式 / 任课教师 / 命题人 / 满分),多占约 6 行高度。
答案卷是 A4、内容不满页,多 6 行不影响版面。
留空的项仍自动不印(
\ouckey@ifempty逻辑不变),所以实际行数随填写项变化。验收标准
dept(含括号说明)编译,抬头各字段无重叠:逐行检查 span 的 x 区间不交叠
备份
示例文件已备份到
/tmp/keybase.tex(WSL 内),改完可比对。已完成,提交
42c1394按你的建议改为「一行一项」
现在抬头是这样:
超长字段自动换行,第二行缩进对齐(从标签后开始,不是顶格)。
根因
\ouckey@inforow用三个\makebox[0.3333\linewidth][l]并排。\makebox是不可断的盒子:
三格布局对短字段友好,对长字段必然重叠。
⚠️ 这个 bug 编译不报任何错,也没有 Overfull 警告。
\makebox内容溢出盒外时 TeX 不认为是"坏行"。所以光看日志发现不了,只能量坐标 ——
实测超长时重叠 190.87bp,把「课程名称 / 试卷类型」整个压住。
三种情况都验证过
附带修掉一个旧版就有的 bug
留空项会印出孤立的「开课学院:」,后面没值。 这是旧版就有的问题,
三格布局下不明显,改成一行一项后暴露。
根因:旧判空宏
\ouckey@ifempty{\ouckey@dept}里\detokenize不展开参数,看到的是字符串
\ouckey@dept(宏名本身),永远非空 ⇒ 判空永远失败。修法:在
\define@key里就规范化空值,13 个 key 全改走\ouckey@setkey。⚠️ 中途试过「先
\edef展开再\detokenize」,报! Incomplete \iffalse——
\if...\else...\fi被\expandafter链打散,TeX 匹配\fi错位。这类宏层展开的修补太脆,放弃了,改用规范化存值的路子。
验证
示例文件测试后已还原,
git diff为空。只改ouckey.sty一个文件。关于页数
3 页 → 4 页。抬头从 3 行变 9 行,这是「一行一项」的必然代价。
你已确认接受。 第 4 页只有说明文字末尾 2 行 + 签字行。
行距我收紧到了 15bp(正文是 16bp)—— 抬头是查阅信息,不需要正文行距,
9 行省了约 52bp,相当于 3 行正文的空间。