CommunityProgramación y desarrollogithub.com

pwquint24/org-babel-literate-tangle

Guía para programación literaria, extracción de código (tangling), expansión de macros noweb, compilación por lotes y gestión de configuración con Org Babel.

¿Qué es org-babel-literate-tangle?

Esta habilidad proporciona una guía completa para implementar el paradigma de **Programación Literaria** de Donald Knuth utilizando Org Babel en Emacs. En lugar de código con comentarios dispersos, esta técnica permite escribir documentación humana (prosa, notas arquitectónicas, razonamiento de diseño) e incrustar bloques de código funcionales dentro de ella. Un único archivo Org actúa como fuente de verdad autoritativa para dos salidas distintas: el tejido (documentación legible para humanos) y el **tangling** (extracción de archivos de código fuente puro y ejecutable). La habilidad explica en detalle cómo usar el argumento `:tangle` para controlar la extracción a archivos (`.py`, `.sh`, `.c`, `.conf`, `.el`), cómo gestionar el ámbito del tangling a nivel de búfer, subtree o bloque, y cómo ensamblar fragmentos de código modulares utilizando la sintaxis **Noweb** (`<<nombre_del_bloque>>`) para crear scripts complejos de forma legible y mantenible. También cubre el manejo de la indentación en lenguajes sensibles a espacios (como Python), la inyección de datos y configuración desde tablas Org, y la automatización del proceso de tangling tanto de forma interactiva en Emacs como en entornos headless (línea de comandos, CI/CD) con `emacs --batch`. Finalmente, presenta el patrón `init.org` para gestionar la configuración de Emacs de forma literaria.

Compatible con~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 Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Programación Literaria y Tangling con Org Babel

Org Babel es una implementación del paradigma de Programación Literaria de Donald Knuth. En lugar de escribir código con comentarios intercalados, se escribe prosa orientada a humanos, notas de arquitectura y razonamiento de diseño, incrustando los bloques de código funcionales en su interior.

Un único archivo Org sirve como fuente de verdad autoritativa para dos salidas distintas:

  1. Tejido (Documentación Humana): Exportar el cuaderno a HTML formateado, LaTeX/PDF o Markdown para los lectores.
  2. Tangling (Ejecución por Máquina): Extraer archivos de código fuente puro y ejecutable (.py, .sh, .c, .conf, .el) para compiladores, intérpretes y sistemas de despliegue.

1. Conceptos Básicos de Tangling: El Argumento de Cabecera :tangle

Por defecto, los bloques de código no se someten a tangling. La familia de argumentos de cabecera :tangle especifica dónde y cómo se extraen los bloques al disco.

1.1 Valores del Argumento :tangle

ValorComportamiento
:tangle no (Por defecto)El bloque no se escribe en ningún archivo. (Aún puede incluirse dentro de otros bloques mediante <<noweb>>).
:tangle "ruta/al/archivo.py"Escribe el cuerpo del bloque directamente en la ruta de archivo especificada (relativa al directorio del búfer o absoluta).
:tangle yesAplica tangling a un archivo que coincide con el nombre base del archivo Org con la extensión de archivo estándar del lenguaje (ej., modelo.org -> modelo.py).

1.2 Argumentos de Cabecera Adicionales para Tangling

  • :shebang "#!/usr/bin/env python3": Antepone la cadena shebang especificada como la primera línea del archivo generado por tangling.
  • :tangle-mode (identity #o755): Establece los permisos del sistema de archivos en el archivo generado (ej., #o755 hace que un script sea ejecutable).
  • :no-expand: Evita que las asignaciones de variables (:var) se inserten en el código generado por tangling; escribe solo el cuerpo del bloque original.
  • :mkdirp yes: Crea automáticamente cualquier directorio padre inexistente en la ruta de tangling.

2. Ámbito del Tangling: Nivel de Bloque, Subárbol y Búfer

Los argumentos de tangling pueden aplicarse limpiamente a lo largo de un proyecto completo:

2.1 Tangling a Nivel de Subárbol (Patrón Recomendado)

Diferentes encabezados pueden aplicar tangling a diferentes archivos o módulos:

* Utilidades Principales
: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

* Canal de Procesamiento de Datos
:PROPERTIES:
:header-args:python: :tangle src/pipeline.py :mkdirp yes
:END:

#+BEGIN_SRC python
  from utils import slugify

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

2.2 Valor por Defecto de Tangling a Nivel de Búfer

Establecerlo al principio del archivo:

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

3. Sintaxis Noweb: Ensamblaje Modular de Código

Noweb permite ensamblar archivos fuente más grandes a partir de fragmentos más pequeños, modulares y fáciles de explicar. Se referencia un bloque de código dentro de otro usando <<nombre_del_bloque>>.

3.1 Habilitación de la Expansión Noweb

Noweb está deshabilitado por defecto. Se controla con el argumento de cabecera :noweb:

Valor :noweb¿Evaluado en Emacs?¿Tangled al Disco?¿Exportado en Documentación?
no (Por defecto)NoNoNo
yesSíSíSí
tangleNoSíNo
strip-tangleSíNo (las referencias se eliminan)Sí
no-exportSíSíNo
evalSíNoNo

3.2 Ejemplo de Noweb: Construcción Literaria de un Script

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

#+NAME: analizador-argumentos
#+BEGIN_SRC python :exports code
  parser = argparse.ArgumentParser(description="Procesar conjunto de datos.")
  parser.add_argument("--input", required=True, type=Path, help="Ruta CSV de entrada")
  parser.add_argument("--threshold", default=0.5, type=float, help="Umbral de puntuación")
  args = parser.parse_args()
#+END_SRC

#+NAME: procesar-datos
#+BEGIN_SRC python :exports code
  print(f"Cargando datos desde {args.input}...")
  # Lógica de procesamiento aquí
#+END_SRC

# Ensamblando el script ejecutable final:
#+NAME: cli-principal
#+BEGIN_SRC python :tangle bin/run_pipeline.py :shebang "#!/usr/bin/env python3" :tangle-mode (identity #o755) :noweb yes :exports none
  <<imports>>

  def main():
      <<analizador-argumentos>>
      <<procesar-datos>>

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

¡Cuando se aplica tangling, bin/run_pipeline.py se escribe como un script limpio y ejecutable con todos los fragmentos correctamente colocados e indentados!

3.3 Prefijo e Indentación de Noweb

  • Noweb respeta la indentación: si <<analizador-argumentos>> está indentado con 4 espacios dentro de def main():, cada línea del bloque expandido se indentará con 4 espacios.
  • Para deshabilitar el comportamiento de prefijo: :noweb-prefix no.
  • Para insertar los resultados de la ejecución de un bloque en lugar de su código fuente, añadir paréntesis: <<calcular_constante()>>

3.4 Depuración de la Expansión

Para verificar cómo se expandirán los bloques noweb antes de aplicar tangling o ejecutar:

  • Colocar el punto dentro del bloque y presionar C-c C-v v (org-babel-expand-src-block).
  • Org abre un búfer temporal que muestra el código exacto después de todas las sustituciones de noweb y :var.

4. Inserción de Configuración y Datos en Archivos Tangled

Babel puede insertar variables de tablas Org o propiedades de encabezado directamente en el código generado por tangling:

# Configuración almacenada en una Tabla Org:
#+NAME: config_servidor
| Clave   | Valor     |
|---------+-----------|
| host    | 10.0.1.25 |
| puerto  | 8080      |
| time out| 30        |

# El módulo de configuración generado por tangling:
#+BEGIN_SRC python :tangle config.py :var cfg=config_servidor :colnames yes
  HOST = cfg[0][1]
  PUERTO = int(cfg[1][1])
  TIME_OUT = int(cfg[2][1])
#+END_SRC

Para evitar que Babel genere envoltorios de variables en el código generado por tangling, pase :no-expand.


5. Manejo de la Indentación: Lenguajes Sensibles a Espacios

En lenguajes sensibles a espacios como Python o YAML, la re-indentación automática de Org puede romper la sintaxis.

Regla Crítica para Tangling en Python:

Establecer org-src-preserve-indentation a t. Cuando es t, Org no elimina ni añade indentación durante la exportación o el tangling:

;; En la configuración de Emacs:
(setq org-src-preserve-indentation t)

O por bloque con el modificador -i:

#+BEGIN_SRC python -i :tangle script.py

6. Cómo Ejecutar el Tangling

6.1 Interactivamente Dentro de Emacs

Combinación de TeclasComandoDescripción
C-c C-v t / C-c C-v C-torg-babel-tangleAplica tangling a todos los bloques de código en el búfer actual.
C-c C-v f / C-c C-v C-forg-babel-tangle-fileSolicita un archivo Org en el disco y le aplica tangling.

6.2 Navegación desde Archivos Tangled de Vuelta al Org

Cuando se aplica tangling, Babel inserta comentarios de enlace inverso en los archivos generados:

# [[file:~/proyecto/cuaderno.org::*Utilidades%20Principales][slugify-principal]]
def slugify(texto: str) -> str:
...
# slugify-principal termina aquí

¡En Emacs, al abrir el archivo generado y ejecutar M-x org-babel-tangle-jump-to-org se salta instantáneamente al encabezado y bloque exactos en el documento .org fuente!

6.3 Tangling por Lotes desde Línea de Comandos / CI / Make

Aplicar tangling a archivos sin abrir una ventana GUI de Emacs (ideal para scripts de compilación, Makefiles e integración continua):

# Aplicar tangling a un solo archivo:
emacs -Q --batch \
  --eval "(require 'org)" \
  --eval "(require 'ob-tangle)" \
  --eval '(org-babel-tangle-file "analysis.org")'

# Aplicar tangling a múltiples archivos desde un bucle de shell o 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. Gestión Literaria de Configuración: El Patrón init.org

Un caso de uso popular para la programación literaria con Org Babel es la gestión de configuraciones de Emacs o dotfiles del sistema.

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

;; Inicializar configuración literaria con Org Babel
(require 'org)
(require 'ob-tangle)
(org-babel-load-file (expand-file-name "config.org" user-emacs-directory))

org-babel-load-file comprueba automáticamente si config.org ha sido modificado desde que se generó config.el por última vez, aplica tangling de la nueva versión si es necesario y carga el archivo .el resultante.


8. Lista de Verificación para Proyectos con Tangling

  1. Rutas de Tangling Explícitas: Utilizar nombres de archivo explícitos (ej. :tangle "src/core.py").
  2. Usar Noweb para Legibilidad: Dividir algoritmos complejos en pasos lógicos (<<inicializar-pesos>>, <<pase-adelante>>, <<retropropagacion>>) para que la narrativa fluya naturalmente para los lectores.
  3. Preservar la Indentación: Asegurarse siempre de que org-src-preserve-indentation esté en t para código Python.
  4. Automatizar con Make/CI: Incluir un paso de tangling headless con emacs --batch en el sistema de compilación para mantener el código fuente generado sincronizado con el documento Org.

Individual skills in this repo

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

Skills relacionados