laoyang
|
42c1394aec
|
答案卷抬头改为一行一项,修复长学院名重叠 #22
## 用户诉求
「评分标准最开始不是有个表格吗,里面有开课学院什么的,如果学院名字太长,
就和后面课程名称重合在一起了。看看怎么解决。我建议一行一个信息,
因为这个又不怕长,如果太长,一行都放不下,就直接换行。」
## 现象(已复现并量化)
`dept` 填超长值后,pymupdf 读出:
开课学院:(70.87~123.37) 值:(123.37~406.87)
而第二格「课程名称」本该从 216.0 开始 ⇒ **重叠 190.87bp**,
把「课程名称 / 试卷类型」整个压住。
⚠️ **编译完全不报错,也没有 Overfull**(rc=0 over=0)。
`\makebox` 内容溢出盒外时 TeX 不认为是坏行。这类 bug 只能靠
量 span 坐标发现,看日志发现不了。
## 根因
`\ouckey@inforow` 用三个 `\makebox[0.3333\linewidth][l]` 并排。
`\makebox` 是**不可断盒子**:
- 内容比盒宽短 → 左对齐(正常)
- 内容比盒宽长 → **直接溢出盒外,压到右边一格**(就是 bug)
- 盒内中文**不能换行**(LR 模式,不做段落断行)
⇒ 三格布局对短字段友好,对长字段必然重叠。
## 改动一:一行一项
\newcommand{\ouckey@inforow}[2]{%
\ouckey@ifempty{#2}{}{%
{\fontsize{10.5bp}{15bp}\selectfont
\par\noindent\textbf{#1:}#2\par}}}
调用点从「三参数一组」改成「两参数一行」,共 9 项:
课程名称 / 开课学院 / 学生学院 / 年级专业 / 试卷类型 / 考试方式 /
任课教师 / 命题人 / 满分。顺序按"读者关心程度"排。
行距收紧到 15bp(`\Fivhao` 基线距是 16bp)—— 抬头是查阅信息,
不需要正文行距;9 行省约 52bp,将近 3 行正文。
## 改动二:附带修掉一个旧版就有的判空 bug
**旧实现**:
\newcommand{\ouckey@ifempty}[1]{%
\if\relax\detokenize{#1}\relax ... }
调用 `\ouckey@ifempty{\ouckey@dept}{空}{非空}`。
`\detokenize` **不展开参数**,看到的是字符串 `\ouckey@dept`(宏名),
永远非空 ⇒ 判空永远失败。
后果:`dept = {}` 时抬头印出孤立的「开课学院:」,后面没有值。
这是旧版就有的 bug(三格布局下不明显),改成一行一项后暴露。
**修法**:在 `\define@key` 里就规范化空值,新增
\newcommand{\ouckey@setkey}[2]{%
\if\relax\detokenize{#2}\relax \def#1{}\else \def#1{#2}\fi}
13 个 key 全改走它。
⚠️ 试过「先 `\edef` 展开再 `\detokenize`」的写法,报
`! Incomplete \iffalse` —— `\if...\else...\fi` 被 `\expandafter`
链打散,TeX 匹配 `\fi` 时错位。这类宏层展开的修补太脆,放弃。
⚠️ `\ouckey@setkey` 必须定义在 `\define@key` **之前**,否则 undefined。
## 验证
### 三个场景
| 场景 | 结果 |
|---|---|
| 正常(学院名 12 字) | 9 项齐全,无重叠,无越界 |
| 长(含括号说明,约 40 字) | 单行排到 x=406.90,无重叠(下面没有格子可压) |
| 极长(约 70 字) | **自动换行成两行**,第二行缩进对齐,右缘正好 524.40 |
| 留空(dept/college/major 全空) | 三项**整项不印**,不留空行 |
### 编译
试卷题型示例 6 页 err=0 over=0
参考答案与评分标准 4 页 err=0 over=0
全库 `bash build.sh all` → **13/13 通过,0 失败**。
### 页数变化
答案卷 3 页 → 4 页。抬头从 3 行变 9 行,是「一行一项」的必然代价。
**已向用户确认,接受 4 页**(第 4 页只有说明文字末尾 2 行 + 签字行)。
## 示例文件未改
`参考答案与评分标准示例.tex` 测试后已还原,`git diff` 为空。
只改 `ouckey.sty` 一个文件。
|
2026-10-29 22:58:34 +08:00 |
|
laoyang
|
fb7c76b944
|
装订线虚线方向修正:横杠改回竖杠 #20
用户反馈:「这个装订线不行,得改,需要跟之前的模板保持一致。」
## 问题:整条装订线成了「梯子」
#20 把连字符虚线改成几何线画时,方向画反了。逐像素对比基线与修改后:
基线(18bp 连字符 rotate 90°):x 51.10~52.10(宽 1.10)、y 跨 4.30
改后(我画的水平线) :x 49.40~53.70(宽 4.30)、y 跨 1.00
即基线的每一笔是**竖着的短杠**,我画成了**横着的短杠**。一排横杠叠在
竖线位置上,视觉上就是一把梯子,与原卷完全不同。
## 根因:量数据时没分辨长宽各自对应哪个轴
上一轮 720dpi 扫描得到「长 4.40bp、粗 1.10bp、x 中心 51.60bp」,
三个数都对,但**装配时把「长」放到了 x 轴、「粗」放到了线宽**。
连字符经 rotate=90 后,字面长度落到**纵轴**、线粗落到**横轴**:
竖:y 跨 4.30bp(连字符的字面长度)
横:x 跨 1.10bp(连字符的笔画粗细)
中心 x = 51.60bp
## 修法
- \draw[line width=1.10bp] (49.40, -y) -- (53.70, -y); ← 水平线(错)
+ \draw[line width=1.10bp] (51.60, -y) -- (51.60, -y-4.30); ← 竖直线(对)
x 恒定在 51.60,y 跨 4.30bp。单笔画长度用 4.30(720dpi 实测的墨迹边界),
不是之前写的 4.40(那是含抗锯齿溢出的粗估值)。
## 验证:与基线逐像素同值
装订线区域(x 48~56, y 55~690)在 300dpi 下的墨迹像素数:
基线 7553 像素(8.40%)
新版 7553 像素(8.40%) ← 完全相同
逐段比对(720dpi 逐行扫描,过滤掉「装订线」三个汉字的干扰):
段 笔数 顶端 y 末笔底 y 单笔长 笔距
1 24 62.20 204.90 4.30 6.00
2 24 216.50 358.60 4.30 6.00
3 3 364.80 379.50 4.30 6.00
4 13 393.40 469.60 4.30 6.00
5 16 475.80 568.30 4.30 6.00
6 16 582.10 676.30 4.30 6.00
新版逐段同值,单笔长 4.20 vs 4.30 的 0.1bp 差异是抗锯齿边缘取整。
x 位置 51.00~52.00 vs 51.10~52.10 同样差 0.1bp(亚像素取整),肉眼不可见。
## 编译验证
Windows / TeX Live 2022 试卷 rc=0 err=0 over=0 6页
答案卷 rc=0 err=0 over=0 3页
WSL / TeX Live 2025 试卷 rc=0 err=0 over=0 6页
答案卷 rc=0 err=0 over=0 3页
答案卷不走装订线(\oucexam 的 shipout 钩子只属于试卷),未受影响。
涉及文件:试卷/oucexam.sty(仅 \ouc@dashseg 一个宏 + 注释)
|
2026-10-29 21:35:57 +08:00 |
|
laoyang
|
93b03c8a78
|
试卷字体统一为思源宋体 #20
用户要求:「试卷的字体,需要改一下,全部都用思源宋体就可以了。」
pymupdf 提取两份成品 PDF 定位到四类需要统一的字体:
试卷题型示例(6 页) 参考答案与评分标准示例(3 页)
OUCSerif-Regular 203 中文 OUCSerif-Regular 333 中文
TeXGyreTermes-Regular 133 西文 TeXGyreTermes-Regular 197 西文
TeXGyreTermes-Bold 85 题号分值 OUCSans-Regular 37 黑体小标题
OUCSerif-Bold 81 中文加粗 CMR10/CMMI10/CMSY10 49 数学公式
OUCKai-Regular 25 卷头与成绩表 TeXGyreTermes-Bold 21 数字
一、西文与数字:Termes → 思源宋体(oucexam.sty / ouckey.sty)
先在包里用 \newfontfamily 登记 \OUCLatinSerif / \OUCLatinSerifBold
(四个档位全给,斜体指回 Regular —— 思源宋体没有真斜体),再把
\tnr / \tnrb / \sunfont 都 \let 过去。
⚠️ 只做这一步**不够**,这点踩了一轮:模板里大量文字根本没走 \tnr,
而是走 \setmainfont(默认西文族)——\textbf{learning outcome} 的裸西文、
页脚的页码与总页数、任何 \selectfont 之后的裸 ASCII。
第一轮只 \let 时,PDF 里仍残留 22 个 TeXGyreTermes span:
页脚 6 个页码 + 6 个总页数 + 第 4 页的 A./B./C./D. 与 learning outcome 等。
⇒ 必须连 \setmainfont / \setsansfont 一起指到 OUCSerif。
二、卷头与成绩表题号:霞鹜文楷 → 思源宋体(oucexam.sty)
\kh 与 \scoretable 用 \kaiti。包里 \let\kaiti\songti 一次性收口,
不动 ../fonts.tex 的 \def\kaiti —— 别的模板还要用楷体。
三、答案卷黑体小标题:思源黑体 → 思源宋体(ouckey.sty)
\heiti 共 37 处(卷头大标题与各节小标题)。同样 \let\heiti\songti。
四、数学公式:保持不动
$x$ / $\dfrac{1}{45}\sum f_i x_i$ 等 49 处仍走 Computer Modern。
思源宋体没有 MATH 表(实测只有 GSUB/GPOS),不能作数学字体;
强行塞进正文字体会破坏斜体变量、正体数字、运算符间距。用户已确认。
五、装订线虚线:连字符排字 → 用线画(oucexam.sty)
原卷那 6 段竖虚线是 18bp Times 连字符排出来的。换成思源宋体后连字符
每个宽 0.346 em(Termes 0.333),每串会长 4~7bp,破坏"复刻原卷长度"。
⇒ 改为几何画的短横线段,长度锁死。实测原卷(720dpi 逐笔画测量):
单个连字符笔画 长 4.40bp、粗 1.10bp、x 中心 51.60bp
相邻笔画步距 6.00bp
新增 \ouc@dashseg{起点y}{笔画数},六段坐标与笔画数逐段照抄原卷
(含原卷被白底遮断成 13+3 两截的那一段)。
⚠️ \newcommand 必须定义在 \ouc@dobindstrip 外面,否则每次 shipout
重新定义,第二页起报 already defined。
⚠️ y 坐标不能写 \dimexpr#1bp+\i*6bp —— TikZ 坐标解析器不认小数 +
\dimexpr 组合,报 Illegal unit of measure。要先 \pgfmathsetmacro。
六、直引号归入 CJK(ouckey.sty)
答案卷正文用 ASCII 直引号 "" 表示中文引号(32 处)。U+0022 在
Basic Latin,xeCJK 判为西文 ⇒ 引号走 \setmainfont,与两侧汉字不同字体,
并挤压出 Overfull(第 88 行 +8.07pt)。
\xeCJKDeclareCharClass{CJK}{"0022} 归位后解决。
⚠️ 不在 fonts.tex 里改:那里全库共用,会让正文真正的英文引号(代码
片段 "hello world")也变全角。
七、Overfull 的修法:改源码断行,不调参数(ouckey.sty 留有完整记录)
换字体后 \keyitem{3}{4} 那段 Overfull 2.61pt,实际压出版心
(最右 527.01bp,版心止于 524.41)。试过并确认**全部无效**的五种:
· \emergencystretch 1.5em —— 本行没有弹性胶可拉,无从施展
· \tolerance 3000 —— 不是不满意断点,是没有更早的合法断点
· PunctStyle=kaiming —— 能消 Overfull,但标点悬挂探出版心 6.5bp
· PunctStyle=quanjiao —— 同样探出 8bp
(xeCJK 这几个 PunctStyle 做的是"标点悬挂"不是"标点压缩",
指望它消 Overfull 必翻车)
· \rightskip 0pt plus 6bp(含 \AtBeginDocument 版)—— 6bp 远小于
需要的 150bp,TeX 仍选"撑破"这个解
正解:第 124 行句号「。」后加 \\。分项给分的答案本来就该一句一行,
读者靠句号扫分点 —— 既解决排版,又让内容结构更清楚。
验证(两套环境各跑,逐项同数)
WSL / TeX Live 2025 试卷 rc=0 err=0 over=0 6页
答案卷 rc=0 err=0 over=0 3页
Windows / TeX Live 2022 试卷 rc=0 err=0 over=0 6页
答案卷 rc=0 err=0 over=0 3页
pymupdf 提取字体分布:
试卷题型示例 OUCSerif-Regular 291 + OUCSerif-Bold 70
→ 非宋体文字字体:无
参考答案示例 OUCSerif-Regular 235 + OUCSerif-Bold 53
+ CMR10/CMMI10/CMSY10/CMMI7/CMEX10(数学,保留)
→ 非宋体文字字体:无
几何核对(逐 span 比对,均与基线一致或更优):
· 成绩表 17 栏逐字符坐标与基线**完全相同**(硬编码坐标,不受字体影响)
· 装订线 96 笔全部绘出:x 49.40~53.60(宽 4.40bp)、步距 6.00bp,
六段位置与原卷实测一致
· 三页最右墨迹均为 524.41bp,与版心严丝合缝,无越界
· 试卷 6 页最右最大 523.33bp(第 4 页 \mtpair 的 44% 栏宽设计,
基线同位置同样数值,非本次引入)
涉及文件:
试卷/oucexam.sty 默认族、西文字族、\kaiti、装订线虚线
试卷/ouckey.sty 默认族、西文字族、\heiti、直引号、踩坑记录
试卷/参考答案与评分标准示例.tex 第 124 行句号后加断行
|
2026-10-29 21:29:15 +08:00 |
|
laoyang
|
8984b93ee7
|
模板内容填充:全库 × 占位换成完整虚构示例,README 表述同步 #11
把 11 个模板里满篇的 × 换成一套连贯的虚构数据,让样张能看出排版效果。
虚构设定(跨模板统一):
- 数字逻辑 / 2025 秋 / 张远航 / 计算机科学与技术学院,教学日历、成绩构成
说明、试卷归档封面、试卷四份互相对得上
- 简历:张远航,1985.03,教授博导,论文/专利/项目/获奖全套虚构
- 年度考核:同一人的 2025 年度考核表,年度总结四段写满
- 执行大纲:刻意不套用上面那套(原件就是《信号与线性系统分析》的课,
强行改课程名会让章节体系、学时分配、思政案例全对不上)
假数据都留肉眼可辨标记:DOI 统一 10.9999/、专利号 ZL209999…、
软著 2024SR99999…、手机 138 0000 0000、邮箱 example.net。
签字/日期/评语栏仍然留空——编了就分不清该改哪儿。
修掉一个既有 bug(填充时才暴露):
年度考核登记表「出生年月」的值从来不显示,连字符都不在 PDF 里。
根因是 tabularray 的 cell{r}{c}={c=n} 里那个 c 是数据行的单元序号、
不是视觉列号,表头三处 c=2 要求该行吃 15 个视觉列而表只有 11 列,
超出部分静默丢弃。迷惑点:写 12 格丢值,写 9 格反而正常。
正解是表头不写 cell{},改用行内 \SetCell[c=n]{c},每行照常写满 11 格。
同时 R0 行原件本就装不下(前六字段 115.76mm,剩 42.20mm 要放
19.68mm 标签 + 17.22mm 值,但列宽被切成 15.31/1.38/25.51),
把标签折两行「出生/年月」解决,列宽一个没改。
README 同步:根 README 与 8 个模板 README 里「一律用 × 占位」的说法
已不成立,统一改为「示例内容全部虚构」,并说明哪些位置仍必须留空。
验证:12 个模板零 error,4 处基线警告未新增;干净副本重编页数一致;
PDF 正文 × 清零;真实信息零泄漏。
|
2026-10-27 12:50:02 +08:00 |
|
laoyang
|
8aa979739a
|
字体统一:建公共字体目录,全部改用开源可商用字体 (#6)
七个模板原先分两套做法:幻灯片/fonts(49MB 鸿蒙 18 个字重)与
科技报告/font(92MB,含 5 款方正商业字体),其余模板直接调系统
SimSun/SimHei/KaiTi/FangSong/Times New Roman。换机器就编不出来,
方正系列也不允许随仓库分发。
统一到仓库根的 fonts/ + fonts.tex:
- OUC Serif(思源宋体 SC 子集) —— 宋体
- OUC Sans(思源黑体 SC 子集) —— 黑体
- OUC Kai(霞鹜文楷子集) —— 楷体
- Zhuque Fangsong(朱雀仿宋) —— 仿宋
- TeX Gyre Termes —— 西文 Times 等价(度量逐字相同)
- HarmonyOS Sans —— 幻灯片/科技报告原有字体
fonts.tex 是唯一允许声明字体的地方,7 个模板全部 \input 它。
字体体积 141MB -> 49MB(去掉重复),全库共用一套最小集合。
几处踩过的坑(均已写进源码注释):
- \newCJKfontfamily 与 ctex 默认 fontset 冲突会中断编译,改用
\setCJKfamilyfont + \def
- \newfontfamily 缺粗体档会让 \bfseries 静默失效,四档必须全给
- UprightFont= 与主参数不能同时给,否则文件名被拼两次
- Path= 相对编译时工作目录,不是相对 .sty
- ×/□/○ 等符号按 Unicode 区段被判成西文,需 \xeCJKDeclareCharClass
- 中文斜体的 ItalicFont 与主字体不在同一目录,须在 ItalicFeatures
里单独写 Path/Extension(否则报 OUCKai-Regular cannot be found)
顺带:
- 科技报告 report.tex 的字体演示正文改为新字体名(原文写着方正系列)
- 试卷归档封面新模板并入本库
- 科技报告 shell 命令框底色改海大蓝(#5 遗留)
验证(7 个模板 8 个 PDF 全量重编 + 逐行 A/B 对照):
- 错误 0,缺字 0
- 幻灯片 362 行逐行完全一致,零漂移
- 年度考核登记表 / 劳务发放说明表 / 试卷题型示例 / 参考答案 文本完全一致
- 课程执行大纲 仅 2 处断字连字符差异(throughout、processing),
1 条 6.39pt Overfull 已论证不可见(距纸张右边缘仍有 20.7mm)
- 科技报告 内嵌字体方正归零,只剩 OUC Serif/Sans/Kai + Zhuque
- 全库正文 857 个非 ASCII 字符,四款中文字体(含粗体)覆盖 100%
|
2026-10-27 00:43:14 +08:00 |
|
laoyang
|
1f807e9cce
|
所有模板目录改为中文名,并入幻灯片与科技报告两个仓库(#3)
目录改名(git mv 保留历史,包名不变):
exam/ -> 试卷/
form/ -> 年度考核登记表/
form2/ -> 劳务发放说明表/
course/ -> 课程执行大纲/
改名即可编译:实测 6 个模板在含中文的目录下 XeLaTeX 均零报错,
PDF 逐页文本与改名前的版本完全一致(0 页差异,仅元数据时间戳变化)。
并入两个此前独立维护的仓库:
ouc-slide-latex-template -> 幻灯片/
ouc-report-latex-template -> 科技报告/
带入了 theme/ fonts/ logos/ figs/ cls/ input/ 与 fontawesome.pdf,
字体随模板附带(无须在系统安装)。中间文件一律不入库。
同步修正的文档:根 README 目录表改为中文名并说明统一维护;
四个子 README 的标题;ouclw.sty 注释里对 form/ 的交叉引用;
幻灯片与科技报告 README 里「从旧仓库 clone」「按年份切分支」等已失效的说明
(并入后只有 main 一个分支,各年份 TeX Live 通用)。
两个迁入模板的 PDF 保留源仓库原版(逐字节一致),未重新编译:
源 PDF 出自 TeX Live 2026,本机为 2022,重新编译会让结尾页装饰层定位
产生细微偏移,保留原版以保证样张与原来完全一致。
|
2026-10-26 18:31:04 +08:00 |
|