Search code examples
makefilelatexmetadatapandoc

Is there a way to include latex symbols in the pandoc title metadata (like -M title "$x\rightarrow y$" for example)?


I would like to run a command of the form

'pandoc foo.md -o foo.tex -M title='Some Notes on $x^{y^z}\pi$' --template=mytemplate.pandoc

where mytemplate.pandoc uses $title$ to print a title, put the title in each page header, etc.

Because I build many sets of notes from the same template and Makefile, I'd like to specify the title on the CLI as stated above. My actual call has other flags too, but none of these are relevant.

The problem is that I can't get pandoc to pass the latex code along. This is true even if I properly escape the text for use in Makefile. If I write echo '$$x^{y^z}\pi$$' or echo '\[x^{y^z}\pi\]' in my Makefile, I produce $x^{y^z}\pi$ and \[x^{y^z}\pi\] as expected, so I'm definitely passing the desired code to pandoc.

However, pandoc converts these into \$x\^{}\{y\^{}z\}\textbackslash\textbackslash pi\$ and \textbackslash{[}x\^{}\{y\^{}z\}\textbackslash\textbackslash pi\textbackslash{]}, which prevents the latex code from being rendered when I compile the file to a pdf.

I can't find any way to appease both Makefile and have pandoc pass through the latex code without turning it into literal text.

Is there any way to manage this --- or do I have to resort to autogenerating a template from python for each set of notes (which kind of defeats the point of a template).

Thanks in advance for your help!

Cheers, Ken

At the request of commenters, here is a minimal reproducible example:

File foo.md:

Blah Blah Blah

File foo.pandoc:

\documentclass{article}
\usepackage{amsmath}
\title{$title$}
\begin{document}

\maketitle

$body$

\end{document}

File Makefile:

main: ./foo1.tex ./foo2.tex

./foo1.tex: ./foo.md
        pandoc $< -o $@ -M title='Some Notes on the \[x^{y^z}\pi\]' --template=foo.pandoc
        echo '\[x^{y^z}\pi\]'

./foo2.tex: ./foo.md
        pandoc $< -o $@ -M title='Some Notes on the $$x^{y^z}\pi$$' --template=foo.pandoc
        echo '$$x^{y^z}\pi$$'

Solution

  • Pandoc interprets the metadata value as an unformatted string, and will output code that produces the string in the output format. Thus all the escaping.

    There are two ways to solve this: either convince pandoc to accept the input as a formatted string, or tell pandoc to insert the string verbatim.

    The latter is easier, just replace --metadata/-M with --variable/-V. Pandoc will use variables just as they are, and insert them in the template. The downside is that this requires format-specific input, so it won't work for output formats other than LaTeX in this specific case.

    pandoc --variable='title:Some Notes on $x^{y^z}\pi$' …
    

    The alternative is to convince pandoc that the metadata is formatted. And yet again, there are two ways to do this.

    1. Use a metadata file. This is a YAML file, and string scalars in there will be parsed as Markdown. So you could do something like this:

      my_metadata=$(mktemp 'metadata-yaml.XXX')
      echo 'title: Some Notes on $x^{y^z}\pi$' > ${my_metadata}
      pandoc --metadata-file=${my_metadata} …
      rm ${my_metadata}
      
    2. Use a Lua filter to parse the metadata strings. For that you need a Lua script, e.g., parse-metadata.lua, with the content

      function Meta (meta)
        for key, value in pairs(meta) do
          if type(value) == 'string' then
            meta[key] = pandoc.utils.blocks_to_inlines(
              pandoc.read(value).blocks)
          end
        end
        return meta
      end
      

      Pass this script to pandoc via --lua-filter/-L and keep using --metadata/-M as before. The metadata will now be parsed as Markdown.

      pandoc --lua-filter=parse-markdown.lua -M 'title:Some Notes on $x^{y^z}\pi$'