我的目标是在markdown
(更具体地说是rmarkdown
)中写一个文档,该文档可以被编译成常规PDF(或其他)文件和来自同一来源的演示文稿。 (使用knitr
。)场景:除常规文本外,文档还包括每个段落的一句话摘要,这些摘要应作为要点显示在演示文稿中。
我知道I can使用knitr
同时将一个文档编译成几种不同的输出格式,但是这里的问题是另外一个问题:文档的内容。如何包含这些句子...?我必须以某种方式标记它们,并实现将它们 not 编译为常规PDF,和,同时仅将它们编译进入投影仪演示!
这里有什么解决方案?
(我打算用bookdown
来做到这一点,但我觉得没关系。)
答案 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中默认的三种格式)(同时来自同一来源)。一个是增量的,其中要点一个一出现,另一个是非动画。 (前者适合演示,后者可以打印成讲义。)
一些评论:
documentclass
“全局”(在index.Rmd
中设置为book
,这不适用于投影仪。因此,在两种投影仪格式中,我们都必须将其重置:function Meta(m)
if FORMAT=="beamer" then m.documentclass="beamer" end
return m
end
handout
类div
中的所有内容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
(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]}
\setbeamertemplate{frametitle continuation}{%
\ifnum\insertcontinuationcount>1
\insertcontinuationcount.
\fi}
--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
版本。