在书本图形环境中包含TikZ代码

eks*_*oem 5 r knitr r-markdown bookdown tikzdevice

我想在bookdown文档中添加TikZ图形,以便包含一些精美的图形。

我的主要输出格式是LaTeX,这意味着我基本上可以在Rmarkdown文件中逐字包含TikZ图形,并且可以很好地呈现。但是,有两个问题困扰着我:

  • 我希望TikZ图形成为图形环境的一部分(用于编号,标题等)。
  • 我希望能够将相同的代码呈现给PDF(LaTeX)和Gitbook(HTML)。

现在,我有以下块,当我将其渲染为pdf时,可以很好地生成相关图形。

```{r, echo=FALSE, engine='tikz', out.width='90%', fig.ext='pdf', fig.cap='Some caption.'}
\begin{tikzpicture}[scale=.7]
\draw [fill=gray!30,very thick] (0,-1) rectangle (5,1);
\draw [very thick] (5, 0) -- (13,0);
\node [below] at (2,-1) {\large Hello};
\node [below, align=center] at (0,-1) {\large Two\\ lines};
\end{tikzpicture}
```
Run Code Online (Sandbox Code Playgroud)

但是,代码有两个问题:

  1. 渲染到gitbook时,我没有得到任何输出(使用knitrbookdown)。但是,我确实获得了图形标题,如果我渲染到html_document它,那么它也可以工作,并且我可以看到图形。
  2. 对于PDF,使用计算机现代字体呈现文本。我真的很想更改此设置,并且LaTeX文档中的主要字体已经设置为其他字体。但是,由于代码是由TikZ引擎本地渲染然后插入的,因此它不是完整LaTeX文档的一部分。我可以呈现代码之前添加一些TikZ引擎包含的LaTeX选项,软件包等吗?

如果还有其他方法可以将TikZ代码作为图形环境的一部分包含在内,那么我很高兴知道。

更新:我猜第二点可以通过设置文件中engine.opts = list(template = "latex/tikz2pdf.tex")包含LaTeX的必要设置的位置来解决tikz2pdf.tex。该文件是使用LaTeX读取的,但xelatex由于要使用fontspecLaTex软件包,因此我想使用该文件进行解析。仍然可以更改吗?

eks*_*oem 6

我想我找到了两个问题的答案。正如Yihui指出的,确实花了相当长的时间。我将答案包括在这里,以防万一有人(或我自己)需要这个。

关于1)将TikZ代码渲染为pdf和gitbook

事实证明,这比我预期的要容易。将参数设置fig.ext=if (knitr:::is_latex_output()) 'pdf' else 'png'为块参数的一部分可以帮助实现这一点。如果我没有编织成PDF,那么imagemagick或其他软件会自动将其转换为PNG。

关于2)修改字体

正如我更新的问题中列出的那样,可以通过调整tikz2pdf.texknitr的一部分文件来进行设置。下面包含它的副本,因此您无需自己搜索。设置chunk参数engine.opts = list(template = "latex/tikz2pdf.tex")可以使您在呈现TikZ代码之前将所需的字体,LaTeX包等放入序言中。

浏览knitr代码,您可以看到该代码texi2dvi用于解析tikz2pdf.tex插入了TikZ代码的文件。如果您需要使用XeLaTeX或LuaLaTeX来使用来包含TrueType字体,则这些texi2dvi调用pdflatex会弄乱事情fontspec

我敢肯定,可以在texi2dvi代码中以某种方式解决此问题,但是(至少对我而言)更简单的解决方案是更改环境。如果我启动R和渲染书之前设置了两个环境变量则xelatex将自动用于编译所有代码。在我的bash终端中,使用

export LATEX="xelatex"
export PDFLATEX="xelatex"
Run Code Online (Sandbox Code Playgroud)

瞧!

块变成

```{r, echo=FALSE, engine='tikz', out.width='90%', fig.ext=if (knitr:::is_latex_output()) 'pdf' else 'png', fig.cap='Some caption.', engine.opts = list(template = "latex/tikz2pdf.tex")
}
\begin{tikzpicture}[scale=.7]
\draw [fill=gray!30,very thick] (0,-1) rectangle (5,1);
\draw [very thick] (5, 0) -- (13,0);
\node [below] at (2,-1) {\large Hello};
\node [below, align=center] at (0,-1) {\large Two\\ lines};
\end{tikzpicture}
```
Run Code Online (Sandbox Code Playgroud)

并且tikz2pdf.tex

\documentclass{article}
\include{preview}
\usepackage[pdftex,active,tightpage]{preview}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{matrix}
%% INSERT YOUR OWN CODE HERE 
\begin{document}
\begin{preview}
%% TIKZ_CODE %%
\end{preview}
\end{document}
Run Code Online (Sandbox Code Playgroud)

我仍然对knitr和相关软件包的整体灵活性感到惊讶。干得好逸熙!