Pandoc中带有列的幻灯片

38

我希望在Beamer幻灯片中将代码和图片并排显示。

在LaTeX中,可以通过列来实现此目的。我希望在列结构内使用markdown。

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

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

\column{.5\textwidth}

![](A_generated_image.pdf)

\end{columns}

不幸的是,Pandoc无法处理\begin{columns}和\end{columns}语句中的Markdown。有什么解决方法吗?

  • 有没有办法在内联LaTeX中使用Markdown?
  • 有没有纯Markdown的解决方案?

你可能会对tex.sx上最近的这个问题感兴趣:http://tex.stackexchange.com/questions/101717/converting-markdown-to-latex-in-latex/101731。 - G. Poore
你尝试把这个数字放在表格里了吗? - Jakob
6个回答

37

当前版本的pandoc(即pandoc 2.0及更高版本)支持围栏式div。当针对幻灯片格式时,特定命名的div会被转换为列:

# This slide has columns

::: columns

:::: column
left
::::

:::: column
right
::::

:::

Pandoc 将此转换为以下 LaTeX 演示文稿代码:

\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}

这是简单的,并且具有另一个优点,即在针对其他演示格式(如reveal.js)时给出类似的结果。

Beamer输出可以直接使用两列以上的内容。然而,Powerpoint只支持两列。对于reveal.js,三列或更多列的宽度必须明确给出:

::: columns

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

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

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

:::

有没有办法指定列的垂直对齐方式?最好是分别为每个列指定? - mavericks
请参阅我的相关问题 - mavericks
请注意,为了使其正常工作,您需要显式启用扩展,例如通过 --from markdown+fenced_divs - luator
@luator 是和否。fenced_divs 扩展在 pandoc 的 Markdown 中默认启用,因此这不是必需的。但是,在 CommonMark 及其变体 GitHub Flavored Markdown 中,您是正确的。在这些情况下,必须手动启用扩展:--from=gfm+fenced_divs - tarleb
@tarleb 确实,它使用默认设置可以工作。我之前遇到了一些问题,认为设置 --from 可以解决,但显然我搞混了。感谢您澄清这一点! - luator

21

我希望这仍然有价值。我用Python编写了一个Pandoc过滤器,以便轻松地放置列,因此您可以以以下方式编写演示文稿:

# 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]

过滤器将把每个标记转换为\begin{columns}和\column{.5\textwidth},因此上面的文档将变成:
\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}

代码过滤器在这里。
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)

如果您从未使用过pandoc筛选器,只需将筛选器保存到与columnfilter.py(或其他名称)相同的文件位置,然后运行该命令即可。

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

享受吧!


1
最好将其放在Gist(或类似的地方),以便用户可以报告问题。 - Dilawar

21

问题在于pandoc会忽略Markdown文件中的内容,如果遇到\begin{}命令。一种替代方案是编辑Beamer模板,加入以下内容:

问题是pandoc如果发现一个\begin{}就会忽略Markdown。解决方法是编辑Beamer模板,并添加以下内容:

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

并将它写成这样:

\columnsbegin
\column{.5\textwidth}

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

\column{.5\textwidth}

![](A_generated_image.pdf)

\columnsend

5

针对Beamer的答案。当我尝试在常规文档中为Pandoc添加多个列时,我找到了一种解决方法。在这里也适用,但这会将您限制为使用Beamer;不过这正是您的用例。

在幻灯片中,仅需插入:

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

然后添加内容如下:

\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}

创建“hideFromPandoc”命令,让您可以在整个代码块中插入开始/结束语句而不剥夺您使用markdown的权利。

围栏式区块答案。 上面有一个涉及围栏式区块的答案。我评论说这个答案只适用于两列。它不能处理更多。以下是如何在多个div中使用该答案:

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

为了得到这个答案,我需要查看添加列功能的提交记录,具体可以查看该提交记录

2
您可以使用FletcherPenney MultiMarkdown将Markdown处理为LaTeX/Beamer。与Pandoc相比,MultiMarkdown的功能不是很多。但是,特别是在使用LaTeX时,它的优点在于您可以直接将LaTeX代码嵌入HTML注释中的Markdown中。
您的代码应该像这样:
<!-- \begin{columns} -->
<!-- \column{.5\textwidth} -->

        >>> some python code


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

![](A_generated_image.pdf)

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

对我来说,这个解决方案很好用。使用好的编辑器(例如Scrivener、Sublime Text),您可以在不包括所有注释的情况下编写LaTeX代码,并在编辑后查找/替换它们。此外,Multimarkdown中的元数据支持更加灵活,因此更容易定制演示文稿。

同时,我希望Pandoc团队能够提供一个解决这个问题的方案。我认为有一些用户想要在他们的Markdown文档中嵌入小的LaTeX代码粒子,而不必将它们转换/转义。


2
您可以在Pandoc中使用MultiMarkDown注释(“<!-- Your LaTeX Code inside -->”),只需在将Markdown转换为LaTeX的Pandoc命令中使用两个sed命令即可。
在第一个sed运行中,您需要将MultiMarkDown注释更改为“\verb+AAAAAAALaTeX-StuffZZZZZZ+”。然后按照通常的方式使用Pandoc进行LaTeX转换,所有在“\verb+AAAAAAALaTeX-StuffZZZZZZZ+”内部的内容都将保持原样。接下来,在TeX文件上运行sed并删除“\verb+AAAAAAA+”和“ZZZZZZ+”,以展开您的LaTeX代码。
在Pandoc转换之前的第一个sed命令行可能如下所示:
 sed -E -e "s/<\\!--(.+)--\\>/\\\\verb\+AAAAAAA\1ZZZZZZZ\+/g " \
     source.md > source.i.md

然后像往常一样使用Pandoc将source.i.md转换为source.tex。第二次使用sed时,请按以下方式运行:
 sed -E -e "s/\\\\verb\+AAAAAAA(.+)ZZZZZZZ\+/\1/g" -i "" source.tex

我将所有内容都自动化到了Makefile中,这样我可以在一步中进行更多的更改,例如表定义。乍一看,这种方法很有效(我已经在beamer类的列定义上进行了测试)。
有了这些小的sed脚本,你可以使用Pandoc的所有好东西。你只需要将那些成为转义或包含较大部分Markdown的TeX和LaTeX命令放入mmd注释中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接