Documentos TeXmacs
Um guia prático para agentes trabalhando com GNU TeXmacs, coletado enquanto
convertia notas de aula e palestras, escrevia pacotes de estilo e auditava longos
manuscritos matemáticos. Mantenha-o vivo: adicione o que for aprendido recentemente em
"Pitfalls" e mantenha os scripts em scripts/ funcionando. Adições específicas de projeto
pertencem a uma skill local separada que aponta para cá; a seção
"Convenções (obrigatório)" se aplica em todos os lugares.
Fonte: https://github.com/mgubi/texmacs-skill. Última atualização: 2026-11-04.
Mantendo esta skill atualizada
Esta skill foi feita para ser instalada como um clone git (geralmente
~/.claude/skills/texmacs). Antes de trabalhar em documentos TeXmacs:
- Atualize-a: execute
git -C <diretório da skill> pull --ff-only(se SSH para o GitHub falhar, faça pull dehttps://github.com/mgubi/texmacs-skill.git main). Se o clone tiver alterações locais ou commits que não foram enviados, informe o usuário em vez de fazer pull sobre eles. - Contribua de volta: quando algo novo sobre TeXmacs for aprendido, adicione-o aqui (geralmente em "Pitfalls", ou corrija um script), faça commit no clone e envie para o GitHub (ou abra um pull request se você não puder enviar), para que toda instalação receba a atualização. Material específico de projeto permanece no projeto.
O formato do arquivo
-
Um arquivo
.tmé uma árvore serializada:<tag|arg1|arg2>inline,<\tag>…</tag>(com<|tag>entre argumentos) para argumentos de bloco, parágrafos são separados por linhas em branco, indentação é apenas para layout. Dentro de strings\<alpha\>é um símbolo,<less>/<gtr>são</>,\|é uma barra literal,<#89AB…>são dados hexadecimais brutos (imagens incorporadas). -
Codificação: strings são codificadas em Cork (T1), não UTF-8. Letras latinas acentuadas coincidem principalmente com bytes Latin-1 (é = 0xE9, à = 0xE0, ö = 0xF6), mas por exemplo travessão en dash = 0x15, travessão em dash = 0x16, § = 0x9F; qualquer outro caractere Unicode é escrito
<#XXXX>(ponto de código hex). Não escreva<#XX>sozinho como um token independente: ele é lido como dados brutos (veja "Escrevendo pacotes de estilo"). Consequências: nunca edite um .tm com ferramentas UTF-8 (as ferramentas Edit/Write recusam ou corrompem o arquivo). Leia/escreva com Pythonencoding='latin-1', newline='', ou melhor, vá pela rota stree abaixo e deixe o TeXmacs escrever o arquivo. -
Escrevendo um arquivo
.tmà mão: copie este esqueleto exatamente. Os itens de nível superior são separados por linhas em branco; sem elas o TeXmacs mantém apenas o cabeçalho<TeXmacs|…>e descarta silenciosamente todo o resto (o despejo stree é(document (TeXmacs "2.1.5")), o PDF está vazio, e não há erro):<TeXmacs|2.1.5> <style|<tuple|article|british>> <\body> Primeiro parágrafo com <math|x<rsup|2>>. Segundo parágrafo. </body> <\initial> <\collection> <associate|font|TeX Gyre Pagella> </collection> </initial>Dentro de
<\body>os parágrafos (e os blocos de qualquer<\tag>…</tag>) também são separados por linhas em branco; uma única quebra de linha continua o mesmo parágrafo. Feche cada tag de bloco em sua própria linha, escape símbolos como\<alpha\>e<,>,|literais no texto como<less>,<gtr>,\|, e mantenha o arquivo em Cork/Latin-1 (escreva-o com Python, não comprintfou a ferramenta Write, assim que ele contiver um caractere não-ASCII). -
Prefira gerar em vez de escrever à mão. Para qualquer coisa além de algumas linhas, construa a stree em Python (
scripts/latex2tm/stree.py) e deixe o TeXmacs serializá-la (tm-undumpemdump.scm); ou escreva o fragmento, façatm-dumpe emende a árvore. Ao escrever à mão, verifique o resultado antes de usá-lo: façatm-dumpe confirme que o corpo tem o número esperado de parágrafos, ou componha tipograficamente e confirme que o texto do PDF não está vazio e está completo (mutool draw -F txt). Um PDF vazio ou curto, ou um despejo com um nó enorme, significa um erro de formatação, não um bug do TeXmacs. -
Arquivos grandes: palestras incorporam imagens como dados brutos (10+ MB). Remova sequências
<#…>antes de ler:re.sub(r'<#[0-9A-F]{200,}>', '<#HEX>', s).
Executando TeXmacs sem cabeça
Binário (macOS): /Applications/TeXmacs.app/Contents/MacOS/TeXmacs; no Linux
texmacs. Testado com 2.1.4 e 2.1.5. scripts/latex2tm/run.sh contém o
caminho; ajuste-o lá.
- Converter:
TeXmacs -headless -c entrada.tex saída.tm -q(importação LaTeX),-c entrada.tm saída.pdf -q(PDF do buffer atual). - Scheme:
TeXmacs -headless -x "(begin (load \"/abs/dump.scm\") … (quit-TeXmacs))".Sempre envolva o corpo em(catch #t (lambda () …) (lambda args (display args)))e termine com(quit-TeXmacs): um erro, caso contrário, deixa o processo pendurado para sempre. Execute-o em segundo plano e monitore seu PID (vejascripts/latex2tm/run.sh); mate apenas esse PID — nuncapkill TeXmacs(o usuário pode ter o TeXmacs aberto). - Execuções sem cabeça escrevem o estado do próprio TeXmacs em
~/.TeXmacs/system; isso é normal.
API Scheme que funciona sem cabeça (scripts/latex2tm/dump.scm)
(tree-import (string->url f) "texmacs")/"latex", e(tree-export t (string->url f) "texmacs"): arquivo ↔ árvore sem um buffer.(tree->stree t)/(stree->tree s): expressões s. Escreva-as com(call-with-output-file f (lambda (p) (write s p)))—with-output-to-filenão redireciona no Guile do TeXmacs. Guile escreve caracteres de controle como escapes\xHH(tratado porscripts/latex2tm/stree.py).- Composição tipográfica:
(load-buffer u) (switch-to-buffer u) (export-buffer-main u (string->url pdf) "pdf" (list))— a exportação PDF é o que compõe tipograficamente.(update-document "all")não faz nada sem cabeça (é um comando ocioso atrasado); chame(generate-all-aux) (update-current-buffer)diretamente para preencher o sumário / bibliografia, exporte novamente, então(buffer-pretend-modified u) (buffer-save u)para armazenar<\references>. Um arquivo novo precisa de duas execuções de composição tipográfica, em processos separados, cada um com uma exportação PDF real antes que todas as referências sejam resolvidas (scripts/latex2tm/typeset.sh). Sempre exporte com(list :overwrite)como as opções: sem cabeça,export-buffer-mainpergunta confirmação para substituir um arquivo existente, ninguém responde, e a exportação é silenciosamente pulada (mgubi/texmacs#807).tm-typesetetm-htmlemdump.scmfazem isso. - Apresentações (
screens) exportam apenas a tela atual. Para uma verificação visual construa uma cópia de prévia com as telas achatadas em páginas separadas pornew-page*(scripts/latex2tm/preview_slides.py); entregue a versão de telas. - Verifique a saída com
mutool draw -r 60 -o p%d.png arquivo.pdfemagick montage … -tile 4x1 -geometry +4+4; texto commutool draw -F txt -o - arquivo.pdf(conte?para referências não resolvidas).
Exportação HTML
Faça a customização HTML dentro do TeXmacs: pacotes de estilo (ou um plugin)
definem as variáveis do exportador e fornecem renderizações tmhtml- de macros; um
site é construído exportando um diretório (tmweb-convert-dir) com
TEXMACS_HOME_PATH apontando para a pasta de plugins do site e
(style-clear-cache). Não pós-processe o HTML gerado com scripts.
Colete as correções genéricas em um plugin (abaixo chamado max-html, vinculado
como ~/.TeXmacs/plugins/max-html), e mantenha as configurações específicas do documento no
pacote do documento. Esse plugin contém:
-
progs/max-html/fixes.scm, carregado na inicialização, corrige a exportação MathJax. Rótulos dentro de fórmulas recebem âncoras (#617),\ringé escrito\mathring(#607) eequations-baseé escritoaligned(#611). Ele substitui a ligação detmhtml-mathjax-formula*dentro de(convert html tmhtml)(module-variable+variable-set!; ajudantes internos comocork->htmlviamodule-ref) e estendelatex-mathjaxcomtm-define … (former x). -
O pacote
max-html(artigos) fornece teoremas emoldurados, rótulos de lista e o painel lateral de conteúdodiv.max-toc. O pacotemax-html-slidesfornece o visualizador de slides etmhtml-mytitle/myframed/myframed-2. -
resources/contémmax-html.css/jsemax-html-slides.css/js, para copiar ao lado das páginas. Pacotes de documento<use-package|max-html>e atribuem a tuplahtml-extra-cssinteira novamente (arquivo do plugin primeiro):mergenão funciona, porque o exportador lê a variável não avaliada. Fontes são variáveis CSS (--max-text-font,--max-slide-font). -
Correções genéricas para exportação HTML vão no plugin. Coisas específicas do documento (fontes, favicon, macros de palestra) vão no pacote do documento.
-
Exportação:
(tm-html entrada saída mathjax?)emscripts/latex2tm/dump.scm(preferênciastexmacs->html:mathjax|css|images, então(export-buffer-main u (string->url "x.html") "html" (list))). Exporte o .tm composto tipograficamente (<\references>armazenados fornecem os números). Linksdoc.tm#labeltornam-sedoc.html#label; imagens tornam-se<base>-N.pngao lado da página; MathJax 3 vem de jsdelivr. -
Variáveis de estilo lidas pelo exportador (defina-as em um pacote de estilo):
html-css(substitui o css inline padrão),html-extra-css(tupla de folhas de estilo extras, css padrão mantido),html-extra-javascript-src(tupla, adiado),html-extra-javascript,html-head-javascript(-src),html-head-favicon,html-title,html-doc-title,html-site-version. -
Renderizações HTML de macros: defina
tmhtml-NOMEao lado deNOME. O exportador a usa em vez deNOME. Ajudantes de marcação para ela:html-div-class|classe|corpo(bloco),html-class|classe|corpo(span inline),html-style,html-div-style,html-attr,html-tag,html-javascript. Isso só funciona para macros definidas em um pacote de estilo: macros atribuídas nohide-preambledo documento são expandidas antes da exportação e suas variantestmhtml-são ignoradas. Portanto, coloque macros de apresentação em um pacote. -
Um pacote
foo.tsao lado do documento é encontrado quando a tupla de estilo listafoo. Após editar um pacote, chame(style-clear-cache)(TeXmacs armazena em cache ambientes de estilo em~/.TeXmacs/system/cache), caso contrário, definições antigas são usadas. -
Sumário (e outras listas geradas): as entradas são escritas nos dados auxiliares já expandidas (
writeavalia seu argumento), então wrappers em torno detoc-main-*/toc-1…5desaparecem e suas variantestmhtml-nunca são vistas. Apenas a macro externatable-of-contentspode ter uma renderizaçãotmhtml-. Marcadores que sobrevivem à expansão e exportação:<b>(seções em negrito),<with|font-size|…>→<font style=…>,font-shape→<i>/versaletes,color→<font color>; indentaçãopar-lefté perdida. Cada entrada termina com<a href="#auto-N">página</a>. Receita para painel lateral (pacote do pluginmax-html):tmhtml-table-of-contents→div.max-tocfixo à esquerda; oculte e estique o link da página com.max-toc p a[href^="#auto-"] {position:absolute; inset:0; font-size:0}(selecione por href: umeqrefem um título também é um link); marque entradas de nível de parágrafo redefinindotoc-3…5com um<with|font-size|0.92|…>aninhado e selecionep:has(> font). Regere o sumário (duas execuções de composição tipográfica) após alterar macrostoc-*. -
Destacar a seção atual no painel precisa de JavaScript:
max-html.js(plugin), anexado comhtml-extra-javascript-srcno pacote; ele mapeia o link#auto-Nde cada entrada para o título com aquele id, marca o último título acima de 25% do viewport (p.toc-current, e seu pai em negritop.toc-current-section) e rola o painel para mantê-lo visível. -
Teoremas emoldurados (artigos web de Joris van der Hoeven, e.g. texmacs.org/joris/fftcomp; o modelo é
styles/article/texmacs/tmarticle.tsno TeXmacs): definatmhtml-render-theorem→<html-div-class|theorem|<render-enunciation|…>>etmhtml-render-enunciationcom<html-class|enunciation-name|qual>; teorema, proposição, lema, corolário e definição usamrender-theorem, enquanto observações e provas usamrender-remark. O css de Joris (texmacs.org/css/theme-dark-colored.css) é.theorem {border: 1px solid; border-left: 1em solid; padding: 0 1em}; uma cor suave e uma barra de .5em também funcionam bem (max-html.css). Isso é apenas HTML; o PDF permanece inalterado. Cores (também como no tema de Joris):h1…h6, strong, b, dt, .enunciation-nameem um vermelho escuro suave, saída MathJax viamjx-container {color: …}; redefinabdentro do painel do sumário. -
A exportação HTML transforma cada
enumerate-alpha|Alpha|romanem uma<ol>simples (rótulos decimais). Correção:tmhtml-enumerate-alpha→<html-div-class|enum-alpha|<enumerate|…>>mais.enum-alpha > ol > li::marker {content: "(" counter(list-item, lower-alpha) ") ". -
MathJax: o conversor escreve o acento circunflexo
<abovering>como\ring{…}(pacote LaTeX accents), que o MathJax não tem (mgubi/texmacs#607). Corrigido pelo plugin. Uma alternativa a nível de página é uma configuração inline do MathJax emhtml-extra-javascript(ela é executada antes da tag<script>do MathJax): `window.MathJax = {tex: {macros: {ring: [String.fromCharCode(92)- 'mathring{#1}', 1]}}}`.
-
MathJax:
aligneddentro de umaequationé pré-expandido pelo exportador HTML paraequations-basee chega ao MathJax como\begin{equationsbase}(mgubi/texmacs#611). Corrigido pelo plugin; a alternativa a nível de página éenvironments: {equationsbase: […aligned…]}nessa configuração. -
Verifique todas as fórmulas de uma exportação com
scripts/mathjax-check/:npm install [email protected]em uma pastadeps/de teste, entãopython3 extract.py DIRETORIO_HTML formulas.json(usa um parser HTML:<bruto em\(t < \infty\)é texto, como em navegadores) enode check.js deps/node_modules formulas.json. Ele renderiza cada fórmula sem o pacotenoundefined(que no navegador silenciosamente mostra macros indefinidas em vermelho) e agrupa os erros. Ele não vê fórmulas vazias (conte\(\)separadamente) ou links mortos: também verifique se todohref="…#x"interno tem umid="x"correspondente. -
Slides: uma imagem com
width=100%estreitada por um cssmax-heightfica à esquerda de seu parágrafo; centralize-a comdiv.toggle img.image {display: block; margin: 0 auto}. -
Firefox sem cabeça: a preferência
content-overridede modo escuro emuser.jsnão surtiu efeito; para alterar o
…
[truncado para tradução]