如果将包加载到独立输入文件之一中,则包standalone
及其subpreambles
选项会出现错误xy
。以下 M(n)WE 显示了这一点:
\begin{filecontents}{testxy}
\documentclass{article}
\usepackage{xy}
\begin{document}
Foo.
\end{document}
\end{filecontents}
%
\documentclass{article}
\usepackage[subpreambles]{standalone}
\begin{document}
\input{testxy}
\end{document}
编译失败并出现错误(需要两次编译):
! Undefined control sequence.
l.58 \xylet
@\xy@begindvi=\literal@
?
你知道发生了什么吗?
答案1
错误发生在第 58 行xyidioms.tex
;我们来看看
43 \ifx\AtEndDocument\undefined
44 \expandafter\ifx\csname amsppt.sty\endcsname\relax
45 \let\xysetup@@=\xysetup@dummy
46 \else
47 \def\xysetup@@#1{%
48 \expandafter\def\expandafter\topmatter\expandafter{\topmatter
49 #1\xyuncatcodes}}\fi
50 \else
51 \def\xysetup@@#1{\AtBeginDocument{#1\xyuncatcodes}}
52 \fi
53 \ifx\xysetup@@\xysetup@dummy\else
54 \xysetup@@{\let\xysetup@@=\xysetup@dummy \xyuncatcodes}\fi
55 \xywarnifdefined\xyclosedown@@
56 \ifx\AtEndDocument\undefined \let\xyclosedown@@=\eat@
57 \else \def\xyclosedown@@#1{\AtEndDocument{#1}}\fi
58 \xylet@\xy@begindvi=\literal@
第 43 行的条件返回 false,因此
\def\xysetup@@#1{\AtBeginDocument{#1\xyuncatcodes}}
执行。由于现在\xysetu@@
与 不同\xysetup@dummy
,
\xysetup@@{\let\xysetup@@=\xysetup@dummy \xyuncatcodes}
执行。不幸的是,在内部\standalonepreambles
,宏\AtBeginDocument
被重新定义为立即传递其参数,正如此交互式运行所示。
(/usr/local/texlive/2015/texmf-dist/tex/generic/xypic/xyidioms.tex
! Undefined control sequence.
l.58 \xylet
@\xy@begindvi=\literal@
? i\show\AtBeginDocument
> \AtBeginDocument=\long macro:
#1->#1.
<insert> \show\AtBeginDocument
l.58 \xylet
@\xy@begindvi=\literal@
?
这意味着该命令使 TeX立即\xysetup@@
执行。除其他外,它执行。所以现在不再是字母了。\xyuncatcodes
\makeatother
@
第 55 行打印了两个@
字符,但我们已经位于之后\begin{document}
,因此没有错误。以下条件返回 false 并定义\xyclosedown
而不是,\xyclosedown@@
但这不会引发错误。现在第 58 行有标记
\xylet•@•\xy•@•b•e•g•i•n•d•v•i•=•\literal•@
(•
用于分隔标记)。由于\xylet
未定义,因此会引发错误。
结论:它无法工作。任何执行@
at类别代码更改的包\AtBeginDocument
都会以类似的方式失败。