pwquint24/org-babel-polyglot

Guia para construir pipelines de análise de dados multilinguagem, passagem de variáveis entre blocos, fórmulas de tabela com org-sbe e chamadas remotas de blocos no Org Babel.

O que é org-babel-polyglot?

Esta skill capacita agentes de IA e desenvolvedores a criar pipelines de dados poliglotas dentro de documentos Org Mode, permitindo que dados fluam perfeitamente entre linguagens como SQL, Python, R e Shell em um único notebook. O principal mecanismo é o cabeçalho `:var`, que suporta a passagem de valores literais, tabelas nomeadas, listas de itens, saídas de blocos de código e até mesmo avaliação Elisp, com suporte a indexação e fatiamento de tabelas para controle refinado dos dados. Além disso, a skill explora recursos avançados como chamadas programáticas de blocos com `#+CALL:`, planilhas reativas usando `org-sbe` em fórmulas de tabela, pós-processamento de resultados com o cabeçalho `:post` e reutilização de blocos compartilhados através da Biblioteca de Babel. Projetada para as plataformas Claude Code, Cursor e Codex, esta skill transforma o Org Mode em um poderoso barramento de dados universal, eliminando a necessidade de ferramentas externas de ETL para análises exploratórias e relatórios reproduzíveis.

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

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

Pipelines de Dados Poliglotas e Interoperabilidade com Org Babel

Uma das capacidades mais poderosas do Org Babel é a interoperabilidade agnóstica a linguagens: os dados podem fluir perfeitamente entre diferentes linguagens de programação, tabelas Org e fórmulas dentro do mesmo documento.

Um único notebook pode consultar dados em SQL, transformá-los e limpá-los em Python, realizar modelagem estatística em R, executar comandos de sistema em Shell e visualizar resultados em Gnuplot ou Matplotlib — com o Org Mode atuando como o barramento de dados universal.


1. O Mecanismo Universal de Passagem de Dados: :var

O argumento de cabeçalho :var possui sintaxe idêntica em todas as linguagens suportadas:

:var NOME_DA_VARIAVEL=ATRIBUICAO
:var NOME_DA_VARIAVEL=ARQUIVO:REFERENCIA

1.1 Tipos de Atribuição Suportados por :var

Fonte de EntradaExemplo de SintaxeNotas
Valor Literal:var n=42 text="exemplo"Números, booleanos e strings.
Tabela Org Nomeada:var dados=medicoes_brutasPassa a tabela 2D como uma lista aninhada/data frame.
Lista Simples Nomeada:var itens=lista_tarefasPassa os itens da lista de nível superior como um array/vetor.
Bloco de Código sem Argumentos:var stats=calcular_estatisticas()Executa calcular_estatisticas e passa seu valor de retorno.
Bloco de Código com Argumentos:var res=calc(taxa=0.05, n=12)Avalia o bloco alvo com parâmetros especificados.
Conteúdo / Literal do Bloco:var modelo=config_template[]Passa o corpo textual de um bloco de exemplo ou código.
Avaliação Emacs Lisp:var arquivo=(buffer-file-name)Qualquer valor começando com (, [, ' ou ` é avaliado como Elisp.
Arquivo Org Externo:var ext=outro.org:tabela_dadosResolve a referência dentro de um arquivo externo.

2. Passagem e Formatação de Tabelas Org

As tabelas Org são convertidas automaticamente em estruturas nativas (listas de listas em Python, data frames em R, etc.). Argumentos de cabeçalho controlam o pré-processamento da tabela:

2.1 Argumentos de Pré-processamento de Tabelas

  • :colnames yes | no | nil (Padrão: nil):
    • Quando nil: Se a tabela tiver uma régua horizontal abaixo da linha 1, o Babel remove os cabeçalhos, converte as linhas e reaplica os cabeçalhos nas tabelas retornadas.
    • Quando yes: Trata explicitamente a primeira linha como nomes de colunas/cabeçalhos.
    • Quando no: Trata a primeira linha como dados normais.
  • :rownames yes | no (Padrão: no):
    • Quando yes: Remove a primeira coluna antes do processamento e a restaura como nomes de linha no retorno.
  • :hlines yes | no (Padrão: no):
    • Quando no (recomendado): Remove todas as réguas horizontais (|-...) antes de passar os dados para o interpretador. Isso previne erros de tipo (como None ou strings 'hline' quebrando rotinas numéricas).
    • Quando yes: Mantém as réguas horizontais como símbolos 'hline.

2.2 Fatiamento e Indexação de Tabelas em :var

Você pode fatiar linhas e colunas diretamente na declaração :var usando a notação de índice baseada em 0 [linhas, colunas]:

#+NAME: dataset_completo
| ID | Idade | Pontuacao |
|----+-------+-----------|
|  1 |    25 |      88.5 |
|  2 |    30 |      92.0 |
|  3 |    22 |      79.0 |
|  4 |    35 |      95.5 |

# Passando apenas a coluna 'Pontuacao' (índice da coluna 2, linhas 1 até o final):
#+BEGIN_SRC python :var pontuacoes=dataset_completo[1:, 2] :results value
  return sum(pontuacoes) / len(pontuacoes)
#+END_SRC

#+RESULTS:
: 88.75
  • Sintaxe de indexação:
    • dados[0] : Primeira linha.
    • dados[,1] : Segunda coluna em todas as linhas.
    • dados[1:3, :] : Linhas 1 a 3, todas as colunas (inclusivo).
    • dados[-1] : Última linha.
    • dados[*] ou dados[0:-1] : Todas as linhas.
  • Importante: A indexação ocorre antes da remoção de :colnames ou :hlines.

3. Padrão de Pipeline Poliglota: SQL -> Python -> R -> Gráficos

Aqui está um fluxo de trabalho de dados completo em várias linguagens:

#+TITLE: Pipeline Multilinguagem

* Etapa 1: Consulta ao Banco de Dados (SQLite)
Extrair contagens brutas de eventos:

#+NAME: eventos_brutos
#+BEGIN_SRC sqlite :db telemetria.db :results table :colnames yes
  SELECT device_id, event_type, count(*) as count
  FROM events
  WHERE event_date >= '2025-01-01'
  GROUP BY device_id, event_type;
#+END_SRC

#+RESULTS: eventos_brutos
| device_id | event_type | count |
|-----------+------------+-------|
| dev-01    | heartbeat  |  1420 |
| dev-01    | alert      |    12 |
| dev-02    | heartbeat  |  1380 |
| dev-02    | alert      |    45 |

* Etapa 2: Limpeza e Normalização dos Dados (Python)
Consumir a tabela SQLite no Python:

#+NAME: telemetria_limpa
#+BEGIN_SRC python :var eventos=eventos_brutos :colnames yes :results value table
  limpo = []
  for linha in eventos:
      dev_id, ev_type, count = linha[0], linha[1], int(linha[2])
      taxa = round(count / 1440.0, 4)  # eventos por minuto
      limpo.append([dev_id, ev_type, count, taxa])
  return [["Dispositivo", "Evento", "Contagem", "TaxaPorMin"]] + limpo
#+END_SRC

#+RESULTS: telemetria_limpa
| Dispositivo | Evento    | Contagem | TaxaPorMin |
|-------------+-----------+----------+------------|
| dev-01      | heartbeat |      1420 |     0.9861 |
| dev-01      | alert     |        12 |     0.0083 |
| dev-02      | heartbeat |      1380 |     0.9583 |
| dev-02      | alert     |        45 |     0.0313 |

* Etapa 3: Modelagem Estatística (R)
Consumir a saída Python limpa no R:

#+NAME: resumo_estatistico_r
#+BEGIN_SRC R :var df=telemetria_limpa :colnames yes :results value table
  summary_df <- aggregate(TaxaPorMin ~ Evento, data=df, FUN=mean)
  colnames(summary_df) <- c("Evento", "TaxaMediaPorMin")
  summary_df
#+END_SRC

#+RESULTS: resumo_estatistico_r
| Evento    | TaxaMediaPorMin |
|-----------+-----------------|
| alert     |          0.0198 |
| heartbeat |          0.9722 |

4. Chamando Blocos Programaticamente: #+CALL: e call_ Embutido

Você pode tratar qualquer bloco nomeado como uma função reutilizável e invocá-lo sem reescrever o bloco.

4.1 Sintaxe

# Forma de bloco:
#+CALL: <nome>[<cabeçalhos_avaliação_interna>](<argumentos>) <cabeçalhos_resultado_final>

# Forma embutida:
... call_<nome>[<cabeçalhos_avaliação_interna>](<argumentos>)[<cabeçalhos_resultado_final>] ...
  • <nome>: O #+NAME: do bloco alvo.
  • <argumentos>: Parâmetros no estilo de função, por exemplo, (n=5, metrica="acuracia").
  • [<cabeçalhos_avaliação_interna>]: Aplicados durante a execução (por exemplo, [:results output]).
  • [<cabeçalhos_resultado_final>]: Aplicados à formatação do resultado retornado (por exemplo, :results raw).

4.2 Exemplo

#+NAME: calculo_potencia
#+BEGIN_SRC python :var base=2 exp=3 :results value
  return base ** exp
#+END_SRC

# Chamando com argumentos personalizados:
#+CALL: calculo_potencia(base=3, exp=4)

#+RESULTS:
: 81

# Invocação embutida:
A capacidade total é call_calculo_potencia(base=2, exp=8) unidades.

5. Planilhas Reativas: Babel em Fórmulas de Tabela (org-sbe)

As tabelas do Org Mode possuem uma calculadora de planilha embutida (#+TBLFM:). A macro org-sbe permite que qualquer fórmula de célula de tabela chame um bloco Babel arbitrário em qualquer linguagem:

(org-sbe "nome-do-bloco" (param1 valor1) (param2 valor2))
;; Forma abreviada:
(sbe "nome-do-bloco" (param1 valor1))

Exemplo: Tabela Alimentada por Fórmulas Python & R

#+NAME: taxa_imposto_py
#+BEGIN_SRC python :var pais="US" :results value
  taxas = {"US": 0.08, "UK": 0.20, "DE": 0.19}
  return taxas.get(pais, 0.0)
#+END_SRC

#+NAME: tabela_fatura
| Item         | Pais | Preco Base | Taxa Imposto | Preco Total |
|--------------+------+------------+--------------+-------------|
| Nó Servidor  | US   |       1200 |         0.08 |      1296.0 |
| Storage SAN  | UK   |       3000 |          0.2 |      3600.0 |
| Gateway      | DE   |        800 |         0.19 |       952.0 |
#+TBLFM: $4='(org-sbe "taxa_imposto_py" (pais $"$2")) :: $5=$3 * (1 + $4)
  • Na tabela, pressionar C-u C-c C-c na linha #+TBLFM recalcula todas as fórmulas, avaliando o bloco Python dinamicamente para cada linha!
  • $"$2" passa o valor da coluna 2 como uma string literal.

6. Pós-processamento de Resultados com :post

O argumento de cabeçalho :post encadeia a saída de um bloco através de um bloco de formatação secundário antes de ser inserido no documento. A saída do bloco primário é vinculada a *this*:

# Bloco de pós-processamento que adiciona atributos personalizados de exportação LaTeX:
#+NAME: wrap_figura_latex
#+BEGIN_SRC emacs-lisp :var dados="" legenda="Figura"
  (format "#+CAPTION: %s\n#+ATTR_LATEX: :width 0.8\\textwidth\n%s" legenda dados)
#+END_SRC

# Bloco primário de plotagem usando :post:
#+BEGIN_SRC python :results file link :file figuras/saida.pdf :post wrap_figura_latex(legenda="Acuracia do Modelo", dados=*this*)
  import matplotlib.pyplot as plt
  plt.plot([1, 2, 3], [4, 5, 6])
  plt.savefig("figuras/saida.pdf")
  plt.close()
  return "figuras/saida.pdf"
#+END_SRC

7. A Biblioteca de Babel: Bibliotecas Globais de Funções Compartilhadas

A Biblioteca de Babel permite que você importe e compartilhe blocos nomeados entre vários arquivos .org distintos sem duplicar código.

  1. Crie um arquivo de biblioteca compartilhada (por exemplo, ~/org/biblioteca_compartilhada.org) contendo blocos nomeados.
  2. Ingira a biblioteca na sua sessão Emacs:
    (org-babel-lob-ingest "~/org/biblioteca_compartilhada.org")
    
    Ou através do atalho de teclado: C-c C-v i (org-babel-lob-ingest).
  3. Chame qualquer bloco desse arquivo usando #+CALL: nome_do_bloco(args) em qualquer buffer!

8. Armadilhas Comuns de Pipelines Poliglotas e Melhores Práticas

ArmadilhaConsequênciaRemédio
Cabeçalhos de coluna incompatíveisCálculos numéricos falham porque strings de cabeçalho são lidas como dados da linha 0Sempre especifique :colnames yes em blocos que consomem entradas tabulares.
Réguas horizontais de tabela (`-`) causando travamentosPython/R recebem o símbolo 'hline onde um número era esperado
Blocos sem nome em :varErro Referência 'xyz' não encontrada no bufferCertifique-se de que o bloco ou tabela de entrada tenha uma palavra-chave #+NAME: xyz correspondente diretamente acima dele.
Aspas em variáveis de célula de tabela em org-sbeCélulas de texto sem aspas são lidas como símbolos Lisp indefinidosColoque referências de coluna entre aspas: (pais $"$2").
Ordem de indexação com cabeçalhosdados[0] retorna a linha de cabeçalho ao indexarObserve que o fatiamento da tabela ocorre antes da remoção de :colnames.

Individual skills in this repo

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

Habilidades Relacionadas