尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LaTeX2e 内核开发中的双重 `\kern` 探针:`usage-of-kern-kern.md` 扫描清单与宏包兼容性解读

LaTeX2e 内核开发中的双重 `\kern` 探针:`usage-of-kern-kern.md` 扫描清单与宏包兼容性解读 编程语言标准库【免费下载链接】latex2eThe LaTeX2e kernel项目地址https://gitcode.com/gh_mirrors/la/latex2e点击查看免费下载导读在 LaTeX2e 内核本项目latex2e的日常开发中开发团队需要持续审计 CTAN 上数以千计的第三方宏包确保内核改动不会破坏既有生态。本文围绕required/latex-lab/usage-of-kern-kern.md这份扫描清单展开它记录了 TeX Live 2022 中通过成对微小\kerndouble\kern进行状态探针的宏包与类文件。读完本文你将理解这类双 kern 探针技巧的底层原理、清单中各真实用法的动机与风险以及它与 LaTeX2e 内核脚注机制footmisc 兼容层、fnmark钩子之间的关联并掌握在自有宏包中安全使用该技巧的判断准则。这份文档是什么TeX Live 生态中的双\kern用法扫描required/latex-lab/usage-of-kern-kern.md是 LaTeX2e 开发团队为latex-lab实验室模块维护的一份内部审计笔记。文档标题为Packages that use double\kerns正文开篇即自述其性质Scan of TeXlive 2022 for checking ... may not be longer accurate and may contain a few false positives (definitely contains bogus entries right now)也就是说这份清单是基于 TeX Live 2022 快照的一次静态扫描快照并非权威注册表它本身可能过时也可能含有误报。它真正的价值在于当内核团队尤其是 latex-lab-footnotes.dtx 这类脚注兼容层需要引入或修改依赖连续微小 kern的探针机制时先盘点生态中有哪些宏包正在依赖同一块公共信标评估冲突与回退策略。清单以代码片段 文件路径的格式组织共收录了 14 处真实用法分布在 13 个宏包/类/驱动文件中。它们几乎全部围绕同一个约定俗成的空间量级1 sp 到 5 spsp 即 scaled point1 pt 65536 sp1 sp ≈ 1.53×10⁻⁵ pt并成对出现先插入一个负 kern再插入一个同绝对值正 kern。底层原理为什么成对微小\kern能当探针在 TeX 排版模型中\kern插入的是固定无弹性的水平空间与\hskip不同它不能被拉伸/收缩且不受断行影响。若在水平模式中依次插入\kern -3sp与\kern 3sp两者的总效果是零位移不改变最终版面但在插入后的那一瞬间当前列表末尾的信息是可观测的\lastkern原语返回列表末尾最后一个 kern 的宽度\dimen可用\ifdim\lastkern值比较\unkern原语则移除列表末尾的最后一个 kern。因此宏包可以这样设计协议用一个微小且可逆的 kern 序列作为签名自己的代码在排版某标记如脚注标记、注音符号、汉字间隔前先插入成对 kern而同一宏包或协作方的另一个执行点再通过\ifdim\lastkern3sp\relax \unkern\unkern ...判断上一步是否是我自己留下的标记从而识别上下文、合并重复输出、或在连续标记之间插入分隔符。这个技巧的吸引力在于零视觉副作用1~5 sp 的正负对互相抵消肉眼与测量上都看不出间距变化不污染语义它不是字符、盒子或 whatsit理论上不会影响断行、行间粘连与\spacefactor虽然部分实现会额外保存/恢复 spacefactor低开销\kern/\lastkern/\unkern都是原语级操作比保存计数器或宏状态更快局部可回滚\unkern可以精确弹出末尾 kern适合探测后立即清理的流程。代价也很明显它依赖排版执行时机只能在水平模式下工作一旦中间插入了其他水平材料探测就会失效而且多个宏包如果共用相同数值的 kern 签名就会互相误判——这正是清单存在的原因。清单逐条解读14 处真实用法1. 脚注标记折叠协议3sp家族6 处清单中最大的家族共用同一个探针宽度3 sp用于合并连续脚注标记并插入分隔符文件用法tufte-latex/tufte-common.def\providecommand*{\multiplefootnotemarker}{3sp}memoir/memoir.cls\newcommand*{\multiplefootnotemarker}{3sp}eledmac/eledmac.sty\providecommand*{\multiplefootnotemarker}{3sp}reledmac/reledmac.sty\providecommand*{\multiplefootnotemarker}{3sp}parnotes/parnotes.sty\providecommand*{\multiplefootnotemarker}{3sp}lwarp/lwarp-footmisc.sty\providecommand*{\multiplefootnotemarker}{3sp}这些包都兼容或重实现了 footmisc 的multiple footnote行为当同一位置连续出现两个脚注标记时把它们合并为1,2的形式。其协议是第一个标记之后\kern 3sp作为还有后续的信号第二个标记之前检查\ifdim\lastkern3sp确认后\unkern弹出该 kern、插入\multfootsep默认,再排版下一个标记。这一协议与 LaTeX2e 内核实验室模块直接相关在 latex-lab-footnotes.dtx 中footmisc 兼容层以几乎相同的代码实现了该协议\ifFNmultiplefootnote \providecommand*{\multiplefootnotemarker}{3sp} \providecommand*{\multfootsep}{,} \AddToHook{fnmark} {\FNmfcheck} \AddToHook{fnmark/end} {\FNmfprepare} % \def\FNmfprepare{% \kern-\multiplefootnotemarker \kern\multiplefootnotemarker\relax } \def\FNmfcheck{% \ifdim\lastkern\multiplefootnotemarker\relax \edef\xsf{\the\spacefactor}% \unkern \unkern \textsuperscript{\multfootsep}% \spacefactor\xsf\relax \fi } \else \let\FNmfprepare\relax \fi注意这里的具体实现与清单中 microtype 一行所展示的旧模式有细微差别内核兼容层用\kern-\multiplefootnotemarker\kern\multiplefootnotemarker一对负/正 kern作为签名\FNmfcheck在fnmark钩子处检测\lastkern等于3sp时连续执行两次\unkern源码中留有一句开发注释?? shouldnt that be 2 unkerns ?? (none would also be ok)说明该处是经过斟酌的实现细节再插入上标形式的分隔符\textsuperscript{\multfootsep}并保存/恢复\spacefactor以免影响后续字母间距。而探测后清理正是这类技巧的标准收尾方式。更有意思的是同目录下的姊妹文档 usage-of-footnotemark.md 记录了 bxjscls 对\footnotemark的重新定义——其中同样出现\ifdim\lastkern\z\ifdim\lastkern5sp\relax \unkern\unkern ...的模式先判断末位 kern 落在 (0, 5sp) 区间再弹出两个 kern。这印证了1~5 sp 这个数值区间已成为 LaTeX 生态中探针保留区的社区共识。2. microtype 的字距调整边界标记3 处letterspace.sty 与 microtype-pdftex.def、microtype-luatex.def 中的用法完全相同\ifdim\lastkern-3sp \unkern \ifdim\lastkern3sp \kern-3sp {\kern\MTouterkern\kern3sp\kern-3sp\relax}%microtype 在进行字距调整letterspacing时需要用\MTouterkern保存进入字距调整区域之前的外层 kern以便恢复同时插入\kern3sp\kern-3sp一对正负 kern 作为边界标记。后续通过\ifdim\lastkern-3sp与\ifdim\lastkern3sp两级判断识别当前处于字距调整边界再决定是否执行\unkern与\kern-3sp的弹入弹出。这里负值在前、正值在后的顺序与脚注协议正好相反说明方向本身也是协议的一部分不可混用。3. CJK 生态拼音与注音间隔4 处CJK 宏包家族用成对 kern 实现汉字之间、拼音音节之间的隐形间隔标记CJK.sty\edef\CJKkern{\kern -2sp\kern 2sp}、\edef\CJKCJK{\kern -1sp\kern 1sp}—— 注意这里把 kern 序列放入\edef意味着它会在展开上下文中被使用例如写入辅助文件或进入 token 列表时仍保持可逆性ruby.sty\edef\rubykern{\kern -5sp\kern 5sp}用于拼音注音ruby文本的定位pinyin.sty\edef\pysp{\kern -4sp\kern 4sp}注释明确写着hyphenation between pinyin syllables. Values 1sp-3sp are already used—— 这说明该生态内部已经约定1sp、2sp、3sp 已被其他用途占用新用途应从 4sp 起分配以免互相干扰。这一条的注释是理解整份清单的关键sp 级数值是稀缺资源多个宏包共享同一数值会互相误判因此新用法往上分配、不占用 1–3sp成为一种自发约定。4. 列表边界探测examdesign 与 gloss-korean5 处examdesign.cls\bgroup \kern-3sp\kern3sp % kerns so I can test for beginning of list注释明确说明其目的——用 kern 对来探测是否位于列表list开头gloss-korean.ldfpolyglossia 韩语支持连续使用 4 组探针\kern-1sp \kern1sp } \kern-2sp \kern2sp } \kern-3sp \kern3sp } \kern-4sp \kern4sp }不同的数值用于区分不同的排版状态如不同层级的韩语格助词粘连处理。5. 侧注标记sidenotessidenotes.sty 使用\NewDocumentCommand \sidenotesmultisign { } {3sp}把多标记信号直接实现为一个返回3sp的文档命令再次使用 3 sp 这个共享数值。清单表格汇总数值用途涉及文件3sp负/正或正/负对连续脚注标记合并信号tufte-common.def、memoir.cls、eledmac、reledmac、parnotes、lwarp-footmisc、sidenotes3sp边界两级判断字距调整边界microtype 的 letterspace.sty、microtype-pdftex.def、microtype-luatex.def3sp负/正对列表开头探测examdesign.cls1sp/2sp负/正对CJK 汉字间隔CJK.sty\CJKCJK、\CJKkern4sp负/正对拼音音节间隔cjk pinyin.sty5sp负/正对注音 ruby 间隔cjk ruby.sty1sp~4sp 四组韩语状态区分polyglossia gloss-korean.ldf内核同源实现脚注钩子与\lastkern探测清单并非孤立笔记它与 LaTeX2e 内核/latex-lab 的实现一一对应。在 latex-lab-footnotes.dtx 中footmisc 兼容层通过内核 lthooks.dtx 提供的标准钩子fnmark与fnmark/end挂接探测代码从而把合并连续脚注从宏包自定义实现提升为内核级标准行为。测试侧firstaid-memoir.tlgfirstaid 对 memoir 的补丁测试与 base 下testfiles-lthooks、testfiles-lthooks2中大量.tlg结果都直接引用了\lastkern相关输出用于回归验证钩子执行顺序与 kern 状态的正确性。此外amsmath.dtx 提供了一个轻量级单 kern 变体alignedleftspaceyesifneg选项用\edef\tempa{\expandafter\car\the\lastkern\nil}读取\lastkern的首字符判断是否为负数从而决定\begin{aligned}前是否补\,间距。这说明\lastkern探针在数学环境排版中同样有应用不过它只读不弹属于单向检测与本文讨论的可逆成对签名有所不同。给宏包作者的实践准则结合清单与内核实现可以提炼出如下可操作建议先查清单再分配数值若你的宏包需要成对微小 kern探针先对照usage-of-kern-kern.md确认目标数值未被常见包占用1~3 sp 已被脚注、CJK、microtype 广泛使用新用法优先从 4~5 sp 或更高分配总是成对插入、用完即弹插入负/正对保证零净位移探测成功后立即\unkern必要时两次清理避免把签名泄漏给下游代码若探针被中途打断应有回退路径只在水平模式使用\lastkern在垂直模式会报错或返回其他值使用前应确保处于\hbox或水平段落中宏包层通常配合\leavevmode使用参见 usage-of-footnotemark.md 中 bxjscls 的写法关注内核钩子方案在 LaTeX2e 当前内核中类似合并连续脚注的需求已有标准钩子fnmark、fnmark/end与内核实现latex-lab-footnotes.dtx新宏包应优先复用而非自造探针注意\edef展开语义CJK 系列把 kern 序列放入\edef以便在展开上下文使用此时应确认\kern的原语 token 在目标上下文中仍能正确执行例如写入辅助文件后的重放审慎对待共享数值清单本身也承认存在误报正式发布前应在目标引擎pdfTeX、LuaTeX、XeTeX上实测并留意 TeX Live 版本更迭后生态用法的变化。结语usage-of-kern-kern.md虽然只是一份内部扫描笔记却精准刻画了 TeX 生态中一个被广泛使用却少被系统记录的技巧以 1~5 sp 量级的可逆成对\kern作为零视觉副作用的排版状态信标。从 footmisc 系脚注合并、microtype 字距调整到 CJK 拼音注音与 polyglossia 韩语处理再到 LaTeX2e 内核 latex-lab-footnotes.dtx 对fnmark钩子的标准实现同一机制在不同层面反复出现。理解这份清单既是理解 TeX 低层排版原语的窗口也是在内核与宏包生态之间做兼容性设计时的重要参考。延伸阅读清单原文件usage-of-kern-kern.md姊妹清单\footnotemark重定义扫描usage-of-footnotemark.md内核脚注兼容层实现latex-lab-footnotes.dtx标准钩子机制lthooks.dtx同名技术单 kern 负值检测amsmath.dtx赞分享编程语言标准库【免费下载链接】latex2eThe LaTeX2e kernel项目地址https://gitcode.com/gh_mirrors/la/latex2e点击查看免费下载相关推荐Cap开源录屏工具免费录制、剪辑、一键分享3步出片Cap开源录屏工具免费录制、剪辑、一键分享3步出片 用过的录屏工具十个里有八个让人皱眉免费版带水印、导出要会员、剪完还要传网盘等半天。Cap 是一款开源编程语言标准库上一篇Cirq 量子计算实战指南电路构建、模拟与硬件执行全解析基于 agentic-awesome-skills 技能文档下一篇WinUtil 快速上手3 个真实场景搞定 Windows 优化、装软件和更新策略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表