aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2019-09-29 15:00:34 -0700
committerJohn MacFarlane <jgm@berkeley.edu>2019-09-29 15:00:34 -0700
commitac4067fe2e6e798da3e771d56dfd9a9c1b5fb366 (patch)
tree482d97564a875552b6e8cb76194be10564feed24
parent0e02d5cacc7adb76ff5d1091849a314e29235153 (diff)
downloadpandoc-ac4067fe2e6e798da3e771d56dfd9a9c1b5fb366.tar.gz
MANUAL.txt: Add fuller documentation of templates.
Including new template syntax, partials, etc. Closes #5779.
-rw-r--r--MANUAL.txt333
-rw-r--r--changelog.md25
2 files changed, 274 insertions, 84 deletions
diff --git a/MANUAL.txt b/MANUAL.txt
index 384bff7fe..418683c5d 100644
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -1438,9 +1438,268 @@ directory (see `--data-dir`, above). *Exceptions:*
Templates contain *variables*, which allow for the inclusion of
arbitrary information at any point in the file. They may be set at the
command line using the `-V/--variable` option. If a variable is not set,
-pandoc will look for the key in the document's metadata – which can be set
+pandoc will look for the key in the document's metadata, which can be set
using either [YAML metadata blocks][Extension: `yaml_metadata_block`]
-or with the `-M/--metadata` option.
+or with the `-M/--metadata` option. In addition, some variables
+are given default values by pandoc.
+
+If you use custom templates, you may need to revise them as pandoc
+changes. We recommend tracking the changes in the default templates,
+and modifying your custom templates accordingly. An easy way to do this
+is to fork the [pandoc-templates] repository and merge in
+changes after each pandoc release.
+
+ [pandoc-templates]: https://github.com/jgm/pandoc-templates
+
+Template syntax
+---------------
+
+To mark variables and control structures in the template, either
+`$`...`$` or `${`...`}` may be used as delimiters. The styles
+may also be mixed in the same template, but the opening and
+closing delimiter must match in each case. The opening
+delimiter may be followed by one or more spaces or tabs, which
+will be ignored. The closing delimiter may be followed by one or
+more spaces or tabs, which will be ignored.
+
+To include a literal `$` in the document, use `$$`.
+
+### Comments
+
+Anything between the sequence `$--` and the end of the
+line will be treated as a comment and omitted from the output.
+
+### Interpolated variables
+
+A slot for an interpolated variable is a variable name surrounded
+by matched delimiters. Variable names must begin with a letter
+and can contain letters, numbers, `_`, `-`, and `.`. The
+keywords `it`, `if`, `else`, `endif`, `for`, `sep`, and `endfor` may
+not be used as variable names. Examples:
+
+```
+$foo$
+$foo.bar.baz$
+$foo_bar.baz-bim$
+$ foo $
+${foo}
+${foo.bar.baz}
+${foo_bar.baz-bim}
+${ foo }
+```
+
+Variable names with periods are used to get at structured
+variable values. So, for example, `employee.salary` will return the
+value of the `salary` field of the object that is the value of
+the `employee` field.
+
+- If the value of the variable is simple value, it will be
+ rendered verbatim. (Note that no escaping is done;
+ the assumption is that the calling program will escape
+ the strings appropriately for the output format.)
+- If the value is a list, the values will be concatenated.
+- If the value is a map, the string `true` will be rendered.
+- Every other value will be rendered as the empty string.
+
+The value of a variable that occurs by itself on a line
+will be indented to the same level as the opening delimiter of
+the variable.
+
+### Conditionals
+
+A conditional begins with `if(variable)` (enclosed in
+matched delimiters) and ends with `endif` (enclosed in matched
+delimiters). It may optionally contain an `else` (enclosed in
+matched delimiters). The `if` section is used if
+`variable` has a non-empty value, otherwise the `else`
+section is used (if present). (Note that even the
+string `false` counts as a true value.) Examples:
+
+```
+$if(foo)$bar$endif$
+
+$if(foo)$
+ $foo$
+$endif$
+
+$if(foo)$
+part one
+$else$
+part two
+$endif$
+
+${if(foo)}bar${endif}
+
+${if(foo)}
+ ${foo}
+${endif}
+
+${if(foo)}
+${ foo.bar }
+${else}
+no foo!
+${endif}
+```
+
+The keyword `elseif` may be used to simplify complex nested
+conditionals. Thus
+
+```
+$if(foo)$
+XXX
+$elseif(bar)$
+YYY
+$else$
+ZZZ
+$endif$
+```
+
+is equivalent to
+
+```
+$if(foo)$
+XXX
+$else$
+$if(bar)$
+YYY
+$else$
+ZZZ
+$endif$
+$endif$
+```
+
+### For loops
+
+A for loop begins with `for(variable)` (enclosed in
+matched delimiters) and ends with `endfor` (enclosed in matched
+delimiters. If `variable` is an array, the material inside
+the loop will be evaluated repeatedly, with `variable` being set
+to each value of the array in turn. If the value of the
+associated variable is not an array, a single iteration will be
+performed on its value.
+
+Examples:
+
+```
+$for(foo)$$foo$$sep$, $endfor$
+
+$for(foo)$
+ - $foo.last$, $foo.first$
+$endfor$
+
+${ for(foo.bar) }
+ - ${ foo.bar.last }, ${ foo.bar.first }
+${ endfor }
+```
+
+You may optionally specify a separator between consecutive
+values using `sep` (enclosed in matched delimiters). The
+material between `sep` and the `endfor` is the separator.
+
+```
+${ for(foo) }${ foo }${ sep }, ${ endfor }
+```
+
+Instead of the variable name, the special anaphoric keyword `it`
+may be used inside the loop.
+
+```
+${ for(foo.bar) }
+ - ${ it.last }, ${ it.first }
+${ endfor }
+```
+
+### Partials
+
+Partials (subtemplates stored in different files) may be
+included using the syntax
+
+```
+${ boilerplate() }
+```
+
+Partials will be sought in the directory containing
+the main template, and will be assumed to have the
+same extension as the main template if they lack
+an explicit extension. (If the partials are not
+found here, they will also be sought in the `templates`
+subdirectory of the user data directory.)
+
+Partials may optionally be applied to variables using
+a colon:
+
+```
+${ date:fancy() }
+
+${ articles:bibentry() }
+```
+
+If `articles` is an array, this will iterate over its
+values, applying the partial `bibentry()` to each one.
+So the second example above is equivalent to
+
+```
+${ for(articles) }
+${ it:bibentry() }
+${ endfor }
+```
+
+Note that the anaphoric keyword `it` must be used when
+iterating over partials. In the above examples,
+the `bibentry` partial should contain `it.title`
+(and so on) instead of `articles.title`.
+
+Final newlines are omitted from included partials.
+
+Partials may include other partials. If you exceed
+a nesting level of 50, though, in resolving partials,
+the literal `(loop)` will be returned, to avoid infinite loops.
+
+A separator between values of an array may be specified
+in square brackets, immediately after the variable name
+or partial:
+
+```
+${months[, ]}$
+
+${articles:bibentry()[; ]$
+```
+
+The separator in this case is literal and (unlike with `sep`
+in an explicit `for` loop) cannot contain interpolated
+variables or other template directives.
+
+### Breakable spaces
+
+Normally, spaces in the template itself (as opposed to values of
+the interpolated variables) are not breakable, but they can be
+made breakable in part of the template by using the `+reflow`
+keyword (ended with `-reflow`).
+
+```
+${ +reflow }This long line may break if the document is rendered
+with a short line length.${ -reflow }
+```
+
+### Nesting
+
+As noted above, the value of a variable that occurs by itself on
+a line will be indented to the same level as the opening
+delimiter of the variable.
+
+In addition, any part of a template can be marked explicitly for
+indented rendering, using the `+nest` keyword (o start nesting at
+the column where it appears) and `-nest` to stop nesting.
+
+Example:
+
+```
+$for(article)$
+- $+nest$$article.author$, "$article.title$," in $article.book$
+ ($article.year$).$-nest$
+$endfor$
+```
+
Metadata variables
------------------
@@ -2014,76 +2273,6 @@ on the output format, and include the following:
: title of table of contents (works only with EPUB,
opendocument, odt, docx, pptx, beamer, LaTeX)
-Using variables in templates
-----------------------------
-
-Variable names are sequences of alphanumerics, `-`, and `_`,
-starting with a letter. A variable name surrounded by `$` signs
-will be replaced by its value. For example, the string `$title$` in
-
- <title>$title$</title>
-
-will be replaced by the document title.
-
-To write a literal `$` in a template, use `$$`.
-
-Templates may contain conditionals. The syntax is as follows:
-
- $if(variable)$
- X
- $else$
- Y
- $endif$
-
-This will include `X` in the template if `variable` has a truthy
-value; otherwise it will include `Y`. Here a truthy value is any
-of the following:
-
-- a string that is not entirely white space,
-- a non-empty array where the first value is truthy,
-- any number (including zero),
-- any object,
-- the boolean `true` (to specify the boolean `true`
- value using YAML metadata or the `--metadata` flag,
- use `true`, `True`, or `TRUE`; with the `--variable`
- flag, simply omit a value for the variable, e.g.
- `--variable draft`).
-
-`X` and `Y` are placeholders for any valid template text,
-and may include interpolated variables or other conditionals.
-The `$else$` section may be omitted.
-
-When variables can have multiple values (for example, `author` in
-a multi-author document), you can use the `$for$` keyword:
-
- $for(author)$
- <meta name="author" content="$author$" />
- $endfor$
-
-You can optionally specify a separator to be used between
-consecutive items:
-
- $for(author)$$author$$sep$, $endfor$
-
-Note that the separator needs to be specified immediately before the `$endfor`
-keyword.
-
-A dot can be used to select a field of a variable that takes
-an object as its value. So, for example:
-
- $author.name$ ($author.affiliation$)
-
-The value of a variable will be indented to the same level as the variable.
-
-If you use custom templates, you may need to revise them as pandoc
-changes. We recommend tracking the changes in the default templates,
-and modifying your custom templates accordingly. An easy way to do this
-is to fork the [pandoc-templates] repository and merge in changes after each
-pandoc release.
-
-Templates may contain comments: anything on a line after `$--`
-will be treated as a comment and ignored.
-
[pandoc-templates]: https://github.com/jgm/pandoc-templates
Extensions
diff --git a/changelog.md b/changelog.md
index 3ce84a10e..d4314aaa3 100644
--- a/changelog.md
+++ b/changelog.md
@@ -498,20 +498,21 @@
* Improvements in templates system (from doctemplates-0.6.1):
+ Pandoc templates now support a number of new features that
- have been added in doctemplates: notably, partials and keywords
- to control nesting and reflowing of text.
+ have been added in doctemplates: notably, `elseif`, `it`,
+ partials and keywords to control nesting and reflowing of
+ text.
+ We now used templates parameterized on doclayout Doc types.
- The main impact of this change is better reflowing of content
- interpolated into templates. Previously, interpolated variables
- were rendered independently and intepolated as strings,
- which could lead to overly long lines. Now the templates
- interpolated as Doc values which may include breaking
- spaces, and reflowing occurs after template interpolation
- rather than before.
+ The main impact of this change is better reflowing of
+ content interpolated into templates. Previously,
+ interpolated variables were rendered independently and
+ intepolated as strings, which could lead to overly long
+ lines. Now the templates interpolated as Doc values which
+ may include breaking spaces, and reflowing occurs after
+ template interpolation rather than before.
+ Remove code from the LaTeX, Docbook, and JATS writers that
- looked in the template for strings to determine whether it is a
- book or an article, or whether csquotes is used. This was
- always kludgy and unreliable.
+ looked in the template for strings to determine whether it
+ is a book or an article, or whether csquotes is used. This
+ was always kludgy and unreliable.
+ Change template code to use new API for doctemplates.
* Template changes: