Communityライティング&編集github.com

mgubi/texmacs

GNU TeXmacs文書(.tmファイル)の読み取り、書き込み、変換、組版を行います。.tmファイル、TeXmacsアプリ、LaTeX/beamerからネイティブTeXmacsへの変換、TeXmacsプレゼンテーション(beamerスタイル、スクリーン)、TikZプラグイン、またはTeXmacsをヘッドレスでPDFにエクスポートするタスクに関わる場合に使用します。

texmacs とは?

このスキルは、GNU TeXmacs文書(.tmファイル)を扱うエージェント向けの実践的なガイドです。講義ノートや講演の変換、スタイルパッケージの作成、長大な数学原稿の監査を通じて収集された知見を集約しています。Claude Code、Cursor、Codexなどのエージェントが、.tmファイルの読み書き、LaTeX/beamerからTeXmacsへの変換、ヘッドレスモードでのPDFやHTMLへのエクスポート、さらにTeXmacsプレゼンテーション(スクリーン機能)の生成などを確実に行えるようにします。特にファイルフォーマットの詳細(Corkエンコーディング、S式による内部構造)、ヘッドレス操作のためのScheme API、HTMLエクスポートのカスタマイズ方法、そして数式の検証スクリプトなど、実運用で役立つ具体的な手順が記述されています。このスキルはGitクローンとしてインストールし、プロジェクト固有の知見は別のローカルスキルに分離する運用を想定しています。

対応✓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に質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

TeXmacs文書

GNU TeXmacsを扱うエージェントのための実践的なガイド。講義ノートや講演の変換、スタイルパッケージの作成、長大な数学原稿の監査を通じて収集。継続的に更新するため、新しく学んだことは「落とし穴」に追加し、scripts/内のスクリプトを動作可能な状態に保ってください。プロジェクト固有の追加事項は、このスキルを参照する別のローカルスキルに属します。「(必須)規約」セクションはすべてのプロジェクトに適用されます。 出典: https://github.com/mgubi/texmacs-skill。最終更新日: 2026-11-04。

このスキルを最新の状態に保つ

このスキルはgitクローンとしてインストールすることを前提としています(通常は ~/.claude/skills/texmacs)。TeXmacs文書を扱う前に:

  • 更新: git -C <スキルディレクトリ> 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…> が16進数の生データ(埋め込み画像)です。

  • エンコーディング: 文字列はCork(T1)エンコードであり、UTF-8ではありません。 アクセント付きラテン文字の多くはLatin-1バイトと一致します(é = 0xE9、à = 0xE0、ö = 0xF6)。ただし、enダッシュ = 0x15、emダッシュ = 0x16、§ = 0x9Fなどは異なります。その他のUnicode文字は <#XXXX>(16進コードポイント)で記述します。<#XX> を単独のトークンとして自分で記述しないでください。生データとして読み取られます(「スタイルパッケージの作成」を参照)。結果: UTF-8ツールで.tmファイルを編集しないでください(Edit/Writeツールは拒否するか破損させます)。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>
      First paragraph with <math|x<rsup|2>>.
    
      Second paragraph.
    </body>
    
    <\initial>
      <\collection>
        <associate|font|TeX Gyre Pagella>
      </collection>
    </initial>
    

    <\body> 内では、段落(および任意の <\tag>…</tag> ブロック)も空行で区切られます。単一の改行は同じ段落を継続します。すべてのブロックタグは独自の行で閉じ、シンボルを \<alpha\> として、テキスト内のリテラル <、>、| を <less>、<gtr>、\| としてエスケープし、ファイルをCork/Latin-1に保ちます(非ASCII文字が含まれるとすぐに、printf やWriteツールではなくPythonで作成してください)。

  • 手書きよりも生成を優先する。 数行を超える場合は、Pythonでstreeを構築し(scripts/latex2tm/stree.py)、TeXmacsにシリアライズさせてください(dump.scm の tm-undump)。または、断片を作成し、tm-dump してツリーを結合します。手書きの場合は、使用前に結果を確認してください: tm-dump して本文の段落数が期待通りであることを確認するか、組版してPDFテキストが空でなく完全であることを確認してください(mutool draw -F txt)。PDFが空か短い場合、または巨大なノードが1つあるダンプは、TeXmacsのバグではなくフォーマットエラーを示します。

  • 大きなファイル: トークは画像を生データとして埋め込みます(10MB以上)。読み取り前に <#…> の連続を除去: 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エクスポートを含む、2回の組版実行が必要です(scripts/latex2tm/typeset.sh)。オプションとして 常に (list :overwrite) を指定してエクスポートしてください: ヘッドレスでは、export-buffer-main は既存のファイルを置き換える確認を求め、誰も応答しないため、エクスポートは静かにスキップされます(mgubi/texmacs#807)。tm-typeset と tm-html(dump.scm 内)はこれを行います。
  • プレゼンテーション(screens)は現在のスクリーンのみをエクスポートします。視覚的な確認のため、スクリーンを new-page* で区切られたページにフラット化したプレビューコピーを作成してください(scripts/latex2tm/preview_slides.py)。スクリーンバージョンを納品します。
  • 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エクスポート

HTMLのカスタマイズは TeXmacs内部 で行ってください: スタイルパッケージ(またはプラグイン)がエクスポーターの変数を設定し、マクロの tmhtml- レンダリングを提供します。ウェブサイトは、TEXMACS_HOME_PATH をサイトのプラグインフォルダに向け、(style-clear-cache) を呼び出した状態で、ディレクトリをエクスポート(tmweb-convert-dir)することで構築します。生成されたHTMLをスクリプトで後処理しないでください。

汎用的な修正は1つのプラグインにまとめてください(以下では 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 経由)、latex-mathjax を tm-define … (former x) で拡張します。

  • パッケージ max-html(記事)は、枠付き定理、リストラベル、コンテンツサイドパネル 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エクスポートのための一般的な修正はプラグインに含めます。ドキュメント固有のもの(フォント、ファビコン、トークマクロ)はドキュメントのパッケージに含めます。

  • エクスポート: (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(タプル、deferred)、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(インラインスパン)、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 もリンクです)。toc-3…5 をネストされた <with|font-size|0.92|…> で再定義し、p:has(> font) で選択して、段落レベルのエントリをマークします。toc-* マクロを変更した後は、TOCを再生成します(2回の組版実行)。

  • パネル内の現在のセクションをハイライトするには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>(10進数のラベル)に変換します。修正: 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" があることも確認してください。

  • スライド: width=100% でCSSの max-height によって狭められた画像は、段落の左側に留まります。div.toggle img.image {display: block; margin: 0 auto} で中央揃えにします。

  • ヘッドレスFirefox: user.js のダークモード content-override 設定は有効になりませんでした。変更するには…

…(以下略)

関連スキル