pwquint24/org-babel-literate-tangle

Guide pour la programmation lettrée, l'extraction de code (tangling), l'expansion de macros noweb, la compilation par lots et la gestion de configuration avec Org Babel.

Qu'est-ce que org-babel-literate-tangle ?

Ce guide fournit une référence complète pour utiliser Org Babel dans le cadre de la programmation lettrée, en se concentrant sur l'extraction de code (tangling). Il explique comment passer d'un fichier `.org` unique, qui fait office de source de vérité, à des fichiers de code source exécutables (`.py`, `.sh`, `.c`, etc.). Il couvre les arguments d'en-tête essentiels comme `:tangle` pour définir les chemins de sortie, la syntaxe Noweb pour assembler du code modulaire, et les options de portée (bloc, sous-arbre, tampon) pour organiser des projets complexes. Le guide est particulièrement utile pour les développeurs qui souhaitent documenter minutieusement leur logique tout en produisant du code propre et prêt à la production, avec une prise en charge des langages sensibles à l'indentation comme Python. Il fonctionne entièrement dans Emacs, avec des commandes pour le tangling manuel (`C-c C-v t`), l'automatisation headless via `emacs --batch` pour l'intégration continue, et la gestion de configuration comme celle d'Emacs lui-même avec le motif `init.org`. Le guide inclut également des astuces pour le débogage de l'expansion Noweb, la gestion des permissions de fichiers et l'injection de données depuis des tableaux Org.

Compatible avec~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 Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Programmation lettrée et Tangling avec Org Babel

Org Babel est une implémentation du paradigme de programmation lettrée de Donald Knuth. Au lieu d'écrire du code avec des commentaires épars, vous rédigez une prose centrée sur l'humain, des notes d'architecture et des justifications de conception, en intégrant les blocs de code fonctionnels à l'intérieur.

Un seul fichier Org sert de source de vérité définitive pour deux sorties distinctes :

  1. Weaving (Documentation Humaine) : Exporter le notebook vers du HTML formaté, du LaTeX/PDF ou du Markdown pour les lecteurs.
  2. Tangling (Exécution Machine) : Extraire des fichiers de code source purs et exécutables (.py, .sh, .c, .conf, .el) pour les compilateurs, les interpréteurs et les systèmes de déploiement.

1. Bases du Tangling : L'argument d'en-tête :tangle

Par défaut, les blocs de code ne sont pas extraits. La famille d'arguments d'en-tête :tangle spécifie où et comment les blocs sont extraits sur le disque.

1.1 Les Valeurs de l'Argument :tangle

ValeurComportement
:tangle no (Défaut)Le bloc n'est écrit dans aucun fichier. (Il peut néanmoins être inclus à l'intérieur d'autres blocs via <<noweb>>).
:tangle "chemin/vers/fichier.py"Écrit le corps du bloc directement dans le chemin de fichier spécifié (relatif au répertoire du tampon ou absolu).
:tangle yesExtrait vers un fichier correspondant au nom de base du fichier Org avec l'extension de fichier standard du langage (ex : model.org -> model.py).

1.2 Arguments d'en-tête de Tangling Supplémentaires

  • :shebang "#!/usr/bin/env python3" : Ajoute la chaîne shebang spécifiée comme première ligne du fichier extrait.
  • :tangle-mode (identity #o755) : Définit les permissions du système de fichiers sur le fichier généré (ex : #o755 rend un script exécutable).
  • :no-expand : Empêche les affectations de variables (:var) d'être intégrées dans le code extrait ; écrit uniquement le corps brut du bloc.
  • :mkdirp yes : Crée automatiquement tous les répertoires parents inexistants dans le chemin d'extraction.

2. Portée du Tangling : Niveaux Bloc, Sous-arbre et Tampon

Les arguments de tangling peuvent être appliqués proprement à l'ensemble d'un projet :

2.1 Tangling au Niveau du Sous-Arbre (Modèle Recommandé)

Différentes rubriques peuvent extraire du code vers différents fichiers ou modules :

* Utilitaires Principaux
:PROPERTIES:
:header-args:python: :tangle src/utils.py :mkdirp yes
:END:

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

* Pipeline de Traitement de Données
: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 Valeur par Défaut du Tangling pour l'Ensemble du Tampon

Définissez-le en haut du fichier :

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

3. Syntaxe Noweb : Assemblage Modulaire de Code

Noweb vous permet d'assembler des fichiers source plus volumineux à partir de fragments plus petits, modulaires et facilement explicables. Vous référencez un bloc de code à l'intérieur d'un autre en utilisant <<nom_du_bloc>>.

3.1 Activation de l'Expansion Noweb

Noweb est désactivé par défaut. Contrôlez-le avec l'argument d'en-tête :noweb :

Valeur :nowebÉvalué dans Emacs ?Extrait sur le Disque ?Exporté dans le Document ?
no (Défaut)NonNonNon
yesOuiOuiOui
tangleNonOuiNon
strip-tangleOuiNon (références supprimées)Oui
no-exportOuiOuiNon
evalOuiNonNon

3.2 Exemple Noweb : Construction Littérale d'un Script

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

#+NAME: analyseur-arguments
#+BEGIN_SRC python :exports code
  parser = argparse.ArgumentParser(description="Traiter le jeu de données.")
  parser.add_argument("--input", required=True, type=Path, help="Chemin du fichier CSV d'entrée")
  parser.add_argument("--threshold", default=0.5, type=float, help="Seuil de score")
  args = parser.parse_args()
#+END_SRC

#+NAME: traiter-donnees
#+BEGIN_SRC python :exports code
  print(f"Chargement des données depuis {args.input}...")
  # Logique de traitement ici
#+END_SRC

# Assemblage du script exécutable 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():
      <<analyseur-arguments>>
      <<traiter-donnees>>

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

Lors de l'extraction, bin/run_pipeline.py est écrit comme un script propre et exécutable avec tous les fragments correctement placés et indentés !

3.3 Préfixe et Indentation Noweb

  • Noweb respecte l'indentation : si <<analyseur-arguments>> est indenté de 4 espaces à l'intérieur de def main():, chaque ligne du bloc développé sera indentée de 4 espaces.
  • Pour désactiver le comportement de préfixe : :noweb-prefix no.
  • Pour insérer les résultats de l'exécution d'un bloc au lieu de son code source, ajoutez des parenthèses : <<compute_constant()>>

3.4 Débogage de l'Expansion

Pour vérifier comment les blocs noweb vont se développer avant l'extraction ou l'exécution :

  • Placez le point à l'intérieur du bloc et appuyez sur C-c C-v v (org-babel-expand-src-block).
  • Org ouvre un tampon temporaire montrant le code exact après toutes les substitutions noweb et :var.

4. Intégration de la Configuration et des Données dans les Fichiers Extrait

Babel peut intégrer des variables provenant de tableaux Org ou de propriétés de rubrique directement dans le code extrait :

# Configuration stockée dans un tableau Org :
#+NAME: config_serveur
| Clé     | Valeur    |
|---------+-----------|
| host    | 10.0.1.25 |
| port    | 8080      |
| timeout | 30        |

# Le module de configuration extrait :
#+BEGIN_SRC python :tangle config.py :var cfg=config_serveur :colnames yes
  HOST = cfg[0][1]
  PORT = int(cfg[1][1])
  TIMEOUT = int(cfg[2][1])
#+END_SRC

Pour empêcher Babel de générer des wrappers de variables dans le code extrait, passez :no-expand.


5. Gestion de l'Indentation : Langages Sensibles aux Espaces

Dans les langages sensibles aux espaces comme Python ou YAML, la ré-indentation automatique d'Org peut casser la syntaxe.

Règle Critique pour le Tangling Python :

Définissez org-src-preserve-indentation à t. Lorsqu'il est t, Org ne supprime ni n'ajoute d'indentation pendant l'exportation ou l'extraction :

;; Dans la configuration Emacs :
(setq org-src-preserve-indentation t)

Ou par bloc avec le commutateur -i :

#+BEGIN_SRC python -i :tangle script.py

6. Comment Exécuter le Tangling

6.1 De Manière Interactive dans Emacs

RaccourciCommandeDescription
C-c C-v t / C-c C-v C-torg-babel-tangleExtrait tous les blocs de code du tampon actuel.
C-c C-v f / C-c C-v C-forg-babel-tangle-fileDemande un fichier Org sur le disque et l'extrait.

6.2 Navigation des Fichiers Extrait vers l'Org

Lors de l'extraction, Babel insère des commentaires de rétrolien dans les fichiers générés :

# [[file:~/project/notebook.org::*Utilitaires Principaux][core-slugify]]
def slugify(text: str) -> str:
...
# core-slugify se termine ici

Dans Emacs, ouvrez le fichier généré et exécutez M-x org-babel-tangle-jump-to-org pour sauter instantanément vers la rubrique et le bloc exacts dans le document .org source !

6.3 Extraction Headless par Ligne de Commande / CI / Make

Extrayez des fichiers sans ouvrir une fenêtre graphique Emacs (idéal pour les scripts de build, les Makefiles et l'intégration continue) :

# Extraire un seul fichier :
emacs -Q --batch \
  --eval "(require 'org)" \
  --eval "(require 'ob-tangle)" \
  --eval '(org-babel-tangle-file "analysis.org")'

# Extraire plusieurs fichiers depuis une boucle shell ou un 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. Gestion Littérale de la Configuration : Le Modèle init.org

Un cas d'usage populaire de la programmation lettrée avec Org Babel est la gestion des configurations Emacs ou des dotfiles système.

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

;; Amorçage de la configuration lettrée Org Babel
(require 'org)
(require 'ob-tangle)
(org-babel-load-file (expand-file-name "config.org" user-emacs-directory))

org-babel-load-file vérifie automatiquement si config.org a été modifié depuis la dernière génération de config.el, extrait la nouvelle version si nécessaire, et charge le fichier .el résultant.


8. Liste de Vérification pour les Projets de Tangling

  1. Chemins d'extraction explicites : Utilisez des noms de fichiers explicites (ex : :tangle "src/core.py").
  2. Utilisez Noweb pour la Lisibilité : Décomposez les algorithmes complexes en étapes logiques (<<init-poids>>, <<passe-avant>>, <<retropropagation>>) afin que le récit soit fluide pour les lecteurs.
  3. Préservez l'Indentation : Assurez-vous toujours que org-src-preserve-indentation est t pour le code Python.
  4. Automatisez avec Make/CI : Incluez une étape d'extraction headless emacs --batch dans votre système de build pour maintenir le code source généré synchronisé avec le document Org.

Individual skills in this repo

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

Skills associés