TeXmacs 文档
面向处理 GNU TeXmacs 的智能体的实用指南,内容来源于转换课堂笔记和讲座、编写样式包以及审核长数学手稿。请保持更新:将新学到的内容添加到“陷阱”部分,并确保 scripts/ 中的脚本正常工作。项目特定的添加内容应放在指向此处的单独本地技能中;“强制约定”部分适用于所有情况。
来源:https://github.com/mgubi/texmacs-skill。最后更新:2026-11-04。
保持此技能更新
此技能旨在作为 git 克隆安装(通常为 ~/.claude/skills/texmacs)。在处理 TeXmacs 文档之前:
- 更新它: 运行
git -C <skill dir> pull --ff-only(如果 SSH 连接到 GitHub 失败,则从https://github.com/mgubi/texmacs-skill.git main拉取)。如果克隆包含未推送的本地更改或提交,请告知用户,而不是直接拉取覆盖。 - 贡献回来: 当学到关于 TeXmacs 的新内容时,将其添加到此(通常添加到“陷阱”,或修复脚本),在克隆中提交并推送到 GitHub(如果无法推送,则打开拉取请求),以便每次安装都能获得。项目特定内容保留在项目中。
文件格式
-
.tm文件是一个序列化树:<tag|arg1|arg2>内联,<\tag>…</tag>(参数之间使用<|tag>)用于块参数,段落由空行分隔,缩进仅为布局。在字符串内部,\<alpha\>是符号,<less>/<gtr>是</>,\|是字面竖线,<#89AB…>是十六进制原始数据(嵌入图像)。 -
编码:字符串是 Cork (T1) 编码,而非 UTF-8。 带重音的拉丁字母大多与 Latin-1 字节一致(é = 0xE9,à = 0xE0,ö = 0xF6),但例如短破折号 = 0x15,长破折号 = 0x16,§ = 0x9F;任何其他 Unicode 字符都写作
<#XXXX>(十六进制码点)。不要自行编写<#XX>作为独立标记:它会被读取为原始数据(请参阅“编写样式包”)。后果:永远不要使用 UTF-8 工具编辑 .tm 文件(“编辑/写入”工具会拒绝或损坏它)。使用 Python 的encoding='latin-1', newline=''进行读写,或者更好的方法是使用下面的 stree 路径,让 TeXmacs 写入文件。 -
手动编写
.tm文件:完全复制此骨架。 顶层项之间必须用空行分隔;没有空行,TeXmacs 将只保留<TeXmacs|…>头并静默丢弃其他所有内容(stree 转储将是(document (TeXmacs "2.1.5")),PDF 为空,并且没有错误):<TeXmacs|2.1.5> <style|<tuple|article|british>> <\body> 第一段包含 <math|x<rsup|2>>。 第二段。 </body> <\initial> <\collection> <associate|font|TeX Gyre Pagella> </collection> </initial>在
<\body>内部,段落(以及任何<\tag>…</tag>的块)也由空行分隔;单个换行表示继续同一段落。每个块起始标签在自己的行上关闭,将符号转义为\<alpha\>,并将文本中的字面<、>、|转义为<less>、<gtr>、\|,并保持文件为 Cork/Latin-1 编码(一旦包含非 ASCII 字符,就使用 Python 编写,而不是使用printf或“写入”工具)。 -
首选生成而非手动编写。 对于超过几行的内容,在 Python 中构建 stree(
scripts/latex2tm/stree.py)并让 TeXmacs 序列化它(dump.scm中的tm-undump);或者编写片段,tm-dump它并拼接树。手动编写时,在使用前检查结果:tm-dump它并确认 body 具有预期的段落数,或者排版它并确认 PDF 文本非空且完整(mutool draw -F txt)。空的或过短的 PDF,或包含一个巨大节点的转储,意味着格式化错误,而不是 TeXmacs 的错误。 -
大文件:演讲将图像嵌入为原始数据(10+ MB)。在读取前剥离
<#…>序列:re.sub(r'<#[0-9A-F]{200,}>', '<#HEX>', s)。
无头运行 TeXmacs
二进制(macOS):/Applications/TeXmacs.app/Contents/MacOS/TeXmacs;在 Linux 上为 texmacs。已在 2.1.4 和 2.1.5 上测试。scripts/latex2tm/run.sh 包含路径;请在那里调整。
- 转换:
TeXmacs -headless -c in.tex out.tm -q(LaTeX 导入),-c in.tm out.pdf -q(当前缓冲区的 PDF)。 - Scheme:
TeXmacs -headless -x "(begin (load \"/abs/dump.scm\") … (quit-TeXmacs))"。 始终将主体包装在(catch #t (lambda () …) (lambda args (display args)))中,并以(quit-TeXmacs)结束:否则错误会导致进程永远挂起。在后台运行并轮询其 PID(请参阅scripts/latex2tm/run.sh);仅杀死该 PID — 永远不要使用pkill TeXmacs(用户可能正在打开 TeXmacs)。 - 无头运行会将 TeXmacs 自身的状态写入
~/.TeXmacs/system;这是正常的。
可无头工作的 Scheme API(scripts/latex2tm/dump.scm)
(tree-import (string->url f) "texmacs")/"latex",以及(tree-export t (string->url f) "texmacs"):无缓冲区的文件 ↔ 树。(tree->stree t)/(stree->tree s):s 表达式。使用(call-with-output-file f (lambda (p) (write s p)))写入它们 —with-output-to-file在 TeXmacs 的 Guile 中不会重定向。Guile 将控制字符写为\xHH转义(由scripts/latex2tm/stree.py处理)。- 排版:
(load-buffer u) (switch-to-buffer u) (export-buffer-main u (string->url pdf) "pdf" (list))— 实际排版的是 PDF 导出。(update-document "all")在无头模式下不起作用(它是一个延迟的空闲命令);直接调用(generate-all-aux) (update-current-buffer)以填充目录/参考文献,再次导出,然后(buffer-pretend-modified u) (buffer-save u)以存储<\references>。一个新文件需要两次排版运行,在单独的进程中,每次都要进行真正的 PDF 导出,然后所有引用才能解析(scripts/latex2tm/typeset.sh)。 始终使用(list :overwrite)作为选项导出:在无头模式下,export-buffer-main否则会要求确认替换现有文件,无人响应,并且导出会被静默跳过(mgubi/texmacs#807)。dump.scm中的tm-typeset和tm-html执行此操作。 - 演示文稿(
screens)仅导出当前屏幕。要进行视觉检查,请构建一个预览副本,其中屏幕被展平为用new-page*分隔的页面(scripts/latex2tm/preview_slides.py);交付 screens 版本。 - 使用
mutool draw -r 60 -o p%d.png file.pdf和magick montage … -tile 4x1 -geometry +4+4检查输出;使用mutool draw -F txt -o - file.pdf检查文本(统计?以查找未解析的引用)。
HTML 导出
在 TeXmacs 内部 进行 HTML 自定义:样式包(或插件)设置导出器的变量,并给出宏的 tmhtml- 渲染;网站通过使用 TEXMACS_HOME_PATH 指向站点的插件文件夹并调用 (style-clear-cache) 来导出目录(tmweb-convert-dir)而构建。不要使用脚本后处理生成的 HTML。
将通用修复收集到一个插件中(下面称为 max-html,链接为 ~/.TeXmacs/plugins/max-html),并将文档特定的设置保留在文档的包中。这样的插件包含:
-
progs/max-html/fixes.scm,在启动时加载,修复 MathJax 导出。公式内的标签获取锚点(#617),\ring写入为\mathring(#607),equations-base写入为aligned(#611)。它替换(convert html tmhtml)内部tmhtml-mathjax-formula*的绑定(module-variable+variable-set!;内部辅助函数如cork->html通过module-ref),并使用tm-define … (former x)扩展latex-mathjax。 -
包
max-html(articles)提供带框定理、列表标签和内容侧面板div.max-toc。包max-html-slides提供幻灯片查看器和tmhtml-mytitle/myframed/myframed-2。 -
resources/包含max-html.css/js和max-html-slides.css/js,用于复制到页面旁边。文档包<use-package|max-html>并再次分配整个html-extra-css元组(插件文件在前):merge不起作用,因为导出器读取未求值的变量。字体是 CSS 变量(--max-text-font、--max-slide-font)。 -
HTML 导出的通用修复放入插件中。文档特定内容(字体、favicon、演讲宏)放入文档的包中。
-
导出:
(tm-html in out mathjax?)在scripts/latex2tm/dump.scm中(首选项texmacs->html:mathjax|css|images,然后(export-buffer-main u (string->url "x.html") "html" (list)))。导出版排好的 .tm 文件(存储的<\references>提供数字)。doc.tm#label链接变为doc.html#label;图像变为页面旁边的<base>-N.png;MathJax 3 来自 jsdelivr。 -
导出器读取的样式变量(在样式包中设置):
html-css(替换默认的内联 css)、html-extra-css(额外样式表的元组,保留默认 css)、html-extra-javascript-src(元组,延迟)、html-extra-javascript、html-head-javascript(-src)、html-head-favicon、html-title、html-doc-title、html-site-version。 -
宏的 HTML 渲染:在
NAME旁边定义tmhtml-NAME。 导出器会使用它而不是NAME。为此的标记辅助函数:html-div-class|class|body(块)、html-class|class|body(内联 span)、html-style、html-div-style、html-attr、html-tag、html-javascript。这仅适用于在样式包中定义的宏:在文档的hide-preamble中分配的宏在导出前会被展开,它们的tmhtml-变体将被忽略。因此,请将演示宏放在一个包中。 -
文档旁边的包
foo.ts在样式元组列出foo时会被找到。编辑包后,调用(style-clear-cache)(TeXmacs 在~/.TeXmacs/system/cache中缓存样式环境),否则将使用旧的定义。 -
目录(和其他生成的列表):条目被写入 aux 数据时已经展开(
write求值其参数),因此围绕toc-main-*/toc-1…5的包装器会消失,它们的tmhtml-变体永远不会被看到。只有外部的table-of-contents宏可以具有tmhtml-渲染。在展开和导出中幸存下来的标记:<b>(粗体章节)、<with|font-size|…>→<font style=…>、font-shape→<i>/小型大写字母、color→<font color>;par-left缩进丢失。每个条目以<a href="#auto-N">page</a>结束。侧面板配方(插件包max-html):tmhtml-table-of-contents→div.max-toc固定在左侧;使用.max-toc p a[href^="#auto-"] {position:absolute; inset:0; font-size:0}隐藏并拉伸页面链接(按 href 选择:标题中的eqref也是一个链接);通过使用嵌套的<with|font-size|0.92|…>重新定义toc-3…5并选择p:has(> font)来标记段落级条目。更改toc-*宏后,重新生成目录(两次排版运行)。 -
在面板中高亮显示当前章节需要 JavaScript:
max-html.js(插件),通过包中的html-extra-javascript-src附加;它将每个条目的#auto-N链接映射到具有该 ID 的标题,标记视口 25% 以上的最后一个标题(p.toc-current,及其粗体父元素p.toc-current-section)并滚动面板以使其保持可见。 -
带框定理(Joris van der Hoeven 的网络文章,例如 texmacs.org/joris/fftcomp;模型是 TeXmacs 中的
styles/article/texmacs/tmarticle.ts):定义tmhtml-render-theorem→<html-div-class|theorem|<render-enunciation|…>>和tmhtml-render-enunciation与<html-class|enunciation-name|which>;定理、命题、引理、推论和定义使用render-theorem,而备注和证明使用render-remark。Joris 的 css(texmacs.org/css/theme-dark-colored.css)是.theorem {border: 1px solid; border-left: 1em solid; padding: 0 1em};柔和的颜色和 .5em 的条也效果很好(max-html.css)。这仅适用于 HTML;PDF 不变。 颜色(也如 Joris 主题中所用):h1…h6, strong, b, dt, .enunciation-name使用柔和的暗红色,MathJax 输出通过mjx-container {color: …};重置 TOC 面板内部的b。 -
HTML 导出将每个
enumerate-alpha|Alpha|roman转换为普通的<ol>(十进制标签)。修复方法:tmhtml-enumerate-alpha→<html-div-class|enum-alpha|<enumerate|…>>加上.enum-alpha > ol > li::marker {content: "(" counter(list-item, lower-alpha) ")"}。 -
MathJax:转换器将环重音符
<abovering>写为\ring{…}(LaTeX 包 accents),MathJax 缺少它(mgubi/texmacs#607)。由插件修复。页面级别的替代方案是在html-extra-javascript中使用内联 MathJax 配置(它在 MathJax<script>之前运行):window.MathJax = {tex: {macros: {ring: [String.fromCharCode(92) + 'mathring{#1}', 1]}}}。 -
MathJax:
equation内部的aligned会被 HTML 导出器预展开为equations-base,并以\begin{equationsbase}的形式到达 MathJax(mgubi/texmacs#611)。由插件修复;页面级别的替代方案是在该配置中使用environments: {equationsbase: […aligned…]}。 -
使用
scripts/mathjax-check/检查导出的所有公式:在临时deps/文件夹中运行npm install [email protected],然后运行python3 extract.py HTMLDIR formulas.json(使用 HTML 解析器:\(t < \infty\)中的原始<是文本,就像在浏览器中一样)和node check.js deps/node_modules formulas.json。它会在没有noundefined包的情况下渲染每个公式(浏览器中该包会静默地用红色显示未定义的宏)并对错误进行分组。它不会看到空公式(单独统计\(\displaystyle \))或死链接:还要检查每个内部href="… #x"是否有匹配的id="x"。 -
幻灯片:宽度为
100%的图像被 CSSmax-height缩小后,会停留在其段落的左侧;使用div.toggle img.image {display: block; margin: 0 auto}将其居中。 -
无头 Firefox:
user.js中的深色模式content-override首选项未生效;改变声音……