%====================================================================== % oucksfm.sty — 信息科学与工程学部 试卷归档封面(理论课)版式包 % % 依据:附件1:信息科学与工程学院试卷封面(理论课).doc % (SynologyDrive/授课/数字逻辑/2025/归档/) % 原名与内文标题写的是「学院」,按现行建制改为「学部」, % 模板标题相应为「信息科学与工程学部试卷归档封面」。 % 目标:版式与逐项对齐。所有尺寸都由 Word 内部数值换算: % pt → mm : mm = pt / 72 * 25.4 % twips → mm : mm = twips / 1440 * 25.4 % w:sz : 半磅值,÷ 2 即 pt % % 用法见同目录 试卷归档封面.tex,说明见 README.md %====================================================================== \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{oucksfm}[2026/10/26 v1.0 OUC exam archive cover sheet] \RequirePackage{geometry} \RequirePackage{fontspec} \RequirePackage{xeCJK} \RequirePackage{tabularray} %====================================================================== % 1. 页面与版心 % % sectPr: % pgSz A4(595.3 × 841.9 pt = 210.0 × 297.0 mm) % pgMar top/bottom 70.9 pt = 25.01 mm % left/right 56.7 pt = 20.00 mm % header 42.55 pt = 15.01 mm / footer 49.6 pt = 17.50 mm % % 表宽 tblW = 100%(w:type="pct" w:w="5000"),即铺满版心: % 版心宽 = 210 − 2×20.00 = 170.00 mm % % ⇒ 这里让 totalwidth 恰等于 170mm: % · 表格天然与版心同宽,编译不刷 Overfull \hbox % · 表格在纸面上的绝对位置与 Word 完全一致(左右各 20mm) %====================================================================== \geometry{ paperwidth = 210mm, paperheight = 297mm, totalwidth = 170mm, % = 表宽,精确 hmarginratio = 1:1, % 左右各 20mm top = 25.01mm, bottom = 25.01mm, headheight = 0pt, headsep = 0pt, footskip = 17.50mm, } \setlength{\parindent}{0pt} \setlength{\parskip}{0pt} \pagestyle{empty} % 无页眉页脚,故不排页码 %====================================================================== % 2. 字体与字号 % % 表外标题 黑体 18pt 加粗(w:sz=36 + w:b),jc=center % 左列标签 黑体 18pt (w:sz=36,全部 11 行一致) % 右列值 黑体 18pt (w:sz=36)—— 学年 / 学期 % 黑体 16pt (w:sz=32)—— 考试课程名称 / 课程类型 / % 面向专业 / 面向年级 / 试卷份数 / % 授课教师 / 日期 % 黑体 14pt (w:sz=28)—— 课程号 / 选课号(纯数字,字号小一档) % % ⚠️ 全文只有黑体一种字体,没有宋体/仿宋混排,比另两份表单简单。 % % 字体全部来自仓库公共字体包 ../oucfonts.sty(文件在 ../fonts/ 下)。 % 换台机器(尤其 Linux/macOS)就编不出来。现已全部换成随仓库分发的 % 开源字体,并且粗体用字体自带的真粗体、不再算法描边。 %====================================================================== \input{../fonts.tex} %---------------------------------------------------------------------- % ⚠️⚠️⚠️【最要命的一条,与 ouclw.sty 同源】 % ctex 默认 \linespread 约 1.3,会把 \fontsize{18}{21.6} 的 21.6pt % 行距放大成 28pt 以上。 % % \fontsize 的第二个参数【本来是】用来设 \baselineskip 的,但 % \selectfont 时会再乘一次 \linespread,所以必须先把 \linespread 归 1。 % 这一步不能省,也必须在 \AtBeginDocument 之后再设一次 % (ctex 在 begin document 时会重设)。 %---------------------------------------------------------------------- \newcommand{\sfmbodyfont}{% \linespread{1}\relax \fontsize{18}{21.6}\selectfont} % 三档字号(行距取字号的 1.2 倍,与单倍行距一致) \newcommand{\sfmbigfont}{\linespread{1}\relax\fontsize{18}{21.6}\selectfont} \newcommand{\sfmmidfont}{\linespread{1}\relax\fontsize{16}{19.2}\selectfont} \newcommand{\sfmsmlfont}{\linespread{1}\relax\fontsize{14}{16.8}\selectfont} %---------------------------------------------------------------------- % ⚠️ xeCJK 陷阱:局部字体切换命令若紧邻 \par(或落在段落末尾),段末的 % 字体状态会"溢出"到后面段落。故局部切换一律用带 \normalfont 收尾的包装。 %---------------------------------------------------------------------- \newcommand{\SFMHT}[1]{{\heiti #1\normalfont}} %---------------------------------------------------------------------- % 这里做了根治】 % % 现象:写 {\heiti ×××} 后编译,PDF 里这些 × 实际用的是 % Times New Roman, % 不是黑体。§ 29 个 × 撑不满预期宽度,跟汉字混排时基线也偏。 % % 原因:xeCJK 按 Unicode 区段分类。「×」是 U+00D7,落在 Latin-1 补充区, % xeCJK 把它判成【西文字符】⇒ 交给 fontspec 的西文字体(TNR)。 % \heiti / \fangsong 只切换 CJK 字体,对这个字符【不起作用】。 % 所以 {\fangsong ××} 这种写法看着像修好了,实际并没有 % (年度考核登记表/ 的 PDF 里 × 至今仍是 TNR)。 % % 正解:把 U+00D7 显式声明为 CJK 字符类,让它回到 CJK 字体族, % \heiti / \fangsong 才能真正管到它。全角宽度也就与汉字一致了。 % % ⚠️ 这条只在本包内生效,不影响其它模板(年度考核登记表 若也要修, % 把这两行照抄过去即可)。 %---------------------------------------------------------------------- \xeCJKDeclareCharClass{CJK}{"00D7} % × 乘号 → 归 CJK,跟着 \heiti/\fangsong 走 \xeCJKDeclareCharClass{CJK}{"2014} % — 破折号 → 归 CJK(学年区间「2025—2026」用得上) %====================================================================== % 3. 列的宽度模型 % % tblGrid(2 个网格列,col_widths_pct = [30, 70]): % c1 = 170 × 30% = 51.000 mm % c2 = 170 × 70% = 119.000 mm % % cellMar:left/right = 85 twips = 1.4993 mm,top/bottom = 0 % 边框 :w:sz = 4(单位 1/8 pt)⇒ 0.5 pt = 0.1764 mm % %---------------------------------------------------------------------- % ⚠️ 与 ouclw.sty 一样,这里可以如实还原内边距(最窄列 51mm 远宽于两倍 % 内边距 3.00mm,不像年度考核表那样被极窄列逼着取 colsep=0)。 % % tabularray 的 colsep 计在每列【左右两侧】,故 2 列共 4×1.4993 = 5.9972mm; % 竖线 3 根(左边界 + 中间 + 右边界)× 0.1764mm = 0.5292mm。 % 要让 Σwd + 5.9972 + 0.5292 = 170.000,需 % Σwd = 163.4736 mm % 而 (gridCol − 2×1.4993) 之和为 164.0028 mm,两者差 0.5292 mm 正好是竖线宽, % 故每列再减 0.5292/2 = 0.2646 mm。 % % ⚠️ 上式只是理论值。tabularray 的计宽与画宽之间有约 0.45 pt 的取整差, % 实际需再微调(见 3.2 的标定值),否则一直报 % "Table width is too small, need 0.45pt more!" 外加一条 Overfull \hbox。 %====================================================================== \newcommand{\sfmrule}{0.5pt} % 边框粗细(w:sz=4) \newcommand{\sfmcolsep}{1.4993mm} % 单元格左右内边距(85 twips) \newlength{\sfmtblw} \setlength{\sfmtblw}{170mm} % 表宽(含 3 根竖线与 4 处内边距) %---------------------------------------------------------------------- % 3.1 各列宽(= gridCol − 2×colsep − 竖线分摊的理论值) % 与 sfmtable 环境里 colspec 的 wd 必须逐字一致。 %---------------------------------------------------------------------- \newcommand{\sfmwa}{47.7368mm} % c1 51.000 − 2.9986 − 0.2646 \newcommand{\sfmwb}{115.7368mm} % c2 119.000 − 2.9986 − 0.2646 %---------------------------------------------------------------------- % 3.2 各列【内容可用宽】 % % 单列单元格的内容宽 = wd(左右两半 colsep 已被 colspec 扣掉并计入表格宽)。 % 本表全部是不跨列的单列格,没有"合并格回收内边距"的问题(ouclw.sty 的 % \lwspanA / \lwspanB 那类坑在这里不存在)。 %---------------------------------------------------------------------- %====================================================================== % 4. 行高 % % 每行都是 w:trHeight + w:hRule="exact"(固定行高,不是 atLeast): % R1 学年 42.55 pt = 15.011 mm % R2 学期 42.55 pt = 15.011 mm % R3 课程号 43.55 pt = 15.363 mm % R4 选课号 41.05 pt = 14.482 mm % R5 考试课程名称 41.30 pt = 14.570 mm % R6 课程类型 42.55 pt = 15.011 mm % R7 面向专业 93.10 pt = 32.844 mm ← 唯一高行,容 5 个专业名折行 % R8 面向年级 42.55 pt = 15.011 mm % R9 试卷份数 52.80 pt = 18.627 mm % R10 授课教师 42.55 pt = 15.011 mm % R11 日期 42.55 pt = 15.011 mm % ──────────────────────────────────────── % 合计 185.949 mm % % ⚠️ Word 的 exact 是"精确等于",内容超了会【被裁掉】。tabularray 的 % ht= 是最小行高(内容多则自动长高),语义更安全。本表各行内容都远 % 小于行高,两者结果相同,故直接写 ht=。 % % ⚠️ 那几行 42.55 / 43.55 / 41.05 / 41.30 的零头不是随机的:Word 里 % 它们是"字符高 + 段前段后"凑出来的实际测量值,照抄才能与原卷逐行对齐。 %====================================================================== %====================================================================== % 5. 表格环境 % % ⚠️ 用 tblr 而非 longtblr:本表总高约 186 mm,一页装得下(版心高 % 297 − 2×25.01 = 247 mm),不需要断页。 % % ⚠️⚠️ colspec 与 row{} 必须字面写在这里,不能先存进宏再展开: % tabularray 的列类型解析在宏展开之外进行,会报 % "Unexpandable command \xxx inside column type"。 % (所以 3.1 节那些 \sfmwa… 只作文档用,不能拼进 colspec。) % % ⚠️ 选项里的宏名一律不带 @:tabularray 解析选项时 @ 不是字母。 %====================================================================== \newenvironment{sfmtable}{% \par\begingroup \begin{tblr}[label=none]{ colspec={Q[c,m,wd=47.7368mm] Q[c,m,wd=115.7368mm]}, colsep=1.4993mm, rowsep=0pt, stretch=0, hline{1-Z}={\sfmrule}, vline{1-Z}={\sfmrule}, row{1}={ht=15.011mm}, row{2}={ht=15.011mm}, row{3}={ht=15.363mm}, row{4}={ht=14.482mm}, row{5}={ht=14.570mm}, row{6}={ht=15.011mm}, row{7}={ht=32.844mm}, row{8}={ht=15.011mm}, row{9}={ht=18.627mm}, row{10}={ht=15.011mm}, row{11}={ht=15.011mm}, }% }{% \end{tblr}\par\endgroup} %====================================================================== % 6. 单元格内容包装 % % 本表全是单列格,tabularray 的 Q[c,m,wd=…] 已处理好居中与折行, % 不需要 ouclw.sty 那种定宽 \parbox。这里只提供两个语义化的标签宏, % 让 .tex 里不必反复写 \SFMHT{}。 %====================================================================== % \sfmlabel{文字} —— 左列标签:黑体 18pt \newcommand{\sfmlabel}[1]{{\heiti\sfmbigfont #1\normalfont}} % \sfmval{文字} —— 右列值(16pt,最常用) \newcommand{\sfmval}[1]{{\heiti\sfmmidfont #1\normalfont}} % \sfmvalbig{文字} —— 右列值(18pt):学年 / 学期两行 \newcommand{\sfmvalbig}[1]{{\heiti\sfmbigfont #1\normalfont}} % \sfmvalsmall{文字} —— 右列值(14pt):课程号 / 选课号 \newcommand{\sfmvalsmall}[1]{{\heiti\sfmsmlfont #1\normalfont}} %====================================================================== % 7. 表外标题 % % 第 1 段:黑体、加粗、w:sz=36(18pt)、jc=center % % 原文标题是「信息科学与工程学院试卷」,按现行建制与文档实际用途已改为 % 「信息科学与工程学部试卷归档封面」 % 实际18pt 下宽 94.89mm,版心宽 170mm,左右各余约 37mm,单行不折。 % 再加长(比如后面挂"(理论课)")仍有余量,超过 170mm 才会折行。 % % 标题与表格之间有 3 个空段落(idx 13/14/15), % 合计 3 × 21.6pt = 64.8pt = 22.86 mm。这里用 \sfmtitleskip 还原。 %====================================================================== \newlength{\sfmtitleskip} \setlength{\sfmtitleskip}{22.86mm} \newcommand{\sfmtitle}[1]{% \par \begingroup \centering {\heiti\bfseries\sfmbigfont #1\par}% \endgroup \vspace{\sfmtitleskip}} %====================================================================== % 8. 表后空行 % % 表格之后还有一个空段落(idx 212)。 %====================================================================== \newcommand{\sfmtail}{\par\null\par} \AtBeginDocument{\sfmbodyfont} \endinput