我的目标是在markdown
中写一个文档(更具体地说是rmarkdown
),可以同时将其编译为常规PDF(或其他)文件和投影仪演示文稿。相同的来源。 (使用knitr
。)场景:该文档除常规文本外,还包括每个段落的一句话摘要,这些摘要应作为要点进入演示文稿。
[我知道I can与knitr
同时将文档编译为几种不同的输出格式,但是这里的问题是另外一回事:文档的内容。如何包含这些句子...?我必须以某种方式标记它们,并实现将它们[
((我打算使用bookdown
进行此操作,但我觉得这没关系。)
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
我的方法同时产生两种类型的演示文稿-除了Bookdown中的默认三种格式-一次(来自同一来源)。一个是增量的,其中要点一个一出现,另一个是非动画。 (前者适合演示,后者可以打印为讲义。)
一些评论:
documentclass
被全局设置(在index.Rmd
中)设置为book
,这不适用于投影仪。因此,在两种投影仪格式中,我们都必须将其重置:function Meta(m)
if FORMAT=="beamer" then m.documentclass="beamer" end
return m
end
handout
类div
中的所有内容,因为它们只是演示文稿中需要的。 (别忘了这也意味着我们必须将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
或类似的东西,即使将其更改为![]()
来生成直接的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
此凌乱解决方案的更重要的进一步结果是,连续的幻灯片将没有标题。但是,我们可以使用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}
就这样!
您可以在一个完全实现的项目中找到所有内容放在一起:https://github.com/tamas-ferenci/FerenciTamas_ValszamEsStatAlapvonalai。
当然,我非常欢迎您对改进提出任何反馈,批评或建议。