diff --git a/README.md b/README.md index 13579e6..b949200 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Options: Use only this section from the configuration --strict Disallow undefined variables to be used within the template + --latex Use markers that are compatible with LaTeX ``` ## Optional YAML support @@ -43,6 +44,30 @@ If `xmltodict` is present, you can use XML as an input data source. `$ pip install jinja2-cli[xml]` +## LaTeX support +The default markers used by Jinja2 are incompatible with LaTeX, as explained +in blog posts by [Brad Erickson] and [Arthur Miller]. The option `--latex` +changes the default markers to the following ones by passing , which are compatible with +LaTeX and do not require any special escaping. + +| Default markers | LaTeX mode | Jinja2 env settings | +| :-------------------- | :---------------- | :---------------------- | +| `{%` ... `%}` | `\BLOCK{` ... `}` | `block_*_string` | +| `{{` ... `}}` | `\VAR{`... `}` | `variable_*_string` | +| `{#` ... `#}` | `\#{` ... `}` | `comment_*_string` | +| *disabled by default* | `%%` | `line_statement_prefix` | +| *disabled by default* | `%#` | `line_comment_prefix` | + +In addition, the option `trim_blocks` is set to true, and `autoescape` set to +false. + +Example usage: +``` +jinja2 --latex samples/sample.tex samples/sample.json +``` + +[Brad Erickson]: http://eosrei.net/articles/2015/11/latex-templates-python-and-jinja2-generate-pdfs +[Arthur Miller]: https://miller-blog.com/latex-with-jinja2/ ## TODO * Variable inheritance and overrides * Tests! diff --git a/jinja2cli/cli.py b/jinja2cli/cli.py index 79d84db..7576333 100644 --- a/jinja2cli/cli.py +++ b/jinja2cli/cli.py @@ -212,12 +212,13 @@ def _parse_env(data): } -def render(template_path, data, extensions, strict=False): +def render(template_path, data, extensions, env_options, strict=False): from jinja2 import Environment, FileSystemLoader, StrictUndefined env = Environment( loader=FileSystemLoader(os.path.dirname(template_path)), extensions=extensions, + **env_options, keep_trailing_newline=True, ) if strict: @@ -300,6 +301,23 @@ def cli(opts, args): sys.stderr.write("ERROR: unknown section. Exiting.") return 1 + # Set up environment options suitable to use LaTeX templates + if opts.latex: + env_options = dict( + block_start_string = '\BLOCK{', + block_end_string = '}', + variable_start_string = '\VAR{', + variable_end_string = '}', + comment_start_string = '\#{', + comment_end_string = '}', + line_statement_prefix = '%%', + line_comment_prefix = '%#', + trim_blocks = True, + autoescape = False) + + else: + env_options = dict() + data.update(parse_kv_string(opts.D or [])) if opts.outfile is None: @@ -312,7 +330,7 @@ def cli(opts, args): out = codecs.getwriter("utf8")(out) - out.write(render(template_path, data, extensions, opts.strict)) + out.write(render(template_path, data, extensions, env_options, opts.strict)) out.flush() return 0 @@ -398,6 +416,15 @@ def main(): dest="strict", action="store_true", ) + parser.add_option( + # These marker types might be compatible with TeX, too, so --tex + # might be more accurate (but also harder to find) + "--latex", + "--tex", + help="Use variable/block/... markers that are compatible with LaTeX", + dest="latex", + action="store_true", + ) parser.add_option( "-o", "--outfile", diff --git a/samples/sample.tex b/samples/sample.tex new file mode 100644 index 0000000..2b9d578 --- /dev/null +++ b/samples/sample.tex @@ -0,0 +1,11 @@ +\documentclass{article} + +\begin{document} + +\begin{itemize} +\BLOCK{ for i in items } + \item \VAR{i} +\BLOCK{ endfor } +\end{itemize} + +\end{document}