首页 > 解决方案 > 无法在 Bookdown 中使用自定义模板

问题描述

我正在创建一个 R 包,它依赖Bookdown从文件中创建 PDF 书籍.Rmd。我想使用自定义乳胶模板。因此,根据关于模板的Bookdown 文档部分和关于模板Pandoc 文档,我在我的项目中创建了以下结构:

myproj/
├── inst/
│   ├── examples/
│   |   ├── firstbook/
│   |   |   ├── index.Rmd
│   |   |   ├── ...
│   ├── rmarkdown/
│   |   ├── templates/
│   |   |   ├── book_tex/
│   |   |   |   ├── resources/
│   |   |   |   |   ├── template.tex
│   |   |   |   ├── skeleton/
│   |   |   |   |   ├── monograph.cls
│   |   |   |   |   ├── bibliography.bib
│   |   |   |   |   ├── skeleton.Rmd
│   |   |   |   ├── template.yaml
├── R/
│   ├── format.R
│   └── render.R
└── DESCRIPTION

模板工件

新模板被称为book_tex,我在inst/rmarkdown/templates.

template.tex是:

% !TeX program = pdfLaTeX
\documentclass{monograph}

\usepackage{hyperref}
\usepackage{newtxmath}       % Times Roman as basic font

\makeindex

\begin{document}

\author{ $for(authors)$ $authors.name$ \and $endfor$ }
\title{$title$}
$if(subtitle)$
    \subtitle{$subtitle$}
$endif$

\maketitle
\tableofcontents

$body$

\printindex

\end{document}

模板.yaml是:

name: PDF Book
description: >
 Template for creating a TEX book
create_dir: true

骨架.Rmd是:

---
title: Title here
subtitle: Do you have a subtitle? If so, write it here

thanks: | 
    Grants or other notes about the article that should go on the front 
    page should be placed here. General acknowledgments should be placed at the
    end of the article.
authors: 
- name: Author 1
  address: Department of YYY, University of XXX
  email: abc@def

- name: Author 2
  address: Department of ZZZ, University of WWW
  email: djf@wef

keywords:
- key
- dictionary
- word  

abstract: |
  The text of your abstract.  150 -- 250 words.

output: myprojpkg::book_tex
---

# Introduction {#intro}

Your text comes here. Separate text sections with

# Section title {#sec:1}

Some text.

## Subsection title {#sec:2}

Some other text.

建造

我创建了一个自定义格式,它基本上将我的自定义模板设置在文件中format.R

book_tex_format <- function(...) {
  rmarkdown::pdf_document(..., template = "book_tex")
}

然后,在RStudio 中render.R,我从包的示例目录(工作目录为myproj/inst/examples/firstbook)内部调用 Bookdown:

bookdown::render_book(".", book_tex_format())

这给了我错误:

"C:/PROGRA~1/Pandoc/pandoc" +RTS -K512m -RTS _index_merged.utf8.md --to latex --from markdown+autolink_bare_uris+tex_math_single_backslash --output _index_merged.tex --self-contained --template book_tex --highlight-style tango --pdf-engine pdflatex --lua-filter "C:/Users/me/Documents/R/win-library/3.5/rmarkdown/rmd/lua/pagebreak.lua" --lua-filter “C:/Users/me/Documents/R/win-library/3.5/rmarkdown/rmd/lua/latex-div.lua”找不到数据文件模板\book_tex.latex

然后我尝试过:

bookdown::render_book(".", rmarkdown::pdf_document(template="../../rmarkdown/templates/book_tex/resources/template.tex"))

这似乎有效,但随后给了我错误:

"C:/PROGRA~1/Pandoc/pandoc" +RTS -K512m -RTS _index_merged.utf8.md --to latex --from markdown+autolink_bare_uris+tex_math_single_backslash --output _index_merged.tex --self-contained --template " ....\rmarkdown\templates\book_tex\resources\template.tex" --highlight-style tango --pdf-engine pdflatex --lua-filter "C:/Users/me/Documents/R/win-library/ 3.5/rmarkdown/rmd/lua/pagebreak.lua" --lua-filter "C:/Users/me/Documents/R/win-library/3.5/rmarkdown/rmd/lua/latex-div.lua" !LaTeX 错误:找不到文件“monograph.cls”。

我通过查看 RMarkdown 和 Bookdown 的工作方式来模仿结构。但似乎还不够好。我很沮丧,这部分 API 的文档记录很差,我不明白我应该如何让它工作。

我应该如何调用render_book以传递模板?

bookdown::render_book(".", !!HERE!!)

又一次尝试

我遇到了函数rmarkdown::draft,这似乎是使用模板的推荐方式。所以我确实调用了(工作目录:)myproj/inst/examples

rmarkdown::draft("mybook2", "book_tex", "myprojpkg", TRUE)

请注意,我的包被称为myprojpkg(在DESCRIPTION文件中)。此命令工作正常,实际上会发出此文件夹:

myproj/
├── inst/
│   ├── examples/
│   |   ├── firstbook/
│   |   ├── mybook2/
│   |   |   |   ├── monograph.cls
│   |   |   |   ├── bibliography.bib
│   |   |   |   ├── mybook.Rmd
│   ├── rmarkdown/
│   |   ├── templates/
│   |   |   ├── book_tex/
│   |   |   |   ├── ...
├── R/
│   ├── ...
└── DESCRIPTION

哪里改名了mybook.Rmdskeleton.Rmd所以该命令正确地采用了我在我的包中定义的模板并创建了准备提交的目录结构bookdown::render_book,但是问题是调用它不会给我任何错误,但没有应用正确的模板(template.tex里面book_tex)。此处的命令依赖于skeleton.Rmd它指定要在 yaml 标头中使用的模板的位置的内容,但是该模板以某种方式找不到并且未应用:(


(友好)对 Bookdown 文档的反馈

我不得不说,自定义模板的这一部分需要更好的文档记录,因为开发人员应该如何构建项目以使事情与自定义模板一起工作并不是直接的。

编辑我实际上在rmarkdown::draft function上找到了一些关于这些主题的好文档。我的反馈是让它在有关模板部分的帮助页面中更加明显。现在这个doc块(非常重要的块)基本上是隐藏的。

标签: rr-markdownpandocbookdown

解决方案


在分析了代码并玩了一点 Bookdown 和 Rmarkdown 之后,正如我收到的一些评论中所显示的那样(感谢@stefan),我得出的结论是模板及其所有资源需要在同一个您的文件所在的文件夹.Rmd。这实际上反映draft在 Rmarkdown 中实现此目标的功能的存在。所以我的文件夹结构最终会变成:

myproj/
├── monograph.cls
├── bibliography.bib
├── template.tex
├── mybook.Rmd
├── index.Rmd
├── _bookdown.yaml

从这里,我将打开 RStudio 并将文件夹更改为myproj,或者打开 R shell 并将工作目录更改为myproj通过发出:setwd("path/to/myproj")。然后我会调用命令:

bookdown::render_book("index.Rmd", bookdown::pdf_book(template = "template.tex"))

这将启动机器并创建您的 PDF。


警告:定理和其他环境

如果您的模板导入amsthm或其他定义类似theorem或类似块的环境,Bookdown 将失败。Bookdown 将自动在您提供的 Latex 模板中附加定理的定义(在中间文件夹中生成它的副本)。您需要应用此修复程序以使事情正常工作(在您的index.Rmd):

---
title: My book
author: Me
---

```{r, echo=FALSE}
options(bookdown.post.latex = function(x) {
  from <- grep("usepackage\\{amsthm\\}", x)
  to <- grep("newtheorem\\*\\{solution", x)
  x <- x[-c(from:to)]
})
```

推荐阅读