@@ -0,0 +1,111 @@
2+Copyright (C) 2009 John MacFarlane <jgm@berkeley.edu>
4+This program is free software; you can redistribute it and/or modify
5+it under the terms of the GNU General Public License as published by
6+the Free Software Foundation; either version 2 of the License, or
7+(at your option) any later version.
9+This program is distributed in the hope that it will be useful,
10+but WITHOUT ANY WARRANTY; without even the implied warranty of
11+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+GNU General Public License for more details.
14+You should have received a copy of the GNU General Public License
15+along with this program; if not, write to the Free Software
16+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20+ Module : Text.Pandoc.Templates
21+ Copyright : Copyright (C) 2009 John MacFarlane
22+ License : GNU GPL, version 2 or above
24+ Maintainer : John MacFarlane <jgm@berkeley.edu>
26+ Portability : portable
28+A simple templating system with variable substitution and conditionals.
31+> > renderTemplate [("name","Sam"),("salary","50,000")] $
32+> "Hi, $name$. $if(salary)$You make $$$salary$.$else$No salary data.$endif$"
33+> > "Hi, John. You make $50,000."
35+A slot for an interpolated variable is a variable name surrounded
36+by dollar signs. To include a literal @$@ in your template, use
37+@$$@. Variable names must begin with a letter and can contain letters,
38+numbers, @_@, and @-@.
40+A conditional begins with @$if(variable_name)$@ and ends with @$endif$@.
41+It may optionally contain an @$else$@ section. The if section is
42+used if @variable_name@ has a non-null value, otherwise the else section
46+module Text.Pandoc.Templates (renderTemplate) where
48+import Text.ParserCombinators.Parsec
49+import Control.Monad (liftM)
51+-- | Renders a template
52+renderTemplate :: [(String,String)] -- ^ Assoc. list of values for variables
53+ -> String -- ^ Template
55+renderTemplate vals templ =
56+ case runParser (do x <- parseTemplate; eof; return x) vals "template" templ of
60+reservedWords :: [String]
61+reservedWords = ["else","endif"]
63+parseTemplate :: GenParser Char [(String,String)] [String]
65+ many $ plaintext <|> escapedDollar <|> conditional <|> variable
67+plaintext :: GenParser Char [(String,String)] String
68+plaintext = many1 $ satisfy (/='$')
70+escapedDollar :: GenParser Char [(String,String)] String
71+escapedDollar = try $ string "$$" >> return "$"
73+conditional :: GenParser Char [(String,String)] String
74+conditional = try $ do
78+ skipMany (oneOf " \t")
80+ ifContents <- liftM concat parseTemplate
81+ elseContents <- option "" $ do try (string "$else$")
82+ skipMany (oneOf " \t")
84+ liftM concat parseTemplate
86+ skipMany (oneOf " \t")
89+ return $ case lookup id' st of
90+ Just "" -> elseContents
92+ Nothing -> elseContents
94+ident :: GenParser Char [(String,String)] String
97+ rest <- many (alphaNum <|> oneOf "_-")
98+ let id' = first : rest
99+ if id' `elem` reservedWords
103+variable :: GenParser Char [(String,String)] String
109+ return $ case lookup id' st of