使 catchbetweenfiletags 与 lualatex 配合使用的解决方法

使 catchbetweenfiletags 与 lualatex 配合使用的解决方法

我最近发现该包的一个基本示例catchbetweenfiletags不能与一起使用lualatex(但可以与一起使用pdflatex)。

接下来是 MWE。您知道是否有解决方法可以使其与 一起工作吗lualatex

文件catch1.tex

\documentclass{article}
\usepackage{catchfilebetweentags}
\begin{document}
test
\ExecuteMetaData[catch2]{mytag}
\end{document}

文件catch2.tex

\documentclass{article}
\begin{document}
%<*mytag>
CATCH2
%</mytag>
\end{document}

$ pdflatex catch1.tex按预期工作。

$ lualatex catch1.tex给出此错误:

Runaway text?
! File ended while scanning text of \CatchFBT@tok.
<inserted text> 
}
l.7 \ExecuteMetaData[catch2]{mytag}

? 

版本:

pdfTeX 3.14159265-2.6-1.40.15 (TeX Live 2014)

This is LuaTeX, Version beta-0.79.1 (TeX Live 2014) (rev 4971)

catchfilebetweentags : 2011/02/19 v1.1

作为参考,使用包的命令\CatchFileBetweenTags同样会失败。从@egreg的评论来看,它也适用于xelatex

答案1

我认为这是一个与此相同的问题:LuaTeX 中的 \scantokens和这个http://tug.org/pipermail/lualatex-dev/2011-November/001376.html。包发生了变化\endlinechar,因此 luatex 滑到了文件末尾。

可以通过禁用\endlinechar更改来避免错误消息:

\documentclass{article}
\usepackage{catchfilebetweentags,ifluatex}
\makeatletter
\def\CatchFBT@sanitize{%
   \@sanitize
   \@makeother\{%
   \@makeother\}%
   \ifluatex\else
   \endlinechar=`\^^J%
   \fi
}% 
\makeatother
\begin{document}
test
\ExecuteMetaData[catch2]{mytag}
\end{document}

也可以将其设置^^J为“行尾字符”。

\documentclass{article}
\usepackage{catchfilebetweentags,ifluatex}
\makeatletter
\def\CatchFBT@sanitize{%
   \@sanitize
   \@makeother\{%
   \@makeother\}%
   \endlinechar=`\^^J%
   \ifluatex
   \catcode`\^^J=5
   \fi
}% 
\makeatother
\begin{document}
test
\ExecuteMetaData[catch2]{mytag}

\end{document}

但是,如果捕获的文件包含空行,与 pdflatex 相比,两者都会改变输出。

答案2

我尝试了各种方法来解决 LuaTeX 中的错误\scantokens。最后,我认为最可靠的方法是(暂时)\scantokens在该上下文中放弃使用,然后通过真正的中间文件。以下是代码:

% \scantokens is buggy in LuaTeX
% http://tex.stackexchange.com/questions/65151/scantokens-in-luatex
% http://tug.org/pipermail/lualatex-dev/2011-November/001376.html

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{catch2}
\documentclass{article}
\begin{document}
%<*mytag>
CATCH2
SECOND LINE

THIRD LINE AFTER ONE EMPTY LINE


FOURTH LINE AFTER TWO EMPTY LINES
%</mytag>
\end{document}
\end{filecontents*}
\usepackage{catchfilebetweentags}
\usepackage{ifluatex}

% CIRCUMVENTING LUALATEX BUGGY \scantokens

\makeatletter

\ifluatex 
   \newwrite\CATCHPATCHOUT
\fi

\def\CatchFBT@Fin@l#1[#2]{%
   \begingroup
      \endlinechar\m@ne \makeatletter #2%
      \ifluatex
         \immediate\openout\CATCHPATCHOUT=\jobname.catchpatch
         \immediate\write\CATCHPATCHOUT {\CatchFBT@tok{\the\CatchFBT@tok}}%
         \immediate\closeout\CATCHPATCHOUT
         \@@input \jobname.catchpatch
      \else
      \scantokens\expandafter{%
         \expandafter\CatchFBT@tok\expandafter{\the\CatchFBT@tok}}%
      \fi
      \CatchFBT@IsAToken{#1}
         {\global#1\expandafter{\the\CatchFBT@tok}}
         {\xdef#1{\the\CatchFBT@tok}}%
      \ifx\CatchFBT@tok#1\else\global\CatchFBT@tok{}\fi
   \endgroup
}% \CatchFBT@Final
\makeatother

\begin{document}\thispagestyle{empty}
\ttfamily


\CatchFileBetweenTags\tmp{catch2}{mytag}

\meaning\tmp

\noindent\ExecuteMetaData [catch2]{mytag}

\end{document}

在此示例中,无论使用 pdfTeX 还是 LuaLaTeX,都可以获得以下内容:

在此处输入图片描述

请注意,这是包的行为catchfilebetweentags:如果您想重新恢复换行符,您应该使用最后的可选参数来\CatchFileBetweenTags修改\endlinechar-1设置。

例子:

\CatchFileBetweenTags\tmp{catch2}{mytag}[\endlinechar=13 ]

\meaning\tmp

我们再次使用两个引擎获得相同的结果:

在此处输入图片描述

请注意,CATCH 之前的空格来自标记行的行尾。这是包所做的(与我的补丁无关)。

相关内容