pwquint24/org-babel-literate-tangle

Guia para programação literária, extração de código (tangling), expansão de macros noweb, compilação em lote e gerenciamento de configuração com Org Babel.

O que é org-babel-literate-tangle?

Esta skill capacita desenvolvedores a usar o Org Babel do Emacs para implementar o paradigma de Programação Literária de Donald Knuth. Com ela, um único arquivo Org atua como fonte única de verdade, gerando tanto documentação formatada (weaving) quanto arquivos de código executáveis (tangling) para diversas linguagens como Python, Shell e C. A skill detalha o uso de argumentos de cabeçalho `:tangle` para controlar a extração de código, a sintaxe Noweb para montar arquivos maiores a partir de blocos modulares, e o gerenciamento de escopo em nível de buffer, subtree ou bloco. Além disso, aborda a integração com tabelas Org para injeção de configurações, dicas para lidar com linguagens sensíveis a indentação (como Python) e instruções para automação headless via `emacs --batch`, ideal para pipelines CI/CD e Makefiles. Tudo isso mantendo a rastreabilidade entre o código gerado e o documento fonte original.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pwquint24/org-babel-agent-skills/tree/HEAD/skills/org-babel-literate-tangle

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Programação Literária & Tangling com Org Babel

Org Babel é uma implementação do paradigma de Programação Literária de Donald Knuth. Em vez de escrever código com comentários intercalados, você escreve prosa orientada a humanos, notas de arquitetura e justificativas de design, incorporando os blocos de código funcionais dentro dela.

Um único arquivo Org serve como a fonte definitiva da verdade para duas saídas distintas:

  1. Weaving (Documentação Humana): Exportar o caderno para HTML formatado, LaTeX/PDF ou Markdown para leitores.
  2. Tangling (Execução da Máquina): Extrair arquivos de código-fonte executáveis puros (.py, .sh, .c, .conf, .el) para compiladores, interpretadores e sistemas de implantação.

1. Noções Básicas de Tangling: O Argumento de Cabeçalho :tangle

Por padrão, os blocos de código não são "tangled" (extraídos). A família de argumentos de cabeçalho :tangle especifica onde e como os blocos são extraídos para o disco.

1.1 Valores do Argumento :tangle

ValorComportamento
:tangle no (Padrão)O bloco não é gravado em nenhum arquivo. (Ele ainda pode ser incluído dentro de outros blocos via <<noweb>>).
:tangle "caminho/para/arquivo.py"Grava o corpo do bloco diretamente no caminho de arquivo especificado (relativo ao diretório do buffer ou absoluto).
:tangle yes"Tangla" para um arquivo com o nome base do arquivo Org e a extensão de arquivo padrão da linguagem (ex.: model.org -> model.py).

1.2 Argumentos de Cabeçalho Adicionais para Tangling

  • :shebang "#!/usr/bin/env python3": Adiciona a string shebang especificada como a primeira linha do arquivo "tangled".
  • :tangle-mode (identity #o755): Define as permissões do sistema de arquivos no arquivo gerado (ex.: #o755 torna um script executável).
  • :no-expand: Impede que atribuições de variáveis (:var) sejam inseridas no código "tangled"; escreve apenas o corpo bruto do bloco.
  • :mkdirp yes: Cria automaticamente quaisquer diretórios pai inexistentes no caminho do "tangle".

2. Escopo do Tangling: Nível de Bloco, Subárvore e Buffer

Os argumentos de "tangling" podem ser definidos de forma limpa em todo um projeto:

2.1 Tangling em Nível de Subárvore (Padrão Recomendado)

Diferentes títulos podem "tangle" para diferentes arquivos ou módulos:

* Utilitários Principais
:PROPERTIES:
:header-args:python: :tangle src/utils.py :mkdirp yes
:END:

#+BEGIN_SRC python
  def slugify(texto: str) -> str:
      return "-".join(texto.lower().split())
#+END_SRC

* Pipeline de Processamento de Dados
:PROPERTIES:
:header-args:python: :tangle src/pipeline.py :mkdirp yes
:END:

#+BEGIN_SRC python
  from utils import slugify

  def process_record(rec: dict) -> dict:
      rec["slug"] = slugify(rec["name"])
      return rec
#+END_SRC

2.2 Padrão de Tangling em Nível de Buffer

Defina no topo do arquivo:

#+PROPERTY: header-args:python :tangle src/main.py

3. Sintaxe Noweb: Montagem Modular de Código

Noweb permite montar arquivos de código-fonte maiores a partir de fragmentos menores, modulares e facilmente explicados. Você referencia um bloco de código dentro de outro usando <<nome_do_bloco>>.

3.1 Ativando a Expansão Noweb

Noweb está desabilitado por padrão. Controle-o com o argumento de cabeçalho :noweb:

Valor :nowebAvaliado no Emacs?"Tangled" para o Disco?Exportado no Documento?
no (Padrão)NãoNãoNão
yesSimSimSim
tangleNãoSimNão
strip-tangleSimNão (referências removidas)Sim
no-exportSimSimNão
evalSimNãoNão

3.2 Exemplo Noweb: Construção de Script Literário

#+NAME: imports
#+BEGIN_SRC python :exports none
  import sys
  import argparse
  from pathlib import Path
#+END_SRC

#+NAME: analisador-de-argumentos
#+BEGIN_SRC python :exports code
  parser = argparse.ArgumentParser(description="Processa conjunto de dados.")
  parser.add_argument("--input", required=True, type=Path, help="Caminho do CSV de entrada")
  parser.add_argument("--threshold", default=0.5, type=float, help="Limiar de pontuação")
  args = parser.parse_args()
#+END_SRC

#+NAME: processar-dados
#+BEGIN_SRC python :exports code
  print(f"Carregando dados de {args.input}...")
  # Lógica de processamento aqui
#+END_SRC

# Montando o script executável final:
#+NAME: main-cli
#+BEGIN_SRC python :tangle bin/run_pipeline.py :shebang "#!/usr/bin/env python3" :tangle-mode (identity #o755) :noweb yes :exports none
  <<imports>>

  def main():
      <<analisador-de-argumentos>>
      <<processar-dados>>

  if __name__ == "__main__":
      main()
#+END_SRC

Quando "tangled", bin/run_pipeline.py é escrito como um script limpo e executável com todos os fragmentos propriamente posicionados e indentados!

3.3 Prefixo e Indentação Noweb

  • Noweb respeita a indentação: se <<analisador-de-argumentos>> estiver indentado por 4 espaços dentro de def main():, cada linha do bloco expandido será indentada por 4 espaços.
  • Para desabilitar o comportamento de prefixo: :noweb-prefix no.
  • Para inserir os resultados da execução de um bloco em vez de seu código-fonte, acrescente parênteses: <<compute_constant()>>

3.4 Depuração da Expansão

Para verificar como os blocos noweb serão expandidos antes de "tangle" ou executar:

  • Posicione o ponto dentro do bloco e pressione C-c C-v v (org-babel-expand-src-block).
  • O Org abre um buffer temporário mostrando o código exato após todas as substituições noweb e :var.

4. Inserindo Configuração e Dados em Arquivos "Tangled"

O Babel pode inserir variáveis de tabelas Org ou propriedades de título diretamente no código "tangled":

# Configuração armazenada em uma Tabela Org:
#+NAME: config_servidor
| Chave   | Valor     |
|---------+-----------|
| host    | 10.0.1.25 |
| porta   | 8080      |
| timeout | 30        |

# O módulo de configuração "tangled":
#+BEGIN_SRC python :tangle config.py :var cfg=config_servidor :colnames yes
  HOST = cfg[0][1]
  PORTA = int(cfg[1][1])
  TIMEOUT = int(cfg[2][1])
#+END_SRC

Para evitar que o Babel gere wrappers de variáveis no código "tangled", passe :no-expand.


5. Tratamento de Indentação: Linguagens Sensíveis a Espaços em Branco

Em linguagens sensíveis a espaços em branco como Python ou YAML, a reindentação automática do Org pode quebrar a sintaxe.

Regra Crítica para Tangling em Python:

Defina org-src-preserve-indentation como t. Quando t, o Org não remove nem adiciona indentação durante exportação ou "tangling":

;; Na configuração do Emacs:
(setq org-src-preserve-indentation t)

Ou por bloco com o switch -i:

#+BEGIN_SRC python -i :tangle script.py

6. Como Executar o Tangling

6.1 Interativamente Dentro do Emacs

AtalhoComandoDescrição
C-c C-v t / C-c C-v C-torg-babel-tangle"Tangla" todos os blocos de código no buffer atual.
C-c C-v f / C-c C-v C-forg-babel-tangle-fileSolicita um arquivo Org no disco e o "tangla".

6.2 Navegando de Arquivos "Tangled" de Volta para o Org

Quando "tangled", o Babel insere comentários de back-link nos arquivos gerados:

# [[file:~/project/notebook.org::*Utilitários Principais][core-slugify]]
def slugify(texto: str) -> str:
...
# core-slugify ends here

No Emacs, abra o arquivo gerado e execute M-x org-babel-tangle-jump-to-org para saltar instantaneamente de volta para o título e bloco exatos no documento .org de origem!

6.3 Tangling em Lote Headless / CLI / CI / Make

"Tangle" arquivos sem abrir uma janela GUI do Emacs (ideal para scripts de build, Makefiles e integração contínua):

# Tangla um único arquivo:
emacs -Q --batch \
  --eval "(require 'org)" \
  --eval "(require 'ob-tangle)" \
  --eval '(org-babel-tangle-file "analysis.org")'

# Tangla vários arquivos a partir de um loop shell ou Makefile:
emacs -Q --batch --eval "
  (progn
    (require 'org)
    (require 'ob-tangle)
    (dolist (file command-line-args-left)
      (with-current-buffer (find-file-noselect file)
        (org-babel-tangle))))" *.org

7. Gerenciamento de Configuração Literária: Padrão init.org

Um caso de uso popular para programação literária com Org Babel é gerenciar configurações do Emacs ou dotfiles do sistema.

Em ~/.emacs.d/init.el:

;; Inicializa configuração literária do Org Babel
(require 'org)
(require 'ob-tangle)
(org-babel-load-file (expand-file-name "config.org" user-emacs-directory))

org-babel-load-file verifica automaticamente se config.org foi modificado desde que config.el foi gerado pela última vez, "tangla" a nova versão se necessário e carrega o arquivo .el resultante.


8. Lista de Verificação Resumida para Projetos com Tangling

  1. Caminhos de Tangling Explícitos: Use nomes de arquivo explícitos (ex.: :tangle "src/core.py").
  2. Use Noweb para Legibilidade: Divida algoritmos complexos em etapas lógicas (<<init-weights>>, <<forward-pass>>, <<backprop>>) para que a narrativa flua naturalmente para os leitores.
  3. Preserve a Indentação: Sempre certifique-se de que org-src-preserve-indentation esteja como t para código Python.
  4. Automatize com Make/CI: Inclua uma etapa de "tangling" headless emacs --batch em seu sistema de build para manter o código-fonte gerado sincronizado com o documento Org.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Habilidades Relacionadas