[英]Including a TeX comment in rmarkdown/knitr document (or pandoc -> TeX output)
[英]Pandoc version 2.7.3 fails to convert knitr .tex file to .docx
直到今天,我一直在使用 knitr 和 Rstudio 中的 .Rnw 文件来生成 pdf 和 docx 文件,没有任何问题。 pdf 转换在 Rstudio 本地运行,对于 docx 转换,我只是通过提供由“编织”.Rnw 文件产生的 .tex 文件在引擎盖下调用 pandoc。 到目前为止,我一直在使用 pandoc 版本 1.19.2.1 并且工作得很好。 但是,在与同事分享我的一些代码来执行此操作后,我意识到使用较新版本的 pandoc (2.7.3) 时该策略失败。
到目前为止,我已经尝试更新 knitr 并理解错误,但没有取得太大成功。 仅当需要生成的 .tex 文件的阴影区域时才会出现该问题,通常在设置 echo=TRUE 之后。
这是我的 Rnw 文件 (min_reproducible_example.Rnw)
\documentclass{article}
\usepackage{multirow}
\setlength\parindent{0pt}
\usepackage{geometry}
\usepackage{longtable}
\usepackage{float}
\usepackage{verbatim}
\usepackage{hyperref}
\geometry{left=1.5cm,right=1.5cm,top=1.5cm,bottom=1.5cm}
\title{Docx from tex file example}
\begin{document}
\maketitle
<<chunk1,echo=TRUE,message=FALSE>>=
library(survival)
str(lung)
@
\end{document}
在 Rstudio 中点击“编译 PDF”后会生成文件:min_reproducible_example.pdf 和 min_reproducible_example.tex。
以防万一,.Rnw 文件 (min_reproducible_example.tex) 的 .tex 输出是
\documentclass{article}\usepackage[]{graphicx}\usepackage[]{color}
% maxwidth is the original width if it is less than linewidth
% otherwise use linewidth (to make sure the graphics do not exceed the margin)
\makeatletter
\def\maxwidth{ %
\ifdim\Gin@nat@width>\linewidth
\linewidth
\else
\Gin@nat@width
\fi
}
\makeatother
\definecolor{fgcolor}{rgb}{0.345, 0.345, 0.345}
\newcommand{\hlnum}[1]{\textcolor[rgb]{0.686,0.059,0.569}{#1}}%
\newcommand{\hlstr}[1]{\textcolor[rgb]{0.192,0.494,0.8}{#1}}%
\newcommand{\hlcom}[1]{\textcolor[rgb]{0.678,0.584,0.686}{\textit{#1}}}%
\newcommand{\hlopt}[1]{\textcolor[rgb]{0,0,0}{#1}}%
\newcommand{\hlstd}[1]{\textcolor[rgb]{0.345,0.345,0.345}{#1}}%
\newcommand{\hlkwa}[1]{\textcolor[rgb]{0.161,0.373,0.58}{\textbf{#1}}}%
\newcommand{\hlkwb}[1]{\textcolor[rgb]{0.69,0.353,0.396}{#1}}%
\newcommand{\hlkwc}[1]{\textcolor[rgb]{0.333,0.667,0.333}{#1}}%
\newcommand{\hlkwd}[1]{\textcolor[rgb]{0.737,0.353,0.396}{\textbf{#1}}}%
\let\hlipl\hlkwb
\usepackage{framed}
\makeatletter
\newenvironment{kframe}{%
\def\at@end@of@kframe{}%
\ifinner\ifhmode%
\def\at@end@of@kframe{\end{minipage}}%
\begin{minipage}{\columnwidth}%
\fi\fi%
\def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep
\colorbox{shadecolor}{##1}\hskip-\fboxsep
% There is no \\@totalrightmargin, so:
\hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
\MakeFramed {\advance\hsize-\width
\@totalleftmargin\z@ \linewidth\hsize
\@setminipage}}%
{\par\unskip\endMakeFramed%
\at@end@of@kframe}
\makeatother
\definecolor{shadecolor}{rgb}{.97, .97, .97}
\definecolor{messagecolor}{rgb}{0, 0, 0}
\definecolor{warningcolor}{rgb}{1, 0, 1}
\definecolor{errorcolor}{rgb}{1, 0, 0}
\newenvironment{knitrout}{}{} % an empty environment to be redefined in TeX
\usepackage{alltt}
\usepackage{multirow}
\setlength\parindent{0pt}
\usepackage{geometry}
\usepackage{longtable}
\usepackage{float}
\usepackage{verbatim}
\usepackage{hyperref}
\geometry{left=1.5cm,right=1.5cm,top=1.5cm,bottom=1.5cm}
\title{Docx from tex file example}
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\begin{document}
\maketitle
\begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{kframe}
\begin{alltt}
\hlkwd{library}\hlstd{(survival)}
\end{alltt}
\end{kframe}
\end{knitrout}
\end{document}
接下来,我可以调用一个包装函数,该函数在命令行中运行以下代码以生成 docx 文件:
path/to/pandoc/pandoc -o min_reproducible_example.docx min_reproducible_example.tex
我在 Windows 中工作,所以我没有检查这个问题是否仍然存在于其他操作系统中。
我认为有几行可以提供信息:
这条线是罪魁祸首,我相信:
Error at "source" (line 68, column 67):
unexpected end of input
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{kframe}
其中,我一直在挖掘的“kframe”来自 knitr 在进行“编织”时创建的乳胶环境。 此行从 pandoc 生成以下错误:
Warning message:
In shell(command) :
'"C:/pandoc/pandoc" -o min_reproducible_example.docx min_reproducible_example.tex --default-image-extension=png' execution failed with error code 65
我不知道这个错误代码 65 是什么意思。 我已经看到 pandoc 之前问题中的线程建议直接查看代码以了解错误。 如果需要,我可以这样做,因为以前的 pandoc 版本可以正常工作,而较新的版本正在崩溃,这对我来说很奇怪。 我决定把这个贴在这里,想知道是否有人遇到过同样的问题。
我将根据 pandoc-discuss 的另一次对话发布一个可能的解决方案以供将来参考。
在与 John MacFarlane 反复讨论之后,他好心地建议我重新定义给 pandoc 带来麻烦的环境:kframe。 他建议将其简单地重新定义为:
\renewenvironment{kframe}{}{}
所以,我所做的是重新定义一个我在内部调用 pandoc 的自定义 R 函数。 我只包括下面的相关行。
## read the original .tex file (.Rnw output)
tx <- readLines(paste0(fname, '.tex'),warn=FALSE)
## rename the environment to something simpler as suggested by John MacFarlane in the pandoc-discuss thread
tx2 <- gsub(pattern = "\\begin{document}",
replace = "\\renewenvironment{kframe}{}{}\\begin{document}",
x = tx, fixed = TRUE)
## create a file with the workaround for the kframe environment and use it in the pandoc call below
zz <- file(paste0(fname, '_cp.tex'), "wb")
writeLines(tx2, con=zz)
close(zz)
command <- paste0('"',pdwd,'/pandoc" -o ', fname, '.docx ', fname, '_cp.tex ',
"--default-image-extension=png ")
shell(command)
# remove the file
file.remove(paste0(fname, '_cp.tex'))
在那之后 pandoc 可以毫无怨言地执行。 我注意到早期版本的 pandoc (1.19.2.1),虽然执行没有错误,但输出的 docx 文件缺少 kframe 环境中的内容,而此修复程序可以更准确地表示 pdf。
我还没有广泛地尝试过这个修复,所以如果你发现任何问题,请留下评论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.