From b4663bff44f50d6d86abf82170a6560543013d84 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 7 Feb 2026 10:51:00 +0100 Subject: [PATCH] =?UTF-8?q?Initialisation=20du=20d=C3=A9p=C3=B4t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 13 +++ Makefile | 51 ++++++++ README.md | 38 ++++++ docs/Makefile | 27 +++++ filters/Makefile | 16 +++ modele-article.md | 207 +++++++++++++++++++++++++++++++++ reference.odt | Bin 0 -> 13607 bytes src/Blocks.hs | 126 ++++++++++++++++++++ src/Inlines.hs | 60 ++++++++++ src/Makefile | 19 +++ src/diamond.hs | 45 +++++++ templates/diamond.opendocument | 47 ++++++++ 12 files changed, 649 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 docs/Makefile create mode 100644 filters/Makefile create mode 100644 modele-article.md create mode 100644 reference.odt create mode 100644 src/Blocks.hs create mode 100644 src/Inlines.hs create mode 100644 src/Makefile create mode 100755 src/diamond.hs create mode 100644 templates/diamond.opendocument diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be7b842 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +tags + +*.odt +!reference.odt + +docs/* +!docs/Makefile + +filters/* +!filters/Makefile + +**/*.hi +**/*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6b70ee0 --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ +# Nécessaire pour avoir les dépendances dans le répertoire lié à l'article. +.SECONDEXPANSION: + +# Un article par fichier .md. +ARTICLES=$(wildcard *.md) + +# Tâche par défaut. +all: $(patsubst %.md,%.odt,$(ARTICLES)) docs/all +.DEFAULT_GOAL:=all + +# Tâches virtuelles. +.PHONY: all docs/all src/all clean docs/clean filters/clean src/clean filters/diamond + +# Tâches liées à la doc. +docs/clean: + $(MAKE) -C docs clean + +docs/all: + $(MAKE) -C docs all + +# Tâche de nettoyage des sources. +src/clean: + $(MAKE) -C src clean + +# Tâche de génération du filtre. +filters/diamond: + $(MAKE) -C filters diamond + +# Tâche générique pour un article. +ARTICLE_DEPS=$(wildcard $*/*) + +%.odt: %.md filters/diamond reference.odt templates/diamond.opendocument $$(ARTICLE_DEPS) + echo $^ + pandoc \ + $< \ + --data-dir=. \ + --filter=diamond \ + --template=diamond.opendocument \ + --output=$@ + +%.unfiltered.json: %.md $$(ARTICLE_DEPS) + pandoc \ + $< \ + -t json \ + --outpur=$@ + +# Nettoyage. +clean: docs/clean filters/clean src/clean + rm -f $(patsubst %.md,%.odt,$(ARTICLES)) + +# vim: set tw=80 ts=4 sw=4 sts=4 spelllang=fr: diff --git a/README.md b/README.md new file mode 100644 index 0000000..79cf1ba --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# Génération article GLMF avec pandoc + +## Dépendances + +La construction nécessite Haskell et la bibliothèque Pandoc. + +Sous Debian, voici la liste des paquets à installer : + + - haskell + - libghc-pandoc-dev + +## Métadonnées + +Le template utilise les métadonnées suivantes : + + - titre: Titre de l'article + - auteur_nom: Nom de l'auteur + - auteur_description: Description de l'auteur + - editeur_nom: Nom de l'éditeur + - editeur_description: Description de l'éditeur + - chapeau: Chapeau + - mots_cles: Liste de mots clés + +## Construction du document + +Pour construire le document, il faut utiliser la commande : + +``` +pandoc monarticle.md \ + --filter=diamond.hs \ + --template=diamond.opendocument \ + --reference-doc=../guide-auteurs/diamond.ott \ + --output=monarticle.odt +``` + + + + diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..669393f --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,27 @@ + +# Tâche par défaut. +.DEFAULT_GOAL:=all +all: index.html + +.PHONY: all clean + +# Fichiers sources. +HS_FILES=$(wildcard ../src/*.hs) + +# Interfaces. +HI_BASE=$(wildcard /usr/lib/ghc-doc/haddock/ghc/base-*/base.haddock) +HI_PANDOC_TYPES=$(wildcard /usr/lib/ghc-doc/haddock/pandoc-types-*/pandoc-types.haddock) + +# Construction de la documentation. +index.html: ../src/diamond.hs $(HS_FILES) + haddock \ + --read-interface=https://hackage.haskell.org/package/base/docs,$(HI_BASE) \ + --read-interface=https://hackage.haskell.org/package/pandoc-types/docs/,$(HI_PANDOC_TYPES) \ + --source-base=../src \ + --odir . --html $^ + +# Nettoyage. +clean: + rm -f *.html *.css *.js *.json *.png + +# vim: set tw=80 ts=4 sw=4 sts=4 spelllang=fr: diff --git a/filters/Makefile b/filters/Makefile new file mode 100644 index 0000000..458fd14 --- /dev/null +++ b/filters/Makefile @@ -0,0 +1,16 @@ +# Tâche par défaut. +all: diamond +.DEFAULT_GOAL:=all + +# Tâches virtuelles. +.PHONY: all diamond clean + +# Construction du filtre diamond. +diamond: + $(MAKE) -C ../src ../filters/diamond + +# Nettoyage. +clean: + rm -f diamond + +# vim: set tw=80 ts=4 sw=4 sts=4 spelllang=fr: diff --git a/modele-article.md b/modele-article.md new file mode 100644 index 0000000..781879d --- /dev/null +++ b/modele-article.md @@ -0,0 +1,207 @@ +--- +titre: Titre de l'article +auteurs: + - nom: Prénom et Nom + description: Fonction ou métier et/ou contribution à des projets. Adresse e-mail si vous le souhaitez. + - nom: Denis Bodor + description: Chef des rédactions – dbodor@ed-diamond.com +mots_cles_entete: |- + Vous devez lister ici les mots-clés définissant votre article de la manière + suivante, exemple : +mots_cles: + - MALWARE + - PENTEST + - ANALYSE FORENSIQUE + - EXPLOIT + - RÉSEAU + - CYBERCRIMINALITÉ +chapeau: > + Ceci est le chapeau de l'article. Il s'agit d'une courte introduction au + sujet ou à la problématique. Essayez d'être explicite et de donner envie au + lecteur de poursuivre la lecture de l'article. +... +Votre article peut commencer par une introduction (attention, celle-ci ne doit +en principe pas être numérotée). + +Plutôt que de parler des outils les plus fréquemment utilisés, nous nous sommes +en partie concentrés ici sur des outils moins courants, et rarement abordés +dans les colonnes de *MISC* / *GNU/Linux Magazine* / *SysOps Pratique* / +*Hackable* (Attention ! Cet italique est généré par le style de caractère +« italic » et non par l'icône italique de LibreOffice, idem pour le gras) ou des +autres magazines spécialisés. + +# 1. Titre de niveau 1 + +Paragraphe en style « Normal » (et non « Standard » ou « Corps de texte »). +``` +# Ceci est du code +# Une entrée typique de menu.lst +# Le style employé est « code » +title= DEBIAN GNU/Linux 2.6.24 (hdc3 - ext3) +kernel= (hd1,2)/boot/vmlinuz-2.6.24-1-686 root=/dev/hdc3 vga=extended +initusrd (hd1,2)/boot/initrd.img-2.6.24-1-686 +``` + +Paragraphe en « Normal ». On fait ici mention d'un élément de la configuration : +l'étiquette `title` (style de caractère « code_par » pour du code dans du +texte) permet d'ajouter un titre dans les menus de GRUB. La commande +`grub-install` permet l'installation du *bootloader*. Nous pouvons spécifier +le mode graphique à utiliser avec l'option `vga` : + +``` +01: # Une entrée typique de menu.lst +02: title= DEBIAN GNU/Linux 2.6.24 (hdc3 - ext3) +03: kernel= (hd1,2)/boot/vmlinuz-2.6.24-1-686 root=/dev/hdc3 **vga=extended** +04: initrd (hd1,2)/boot/initrd.img-2.6.24-1-686 +``` +Si vous souhaitez faire référence à des lignes de code pour les expliquer, vous +pouvez les numéroter comme dans le code ci-dessus. Pour mettre en avant un +passage du code, utilisez le style « code_em » comme on l’a fait ci-dessus pour +« vga-extended ». + +:::pao +Vous pouvez mentionner de cette manière les éventuelles informations à indiquer +à la rédaction ou au service de mise en page. Cette mention n'apparaîtra pas +dans l'article final. +::: + +Le second thème de ce dossier explore l’audit des applications à la découverte +de failles de sécurité. Il s’ouvre avec un article sur **American Fuzzy Lop** +(Attention, le « gras » est généré par le style de caractère « gras » et non par +l'icône gras de LibreOffice), un outil de fuzzing cherchant à couvrir le maximum +de code du programme audité en analysant son graphe d’exécution. + +:::note +Le texte présent ici, rédigé en style « Note », apparaîtra dans l'article final +dans une boîte spéciale « note ». Vous pourrez ainsi présenter des informations +complémentaires. +::: + +Les indications en style « pragma », comme ci-dessus, doivent toujours être +encadrées de 3 slashs /// … ///. + +Si vous souhaitez une note ayant un titre spécifique, par exemple : +« Attention », il faut utiliser : + +:::attention +Le texte présent ici, rédigé en style « Note », apparaîtra dans l'article final +dans une boîte spéciale « Attention ». Vous pouvez par ce biais donner un titre +à vos encarts de notes. +::: + +Les sessions de commandes interactives sont à utiliser avec le style de +paragraphe « console ». On peut également ici mettre en évidence certaines +parties, grâce au style de caractère « code_em » : + +| $ cat dma +| 2: floppy +| 3: **parport0** # mise en évidence avec **code_em** +| 4: cascade + +Plus d'informations sur nos magazines sur : +(notez l'utilisation du style de caractère « url » et la désactivation de +l'hyperlien). + +Vous pouvez également insérer des listes à puces ou numérotées +dans votre article, comme ceci : + + - item 1 ; + - item 2 ; + - item 3 ; + - etc. + +Notez que nous n'utilisons pas les puces/numérotations automatiques de +LibreOffice. + +De même, les tableaux doivent être présentés le plus simplement possible, le +contenu doit être en style « Normal », par exemple : + +blabla | blabla | blabla +-------+--------+------- +blabla | blabla | blabla + +Les références, à placer entre crochets et à mettre en style « ref_par», doivent +être intégrées dans le discours du texte et leur étiquette sera un nombre OU un +mot-clé. Exemple : + +Vous trouverez tous les sommaires des derniers numéros publiés sur la base +documentaire des Éditions Diamond [^BASEDOC]. + +OU + +Enfin, des infrastructures dédiées sont parfois mises en place pour chacune des +cibles comme l'a décrit cet article [^1]. Vous trouverez également des +informations supplémentaires sur le sujet dans cet ouvrage [^2]. + +C'est seulement lorsqu'une citation apparaît dans le texte qu'elle peut être +développée dans la section « Références » en fin d'article. Dans cette section, +on lui applique alors le style « ref_cible » (voir en bas de l’article). + +N'intégrez pas vos images dans le fichier LibreOffice, mais faites-en mention +avec le style « pragma ». Vous pouvez faire référence à une figure dans le +texte : comme on peut le voir en figure 1... ou encore (voir figure 1). + +![figure_01](nom_article_figure_01.png "Exemple d'écran de démarrage GRUB. Une légende peut être une simple phrase ou même la mention du numéro de figure. Le style utilisé pour une légende.... est « legende ».") + +Lorsqu'on décrit une interface graphique ou texte, il est possible de faire +référence aux menus et options avec le style de caractères « menu ». Exemple : +Cochez l'option [Auto-connexion]{.menu} dans la fenêtre des options qui apparaît via le +menu [Fichier > Préférences]{.menu}. + +Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla +blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla +bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla +blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla +blabla bla blabla, bla bla bla blabla. + +## 1.1 Titre de niveau 2 + +Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla +blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla +bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla +blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla +blabla bla blabla, bla bla bla blabla. + +Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla +blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla +bla bla blabla. + +### 1.1.1 Titre de niveau 3 + +Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla +blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla +bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla +blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla +blabla bla blabla, bla bla bla blabla. + +Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla +blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla +bla bla blabla. + +#### 1.1.1.1 Titre de niveau 4 + +Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla +blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla +bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla +blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla blabla. Bla +blabla bla blabla, bla bla bla blabla. + +Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla bla bla +blabla. Bla blabla bla blabla, bla bla bla blabla. Bla blabla bla blabla, bla +bla bla blabla. + +# Conclusion + +La conclusion de l'article ne comporte pas de numérotation. + +# Remerciements + +Si vous souhaitez ajouter des remerciements à votre article, cette partie pourra +être ajoutée à cet endroit et présentée de cette manière. + +[^BASEDOC]: Base documentaire des Éditions Diamond : +[https://connect.ed-diamond.com/](https://connect.ed-diamond.com/) +[^1]: P. Nom, « Titre de l'article », *MISC n°118*, novembre-décembre 2021 +[^2]: P. Nom et P. Autre-nom, « Titre livre », éditeur, année + + diff --git a/reference.odt b/reference.odt new file mode 100644 index 0000000000000000000000000000000000000000..0f29ad74e9b6d151b1d4abb403f0dac01e95881f GIT binary patch literal 13607 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 literal 0 HcmV?d00001 diff --git a/src/Blocks.hs b/src/Blocks.hs new file mode 100644 index 0000000..bc3a253 --- /dev/null +++ b/src/Blocks.hs @@ -0,0 +1,126 @@ +{- | + Module : Blocks + Description : Ce module contient les fonctions nécessaires au traitement des blocks. +-} +module Blocks (topLvlBlock) where + +import Inlines + +import Data.List +import Data.Maybe +import Data.Text +-- +import Text.Pandoc.Definition +import Text.Pandoc.Builder +import Text.Pandoc.Walk + +-- Construit une structure d'attributs de Div à partir du nom du style. +styleDivAttr :: Maybe String -> Attr +styleDivAttr Nothing = styleDivAttr . Just $ "Normal" +styleDivAttr (Just "") = (pack "", [], []) +styleDivAttr (Just style) = (pack "", [], [(pack "custom-style", pack style)]) + +topLvlBlock :: Block -> Blocks + +-- Traite un block Para (paragraphe). +topLvlBlock (Para inlines) = + divWith + (styleDivAttr Nothing) + (para . mconcat $ inline <$> inlines) + +-- Traite un block Header (titre). +topLvlBlock (Header level attributes inlines) = + headerWith attributes level $ fromList inlines + +-- Transforme un CodeBlock en bloc avec le style "code". +topLvlBlock (CodeBlock _ txt) = + mconcat $ codeBlockLine <$> Data.Text.lines txt + where + codeBlockLine :: Text -> Blocks + codeBlockLine txt = + divWith + (styleDivAttr $ Just "code") + (para . mconcat $ codeEmInline <$> (toList . text $ txt)) + +-- Traite un block Div. +topLvlBlock (Div (identifier, classes, pairs) blocks) + -- Note "PAO" + | pack "pao" `Prelude.elem` classes = + noteBlock + (Just "Début note PAO") + (fromList blocks) + (Just "Fin note PAO") + (Just "Normal") + | pack "note" `Prelude.elem` classes = + noteBlock + (Just $ "Début note") + (fromList blocks) + (Just "Fin note") + (Just "note") + -- Note "Attention" + | Data.List.length classes > 0 = + noteBlock + (Just $ "Début note : " ++ (unpack . toTitle . Data.Text.unwords $ classes)) + (fromList blocks) + (Just "Fin note") + (Just "note") + where + --- Note générique. + noteBlock :: Maybe String -> Blocks -> Maybe String -> Maybe String -> Blocks + noteBlock header blocks footer style = + (pragma . pack $ "/// " ++ fromJust header ++ " ///") + <> (divWith (styleDivAttr style) blocks) + <> (pragma . pack $ "/// " ++ fromJust footer ++ " ///") + -- Block "pragma". + pragma :: Text -> Blocks + pragma txt = + divWith + (styleDivAttr $ Just "pragma") + (para . Text.Pandoc.Builder.singleton $ Str txt) + +-- Transforme un LineBlock avec un seul Div en block avec le style "console". +topLvlBlock (LineBlock inlines) = + divWith + (styleDivAttr $ Just "console") + (mconcat $ lineBlockLine <$> inlines) + where + lineBlockLine :: [Inline] -> Blocks + lineBlockLine inlines = para . mconcat $ codeEmInline <$> inlines + +-- Traite un block BulletList (list à puces). +topLvlBlock (BulletList blocks) = + mconcat $ bulletListItem <$> blocks + where + -- Traite un élément de liste. + -- Note : on traite ici le cas simple. Ça plantera probablement si on met du + -- code ou autre dans un élémente de liste. + bulletListItem :: [Block] -> Blocks + bulletListItem (first:others) = + divWith + (styleDivAttr $ Just "Normal") + (firstBlock first <> fromList others) + where + firstBlock :: Block -> Blocks + firstBlock (Plain inlines) = + para + $ (Text.Pandoc.Builder.singleton . Str $ pack "- ") + <> mconcat (inline <$> inlines) + +-- TODO Alexis Lahouze 2025-09-30 Tables +topLvlBlock (Table attributes caption columns header body footer) = + tableWith attributes caption columns header body footer + +topLvlBlock (Figure attributes caption blocks) = + fromList [Figure attributes caption blocks] + +-- Ignore les blocs HTML bruts. +topLvlBlock (RawBlock (Format format) text) = fromList [] + + +-- Transforme un BlockQuote en bloc avec le style "console" +--diamond (BlockQuote block) = styleBlock block "console" +--topLvlBlock (BlockQuote blocks) = blockQuote . fromList $ blocks + +-- TODO Alexis Lahouze 2025-09-30 Références + +--topLvlBlock block = Text.Pandoc.Builder.singleton block diff --git a/src/Inlines.hs b/src/Inlines.hs new file mode 100644 index 0000000..d964156 --- /dev/null +++ b/src/Inlines.hs @@ -0,0 +1,60 @@ +module Inlines + ( styleInlines + , codeEmInline + , inline + ) where + +import Data.List +import Data.Maybe +import Data.Text + +import Text.Pandoc.Definition +import Text.Pandoc.Builder + +-- Génère une structure d'attributs de Spam à partir du nom du style. +styleSpanAttr :: Maybe String -> Attr +styleSpanAttr Nothing = styleSpanAttr $ Just "" +styleSpanAttr (Just "") = (pack "", [], []) +styleSpanAttr (Just style) = (pack "", [], [(pack "custom-style", pack style)]) + +-- Applique le style ODT à une liste d'Inline. +styleInlines :: Inlines -> Maybe String -> Inlines +-- Intègre la liste d'Inline dans un paragraphe. +styleInlines inlines style = spanWith (styleSpanAttr style) inlines + + +codeEmInline :: Inline -> Inlines +codeEmInline (Emph inlines) = + spanWith (styleSpanAttr $ Just "code_em") $ fromList inlines +codeEmInline (Strong inlines) = + spanWith (styleSpanAttr $ Just "code_em") $ fromList inlines +codeEmInline (Str txt) = + codeEmStr txt + where + codeEmStr :: Text -> Inlines + codeEmStr txt + | isJust strippedSuffix && isJust stripped = + codeEmInline $ Emph [Str . fromJust $ stripped] + | otherwise = text txt + where + strippedSuffix = Data.Text.stripSuffix (pack "**") txt + stripped = Data.Text.stripPrefix (pack "**") $ fromJust strippedSuffix +codeEmInline txt = Text.Pandoc.Builder.singleton txt + +inline :: Inline -> Inlines +inline (Emph inlines) = + spanWith (styleSpanAttr $ Just "italic") $ fromList inlines +inline (Strong inlines) = + spanWith (styleSpanAttr $ Just "gras") $ fromList inlines +inline (Code _ txt) = + spanWith (styleSpanAttr $ Just "code_par") $ text txt +inline (Link _ _ (url, _)) = + spanWith + (styleSpanAttr $ Just "url") + (Text.Pandoc.Builder.singleton $ Str url) + +inline (Span (_, classes, _) inlines) + | Data.List.elem (pack "menu") classes = + spanWith (styleSpanAttr $ Just "menu") $ fromList inlines + +inline inline = Text.Pandoc.Builder.singleton inline diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..9e91ec8 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,19 @@ + +# Tâche par défaut. +all: $(FILTERS_DIR)/diamond +.DEFAULT_GOAL:=all + +# Tâches virtuelles. +.PHONY: lean all + +# Construction du filtre diamond. +SRC_FILES=$(wildcard *.hs) + +../filters/diamond: diamond.hs $(SRC_FILES) + ghc -o $@ $< + +# Nettoyage. +clean: + rm -f *.hi *.o + +# vim: set tw=80 ts=4 sw=4 sts=4 spelllang=fr: diff --git a/src/diamond.hs b/src/diamond.hs new file mode 100755 index 0000000..a094ab3 --- /dev/null +++ b/src/diamond.hs @@ -0,0 +1,45 @@ +{-| Main filter module. +-} + +{- | + Module : Main + Copyright : (c) Alexis Lahouze, 2025 +-} + +module Main (main, diamond) where + +import Inlines +import Blocks + +import Data.Map +import Data.Maybe +import Data.Text + +import Text.Pandoc.Builder +import Text.Pandoc.Definition +import Text.Pandoc.JSON +import Text.Pandoc.Walk + +-- | Extract notes from inline. +note :: Inline -> [Block] +note (Note blocks) = Text.Pandoc.Builder.toList . mconcat $ topLvlBlock <$> blocks +note _ = [] + +-- | Extract notes in a Metavalue. +notes :: [Block] -> MetaValue +notes blocks = MetaBlocks $ query Main.note blocks + + +-- | Fonction de base du filtre. +diamond :: Pandoc -> Pandoc + +-- | Par défaut on retourne le block sans transformation. +diamond (Pandoc meta blocks) = + Pandoc + (Meta $ insert (pack "notes") (notes blocks) (unMeta meta)) + (Text.Pandoc.Builder.toList . mconcat $ topLvlBlock <$> blocks) + -- TODO Alexis Lahouze 2025-11-20 Append notes. + +-- | Fonction principale du filtre. +main :: IO () +main = toJSONFilter diamond diff --git a/templates/diamond.opendocument b/templates/diamond.opendocument new file mode 100644 index 0000000..f669990 --- /dev/null +++ b/templates/diamond.opendocument @@ -0,0 +1,47 @@ + + + + + + + $automatic-styles$ + +$for(header-includes)$ + $header-includes$ +$endfor$ + + +$if(titre)$ +$titre$ +$endif$ +$for(auteurs)$ +$it.nom$ +$if(it.description)$ +$it.description$ +$endif$ +$sep$ +$endfor$ +$if(chapeau)$ + +$chapeau$ + +$endif$ +$if(mots_cles)$ +/// Mots-clés /// +$if(mots_cles_entete)$ +$mots_cles_entete$ +$endif$ +$for(mots_cles)$$mots_cles$$sep$ / $endfor$ +/// Fin Mots-clés /// +$endif$ +$for(include-before)$ +$include-before$ +$endfor$ +$body$ +Références +$for(include-after)$ +$include-after$ +$endfor$ + + +