git.iko.soy/typeable/pandoc
on master help sign in
Added templates module.

git-svn-id: https://pandoc.googlecode.com/svn/trunk@1673 788f1e2b-df1e-0410-8736-df70ead52e1b

commita42bae619a222de6b138b590c4d010ab15532d26 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateThu 31 Dec 2009, 01:08 (17 years ago) parentd86c017
2 files changed+112
pandoc.cabal+1 src/Text/Pandoc/Templates.hs+111
pandoc.cabal+1
@@ -193,6 +193,7 @@ Library
193193 Text.Pandoc.Writers.S5
194194 Other-Modules: Text.Pandoc.XML,
195195 Text.Pandoc.TH,
196+ Text.Pandoc.Templates
196197 Paths_pandoc
197198 Extensions: CPP, TemplateHaskell, FlexibleInstances
198199 Ghc-Options: -O2 -Wall
src/Text/Pandoc/Templates.hsnew file+111
@@ -0,0 +1,111 @@
1+{-
2+Copyright (C) 2009 John MacFarlane <jgm@berkeley.edu>
3+
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.
8+
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.
13+
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
17+-}
18+
19+{- |
20+ Module : Text.Pandoc.Templates
21+ Copyright : Copyright (C) 2009 John MacFarlane
22+ License : GNU GPL, version 2 or above
23+
24+ Maintainer : John MacFarlane <jgm@berkeley.edu>
25+ Stability : alpha
26+ Portability : portable
27+
28+A simple templating system with variable substitution and conditionals.
29+Example:
30+
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."
34+
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 @-@.
39+
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
43+is used.
44+-}
45+
46+module Text.Pandoc.Templates (renderTemplate) where
47+
48+import Text.ParserCombinators.Parsec
49+import Control.Monad (liftM)
50+
51+-- | Renders a template
52+renderTemplate :: [(String,String)] -- ^ Assoc. list of values for variables
53+ -> String -- ^ Template
54+ -> String
55+renderTemplate vals templ =
56+ case runParser (do x <- parseTemplate; eof; return x) vals "template" templ of
57+ Left e -> show e
58+ Right r -> concat r
59+
60+reservedWords :: [String]
61+reservedWords = ["else","endif"]
62+
63+parseTemplate :: GenParser Char [(String,String)] [String]
64+parseTemplate =
65+ many $ plaintext <|> escapedDollar <|> conditional <|> variable
66+
67+plaintext :: GenParser Char [(String,String)] String
68+plaintext = many1 $ satisfy (/='$')
69+
70+escapedDollar :: GenParser Char [(String,String)] String
71+escapedDollar = try $ string "$$" >> return "$"
72+
73+conditional :: GenParser Char [(String,String)] String
74+conditional = try $ do
75+ string "$if("
76+ id' <- ident
77+ string ")$"
78+ skipMany (oneOf " \t")
79+ optional newline
80+ ifContents <- liftM concat parseTemplate
81+ elseContents <- option "" $ do try (string "$else$")
82+ skipMany (oneOf " \t")
83+ optional newline
84+ liftM concat parseTemplate
85+ string "$endif$"
86+ skipMany (oneOf " \t")
87+ optional newline
88+ st <- getState
89+ return $ case lookup id' st of
90+ Just "" -> elseContents
91+ Just _ -> ifContents
92+ Nothing -> elseContents
93+
94+ident :: GenParser Char [(String,String)] String
95+ident = do
96+ first <- letter
97+ rest <- many (alphaNum <|> oneOf "_-")
98+ let id' = first : rest
99+ if id' `elem` reservedWords
100+ then pzero
101+ else return id'
102+
103+variable :: GenParser Char [(String,String)] String
104+variable = try $ do
105+ char '$'
106+ id' <- ident
107+ char '$'
108+ st <- getState
109+ return $ case lookup id' st of
110+ Just val -> val
111+ Nothing -> ""