git.iko.soy/typeable/pandoc
on master help sign in
Added $for$ to template system.

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

commit5ba6c0911cb44c3a095bc3cedc51e4afa79c6b30 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateThu 31 Dec 2009, 01:15 (17 years ago) parent16f0604
3 files changed+77−18
README+15−5 man/man1/pandoc.1.md+15−5 src/Text/Pandoc/Templates.hs+47−8
README+15−5
@@ -472,6 +472,8 @@ the string `$title$` in
472472
473473will be replaced by the document title.
474474
475+To write a literal `$` in a template, use `$$`.
476+
475477Some variables are set automatically by pandoc. These vary somewhat
476478depending on the output format, but include:
477479
@@ -485,12 +487,10 @@ depending on the output format, but include:
485487: body of document
486488`title`
487489: title of document, as specified in title block
488−`authors`
489−: authors of document, as specified in title block
490+`author`
491+: author of document, as specified in title block
490492`date`
491493: date of document, as specified in title block
492−`css`
493−: links to CSS files, as specified using `-c/--css`
494494
495495Variables may be set at the command line using the `-V/--variable`
496496option. This allows users to include custom variables in their
@@ -509,7 +509,17 @@ value; otherwise it will include `Y`. `X` and `Y` are placeholders for
509509any valid template text, and may include interpolated variables or other
510510conditionals. The `$else$` section may be omitted.
511511
512−To write a literal `$` in a template, use `$$`.
512+When variables can have multiple values (for example, `author` in
513+a multi-author document), you can use the `$for$` keyword:
514+
515+ $for(author)$
516+ <meta name="author" content="$author$" />
517+ $endfor$
518+
519+You can optionally specify a separator to be used between
520+consecutive items:
521+
522+ $for(author)$$author$$sep$, $endfor$
513523
514524Pandoc's markdown vs. standard markdown
515525=======================================
man/man1/pandoc.1.md+15−5
@@ -253,6 +253,8 @@ the string `$title$` in
253253
254254will be replaced by the document title.
255255
256+To write a literal `$` in a template, use `$$`.
257+
256258Some variables are set automatically by pandoc. These vary somewhat
257259depending on the output format, but include:
258260
@@ -266,12 +268,10 @@ depending on the output format, but include:
266268: body of document
267269`title`
268270: title of document, as specified in title block
269−`authors`
270−: authors of document, as specified in title block
271+`author`
272+: author of document, as specified in title block
271273`date`
272274: date of document, as specified in title block
273−`css`
274−: links to CSS files, as specified using `-c/--css`
275275
276276Variables may be set at the command line using the `-V/--variable`
277277option. This allows users to include custom variables in their
@@ -290,7 +290,17 @@ value; otherwise it will include `Y`. `X` and `Y` are placeholders for
290290any valid template text, and may include interpolated variables or other
291291conditionals. The `$else$` section may be omitted.
292292
293−To write a literal `$` in a template, use `$$`.
293+When variables can have multiple values (for example, `author` in
294+a multi-author document), you can use the `$for$` keyword:
295+
296+ $for(author)$
297+ <meta name="author" content="$author$" />
298+ $endfor$
299+
300+You can optionally specify a separator to be used between
301+consecutive items:
302+
303+ $for(author)$$author$$sep$, $endfor$
294304
295305# SEE ALSO
296306
src/Text/Pandoc/Templates.hs+47−8
@@ -29,9 +29,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2929A simple templating system with variable substitution and conditionals.
3030Example:
3131
32−> > renderTemplate [("name","Sam"),("salary","50,000")] $
33−> "Hi, $name$. $if(salary)$You make $$$salary$.$else$No salary data.$endif$"
34−> > "Hi, John. You make $50,000."
32+> renderTemplate [("name","Sam"),("salary","50,000")] $
33+> "Hi, $name$. $if(salary)$You make $$$salary$.$else$No salary data.$endif$"
34+> "Hi, John. You make $50,000."
3535
3636A slot for an interpolated variable is a variable name surrounded
3737by dollar signs. To include a literal @$@ in your template, use
@@ -48,6 +48,20 @@ is used.
4848
4949Conditional keywords should not be indented, or unexpected spacing
5050problems may occur.
51+
52+If a variable name is associated with multiple values in the association
53+list passed to 'renderTemplate', you may use the @$for$@ keyword to
54+iterate over them:
55+
56+> renderTemplate [("name","Sam"),("name","Joe")] $
57+> "$for(name)$\nHi, $name$.\n$endfor$"
58+> "Hi, Sam.\nHi, Joe."
59+
60+You may optionally specify separators using @$sep$@:
61+
62+> renderTemplate [("name","Sam"),("name","Joe"),("name","Lynn")] $
63+> "Hi, $for(name)$$name$$sep$, $endfor$"
64+> "Hi, Sam, Joe, Lynn."
5165-}
5266
5367module Text.Pandoc.Templates ( renderTemplate
@@ -55,11 +69,11 @@ module Text.Pandoc.Templates ( renderTemplate
5569 , getDefaultTemplate) where
5670
5771import Text.ParserCombinators.Parsec
58−import Control.Monad (liftM, when)
72+import Control.Monad (liftM, when, forM)
5973import qualified Control.Exception as E (try, IOException)
6074import System.FilePath
6175import Text.Pandoc.Shared (readDataFile)
62−import Data.List (intercalate)
76+import Data.List (intercalate, intersperse)
6377import Text.PrettyPrint (text, Doc)
6478import Text.XHtml (primHtml, Html)
6579import Data.ByteString.Lazy.UTF8 (ByteString, fromString)
@@ -111,11 +125,11 @@ renderTemplate vals templ =
111125 Right r -> toTarget $ concat r
112126
113127reservedWords :: [String]
114−reservedWords = ["else","endif"]
128+reservedWords = ["else","endif","for","endfor","sep"]
115129
116130parseTemplate :: GenParser Char TemplateState [String]
117131parseTemplate =
118− many $ (plaintext <|> escapedDollar <|> conditional <|> variable)
132+ many $ (plaintext <|> escapedDollar <|> conditional <|> for <|> variable)
119133 >>= adjustPosition
120134
121135plaintext :: GenParser Char TemplateState String
@@ -124,9 +138,11 @@ plaintext = many1 $ noneOf "$"
124138escapedDollar :: GenParser Char TemplateState String
125139escapedDollar = try $ string "$$" >> return "$"
126140
141+skipEndline :: GenParser Char st ()
142+skipEndline = try $ skipMany (oneOf " \t") >> newline >> return ()
143+
127144conditional :: GenParser Char TemplateState String
128145conditional = try $ do
129− let skipEndline = try $ skipMany (oneOf " \t") >> newline
130146 TemplateState pos vars <- getState
131147 string "$if("
132148 id' <- ident
@@ -149,6 +165,29 @@ conditional = try $ do
149165 when multiline $ optional skipEndline
150166 return contents
151167
168+for :: GenParser Char TemplateState String
169+for = try $ do
170+ TemplateState pos vars <- getState
171+ string "$for("
172+ id' <- ident
173+ string ")$"
174+ -- if newline after the "if", then a newline after "endif" will be swallowed
175+ multiline <- option False $ try $ skipEndline >> return True
176+ let matches = filter (\(k,_) -> k == id') vars
177+ let indent = replicate pos ' '
178+ contents <- forM matches $ \m -> do
179+ updateState $ \(TemplateState p v) -> TemplateState p (m:v)
180+ raw <- liftM concat $ lookAhead parseTemplate
181+ return $ intercalate ('\n':indent) $ lines $ raw ++ "\n"
182+ parseTemplate
183+ sep <- option "" $ do try (string "$sep$")
184+ when multiline $ optional skipEndline
185+ liftM concat parseTemplate
186+ string "$endfor$"
187+ when multiline $ optional skipEndline
188+ setState $ TemplateState pos vars
189+ return $ concat $ intersperse sep contents
190+
152191ident :: GenParser Char TemplateState String
153192ident = do
154193 first <- letter