如何扩展 Pandoc
How to extend Pandoc
我将 bookdown 用于文档,该文档使用 bookdown::gitbook
和 bookdown::pdf_book
输出。
在我的 Rmd
文件中,我使用 div 环绕注释和警告,并使用 css 文件设置样式。例如:
<div class="note">
This is a note.
</div>
显然,HTML 和 CSS 在生成 PDF 文件时会被忽略。我想知道是否有一种方法可以“注入”一个小脚本来替换 div
,例如,一个简单的前缀文本。
或者,是否有另一种方法可以在 HTML 和 PDF 中格式化它,而不会通过每次添加冗长的内容来乱丢我的文件,例如:
if (knitr::is_html_output(excludes='epub')) {
cat('
<div class="note">
This is a note.
</div>
')
} else {
cat('Note: This is a note.')
}
我也可以按照描述设置块引号的样式 here 但这不是一个选项,因为我仍然需要块引号。
我在 tex.stackexchange.com 上找到了这个 answer,这让我走上了解决问题的正确轨道。
这是我正在做的。
- 使用以下函数创建
boxes.lua
:
function Div(element)
-- function based on https://tex.stackexchange.com/a/526036
if
element.classes[1] == "note"
or element.classes[1] == "side-note"
or element.classes[1] == "warning"
or element.classes[1] == "info"
or element.classes[1] == "reading"
or element.classes[1] == "exercise"
then
-- get latex environment name from class name
div = element.classes[1]:gsub("-", " ")
div = div:gsub("(%l)(%w*)", function(a, b) return string.upper(a)..b end)
div = "Div"..div:gsub(" ", "")
-- insert element in front
table.insert(
element.content, 1,
pandoc.RawBlock("latex", "\begin{"..div.."}"))
-- insert element at the back
table.insert(
element.content,
pandoc.RawBlock("latex", "\end{"..div.."}"))
end
return element
end
- 将
pandoc_args
添加到_output.yml
:
bookdown::pdf_book:
includes:
in_header: latex/preamble.tex
pandoc_args:
- --lua-filter=latex/boxes.lua
extra_dependencies: ["float"]
- 在
preamble.tex
中创建环境(也在_output.yml
中配置):
- 我正在使用
tcolorbox
而不是 mdframed
\usepackage{xcolor}
\usepackage{tcolorbox}
\definecolor{notecolor}{RGB}{253, 196, 0}
\definecolor{warncolor}{RGB}{253, 70, 0}
\definecolor{infocolor}{RGB}{0, 183, 253}
\definecolor{readcolor}{RGB}{106, 50, 253}
\definecolor{taskcolor}{RGB}{128, 252, 219}
\newtcolorbox{DivNote}{colback=notecolor!5!white,colframe=notecolor!75!black}
\newtcolorbox{DivSideNote}{colback=notecolor!5!white,colframe=notecolor!75!black}
\newtcolorbox{DivWarning}{colback=warncolor!5!white,colframe=warncolor!75!black}
\newtcolorbox{DivInfo}{colback=infocolor!5!white,colframe=infocolor!75!black}
\newtcolorbox{DivReading}{colback=readcolor!5!white,colframe=readcolor!75!black}
\newtcolorbox{DivExercise}{colback=taskcolor!5!white,colframe=taskcolor!75!black}
- 因为方框内还有图片和表格,所以我 运行 变成了
LaTeX Error: Not in outer par mode.
。我能够通过将以下命令添加到我的 Rmd
文件来解决此问题:
```{r, echo = F}
knitr::opts_chunk$set(fig.pos = "H", out.extra = "")
```
执行此操作的适当方法是使用围栏 div,而不是将 HTML 直接插入您的 markdown 并稍后尝试使用 LUA 对其进行解析。 Pandoc 已经允许您插入自定义样式并将它们处理为两种文件类型。换句话说,它将负责为您创建适当的 HTML 和 LaTeX,然后您只需要为它们中的每一个设置样式。 Bookdown 文档引用了这个 here, but it simply points to further documentation here, and here.
此方法将在 html 中创建自定义分类 div 并在 LaTeX 代码中应用相同的样式名称。
因此,对于您的示例,它看起来像这样:
::: {.note data-latex=""}
This is a note.
:::
HTML 中的输出将与您的相同:
<div class="note">
<p>This is a note.</p>
</div>
并且您已经得到 CSS 想要的样式。
LaTeX 代码如下:
\begin{note}
This is a note.
\end{note}
要设置样式,您需要在 preamble.tex 文件中添加一些代码,您也已经弄清楚了。这是一个非常简单的 LaTeX 示例,它可以简单地从左侧和右侧缩进文本:
\newenvironment{note}[0]{\par\leftskip=2em\rightskip=2em}{\par\medskip}
我将 bookdown 用于文档,该文档使用 bookdown::gitbook
和 bookdown::pdf_book
输出。
在我的 Rmd
文件中,我使用 div 环绕注释和警告,并使用 css 文件设置样式。例如:
<div class="note">
This is a note.
</div>
显然,HTML 和 CSS 在生成 PDF 文件时会被忽略。我想知道是否有一种方法可以“注入”一个小脚本来替换 div
,例如,一个简单的前缀文本。
或者,是否有另一种方法可以在 HTML 和 PDF 中格式化它,而不会通过每次添加冗长的内容来乱丢我的文件,例如:
if (knitr::is_html_output(excludes='epub')) {
cat('
<div class="note">
This is a note.
</div>
')
} else {
cat('Note: This is a note.')
}
我也可以按照描述设置块引号的样式 here 但这不是一个选项,因为我仍然需要块引号。
我在 tex.stackexchange.com 上找到了这个 answer,这让我走上了解决问题的正确轨道。
这是我正在做的。
- 使用以下函数创建
boxes.lua
:
function Div(element)
-- function based on https://tex.stackexchange.com/a/526036
if
element.classes[1] == "note"
or element.classes[1] == "side-note"
or element.classes[1] == "warning"
or element.classes[1] == "info"
or element.classes[1] == "reading"
or element.classes[1] == "exercise"
then
-- get latex environment name from class name
div = element.classes[1]:gsub("-", " ")
div = div:gsub("(%l)(%w*)", function(a, b) return string.upper(a)..b end)
div = "Div"..div:gsub(" ", "")
-- insert element in front
table.insert(
element.content, 1,
pandoc.RawBlock("latex", "\begin{"..div.."}"))
-- insert element at the back
table.insert(
element.content,
pandoc.RawBlock("latex", "\end{"..div.."}"))
end
return element
end
- 将
pandoc_args
添加到_output.yml
:
bookdown::pdf_book:
includes:
in_header: latex/preamble.tex
pandoc_args:
- --lua-filter=latex/boxes.lua
extra_dependencies: ["float"]
- 在
preamble.tex
中创建环境(也在_output.yml
中配置):- 我正在使用
tcolorbox
而不是mdframed
- 我正在使用
\usepackage{xcolor}
\usepackage{tcolorbox}
\definecolor{notecolor}{RGB}{253, 196, 0}
\definecolor{warncolor}{RGB}{253, 70, 0}
\definecolor{infocolor}{RGB}{0, 183, 253}
\definecolor{readcolor}{RGB}{106, 50, 253}
\definecolor{taskcolor}{RGB}{128, 252, 219}
\newtcolorbox{DivNote}{colback=notecolor!5!white,colframe=notecolor!75!black}
\newtcolorbox{DivSideNote}{colback=notecolor!5!white,colframe=notecolor!75!black}
\newtcolorbox{DivWarning}{colback=warncolor!5!white,colframe=warncolor!75!black}
\newtcolorbox{DivInfo}{colback=infocolor!5!white,colframe=infocolor!75!black}
\newtcolorbox{DivReading}{colback=readcolor!5!white,colframe=readcolor!75!black}
\newtcolorbox{DivExercise}{colback=taskcolor!5!white,colframe=taskcolor!75!black}
- 因为方框内还有图片和表格,所以我 运行 变成了
LaTeX Error: Not in outer par mode.
。我能够通过将以下命令添加到我的Rmd
文件来解决此问题:
```{r, echo = F}
knitr::opts_chunk$set(fig.pos = "H", out.extra = "")
```
执行此操作的适当方法是使用围栏 div,而不是将 HTML 直接插入您的 markdown 并稍后尝试使用 LUA 对其进行解析。 Pandoc 已经允许您插入自定义样式并将它们处理为两种文件类型。换句话说,它将负责为您创建适当的 HTML 和 LaTeX,然后您只需要为它们中的每一个设置样式。 Bookdown 文档引用了这个 here, but it simply points to further documentation here, and here.
此方法将在 html 中创建自定义分类 div 并在 LaTeX 代码中应用相同的样式名称。
因此,对于您的示例,它看起来像这样:
::: {.note data-latex=""}
This is a note.
:::
HTML 中的输出将与您的相同:
<div class="note">
<p>This is a note.</p>
</div>
并且您已经得到 CSS 想要的样式。
LaTeX 代码如下:
\begin{note}
This is a note.
\end{note}
要设置样式,您需要在 preamble.tex 文件中添加一些代码,您也已经弄清楚了。这是一个非常简单的 LaTeX 示例,它可以简单地从左侧和右侧缩进文本:
\newenvironment{note}[0]{\par\leftskip=2em\rightskip=2em}{\par\medskip}