Site WWW de Laurent Bloch
Slogan du site

ISSN 2271-3905
Cliquez ici si vous voulez visiter mon autre site, orienté vers des sujets moins techniques.

Pour recevoir (au plus une fois par semaine) les nouveautés de ce site, indiquez ici votre adresse électronique :

Un seul logiciel pour tous mes textes !
Et aussi pour mon site Web avec Spip
Article mis en ligne le 30 septembre 2020
dernière modification le 10 octobre 2020

par Laurent Bloch

Souvent j’écris un texte en LaTeX pour avoir une sortie PDF présentable, puis on me demande une copie au format docx de Word, par exemple pour une publication. Traduire à la main du LaTeX en docx est fastidieux, et on oublie toujours quelque chose. Les logiciels censés faire cela ne m’ont jamais convaincu, et ceux qui le font en sens inverse sont pires.

Il y a quelque temps un article de Benoît Benedetti, administrateur système Linux à l’Université de Nice Sophia Antipolis, AsciiDoc et AsciiDoctor pour soigner votre documentation, dans Gnu/Linux Magazine France n° 190 de février 2016, m’a fait découvrir le format de document AsciiDoc, qui permet de saisir un texte une fois pour toutes, avec une syntaxe de balises assez simple mais complète (plus complète que celle de Markdown, un système du même genre). À partir de ce document source, les logiciels AsciiDoc ou, mieux, AsciiDoctor permettent de produire des sorties PDF, LaTeX, DocBook, Html, XML, etc. Et à partir de la sortie DocBook le logiciel Pandoc peut produire une sortie docx tout à fait acceptable. J’ai donné le mode d’emploi de ces merveilles dans un autre article.

Il manquait quelque chose : j’utilise pour mon site Web et mon blog le système de publication (CMS) Spip, qui me convient parfaitement, mais pour lequel n’existait pas de traducteur AsciiDoc. Il m’a fallu donc en écrire un, que je vous présente ici. Il s’appelle AsciiDoc-Spip.

AsciiDoc-Spip ne traite qu’un sous-ensemble « raisonnable » d’AsciiDoc : ainsi, il n’accepte que les URL suivis d’une annotation entre crochets, éventuellement vide, mais j’ai besoin de la paire de crochets pour détecter la fin de l’URL. Pour les programmes je suppose l’usage du plugin de coloration du code. Je suppose que chaque paragraphe est saisi sur une seule ligne et séparé du suivant par une ligne vide. Je n’ai pas traité l’insertion de figures, qui de toute façon, avec Spip, se traite facilement dans l’interface d’administration. Je ne traite qu’un seul format de tableau, le plus simple, de toute façon sur une page Web mieux vaut rester simple.

Comme vous le verrez, j’ai programmé cela à grands coups d’expressions régulières. Je sais, il aurait été mieux d’écrire un véritable analyseur syntaxique, ce sera pour une version ultérieure.

Le langage de programmation utilisé est Scheme, avec le compilateur Bigloo. Désolé, pour compiler ce programme il faut installer Bigloo (cet article décrit comment faire avec une machine virtuelle sous Windows, mais sur un machine avec Ubuntu natif ce serait la même chose ; attention aux pré-requis).

L’article que vous lisez a été écrit en AsciiDoc et traduit en Spip par AsciiDoc-Spip. Voici le programme :

  1. (module AsciiDoc-Spip
  2.    (main analyse-fichier))
  3.  
  4. (define (analyse-fichier args)
  5.    (let ((un-fichier (cadr args)))
  6.       (call-with-input-file un-fichier lire-des-lignes)))
  7.  
  8. (define (lire-des-lignes flux)
  9.    (let boucle ((ligne (read-line flux)))
  10.       (if (eof-object? ligne)
  11.           ligne
  12.           (begin
  13. ;; Tableaux
  14.              (if (substring=? ligne "|===" 4)
  15.                  (traite-tableau ligne flux))
  16. ;; Textes de programmes encadrés
  17.              (let ((regexp-code "\\[source, ([a-zA-Z0-9-]+)\\]"))
  18.                 (if (pregexp-match regexp-code ligne)
  19.                     (traite-code regexp-code ligne flux)))
  20.              (analyse ligne)
  21.              (boucle (read-line flux))))))
  22.  
  23. (define (traite-tableau ligne flux)
  24.    (do ((ligne (read-line flux) (read-line flux)))
  25.        ((substring=? ligne "|===" 4))
  26.        (if (not (substring=? ligne "|===" 4))
  27.            (analyse (string-append ligne " |")))))
  28.  
  29. (define (traite-code regexp-code ligne flux)
  30.    (let ((langage (dernier (pregexp-match regexp-code ligne))))
  31.       (set! ligne (string-append "<cadre class=\"" langage "\">"))
  32.       (print ligne)
  33.       (do ((ligne (read-line flux) (read-line flux))
  34.            (debut #t #f))
  35.           ((and (substring=? ligne "----" 4)
  36.                 (not debut)))
  37.           (if (not (substring=? ligne "----" 4))
  38.               (print ligne))
  39.           )
  40.       (print "</ cadre>") ;; espace après / pour éviter que Spip ne traite
  41. ;; la balise... Pour l'utiliser en vrai, il faut supprimer l'espace.
  42.       ))
  43.  
  44. (define (dernier L)
  45.    (if (list? L)
  46.        (if (null? (cdr L))
  47.            (car L)
  48.            (dernier (cdr L)))))
  49.  
  50. (define (traite-lien ligne regexp-lien)
  51.    (let boucle
  52.          ((debut-ligne "")
  53.           (fin-ligne ligne)
  54.           (chaine
  55.              (string-append
  56.                 "[" (dernier (pregexp-match regexp-lien ligne))
  57.                 "->" (cadr (pregexp-match regexp-lien ligne)) "]"))
  58.           (suite 0))
  59.       (set! ligne
  60.          (string-append debut-ligne
  61.             (pregexp-replace regexp-lien fin-ligne chaine)))
  62.       (set! suite (+ (string-contains ligne chaine)
  63.                      (string-length chaine)))
  64.       (set! debut-ligne (substring ligne 0 suite))
  65.       (set! fin-ligne (substring ligne suite))
  66.       (if (pregexp-match regexp-lien fin-ligne)
  67.           (boucle
  68.              debut-ligne
  69.              fin-ligne
  70.              (string-append
  71.                 "[" (dernier (pregexp-match regexp-lien fin-ligne))
  72.                 "->" (cadr (pregexp-match regexp-lien fin-ligne)) "]")
  73.              suite)
  74.           (set! ligne (string-append debut-ligne fin-ligne)))
  75.       ligne))
  76.  
  77. (define (analyse ligne)
  78.    (let* ((carcomp "éèàùçêîâÀÊÎÂÏïëËÇüôäö!-\\?,'’")
  79.           (regexp1 "^(====)(.*)$")
  80.           (regexp2 "^(===)(.*)$")
  81.           (regexp3 "^(==)(.*)$")
  82. ;; Espaces insécables
  83.           (regexp-nbsp "{nbsp}")
  84.           (regexp-ital (string-append
  85.                       "_([^_]*)_"))
  86.           (regexp-gras (string-append
  87.                       "\\*([^\\*]*)\\*"))
  88. ;; Exposants
  89.           (regexp-sup (string-append
  90.                       "\\^([^\\^]*)\\^"))
  91. ;; Indices
  92.           (regexp-sub (string-append
  93.                       "~([^~]*)~"))
  94. ;; Code, chasse fixe
  95.           (regexp-tt (string-append
  96.                       "<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+KFtePC9jb2RlPg=="></span>]*)<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+JnF1b3Q7KSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKHJlZ2V4cC1hcHBlbHJlZiAoc3RyaW5nLWFwcGVuZA0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJnF1b3Q7Jmx0OyZsdDsoW1xcdyAmcXVvdDsgY2FyY29tcCAmcXVvdDtdKikmZ3Q7Jmd0OyZxdW90OykpDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IChyZWdleHAtcmVmIChzdHJpbmctYXBwZW5kDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsmcXVvdDtcXFtcXFtcXFsoW1xcdyAmcXVvdDsgY2FyY29tcCAmcXVvdDtdKilcXF1cXF1cXF0mcXVvdDspKQ0KOzsgVVJMDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IChyZWdleHAtdXJsIChzdHJpbmctYXBwZW5kDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsmcXVvdDsoaHR0cChzKT86Ly8mcXVvdDsNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyZxdW90OyhbYS16QS1aMC05LV0rXFwuKXsxLDV9JnF1b3Q7DQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsmcXVvdDtbYS16QS1aXXsyLDR9KDpcXGQrKT8oLyhbXltdKik/KT8pJnF1b3Q7KSkNCjs7IEFubm90YXRpb24gZCd1biBVUkwNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKHJlZ2V4cC10eHR1cmwgJnF1b3Q7XFxbKFteXFxdXSopXFxdJnF1b3Q7KQ0KOzsgTGllbiBhbm5vdMOpDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IChyZWdleHAtbGllbiAoc3RyaW5nLWFwcGVuZA0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHJlZ2V4cC11cmwgcmVnZXhwLXR4dHVybCkpDQo7OyBUZXh0ZSBkZSBwcm9ncmFtbWUNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKHJlZ2V4cC1jb2RlICZxdW90O1xcW3NvdXJjZSwgKFthLXpBLVowLTktXSspXFxdJnF1b3Q7KQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyApDQo7OyBMaXN0ZQ0KICZuYnNwOyAmbmJzcDsgJm5ic3A7KGlmIChzdWJzdHJpbmc9PyBsaWduZSAmcXVvdDsqICZxdW90OyAyKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAoc3RyaW5nLXNldCEgbGlnbmUgMCAjXC0pKQ0KOzsgRXhwb3NhbnRzDQogJm5ic3A7ICZuYnNwOyAmbmJzcDsoaWYgKHByZWdleHAtbWF0Y2ggcmVnZXhwLXN1cCBsaWduZSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKHNldCEgbGlnbmUNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyhwcmVnZXhwLXJlcGxhY2UqDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHJlZ2V4cC1zdXAgbGlnbmUgJnF1b3Q7Jmx0O3N1cCZndDtcXDEmbHQ7L3N1cCZndDsmcXVvdDspKSkNCjs7IEluZGljZXMNCiAmbmJzcDsgJm5ic3A7ICZuYnNwOyhpZiAocHJlZ2V4cC1tYXRjaCByZWdleHAtc3ViIGxpZ25lKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAoc2V0ISBsaWduZQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7KHByZWdleHAtcmVwbGFjZSoNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgcmVnZXhwLXN1YiBsaWduZSAmcXVvdDsmbHQ7c3ViJmd0O1xcMSZsdDsvc3ViJmd0OyZxdW90OykpKQ0KOzsgQ29kZSwgY2hhc3NlIGZpeGUNCiAmbmJzcDsgJm5ic3A7ICZuYnNwOyhpZiAocHJlZ2V4cC1tYXRjaCByZWdleHAtdHQgbGlnbmUpDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IChzZXQhIGxpZ25lDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsocHJlZ2V4cC1yZXBsYWNlKg0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyByZWdleHAtdHQgbGlnbmUgJnF1b3Q7Jmx0O2NvZGUmZ3Q7XFwxJmx0Oy9jb2RlJmd0OyZxdW90OykpKQ0KICZuYnNwOyAmbmJzcDsgJm5ic3A7KGlmIChwcmVnZXhwLW1hdGNoIHJlZ2V4cC1hcHBlbHJlZiBsaWduZSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKHNldCEgbGlnbmUNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyhwcmVnZXhwLXJlcGxhY2UqDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IHJlZ2V4cC1hcHBlbHJlZiBsaWduZSAmcXVvdDtbXFwxXSZxdW90OykpKQ0KICZuYnNwOyAmbmJzcDsgJm5ic3A7KGlmIChwcmVnZXhwLW1hdGNoIHJlZ2V4cC1yZWYgbGlnbmUpDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IChzZXQhIGxpZ25lDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsocHJlZ2V4cC1yZXBsYWNlKg0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyByZWdleHAtcmVmIGxpZ25lICZxdW90O1tcXDFdJnF1b3Q7KSkpDQo7OyBFc3BhY2VzIGluc8OpY2FibGVzDQogJm5ic3A7ICZuYnNwOyAmbmJzcDsoaWYgKHByZWdleHAtbWF0Y2ggcmVnZXhwLW5ic3AgbGlnbmUpDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IChzZXQhIGxpZ25lDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsocHJlZ2V4cC1yZXBsYWNlKg0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyByZWdleHAtbmJzcCBsaWduZSAmcXVvdDsgJnF1b3Q7KSkpDQo7OyBMaWVuIGFubm90w6kNCiAmbmJzcDsgJm5ic3A7ICZuYnNwOyhpZiAocHJlZ2V4cC1tYXRjaCByZWdleHAtbGllbiBsaWduZSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKHNldCEgbGlnbmUgKHRyYWl0ZS1saWVuIGxpZ25lIHJlZ2V4cC1saWVuKSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKQ0KICZuYnNwOyAmbmJzcDsgJm5ic3A7KGlmIChwcmVnZXhwLW1hdGNoIHJlZ2V4cC1pdGFsIGxpZ25lKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAoc2V0ISBsaWduZSAocHJlZ2V4cC1yZXBsYWNlKg0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7cmVnZXhwLWl0YWwgbGlnbmUgJnF1b3Q7e1xcMX0mcXVvdDspKSkNCiAmbmJzcDsgJm5ic3A7ICZuYnNwOyhpZiAocHJlZ2V4cC1tYXRjaCByZWdleHAtZ3JhcyBsaWduZSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKHNldCEgbGlnbmUgKHByZWdleHAtcmVwbGFjZSoNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwO3JlZ2V4cC1ncmFzIGxpZ25lICZxdW90O3t7XFwxfX0mcXVvdDspKSkNCiAmbmJzcDsgJm5ic3A7ICZuYnNwOyhjb25kICgocHJlZ2V4cC1tYXRjaCByZWdleHAxIGxpZ25lKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7KHByaW50IChwcmVnZXhwLXJlcGxhY2UNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7cmVnZXhwMSBsaWduZSAmcXVvdDt7e3sqKipcXDJ9fX0mcXVvdDspKSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICgocHJlZ2V4cC1tYXRjaCByZWdleHAyIGxpZ25lKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7KHByaW50IChwcmVnZXhwLXJlcGxhY2UNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7cmVnZXhwMiBsaWduZSAmcXVvdDt7e3sqKlxcMn19fSZxdW90OykpKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKChwcmVnZXhwLW1hdGNoIHJlZ2V4cDMgbGlnbmUpDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsocHJpbnQgKHByZWdleHAtcmVwbGFjZQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDtyZWdleHAzIGxpZ25lICZxdW90O3t7eypcXDJ9fX0mcXVvdDspKSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICgoemVybz8gKHN0cmluZy1sZW5ndGggbGlnbmUpKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7KG5ld2xpbmUpKQ0KOzsgUG91ciBzYXV0ZXIgbGVzIGxpZ25lcyBkZSBjb21tYW5kZXMgQXNjaWlEb2MNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICgoY2hhcj0/IChzdHJpbmctcmVmIGxpZ25lIDApICNcOikpDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAoKHN1YnN0cmluZz0/IGxpZ25lICZxdW90O1suJnF1b3Q7IDIpKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKChzdWJzdHJpbmc9PyBsaWduZSAmcXVvdDt8PT09JnF1b3Q7IDQpKQ0KJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgKChwcmVnZXhwLW1hdGNoIHJlZ2V4cC1jb2RlIGxpZ25lKSkNCiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IChlbHNlDQombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsocHJpbnQgbGlnbmUpKSkpKQ0KJmx0Oy9jYWRyZSZndDsNCg0KRXQgbGUgdGV4dGUgQXNjaWlEb2MgZGUgbCdhcnRpY2xlIChtb2lucyBsZSBwcm9ncmFtbWUuLi4pIDoNCg0KJmx0O2NhZHJlJmd0Ow0KOnNvdXJjZS1oaWdobGlnaHRlcjogY29kZXJheQ0KOmFzY2lpZG9jdG9yOg0KOmF1dGhvcjogJm5ic3A7ICZuYnNwO0xhdXJlbnQgQmxvY2gNCjplbWFpbDogJm5ic3A7ICZuYnNwOyBsYkBsYXVyZW50YmxvY2gub3JnDQo6cmV2ZGF0ZTogJm5ic3A7IDMwIHNlcHRlbWJyZSAyMDIwDQo6bGFuZzombmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBmcg0KOm51bWJlcmVkOg0KOnRvYzoNCg0KPSBVbiBzZXVsIGxvZ2ljaWVsIHBvdXIgdG91cyBtZXMgdGV4dGVzICENCg0KRXQgYXVzc2kgcG91ciBtb24gc2l0ZSBXZWIuDQoNClNvdXZlbnQgaifDqWNyaXMgdW4gdGV4dGUgZW4gTGFUZVggcG91ciBhdm9pciB1bmUgc29ydGllIFBERiBwcsOpc2VudGFibGUsIHB1aXMgb24gbWUgZGVtYW5kZSB1bmUgY29waWUgYXUgZm9ybWF0PC9jb2RlPg=="></span>docx<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+ZGUgV29yZCwgcGFyIGV4ZW1wbGUgcG91ciB1bmUgcHVibGljYXRpb24uIFRyYWR1aXJlIMOgIGxhIG1haW4gZHUgTGFUZVggZW48L2NvZGU+"></span>docx` est fastidieux, et on oublie toujours quelque chose. Les logiciels censés faire cela ne m'ont jamais convaincu, et ceux qui le font en sens inverse sont pires.
  97.  
  98. ...
  99.  
  100. L'article que vous lisez a été écrit en AsciiDoc et traduit en Spip par AsciiDoc-Spip. Voici le programme :
  101.  
  102. [source, scheme]
  103. ----
  104. (module AsciiDoc-Spip
  105.   (main analyse-fichier))
  106.  
  107. (define (analyse-fichier args)
  108.   (let ((un-fichier (cadr args)))
  109.      (call-with-input-file un-fichier lire-des-lignes)))
  110.  
  111. ...
  112. ----

Télécharger