在带有RMarkdown的常规文档中嵌入投影仪演示文稿

问题描述 投票:1回答:2

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

[我知道I canknitr同时将文档编译为几种不同的输出格式,但是这里的问题是另外一回事:文档的内容。如何包含这些句子...?我必须以某种方式标记它们,并实现将它们[编译为常规PDF,同时and only它们应该编译为投影仪演示!

这里的解决方案是什么?

((我打算使用bookdown进行此操作,但我觉得这没关系。)

markdown r-markdown knitr bookdown beamer
2个回答
1
投票
您可以使用beamerarticle包从投影仪源构建文章类文档。我无法说服rmarkdown同时创建两个文档,但是以下方法可以在Beamer输出和文章文档的行之间交替标题,并在两者之间重命名输出文件:

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

\usepackage{beamerarticle}

完整的rstudio项目:https://rstudio.cloud/project/725309

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

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

一些评论:

    我发现了使用预处理器的类似solution。取而代之的是,我选择使用Pandoc的过滤器。幸运的是,我们甚至有一个example与我们想要的非常接近!但是,应该调整很多东西...
  • 首先,documentclass被全局设置(在index.Rmd中)设置为book,这不适用于投影仪。因此,在两种投影仪格式中,我们都必须将其重置:
  • function Meta(m) if FORMAT=="beamer" then m.documentclass="beamer" end return m end
      lua过滤器示例中的转换只能在投影仪模式下运行。这是微不足道的,更棘手的是,如果我们处于投影仪模式下,我们不仅不应该运行过滤,还必须删除handoutdiv中的所有内容,因为它们只是演示文稿中需要的。 (别忘了这也意味着我们必须将lua过滤器应用于
    • all输出格式,而不仅仅是投影仪!)所以我们要做的是:]]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或类似的东西,即使将其更改为![]()来生成直接的LaTeX代码,它也将无法使用。因此,我们必须添加另一个条件:
      (el.t == "RawBlock" and el.format == "tex" and string.match( el.text, "includegraphics" ) ) or
  • 这样,我们现在可以在具有适当类的-中包括项目符号点(具有常规的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
    • 但是非优雅传播:如果我们处于增量模式,则应运行以上代码[[only
    ,并且我找不到如何自动检测到它的方法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

    当然,我非常欢迎您对改进提出任何反馈,批评或建议。

  • © www.soinside.com 2019 - 2024. All rights reserved.