与独立包一起使用 \nocite 时出现问题

与独立包一起使用 \nocite 时出现问题

鉴于:

\documentclass{minimal}
\usepackage{standalone}
\begin{document}
\input{inclusion}
\nocite{*}
\bibliographystyle{plain}
\bibliography{test}
\end{document}

和:

\documentclass{minimal}
\begin{document}
Hello World!
\end{document}

和:

@book{Bateman.1906,
 author = {Bateman, Newton and Selby, Paul and Short, William F.},
 year = {1906},
 title = {Historical encyclopedia of Illinois},
 address = {Chicago},
 publisher = {Munsell Pub. Co.}
}


@book{Beckett.1966,
 author = {Beckett, J. C.},
 year = {1966},
 title = {The making of modern Ireland, 1603-1623},
 address = {London},
 publisher = {Faber}
}

我收到以下错误:

! LaTeX Error: Cannot be used in preamble.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...

l.5 \nocite{*}
?

但是,如果我注释掉其中一个\input{inclusion}或两个\nocite{*},测试编译时就不会出错。我在 Win7 Ultimate 上运行命令行latexmk -xelatex test。TeX 由 MikTeX 提供。

所以,要么是我做的太过分,要么是独立版出了问题?欢迎提出建议和批评。

答案1

这是由于\nocite其定义方式:

% latex.ltx, line 6146:
\def\nocite#1{\@bsphack
  \ifx\@onlypreamble\document
    \@for\@citeb:=#1\do{%
      \edef\@citeb{\expandafter\@firstofone\@citeb}%
      \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
      \@ifundefined{b@\@citeb}{\G@refundefinedtrue
          \@latex@warning{Citation `\@citeb' undefined}}{}}%
  \else
    \@latex@error{Cannot be used in preamble}\@eha
    % \AtBeginDocument{\nocite{#1}}
  \fi
  \@esphack}

并且standalone将重新定义\document为与相同\sa@document,这从该包的角度来看是合理的,但却具有破坏性,\nocite因为

\ifx\@onlypreamble\document

测试将返回 false。

\nocite您可以通过提供开始文档的免费测试版本来解决该问题:

\documentclass{article}
\usepackage{standalone}

\makeatletter
\def\@documentnocite#1{\@bsphack
  \@for\@citeb:=#1\do{%
    \edef\@citeb{\expandafter\@firstofone\@citeb}%
    \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
    \@ifundefined{b@\@citeb}{\G@refundefinedtrue
      \@latex@warning{Citation `\@citeb' undefined}}{}}%
  \@esphack}
\AtBeginDocument{\let\nocite\@documentnocite}
\makeatother

\begin{document}
\nocite{*}
\input{myersinput}
\nocite{*}
\bibliographystyle{plain}
\bibliography{myersbib}
\end{document}

更简单的代码使用etoolbox

\documentclass{article}
\usepackage{standalone}

\usepackage{etoolbox}
\makeatletter
\AtBeginDocument{
  \patchcmd{\nocite}
    {\ifx\@onlypreamble\document}
    {\iftrue}
    {}
    {\@latex@warning@no@line{\string\nocite\space changed, no patch possible}}
}
\makeatother

\begin{document}
\input{myersinput}
\nocite{*}
\bibliographystyle{plain}
\bibliography{myersbib}
\end{document}

相关内容