Community写作与编辑github.com

mgubi/texmacs

读取、编写、转换和排版 GNU TeXmacs 文档 (.tm)。当任务涉及 .tm 文件、TeXmacs 应用程序、将 LaTeX/beamer 转换为原生 TeXmacs、TeXmacs 演示文稿(beamer 样式、屏幕)、TikZ 插件或无头导出 TeXmacs 为 PDF 时使用。

texmacs 是什么?

该技能为 AI 代理(如 Claude、Coder 或 Codex)提供了处理 GNU TeXmacs 文档的综合指南。它涵盖了 TeXmacs 独特文件格式的基础知识,该格式使用 Cork(T1)编码而不是 UTF-8,要求正确转义特殊字符,并支持从 LaTeX/beamer 导入、PDF 导出以及通过 Scheme API 进行无头批量操作。该技能包含关键陷阱,例如在 Cork/Latin-1 编码中处理 TeXmacs 的序列化树结构,无头 TeXmacs 执行的正确错误处理,以及从样式包和文档本身定义 HTML 导出变量。它还提供了使用 MathJax、TOC 生成和框架定理的高级 HTML 自定义技术,所有这些都可以通过一个插件收集。安装后,当 .tm 文件出现在上下文中或用户请求 TeXmacs 操作时,应引用此技能。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/mgubi/texmacs-skill/tree/HEAD

Installed? Explore more 写作与编辑 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

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% 的图像被 CSS max-height 缩小后,会停留在其段落的左侧;使用 div.toggle img.image {display: block; margin: 0 auto} 将其居中。

  • 无头 Firefox:user.js 中的深色模式 content-override 首选项未生效;改变声音……

相关技能