使用RMarkdown将投影仪演示文稿嵌入到常规文档中

时间:2019-11-15 23:14:15

标签: markdown r-markdown knitr bookdown beamer

我的目标是在markdown(更具体地说是rmarkdown)中写一个文档,该文档可以被编译成常规PDF(或其他)文件来自同一来源的演示文稿。 (使用knitr。)场景:除常规文本外,文档还包括每个段落的一句话摘要,这些摘要应作为要点显示在演示文稿中。

我知道I can使用knitr同时将一个文档编译成几种不同的输出格式,但是这里的问题是另外一个问题:文档的内容。如何包含这些句子...?我必须以某种方式标记它们,并实现将它们 not 编译为常规PDF,,同时仅将它们编译进入投影仪演示!

这里有什么解决方案?

(我打算用bookdown来做到这一点,但我觉得没关系。)

3 个答案:

答案 0 :(得分:1)

您可以使用country_id包从投影仪源构建文章类文档。我不能说服rmarkdown同时创建两个文档,但是以下方法可以在Beamer输出和文章文档的行之间交替标题,并在两者之间重命名输出文件:

beamerarticle

使用--- output: beamer_presentation: keep_tex: true # pdf_document: # includes: # in_header: preamble.tex --- sentence in both documents ``` {=latex} \only<article>{ sentence only in the article } ``` ``` {=latex} \only<presentation>{ sentence only in the presentation } ```

preamble.tex

完成rstudio项目:https://rstudio.cloud/project/725309

答案 1 :(得分:1)

我终于设法建立了一种可行的方法-我相信-完美,尽管它有一些不太优雅的解决方案,因此很有可能(很多)有改进的余地。

我的方法同时生成两种类型的演示文稿(除了Bookdown中默认的三种格式)(同时来自同一来源)。一个是增量的,其中要点一个一出现,另一个是非动画。 (前者适合演示,后者可以打印成讲义。)

一些评论:

  • 我发现了类似的solution,它使用了预处理器。取而代之的是,我选择使用Pandoc的过滤器。幸运的是,我们甚至有一个example与我们想要的非常接近!但是,应该调整很多东西...
  • 首先,将documentclass“全局”(在index.Rmd中设置为book,这不适用于投影仪。因此,在两种投影仪格式中,我们都必须将其重置:
function Meta(m)
  if FORMAT=="beamer" then m.documentclass="beamer" end
  return m
end
  • lua过滤器示例中的转换只能在投影仪模式下运行。这是微不足道的,更棘手的是,如果我们不是处于投影器模式下,则不仅不应该运行过滤,还必须删除handoutdiv中的所有内容s,因为它们仅在演示中需要。 (不要忘记,这还意味着我们必须将lua过滤器应用于所有输出格式,而不仅是投影仪!)所以我们要做的是:
if FORMAT~="beamer" then
      local hblocks = {}
      for i,el in pairs(doc.blocks) do
          if (el.t ~= "Div" or el.classes[1] ~= "handout") then table.insert(hblocks, el) end
      end
      return pandoc.Pandoc(hblocks, doc.meta)
    else
  • 一个完全不相关的问题,但是如果我们谈论示例lua过滤器的修改:识别图像部分的过滤器部分也应该modified以与Rmarkdown生成的文件一起使用:
(el.t == "Para" and el.c[1].t == "Image") or
  • 更重要的是,如果我们使用fig.align或类似的东西,即使这样也将不起作用,因为它将生成的markdown格式从![]()更改为直接LaTeX代码。因此,我们必须添加另一个条件:
(el.t == "RawBlock" and el.format == "tex" and string.match( el.text, "includegraphics" ) ) or
  • 这样,我们现在可以在具有适当类的- s中包括项目符号点(具有常规的markdown语法,即div)。但是,我们必须小心打破长幻灯片。幸运的是,在Beamer中有一个allowframebreaks选项(这被认为是邪恶的,但我认为这里是完全有道理的,或者,我们没有更好的解决方案);唯一的问题是我们无法将其添加到每张幻灯片中,因为我们无法直接控制框架的LaTeX代码。幸运的是,有一个solution可以修改标头中的选项以使其默认,我们可以在preamble.tex中轻松地做到这一点:
\let\oldframe\frame
\renewcommand\frame[1][allowframebreaks]{\oldframe[#1]}
  • 同样,这是无关紧要的问题,但是,如果我们谈论的是前言,我们还可以添加一个few lines来对损坏的框架进行编号(这里我在数字之后还添加了一个点,但这确实是只是一个口味的问题):
\setbeamertemplate{frametitle continuation}{%
    \ifnum\insertcontinuationcount>1
    \insertcontinuationcount.
    \fi}
  • 现在是我解决方案中最不优雅的部分。增量编译没有问题,幸运的是,我们有一个pandoc选项(--incremental),问题在于它不能与allowframebreaks一起使用。 (由于它与任何叠加层均不兼容,因此记录在文档中供投影仪使用。)我希望它可以工作,但不幸的是,我认为没有解决方案。因此,我能想到的最好的解决方法是:我们放弃自动分帧,我们手动找到应在何处插入分帧符,然后在源代码中插入<div class="framebreak"></div>。即,我引入了一个新的div(没有用于其他任何目的),并且可以通过lua过滤器进行识别,这是必需的,因为我们必须在此时插入一个\end{frame}\begin{frame} ,但我认为不能直接在降价促销中完成
if (el.t == "Div" and el.classes[1] == "framebreak") then
              table.insert(hblocks,pandoc.RawBlock("latex","\\end{frame}\\begin{frame}") )
          end
  • 但是非优雅传播:如果我们处于增量模式,则仅运行上述代码 ,我发现无法自动检测到它within the script 。因此,不幸的是,我不得不使用两个lua过滤器,一个用于增量编译(使用上面的代码),一个用于常规编译器(没有上面的代码)。

  • 此凌乱解决方案的另一个更重要的后果是,连续的幻灯片将没有标题。但是,我们可以使用solution复制以前未命名的幻灯片中的标题,并且可以在这里使用。

  • 当然,这现在很不幸,这意味着我们需要三个前导文件。 (一种常见的包含任何LaTeX编译的通用序言,一种用于包含自动allowframebreaks解决方案的讲义,一种用于包含自动框架标题复制的幻灯片。后两种可以包含在--include-in-header中选项,而对于普通选项,我们可以在includes: in_header中使用常用的_output.yml。)

  • 我们还必须对上述代码进行一些修改,以切掉非光束输出的不必要部分:

if (el.t ~= "Div" or ( el.classes[1] ~= "handout" and el.classes[1] ~= "framebreak" ) ) then
    table.insert(hblocks, el)
end
  • 第二个最不优雅的部分是我们不能将beamer_presentation输出包含两次,并且名称不同,或者至少我不知道solution for this我们必须使用bookdown::render_book 进行手动编译,并且不要忘记随后重命名(并移动)生成的编译文件。

  • 不幸的是,这也意味着我们不得不放弃使用Build Book按钮。我们宁愿创建一个脚本来完成按钮的所有操作(我希望我没有犯错,并且确实与按钮...相同):

bookdown::render_book( "index.Rmd", "bookdown::pdf_book" )
bookdown::render_book( "index.Rmd", "bookdown::gitbook" )
bookdown::render_book( "index.Rmd", "bookdown::epub_book" )
bookdown::render_book( "index.Rmd", "beamer_presentation", output_option = list(
  pandoc_args = c( "--lua-filter", "handoutconverter.lua", "--include-in-header", "preamble_handout.tex" ) ) )
file.rename( "FerenciTamas_ValszamEsStatAlapvonalai.pdf", "./docs/FerenciTamas_ValszamEsStatAlapvonalai_handout.pdf" )
bookdown::render_book( "index.Rmd", "beamer_presentation", output_option = list(
  pandoc_args = c( "--lua-filter",  "handoutconverter_slides.lua", "--incremental",
                   "--include-in-header", "preamble_slides.tex" ) ) )
file.rename( "FerenciTamas_ValszamEsStatAlapvonalai.pdf", "./docs/FerenciTamas_ValszamEsStatAlapvonalai_slides.pdf" )
  • 最后,我们还需要一个自定义的Pandoc模板,因为对于演示文稿,我们很可能需要一个简短的标题(Pandoc目前不支持该标题)。因此,我将\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}更改为\title[$if(short-title)$$short-title$$endif$]{$title$$if(thanks)$\thanks{$thanks$}$endif$}(向short-title添加了index.Rmd元素)。

  • 这又是一个不相关的问题,但是我也将\frame{\sectionpage}中的\AtBeginSection行更改为

\begin{frame}{$toc-title$}
    \tableofcontents[currentsection]
\end{frame}

这当然主要是出于品味的问题,但是客观原因是它也适用于非英语语言(即使选择了非英语语言,原始模板也会显示“ Section 1”)。

就是这样!

您可以在这里完全实现的项目中找到所有组合在一起的内容:https://github.com/tamas-ferenci/FerenciTamas_ValszamEsStatAlapvonalai

当然,我真的很欢迎任何关于改进的反馈,批评或建议。

答案 2 :(得分:0)

我对这次讨论感到非常兴奋,因为我仍然仍然需要帮助和支持。因此,我希望这能使事情复活,因为我显然不是唯一寻求这种功能的人。

除非我弄错了,否则我在这里为您的问题提供了一个(优雅的?)答案:creating accompanying slides for bookdown project
您有机会看到它吗?这不能解决您的问题吗?在我看来,我正在做您正在尝试实现的目标(我检查了您的Github
我刚刚在SO中使用标签beamer bookdown进行了快速搜索,我的帖子首先出现了……不适合您吗?

解决方案是您要提示的解决方案:创建一个具有多种输出类型的bookdown项目。
我无法解决的一个问题是,我无法自定义图书输出文件名(请参见SO问题后面的评论)–很可惜–也许是bookdown功能请求?但是谢一辉(YiHui Xie)并没有提供此建议-尽管有我的暗示-您可能会再问一次?
然后,只需单击一下,就可以获取pdf beamer幻灯片,pdf书,html网络书,epub电子书-绝对了不起,所有谢义辉。现在-相反-我确实需要单击两次,因为当我编译幻灯片和pdf时,它(覆盖)写入同一文件(实际上,它不会!!)它首先写入根文件夹,但随后将其移动到/ _book文件夹中,这就是覆盖发生的时间-所以我认为这对于YiHui Xie应该是一个非常简单的修复程序,但也许不是吗?)

无论如何,所有这些工作都是绝对完美的,直到John McFarlane决定改变Pandoc的工作原理并从根本上扼杀了我的方法。讨论在这里:Pandoc #4317 forces content under title slides to be included in a frame in pandoc > 2.7。要允许{em>垂直幻灯片在pdf输出中显示-完全是废话,我将所有内容 Above 幻灯片级别强制置于幻灯片上!!约翰·麦克法兰(John McFarlane)确实尝试看看他是否可以帮助我,但引用了他们不考虑我的案子的论点,现在他不想回复……他甚至要我在他的电子邮件列表中张贴我的问题,但是在那里没有帮助者... :-(因此,只要我在{{1}中使用pandoc < 2.7(在{{1}中,只需将{{1 1}}文件夹和早期版本。

总结:完美的平滑解决方案还需要做两件事:
1. bookdown: customize the output filename,只是为了方便单击解决方案
2. Obtaining from John McFarlane that Pandoc either does not force content onto slides randomly or allows to escape that unwanted behavior这对于至关重要,因为它可以使用当前的Rstudio版本。