admin管理员组

文章数量:1197776

DocTemplates, which are part of the Pandoc universe, are somewhat tricky to use. Recently, I asked ChatGTP and it produced nice example code - but unfortunately, even after multiple iterations, not working. Applying some human intelligence and changes, it produced the expected output.

The result may be a useful example how to use DocTemplates (version 0.11.0.1):

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Text.Pandoc
import Text.Pandoc.Templates (compileTemplate, renderTemplate)
import qualified Data.Text.IO as TIO
import qualified Data.Text as T
import qualified Data.Map as M
import Control.Monad (when)
import Text.DocLayout -- (Doc, render)

-- Define the (Text, Text) pairs
pairs :: [(T.Text, T.Text)]
pairs =
  [ ("Name", "Alice"),
    ("Age", "30"),
    ("Country", "Wonderland")
  ]

pairsToContext :: [(T.Text, T.Text)] -> M.Map T.Text T.Text
-- |Convert (Text, Text) pairs to a Pandoc template context (Key-Value map)
pairsToContext = M.fromList

compileTemplateFromFile :: FilePath -> IO (  (Template T.Text))
-- | Compile the template from a file
compileTemplateFromFile templateFile = do
  templateContent :: T.Text  <- TIO.readFile templateFile
  c1 :: Either String (Template T.Text)   <- compileTemplate "" templateContent
  case c1 of 
    Left err -> error . unlines $ ["rrwer - compileTemplateFromFile failed with ", err] 
    Right temp -> return temp 
  
renderTemplateWithContext :: Template T.Text -> M.Map T.Text T.Text -> Doc T.Text
renderTemplateWithContext template context = renderTemplate template context

renderPairsWithTemplate :: FilePath -> [(T.Text, T.Text)] -> IO T.Text
-- Render the template with a context
renderPairsWithTemplate templateFile pairs = do 
    let context = pairsToContext pairs
    -- Step 1: Compile the template
    compiledTemplateResult :: Template T.Text <- compileTemplateFromFile templateFile
    -- Step 2: Render the template
    let renderedResult = renderTemplateWithContext compiledTemplateResult context :: Doc T.Text
    -- Step 3: render the Doc to Text 
        result = render (Just 80) renderedResult
    return result 

main :: IO ()
main = do
    let templateFile = "template.md"
    result <- renderPairsWithTemplate templateFile pairs 
    let outputFile = "output.md"
    TIO.writeFile outputFile  result
    putStrLn . unlines $ [ "Template rendered successfully to: ", T.unpack result] 

The template template.md is

# My Document

- Name: $Name$
- Age: $Age$
- Country: $Country$ 

Asking ChatGTP do solve the task with the less expressive Mustache templating method gives (again not working) simpler code...

本文标签: pandocRender a list of pairs (TextText) with DocTemplatesStack Overflow