繁体   English   中英

Pandoc 2.7.3 版无法将 knitr .tex 文件转换为 .docx

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM