声明:本文引用的所有信息均为公开信息,仅代表作者本人观点,与就职单位无关。
故事还要从头开始讲起,6-7 年前,出于学术答辩和课程汇报需要,陆续学习和使用 LaTeX 来排版作业和论文,曾有一段时间深陷此坑不能自拔,以至于遍览 TeXLive 内置的幻灯片制作宏包,收集了大量 beamer 幻灯片的模版,藏于 Github 仓库 awesome-beamers。
LaTeX 在国外是比较流行的学术写作工具,在国内部分学校的数学或统计系会用它来排版毕业论文,相关的学习材料有很多,推荐 CTeX 开发小组翻译的一份(不太)简短的LaTeX介绍。吴康隆的 《简单粗暴LaTeX》,花名包太雷的《雷太赫排版系统简介》,盛文博翻译的《LaTeX2e 插图指南, 第三版》,吕荐瑞的科技文档排版课程材料,曾祥东的现代 LaTeX 入门讲座,都非常适合从零开始学习的。进阶的部分,根据需要去看宏包手册,LaTeX 宏包文档的长度一般都吓死个人,PGF 绘图 1300 多页,pgfplots 3D 绘图 573 页, beamer 幻灯片制作 247 页,geometry 版面设置 42 页,tcolorbox 箱子定制 539页,通常不需要从头到尾的看,除非遇到难处或需要自定义了。在对基础的 LaTeX 排版工具有一些了解后,日常使用过程中必备数学公式速记小抄 ,搭好梯子随时放狗去搜。
去年6月份搬迁完汉风主题,在论坛开帖分享了成果,又被撺掇着在主站立了字句—-要写一篇文章介绍 R Markdown 制作幻灯片模版的过程,一直囿于工作繁忙,难以抽身,前段时间在 WX 上和楚新元 又聊到模版,看到有人又要准备趟我之前踩过的坑,心中不忍,咬咬牙还是把这文债给还了。算起来,从起心动念到最终交付拖延了整整一年零三个月!!!
本文将介绍如何搬迁 beamer 主题到 R Markdown 生态里,涉及谢益辉开发的轻量级 LaTeX 发行版 TinyTeX, LaTeX 幻灯片主题 metropolis 和 beamer-verona,还有使用 Pandoc 内建 LaTeX 模版的经验。
安装 R 包
本文陆续会用到 R Markdown 生态的几个 R 包,复现需要安装下:
install.packages(c("tinytex", "knitr", "rmarkdown", "bookdown", "rticles"))
默认大家已经安装了 R 和 RStudio IDE,这会让操作的过程变得更简单明了。
安装 TinyTeX
平时要是常用 R Markdown 相关扩展包,R 包 tinytex 已经被安装上了,下面用它安装 TinyTeX 这个发行版,在 R 环境里,这一切会比较顺畅,讲真,配置环境什么的最烦了,一次两次三四次,五次六次七八次,但是学什么的时候最好从配置环境开始,记录从第一次安装开始,后面会越来越快!
tinytex::install_tinytex()
遇到啥问题,先去益辉的网站瞅瞅 https://yihui.org/tinytex/,要还没找到解决方案,就来论坛 https://d.cosx.org/ 发帖。
安装字体
为了后续介绍 metropolis 主题,先做些准备,安装和配置其所需字体,此过程分两步走:
-
这里用 tinytex 安装 fira 系列英文字体,firamath 和 xits 数学字体,后续用作 beamer 幻灯片的主要字体,相信大家看惯了千篇一律的字体,也想换换口味吧!
# 顺道把 beamertheme-metropolis 宏包也安装下 tinytex::tlmgr_install(c("beamertheme-metropolis", "fira", "firamath", "firamath-otf", "xits"))
-
通过「人工智能」我们知道上面安装的字体都放在了 TinyTeX 的安装目录下,而且不能直接被调用,故而将它们拷贝到用户指定的字体目录,刷新字体目录后,通过 fontspec 宏包调用。为了加快复现的速度,我已经将这个复制粘贴的过程化作几行代码,如下:
# TinyTeX 字体目录 basedir <- paste(tinytex::tinytex_root(), "texmf-dist/fonts/opentype/public", sep = "/") # MacOS 系统字体放在 ~/Library/Fonts/ 而 Linux 系统字体放在 ~/.fonts distdir <- if (Sys.info()["sysname"] == "Darwin") "~/Library/Fonts/" else "~/.fonts" # 获取字体文件的完整路径 fontfiles <- list.files(path = paste(basedir, c("fira", "xits", "firamath"), sep = "/"), full.names = T) # 拷贝到字体目录下 file.copy(from = fontfiles, to = distdir, overwrite = TRUE)
数学符号
在正式介绍后续的 beamer 主题之前,还要先介绍一点数学符号和数学字体的坑,学术型幻灯片毕竟很难离开数学公式。在遇到花体数学符号,如常用来表示域或空间的 $\mathcal{A,S}, \mathscr{A}, \mathbb{A,R}$
,抑或是常见的损失函数符号 $\mathcal{L}$
。
unicode-math 定义的数学样式有点怪,和通常见到的不一样,以前排版毕业论文的时候坑过我一回,主要原因是 unicode-math 使用 Latin Modern Math 的 OpenType 字体。
---
title: "Untitled"
output:
pdf_document:
latex_engine: xelatex
template: null
extra_dependencies:
ctex:
- fontset=fandol
---
拿一些数学符号举个例子,如 `\mathcal{A},\mathscr{A}` 和 `\mathbb{A}`会被依次渲染成
$$
\mathcal{A},\mathscr{A},\mathbb{A}
$$
Pandoc 内建的 LaTeX 模版1默认调用 unicode-math 宏包的,除非编译 R Markdown 的时候,启用LaTeX 变量 mathspec: yes
,加载 amsfonts 和 mathrsfs 宏包。目前,仅有的数学字体支持的数学符号还不太全,但未来是趋势,为啥?统一性,不需要调其它数学符号包,比如 \mscrA
和 \BbbA
分别等价于 \mathscr{A}
和 \mathbb{A}
。
---
title: "Untitled"
mathspec: yes
output:
pdf_document:
latex_engine: xelatex
template: null
extra_dependencies:
ctex:
- fontset=fandol
amsfonts: null
mathrsfs: null
---
拿一些数学符号举个例子,如 `\mathcal{A},\mathscr{A}` 和 `\mathbb{A}`会被依次渲染成
$$
\mathcal{A},\mathscr{A},\mathbb{A}
$$
注意
Fira 系列字体配 metropolis 主题是比较常见的,只是 Fira Math 提供的字符集有限,不得不借助 XITS Math 补位(比如矩阵转置的符号),后者支持是最广的。在 unicode-math 的世界里,公式环境里,加粗希腊字母,得用 \symbf
而不是 \boldsymbol
。XITS Math、Fira Math 等字体数学符号的支持情况详见unicode-math 宏包的官方文档。
数学字体 | 符号数量 |
---|---|
Latin Modern Math | 1585 |
XITS Math | 2427 |
STIX Math Two | 2422 |
TeX Gyre Pagella Math | 1638 |
DejaVu Math TeX Gyre | 1640 |
Fira Math | 1052 |
metropolis 幻灯片主题
不记得初次见 metropolis 主题是什么时候,不过每次见都让我想到了 MCMC(Markov Chain Monte Carlo,马尔科夫链蒙特卡洛,简称 MCMC)。学过 MCMC 算法的都知道 metropolis 是啥,我这半桶水的统计科班生就不在这献丑了,当年掉在 MCMC 的大坑里好多时间,以至于将 metropolis 和 MCMC 建立了极强的关联,可能这是我介绍 beamer 主题也拿它来举例的原因吧!
回到正题,Pandoc 内建的 LaTeX 模版功能已经很丰富了,通常用不着自己配置了,R Markdown 自从接入 tinytex 自动装缺失的 LaTeX 宏包的功能后,在产出 PDF 文档方面已经方便多了。
metropolis 主题的特点就是干净利索,简洁优雅!顺便一提,在之前的文章可重复性数据分析 介绍过 林莲枝 开发的汉风主题幻灯片,它是 metropolis 主题的衍生品。算上空行,只有十几行代码哈哈!!
\documentclass[169]{beamer}
\usefonttheme{professionalfonts}
\usetheme{metropolis}
\usepackage{fontspec}
\setsansfont[BoldFont={Fira Sans SemiBold}]{Fira Sans Book}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage[
mathrm=sym,
math-style=ISO, % Greek letters also in italics
bold-style=ISO, % bold letters also in italics
]{unicode-math}
\setmathfont{Fira Math} % https://github.com/firamath/firamath
% top is still missing in Fira Math, get it from another font
\setmathfont[range={\top}]{XITS Math}
\begin{document}
\begin{frame}[t]{Example}
\begin{align}
\symbf{\theta} &= (1, 2, 3)^\top \\
\theta_0 &= 1
\end{align}
\end{frame}
\end{document}
注意看加载 unicode-math 宏包时的选项设置,关于 unicode-math 数学符号的样式(比如选择 ISO 还是 TeX?) 说明见文档,对绝大多数的使用者来说,做个拿来主义就好,别看我洋洋洒洒写了这么多,我也不例外,喜欢哪个用哪个!
将上面的模版内容保存到文件 slide-template.tex
,接下来,有两种编译 LaTeX 文件的方式,一种在 RStudio IDE 内打开,点击 Compile PDF 按钮,另一种是在 R 控制台里执行
tinytex::xelatex(file = "slide-template.tex")
编译出来的效果如下:
用 Adobe Acrobat Reader DC 打开 文件->属性->字体
可以看到 PDF 文档中确切使用的字体,如下图所示。
一个永远填不满的坑
最近统计之都论坛里又有人陆续踩到我以前踩过的坑1、坑2、坑3、坑4,都是中文 R Markdown 文档相关, 这里不妨简单说一下。
---
title: "测试"
author:
- 无
documentclass: ctexart
keywords:
- 无
output:
rticles::ctex:
fig_caption: yes
number_sections: yes
toc: yes
geometry: tmargin=1.8cm,bmargin=1.8cm,lmargin=2.1cm,rmargin=2.1cm
---
$\mathbf{\Sigma}$
这位坛友准备在公式环境里用 \mathbf
命令加粗希腊字母 $\Sigma$
,这本身是不行的,它只能用来加粗普通的字母,如 $A,B,C,a,b,c,X,Y,Z,x,y,z$
。加粗希腊字母,需要 \boldsymbol
命令,而 rticles::ctex
中文模版,在默认设置下,会使用 Pandoc 内建 LaTeX 模版,调用 XeLaTeX 编译,加载 unicode-math 宏包处理数学公式,此时,希腊字母对 \boldsymbol
命令免疫,要加粗特效,必须用 unicode-math 的专用命令 \symbf
。
如果准备在文中统一采用 unicode-math 处理数学公式,那么,把 \mathbf
换成 \symbf
,问题即告结束。但是,目前排版数学公式比较通用的方式不是 unicode-math,还是原来的 amsmath 及其扩展宏包。如何转过去呢?其实,很简单,在 YAML 里添加一行 mathspec: yes
即可,Pandoc 的 LaTeX 模版支持原先的方案,此时编译还是会报错,报错的主要信息如下:
! LaTeX Error: Option clash for package fontspec.
这是因为 ctexart 文类自动加载了 fontspec 宏包,而它与 mathspec 宏包冲突,所以要替换为原始的 article 文类,同时加载 ctex 宏包处理中文字符,这里采用 fandol 中文字体作为演示,所以目前最佳的解决方案如下:
---
title: "测试"
author:
- 无
documentclass: article
mathspec: yes
keywords:
- 无
output:
rticles::ctex:
fig_caption: yes
number_sections: yes
toc: yes
template: null
extra_dependencies:
ctex:
- fontset=fandol
geometry: tmargin=1.8cm,bmargin=1.8cm,lmargin=2.1cm,rmargin=2.1cm
---
$\boldsymbol{\Sigma}$ 是希腊字母 $\Sigma$ 的加粗形式,
$\mathcal{A}$ 是普通字母 $A$ 的花体形式。
提示
RStudio IDE 使用 MathJaX 来渲染 R Markdown 文档里的数学公式,MathJaX 不支持的数学符号命令是不能预览的。来自 unicode-math 的
\symbf
命令是不受支持的,会高亮成红色。那支持的有哪些呢?完整的支持列表见这个文档,常见的\mathbb
空心体$\mathbb{A}$
和\mathfrak
火星体$\mathfrak{A}$
来自宏包 amsfonts,\mathscr
花体$\mathscr{A}$
和\bm
粗体$\bm{A}$
命令分别来自 mathrsfs 和 bm。amsmath 相关的大都支持,较为精细地调整数学公式可以去看amsmath 文档,此处仅摘抄一例$\sqrt{x} +\sqrt{y} + \sqrt{z}$
和$\sqrt{x} +\sqrt{\smash[b]{y}} + \sqrt{z}$
,能看出来差别的一定有一双火眼金睛!
再次强行回到本文主题,上述巨坑在 article 普通文类下介绍,而不是在 beamer 幻灯片主题下介绍也是有重要原因的:其一,我见过的大部分坑的背景都是 article 文类。其二,这个坑并不会随文类切换到 beamer 而有所不同!其三,若大家再遇到类似坑不妨也切换到 article 文类,这个是最基础的,褪去尽可能多的外部依赖,方便去根因。
R Markdown 模版(基础篇)
R Markdown 文档开头处为 YAML 元数据,它分两部分:其一是 Pandoc 变量值,其二是文档输出设置。下面是一份完整的 R Markdown 模版,有了前面关于中文 R Markdown 文档的介绍,想必已不再感到陌生。 ctexbeamer 和 ctexart 文类都来自 ctex 宏包,想汉化必须看看它的帮助文档。
---
title: "R Markdown 制作 beamer 幻灯片"
author: "黄湘云"
date: "2021年10月01日"
institute: "美团搜索技术部"
documentclass: ctexbeamer
output:
beamer_presentation:
latex_engine: xelatex
theme: metropolis
template: null
classoption: "fontset=fandol"
---
## 介绍
> A Markdown-formatted document should be publishable as-is, as plain text,
without looking like it’s been marked up with tags or formatting instructions.
>
> --- John Gruber
Markdown 提供一种简洁的格式语法,用来编辑 HTML、PDF 和 MS Word 文档,
数学公式还是用 LaTeX 排版的好,
$\boldsymbol{\Sigma}$ 是希腊字母 $\Sigma$ 的加粗形式,
$\mathcal{A}$ 是普通字母 $A$ 的花体形式。
编译后的效果如下:
提示
将多页PDF格式的幻灯片转为GIF动图可以借助 ImageMagick 一行命令搞定:
convert -delay 250 -density 300x300 -geometry 960x720 beamer.pdf beamer.gif
至此,关于 「R Markdown 制作 beamer 幻灯片」的主题介绍可以告一段落了!眼力犀利的读者可能已经看出上面模版中还是使用 unicode-math 处理数学公式,导致符号样式怪怪的,\boldsymbol
也无法加粗希腊字母,这里留个疑问,希望读者看完本文后,自己能找到答案!
对于想要玩出花样的读者,不妨接着往下看。
R Markdown 模版(高级篇)
下面是另一份完整的 R Markdown 模版,内容十分丰富:添加多个作者,动态日期,bookdown 交叉引用加持,参考文献支持,参考文献样式设置,更换 beamer 主题为 Verona,自定义导言区 header-includes
,添加 Logo,R 绘图设备改为 "cairo_pdf"
,设置幻灯片主题 Verona 的选项等2。读者可以注释和编译交替进行,细节就不说了,可以看看后面的参考文献,边看边玩!
---
title: "R Markdown 制作 beamer 幻灯片"
author:
- 黄湘云
- 李四
institute: "xxx 大学学院"
date: "`r Sys.Date()`"
documentclass: ctexbeamer
output:
bookdown::pdf_book:
number_sections: yes
toc: no
base_format: rmarkdown::beamer_presentation
latex_engine: xelatex
citation_package: natbib
keep_tex: no
template: null
dev: "cairo_pdf"
theme: Verona
header-includes:
- \logo{\includegraphics[height=0.8cm]{`r R.home('doc/html/Rlogo')`}}
- \usepackage{pifont}
- \usepackage{iitem}
- \setbeamertemplate{itemize item}{\ding{47}}
- \setbeamertemplate{itemize subitem}{\ding{46}}
themeoptions:
- colorblocks
- showheader
- red
biblio-style: apalike
natbiboptions: "authoryear,round"
bibliography:
- packages.bib
classoption: "fontset=fandol"
link-citations: yes
section-titles: false
biblio-title: 参考文献
colorlinks: yes
---
bookdown::pdf_book
下的 number_sections
、toc
等皆是其参数,详情可查看帮助文档 ?bookdown::pdf_book
。上面将 rmarkdown::beamer_presentation
作为 bookdown::pdf_book
的 base_format
而不是像默认的 beamer 模版那样直接引用,是为了获得交叉引用的能力。
结合 Pandoc 内建 LaTeX 模版,你会发现,除了 output 字段下的键值对,其它都在。结合位置来看 header-includes
相当于 premble (LaTeX 文档的导言区)。下面摘取设置 beamer 幻灯片的部分 LaTeX 模版内容加以说明。
$if(beamer)$
$if(theme)$
\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$}
$endif$
$if(colortheme)$
\usecolortheme{$colortheme$}
$endif$
$if(fonttheme)$
\usefonttheme{$fonttheme$}
$endif$
$if(mainfont)$
\usefonttheme{serif} % use mainfont rather than sansfont for slide text
$endif$
$if(innertheme)$
\useinnertheme{$innertheme$}
$endif$
$if(outertheme)$
\useoutertheme{$outertheme$}
$endif$
$endif$
beamer 默认的主题提供了一些 block 样式,比如 exampleblock、alertblock、block 等。
::: {.exampleblock data-latex="{提示}"}
提示
:::
当然,有些主题还有自定义的 block 样式,像引用名人名言
::: {.quotation data-latex="[John Gruber]"}
A Markdown-formatted document should be publishable as-is, as plain text,
without looking like it’s been marked up with tags or formatting instructions.
:::
此处,不一一介绍,详情见讨论贴don’t respect beamer theme’s buildin theorem/proof block。完整的 R Markdown 幻灯片模版如下:
---
title: "R Markdown 制作 beamer 幻灯片"
author:
- 黄湘云
- 李四
institute: "xxx 大学学院"
date: "`r Sys.Date()`"
documentclass: ctexbeamer
output:
bookdown::pdf_book:
number_sections: yes
toc: no
base_format: rmarkdown::beamer_presentation
latex_engine: xelatex
citation_package: natbib
keep_tex: no
template: null
dev: "cairo_pdf"
theme: Verona
header-includes:
- \logo{\includegraphics[height=0.8cm]{`r R.home('doc/html/Rlogo')`}}
- \usepackage{pifont}
- \usepackage{iitem}
- \setbeamertemplate{itemize item}{\ding{47}}
- \setbeamertemplate{itemize subitem}{\ding{46}}
themeoptions:
- colorblocks
- showheader
- red
biblio-style: apalike
natbiboptions: "authoryear,round"
bibliography:
- packages.bib
classoption: "fontset=fandol"
link-citations: yes
section-titles: false
biblio-title: 参考文献
colorlinks: yes
---
## 介绍
::: {.quotation data-latex="[John Gruber]"}
A Markdown-formatted document should be publishable as-is, as plain text,
without looking like it’s been marked up with tags or formatting instructions.
:::
Markdown 提供一种简洁的格式语法,用来编辑 HTML、PDF 和 MS Word 文档,数学公式还是用 LaTeX 排版的好,
$\boldsymbol{\Sigma}$ 是希腊字母 $\Sigma$ 的加粗形式,
$\mathcal{A}$ 是普通字母 $A$ 的花体形式。
## 自定义 block
::: {.exampleblock data-latex="{提示}"}
记得安装一些 LaTeX 宏包,如果不记得也没关系,大多数情况下 tinytex [@tinytex] 会找齐依赖安装好,只是初次运行会有点慢!
```{r, eval=FALSE}
# 安装 LaTeX 宏包
tinytex::tlmgr_install(c("psnfss", "iitem", "beamer-verona"))
```
:::
```{r bib, include=FALSE, cache=FALSE}
bib <- knitr::write_bib(
x = c(
.packages(), "tinytex"
), file = NULL, prefix = ""
)
bib <- unlist(bib)
bib <- gsub("(\\\n)", " ", bib)
xfun::write_utf8(bib, "packages.bib")
```
编译出来的效果如下:
此外,R 社区有几个 R 包专门打包了一些 R Markdown 幻灯片模版,比如 binb 和 uiucthemes 包,如何使用便不再赘述,掌握以上介绍的规律,beamer 主题任你玩3。
最后,贴出本文使用的 R 环境信息,供读者复现参考。
xfun::session_info(c("tinytex", "knitr", "rmarkdown", "bookdown"))
R version 4.1.1 (2021-08-10)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 11.6, RStudio 2021.9.0.351
Locale: en_US.UTF-8 / en_US.UTF-8 / en_US.UTF-8 / C / en_US.UTF-8 / en_US.UTF-8
Package version:
base64enc_0.1.3 bookdown_0.24 digest_0.6.28 evaluate_0.14 fastmap_1.1.0
glue_1.4.2 graphics_4.1.1 grDevices_4.1.1 highr_0.9 htmltools_0.5.2
jquerylib_0.1.4 jsonlite_1.7.2 knitr_1.36 magrittr_2.0.1 methods_4.1.1
rlang_0.4.11 rmarkdown_2.11 stats_4.1.1 stringi_1.7.4 stringr_1.4.0
tinytex_0.34 tools_4.1.1 utils_4.1.1 xfun_0.26 yaml_2.2.1
Pandoc version: 2.14.2
参考文献
-
LaTeX 数学符号合集. https://www.ctan.org/pkg/comprehensive/.
-
谢益辉. 2020. 适用于 LaTeX 环境的 Pandoc 选项. https://bookdown.org/yihui/rmarkdown-cookbook/latex-variables.html
-
谢益辉. 2018. R Markdown 制作 Beamer 幻灯片简介. https://bookdown.org/yihui/rmarkdown/beamer-presentation.html
-
谢益辉. 2016. bookdown 交叉引用介绍. https://bookdown.org/yihui/bookdown/cross-references.html
-
Xiangdong Zeng. 2020. 在 LATEX 中使用 OpenType 字体(三). https://stone-zeng.github.io/2020-05-02-use-opentype-fonts-iii/
-
Alison Hill, Christophe Dervieux, Yihui Xie. 2021. R Markdown 又提供一些新的特性. https://blog.rstudio.com/2021/04/15/2021-spring-rmd-news/
-
RStudio IDE 捆绑了 Pandoc 软件,安装完 RStudio IDE 就可以直接用它了。我平时喜欢用最新的稳定版,版本略高于它,如果你网络环境不佳,上 Github 有困难,可以执行如下命令获取 Pandoc 内置的 LaTeX 模版。
pandoc -o custom-reference.tex --print-default-template latex
获取其它文档格式的模版,稍用所不同,比如 DOCX 文档。
↩︎pandoc -o custom-reference.docx --print-default-data-file reference.docx
-
通过查看 Verona 主题 https://ctan.org/pkg/beamer-verona 的手册,知道它有一些额外的选项控制幻灯片样式, ↩︎
-
想来想去,好像只剩一种情况还没有介绍,就是使用 Pandoc 支持的 Lua 外挂,借助 LaTeX 宏包 tcolorbox 自定义 block,而这当属于忍者玩法了! ↩︎