28
votes

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?
6
You might be interested in this recent question on tex.sx: tex.stackexchange.com/questions/101717/….G. Poore
Have you tried putting the figure in a table?Jakob

6 Answers

25
votes

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.

More than two columns work out of the box for Beamer output. Powerpoint, however, only supports two columns. For reveal.js, the widths of three or more columns must be given explicitly:

::: columns

:::: {.column width=30%}
left
::::

:::: {.column width=30%}
middle
::::

:::: {.column width=30%}
right
::::

:::
21
votes

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
21
votes

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!

5
votes

Beamer Specific Answer. I ran across a solution when attempting to add multiple columns for Pandoc in a regular document. It works here as well, though it does constrain you to Beamer; though that is your use case.

In the slide deck, insert once:

---
header-includes:
- \newcommand{\hideFromPandoc}[1]{#1}
- \hideFromPandoc{
    \let\Begin\begin
    \let\End\end
  }
---

Then add content thus:

\Begin{columns}
\Begin{column}{0.3\textwidth}

Res ipsum loquiter, sed in inferno decit?

\End{column}

\Begin{column}{0.3\textwidth}

Res ipsum loquiter, sed in inferno decit?

\End{column}
\Begin{column}{0.3\textwidth}

Res ipsum loquiter, sed in inferno decit?

\End{column}
\End{columns}

Creating the "hideFromPandoc" command lets you insert begin/end statements throughout without depriving you of markdown in the block.

Fenced Div Answer. There's an answer above that refers to fenced divs. I commented that the answer only works with two columns. It breaks down with more. Here is how that answer works with multiple divs:

::: {.columns}
:::: {.column width=0.3}
Test
::::
:::: {.column width=0.3}
Test
::::
:::: {.column width=0.3}
Test
::::
:::

To get this answer, I had to look at the commit that added the column feature specifically.

2
votes

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.

2
votes

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.