CommunityProgramación y desarrollogithub.com

pwquint24/org-babel-notebook

Guía completa para redactar, estructurar, ejecutar y publicar cuadernos computacionales interactivos en Emacs Org Mode usando Org Babel.

¿Qué es org-babel-notebook?

Esta skill proporciona una guía detallada para convertir Emacs Org Mode en un entorno de cuadernos computacionales interactivos y multilenguaje, similar a Jupyter pero en texto plano. Org Babel permite intercalar código ejecutable, resultados, figuras y narrativa en un solo documento, con un control fino sobre la ejecución, los resultados, la exportación y la composición de bloques. La guía cubre la arquitectura central de Org Babel, la configuración del preámbulo del cuaderno, la anatomía de los bloques de código, la gestión de sesiones, el manejo de resultados, la generación de visualizaciones y la exportación a HTML/PDF. También incluye una lista de verificación de problemas comunes y mejores prácticas para garantizar la reproducibilidad. Es ideal para científicos de datos, investigadores y desarrolladores que buscan una alternativa controlable por versión y altamente personalizable a los cuadernos JSON tradicionales.

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

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

Creación de Cuadernos Computacionales con Org Babel

Org Babel convierte Emacs Org Mode en un entorno interactivo de cuadernos computacionales multilenguaje. Al igual que Jupyter o Mathematica, Org Babel entrelaza código ejecutable, resultados de ejecución en vivo, figuras, tablas y prosa narrativa. A diferencia de los cuadernos basados en JSON, los cuadernos Org son texto plano, legibles por humanos, controlables de forma nativa con Git y admiten la combinación de múltiples lenguajes de programación dentro de un solo documento.


1. Arquitectura Central y Separación de Preocupaciones

Cada cuaderno de Org Babel opera en cinco preocupaciones distintas gobernadas por argumentos de cabecera. Confundirlas es la principal fuente de errores en los cuadernos Org:

PreocupaciónArgumentos de Cabecera ClaveQué Gobierna
Ejecución:session, :eval, :dir, :var, :cacheSi el bloque se ejecuta, en qué proceso, dónde y con qué entradas.
Resultados:results (value vs output, formato, tipo, manejo)Qué se captura de la ejecución y cómo se renderiza en el búfer.
Exportación:exports (code, results, both, none)Qué aparece en los informes exportados (HTML, PDF, Markdown).
Tangling:tangle, :shebang, :nowebQué se extrae a archivos de código fuente independientes en disco.
Composición:var, #+CALL:, <<noweb>>, org-sbeCómo los bloques alimentan datos o código entre sí.

2. Estructura del Cuaderno y Configuración del Preámbulo

Un archivo de cuaderno Org (.org) comienza con metadatos del documento y configuraciones predeterminadas de todo el búfer, seguido de encabezados jerárquicos que contienen texto narrativo, fórmulas matemáticas y bloques de código.

2.1 Plantilla de Preámbulo de Cuaderno Estándar

#+TITLE: Análisis Computacional del Experimento X
#+AUTHOR: Jane Doe
#+DATE: [2025-05-18 Sun]
#+OPTIONS: toc:2 num:t ^:{}
#+STARTUP: overview hideblocks inlineimages

# Valores predeterminados globales de Babel para todos los bloques en este búfer:
#+PROPERTY: header-args :eval yes :exports both :results drawer
# Valores predeterminados específicos del lenguaje:
#+PROPERTY: header-args:python :session *py-analysis* :results value :exports both
#+PROPERTY: header-args:R :session *R-analysis* :results value :exports both
#+PROPERTY: header-args:sh :session none :results output :exports both

Configuraciones Clave Dentro del Búfer:

  • #+STARTUP: inlineimages: Muestra automáticamente las imágenes/gráficos generados en línea cuando se insertan los resultados o cuando se abre el búfer.
  • #+STARTUP: hideblocks: Comienza con los bloques de código plegados, mostrando solo la narrativa y los resultados para facilitar la lectura.
  • #+STARTUP: nohideblocks: Muestra todos los bloques de código expandidos.
  • #+PROPERTY: header-args ...: Valores predeterminados de todo el búfer. Se pueden añadir con header-args+.

2.2 Habilitación de Lenguajes en la Configuración de Emacs

Org solo habilita la evaluación de Emacs Lisp de forma predeterminada. Todos los demás lenguajes deben cargarse explícitamente en su configuración de Emacs:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (python     . t)
   (R          . t)
   (shell      . t)
   (sqlite     . t)
   (gnuplot    . t)
   (C          . t)))

Para evitar los diálogos de confirmación de ejecución interactiva en cuadernos de confianza:

;; nil permite que los bloques se ejecuten sin avisos de confirmación
(setq org-confirm-babel-evaluate nil)

3. Anatomía de un Bloque de Código

#+NAME: <nombre_del_bloque>
#+HEADER: <argumentos_de_cabecera_adicionales>
#+BEGIN_SRC <lenguaje> <interruptores> <argumentos_de_cabecera>
  <cuerpo>
#+END_SRC
  • #+NAME: <nombre>: Identificador único opcional. Obligatorio si el bloque se va a referenciar como una función, pasar como entrada a otro bloque mediante :var o llamar a través de #+CALL:.
  • <lenguaje>: Identificador reconocido por Babel (python, R, sh, emacs-lisp, sqlite, sql, julia, calc, gnuplot, etc.).
  • <interruptores>: Interruptores opcionales (por ejemplo, -n para numeración de líneas durante la exportación, -r para eliminar etiquetas).
  • <argumentos_de_cabecera>: Pares clave-valor que controlan la ejecución, los resultados y la exportación.
  • #+HEADER:: Líneas secundarias para especificar limpiamente listas largas de argumentos de cabecera.

Bloques de Código en Línea

Para incrustar valores calculados dinámicamente dentro de un párrafo:

La precisión final calculada fue src_python[:session *py* :results value]{f"{acc * 100:.2f}%"}.

4. Referencia de Argumentos de Cabecera

4.1 Gestión de Sesiones: Exploración Interactiva vs. Reproducibilidad Hermética

  • :session none (Predeterminado): Evalúa el bloque en un proceso de intérprete externo único. Hermético, limpio y evita la contaminación del estado, pero reinicializa las importaciones y el entorno en cada ejecución.
  • :session <nombre>: Evalúa en un búfer REPL inferior persistente de Emacs (por ejemplo, *py-analysis*).
    • Las variables, funciones y módulos importados persisten en múltiples bloques que comparten el mismo nombre de sesión.
    • Esencial para conjuntos de datos pesados, pesos de modelos grandes y flujos de trabajo exploratorios.
    • Mejor práctica: Cree prototipos con :session <nombre>; para la verificación final, reinicie la sesión o pruebe las secciones críticas con :session none para garantizar la reproducibilidad.

4.2 Directorios de Trabajo y Entornos Remotos

  • :dir /ruta/al/proyecto: Ejecuta el bloque dentro del directorio especificado.
  • :mkdirp yes: Crea el directorio de destino si no existe.
  • Ejecución Remota (TRAMP): :dir /ssh:usuario@cluster-gpu:/workspace/data ejecuta el bloque de forma remota en un servidor mientras renderiza la salida dentro de su búfer local de Emacs.

4.3 Almacenamiento en Caché de Cálculos Costosos

  • :cache yes: Calcula un hash SHA1 del texto del bloque, las entradas y los parámetros :var.
  • Si el hash coincide con el almacenado en la línea #+RESULTS[hash]:, se omite la evaluación y se conservan los resultados almacenados en caché.
  • Utilícelo solo para cálculos deterministas y puros sin efectos secundarios externos.

5. Manejo de Resultados: La Distinción Crítica

El argumento :results toma hasta cuatro componentes ortogonales:

:results [colección] [tipo] [formato] [manejo]

5.1 Colección: Funcional (value) vs. Scripting (output)

Comprender esta diferencia elimina el 90 % de la confusión con Babel:

Modo de ColecciónQué se CapturaComportamiento en PythonComportamiento en Shell
:results value (Predeterminado para Python, R, elisp)Valor de retorno de la última expresión o return explícito.Debe usar una declaración return <val> explícita. Todo el resultado de print() se descarta.Devuelve el código de salida o el valor de cadena.
:results output (Predeterminado para shell, bash)Flujo de salida estándar emitido durante la ejecución.Captura todas las declaraciones print(). Cualquier return se ignora.Captura toda la salida estándar del comando (echo, ls, etc.).

Ejemplo Funcional en Python (:results value):

#+BEGIN_SRC python :results value
  data = [1, 2, 3, 4]
  # En modo funcional, se REQUIERE un return explícito en Python:
  return sum(data)
#+END_SRC

#+RESULTS:
: 10

Ejemplo de Scripting en Python (:results output):

#+BEGIN_SRC python :results output
  for i in range(3):
      print(f"Época {i}: pérdida={0.5/(i+1):.4f}")
#+END_SRC

#+RESULTS:
: Época 0: pérdida=0.5000
: Época 1: pérdida=0.2500
: Época 2: pérdida=0.1667

5.2 Tipos de Resultados

  • table / vector: Da formato a las listas/arrays devueltos como una tabla de Org Mode.
  • scalar / verbatim: Da formato a la salida como texto entrecomillado sin formato de tabla.
  • file: Dirige la salida a un archivo en disco (especificado con :file <nombre_de_archivo>) e inserta un enlace de archivo Org en los resultados.

5.3 Formatos de Resultados

  • drawer (Recomendado): Envuelve los resultados en delimitadores :RESULTS: … :END:. Mantiene los documentos ordenados, especialmente para salidas de varias líneas.
  • raw: Inserta la salida directamente como texto Org sin escapar (útil para generar encabezados o tablas dinámicos).
  • code: Envuelve la salida en #+BEGIN_SRC <lang> … #+END_SRC.
  • link / graphics: Trata el resultado como una ruta a una imagen/archivo y genera [[file:ruta]].

5.4 Manejo

  • replace (Predeterminado): Reemplaza el bloque #+RESULTS: anterior.
  • append: Agrega nuevos resultados debajo de los resultados existentes.
  • prepend: Inserta nuevos resultados encima de los resultados existentes.
  • silent: Muestra los resultados en el área de eco/minibúfer de Emacs sin escribirlos en el búfer Org.

6. Visualizaciones y Figuras en Cuadernos

Para generar gráficos y figuras que se rendericen directamente en el cuaderno:

6.1 Gráfico de Matplotlib en Python

#+NAME: grafico-distribucion-normal
#+BEGIN_SRC python :session *py-vis* :results graphics file :file figures/normal_dist.png :exports both
  import matplotlib.pyplot as plt
  import numpy as np

  plt.figure(figsize=(6, 3.5))
  x = np.linspace(-3, 3, 200)
  plt.plot(x, np.exp(-x**2 / 2) / np.sqrt(2 * np.pi), color="#2b5c8f", lw=2)
  plt.title("Distribución Normal Estándar")
  plt.xlabel("z")
  plt.ylabel("Densidad")
  plt.tight_layout()
  plt.savefig("figures/normal_dist.png", dpi=150)
  plt.close()
#+END_SRC

#+RESULTS: grafico-distribucion-normal
[[file:figures/normal_dist.png]]

6.2 Gráfico ggplot2 en R

#+NAME: grafico-dispersion-r
#+BEGIN_SRC R :session *r-vis* :results graphics file :file figures/r_scatter.png :exports both
  library(ggplot2)
  p <- ggplot(mtcars, aes(x=wt, y=mpg, color=factor(cyl))) +
    geom_point(size=3) +
    theme_minimal() +
    labs(title="Eficiencia de Combustible vs. Peso", x="Peso (1000 lbs)", y="MPG")
  ggsave("figures/r_scatter.png", plot=p, width=6, height=4, dpi=150)
#+END_SRC

#+RESULTS: grafico-dispersion-r
[[file:figures/r_scatter.png]]

Consejo: Ejecute M-x org-toggle-inline-images (C-c C-x C-v) en Emacs para alternar la visualización de los gráficos generados directamente dentro del búfer.


7. Ejecución Interactiva y Flujo de Trabajo de Edición

Combinaciones de Teclas Esenciales

Combinación de TeclasComandoDescripción
C-c C-corg-babel-execute-src-blockEjecuta el bloque bajo el punto e inserta/actualiza los resultados.
C-c 'org-edit-specialAbre el cuerpo del bloque en un búfer dedicado de modo principal (LSP completo, resaltado de sintaxis, autocompletado). Presione C-c ' de nuevo para guardar y volver.
C-c C-v borg-babel-execute-bufferEjecuta todos los bloques de código en el cuaderno secuencialmente (como "Ejecutar todas las celdas").
C-c C-v sorg-babel-execute-subtreeEjecuta todos los bloques de código bajo el encabezado actual.
C-c C-oorg-open-at-pointEn un enlace #+RESULTS:, abre la imagen o el archivo generado en un visor o búfer externo.
M-<down>org-babel-pop-to-sessionCambia el enfoque directamente al búfer REPL interactivo para la sesión de este bloque.
C-c C-v vorg-babel-expand-src-blockPrevisualiza el bloque completamente expandido (con todas las expansiones :var y noweb resueltas).

8. Exportación y Publicación de Informes

Un cuaderno se puede convertir en documentos HTML, PDF o Markdown independientes.

8.1 Control del Contenido de Exportación con :exports

  • :exports code: Exporta solo el bloque de código.
  • :exports results: Exporta solo la salida/figura (oculta el código, ideal para informes ejecutivos).
  • :exports both: Exporta tanto el código como la salida (ideal para documentación técnica).
  • :exports none: Oculta tanto el código como los resultados del documento exportado (se ejecuta durante la evaluación si es necesario).

8.2 Control de la Evaluación de Exportación con :eval

  • :eval never-export: Evita volver a ejecutar bloques durante la exportación, utilizando los #+RESULTS: existentes en el búfer. Acelera la exportación y evita cambios no deterministas.
  • :eval query-export: Pregunta antes de ejecutar durante la exportación.

8.3 Comandos de Exportación

  • C-c C-e h h (org-html-export-to-html): Genera un informe HTML.
  • C-c C-e h o (org-html-export-to-html-and-open): Genera y abre HTML en su navegador.
  • C-c C-e l p (org-latex-export-to-pdf): Genera un informe PDF con formato tipográfico a través de LaTeX.

9. Errores Comunes y Lista de Verificación de Solución de Problemas

Síntoma / ErrorCausaSolución
El bloque de Python no devuelve resultadosSe usó :results value con print(...) en lugar de return ...Reemplace print(...) con return ..., o cambie la cabecera a :results output.
No org-babel-execute function for <lang>El lenguaje no está registrado en org-babel-load-languagesAgregue (<lang> . t) a org-babel-load-languages en su configuración de Emacs y evalúelo.
Se produce un enlace de imagen pero la imagen no se muestraLas imágenes en línea están desactivadas en Org ModeEjecute M-x org-toggle-inline-images (C-c C-x C-v) o agregue #+STARTUP: inlineimages.
Las salidas de la sesión contienen indicaciones repetidas (>>>)Texto de indicación interactiva persistente en el búfer REPLLimpie o reinicie el búfer de la sesión (*nombre-de-sesión*).
La exportación es lenta o se cuelgaOrg está re-ejecutando todos los bloques del cuaderno durante la exportaciónEstablezca :eval never-export en bloques de larga duración o globalmente mediante #+PROPERTY: header-args :eval never-export.
La entrada de tabla produce un error en las reglas horizontalesLas reglas horizontales (`-`) se tratan como filas sin procesar

10. Ejemplo de Cuaderno Anotado Completo

#+TITLE: Análisis de Frecuencia de Llamaradas Solares
#+AUTHOR: Dr. Alex Rivera
#+DATE: [2025-05-18 Sun]
#+OPTIONS: toc:nil num:nil
#+STARTUP: inlineimages nohideblocks
#+PROPERTY: header-args :session *solar* :results drawer :exports both

* Introducción
Analizamos las frecuencias de llamaradas observacionales registradas durante una ventana de observación de 6 meses.

* Observaciones en Bruto
Aquí está la tabla de medición de referencia:

#+NAME: observaciones_en_bruto
| Mes  | Clase C | Clase M | Clase X |
|------+---------+---------+---------|
| Ene  |      12 |       3 |       0 |
| Feb  |      19 |       5 |       1 |
| Mar  |      15 |       2 |       0 |
| Abr  |      27 |       8 |       2 |
| May  |      31 |      11 |       3 |
| Jun  |      22 |       7 |       1 |

* Procesamiento de Datos y Estadísticas Resumidas
Calculamos la actividad solar total usando Python:

#+NAME: calcular_totales
#+BEGIN_SRC python :var obs=observaciones_en_bruto :colnames yes :results value table
  eventos_totales = []
  for fila in obs:
      mes = fila[0]
      total = sum(fila[1:])
      eventos_totales.append([mes, total])
  return [["Mes", "Eventos Totales"]] + eventos_totales
#+END_SRC

#+RESULTS: calcular_totales
:RESULTS:
| Mes | Eventos Totales |
|-----+-----------------|
| Ene |              15 |
| Feb |              25 |
| Mar |              17 |
| Abr |              37 |
| May |              45 |
| Jun |              30 |
:END:

* Visualización
generamos un gráfico de barras de eventos totales por mes.

#+NAME: grafico-barras
#+BEGIN_SRC python :session *solar* :results graphics file :file figures/eventos_solares.png :exports both
  import matplotlib.pyplot as plt

  meses = ["Ene", "Feb", "Mar", "Abr", "May", "Jun"]
  totales = [15, 25, 17, 37, 45, 30]

  plt.figure(figsize=(8, 4))
  plt.bar(meses, totales, color="#d62728")
  plt.title("Eventos Solares Totales por Mes")
  plt.xlabel("Mes")
  plt.ylabel("Número de Eventos")
  plt.grid(axis="y", linestyle="--", alpha=0.7)
  plt.tight_layout()
  plt.savefig("figures/eventos_solares.png", dpi=150)
  plt.close()
#+END_SRC

#+RESULTS: grafico-barras
[[file:figures/eventos_solares.png]]

* Resumen
Se observó un pico de actividad en mayo con 45 eventos totales, principalmente impulsado por llamaradas de clase C y M.

Créditos: Este documento es un resumen traducido de la guía original en inglés, manteniendo la estructura y los detalles técnicos clave de Org Babel para su uso en español.

Individual skills in this repo

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

Skills relacionados