Slides with Columns in Pandoc

2019-01-13 13:30发布

问题:

I would like to have code and an image side-by-side in a Beamer slide.

In LaTeX I would do this with columns. I would like to use markdown within the column structure.

\begin{columns}
\column{.5\textwidth}

~~~~~~~~Python
>>> some python code
~~~~~~~

\column{.5\textwidth}

![](A_generated_image.pdf)

\end{columns}

Unfortunately Pandoc doesn't process the markdown within the \begin{columns} and \end{columns} statements. Is there a way around this?

  • Is there a way to use markdown within inlined LaTeX?
  • Is there a pure markdown solution?

回答1:

The problem is that pandoc ignores markdown if it finds a \begin{}. An alternative is to edit the beamer template and add the following:

\newcommand{\columnsbegin}{\begin{columns}}
\newcommand{\columnsend}{\end{columns}}

And write it like this:

\columnsbegin
\column{.5\textwidth}

~~~~~~~~Python
>>> some python code
~~~~~~~

\column{.5\textwidth}

![](A_generated_image.pdf)

\columnsend


回答2:

I hope still valuable. I made a Pandoc filter in Python to put columns easily, so you can write your presentations in this way:

# Hello World

[columns]

[column=0.5]

~~~python
    if __name__ == "__main__":
        print "Hello World"
~~~

[column=0.5]

This is how a "Hello World" looks like in Python

[/columns]

that the filter will convert each markup to \begin{columns} and \column{.5\textwidth}, so, the document above will turn in

\begin{frame}[fragile]{Hello}

\begin{columns}

\column{0.5\textwidth}

\begin{Shaded}
\begin{Highlighting}[]
    \NormalTok{some python code}
\end{Highlighting}
\end{Shaded}

\column{0.5\textwidth}

Hello World

\end{columns}

\end{frame}

The code filter is here

import pandocfilters as pf

def latex(s):
    return pf.RawBlock('latex', s)

def mk_columns(k, v, f, m):
    if k == "Para":
        value = pf.stringify(v)
        if value.startswith('[') and value.endswith(']'):
            content = value[1:-1]
            if content == "columns":
                return latex(r'\begin{columns}')
            elif content == "/columns":
                return latex(r'\end{columns}')
            elif content.startswith("column="):
                return latex(r'\column{%s\textwidth}' % content[7:])

if __name__ == "__main__":
    pf.toJSONFilter(mk_columns)

If you never use a pandoc filter, just save the filter to the same document location as columnfilter.py (or other name you want) and run

pandoc -t beamer --filter columnfilter.py yourDocument.mkd

And enjoy!



回答3:

Current versions of pandoc (i.e., pandoc 2.0 and later) supports fenced divs. Specially named divs are transformed into columns when targeting a slides format:

# This slide has columns

::: columns

:::: column
left
::::

:::: column
right
::::

:::

Pandoc translates this into the following LaTeX beamer code:

\begin{frame}{This slide has columns}
\protect\hypertarget{this-slide-has-columns}{}

\begin{columns}[T]
\begin{column}{0.48\textwidth}
left
\end{column}

\begin{column}{0.48\textwidth}
right
\end{column}
\end{columns}

\end{frame}

This is simple and has the additional advantage of giving similar results when targeting other presentational formats like reveal.js.



回答4:

You could use FletcherPenney MultiMarkdown which can process markdown to LaTeX/Beamer. Compared to Pandoc, MultiMarkdown has not so many features. However, especially when working with LaTeX it has the advantage that you can embed LaTeX code directly into the Markdown in HTML comments.

Your code would look like this:

<!-- \begin{columns} -->
<!-- \column{.5\textwidth} -->

        >>> some python code


<!-- \column{.5\textwidth} -->

![](A_generated_image.pdf)

<!-- \end{columns} -->

For me this solution works fine. With a good editor (e.g. Scrivener, Sublime Text) you can write the latex code without all the comments and find/replace them after editing. In addition, the Metadata support in Multimarkdown is much more flexible, so that it is easier to customize presentations.

In the meantime, I hope that the Pandoc team provides a solution to this problem. I think there are some users who would like to embed small LaTex code particles throughout their markdown documents without having them converted/escaped.



回答5:

You can use MultiMarkDown comments ( "<!-- Your LaTeX Code inside -->" ) with Pandoc when you enclose the Pandoc command in which you transform your markdown to LaTeX with two sed commands.

In the first sed run, you change the MultiMarkDown comments to "\verb+AAAAAAALaTeX-StuffZZZZZZ+". Then you transform to LaTeX with Pandoc as usual, everything inside "\verb+AAAAAAALaTeX-StuffZZZZZZZ+" is left alone. Then you run sed on the TeX-File and delete the "\verb+AAAAAAA" and "ZZZZZZ+" unfolding your LaTeX code.

The first sed command line before the Pandoc transformation could look like this:

 sed -E -e "s/<\\!--(.+)--\\>/\\\\verb\+AAAAAAA\1ZZZZZZZ\+/g " \
     source.md > source.i.md

Then use Pandoc on source.i.md as usual to create source.tex. Second sed run like this:

 sed -E -e "s/\\\\verb\+AAAAAAA(.+)ZZZZZZZ\+/\1/g" -i "" source.tex

I automated everything in a Makefile so that I can make more changes e.g. to table definitions in one step. On first glance this approach works fine (tested it on column definitions with the beamer class).

With this little sed scripts, you can use all the nice things from Pandoc. You need only to mmd-comment those TeX and LaTeX commands which become either escaped or enclose larger parts of your Markdown.