我正在尝试拦截\input
某些文件类型的功能调用和分支。但是,我遇到了以下奇怪的错误:
考虑下面给出的 M(n)WE,其中宏\input
已经以一种几乎不引人注目且简单的方式重新定义。
\documentclass{scrbook}
\let\oldinput=\input
\RenewDocumentCommand{\input}{ o }{
\message{*** DEBUG: (#1)}
\oldinput{#1}
}
\usepackage{tikz}
\begin{document}
Just some random content.
\end{document}
当我尝试加载tikz
包时,编译暂停并显示以下错误消息:
pdflatex mwe
...
(/usr/local/texlive/2023/texmf-dist/tex/latex/pgf/utilities/pgfrcs.sty
*** DEBUG: (-NoValue-)
! LaTeX Error: File `-NoValue-.tex' not found.
Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: tex)
当然,~NoValue~.tex
源于xparse
参数指定。在以前的版本中,我指定了\RenewDocumentCommand{\input}{m}{...}
,但错误消息更加不清楚,并要求文件p.tex
。
此错误与 无关tikz
,我可以使用其他各种包来生成此错误,例如lipsum
。浏览这些相应的包,我找不到\input
没有参数的调用。
因此,有些观点我未能看到和理解:
\input
为什么在那些特定实例中没有传递参数?- 为什么它有时会起作用,例如在文档正文中?
- 我是否做了一些明显错误的事情(除了连接到核心宏)?
- 我该如何尝试进一步调试此问题(但这主要与 1. 再次相关)?
答案1
TeX 按照你的要求执行。根据你的定义,任何指令
\input{file}
将导致
\message{*** DEBUG: (-NoValue-)} \oldinput{-NoValue-} {file}
因为如果没有可选参数,您就会得到这样的结果。
假设我们这样做
\NewDocumentCommand{\foo}{o}{...#1...}
在处理 时\foo
,TeX 会测试后面的标记是否为[
(跳过空格)。如果是,它会确定存在可选参数,因此它会转到匹配]
以捕获参数并用#1
其替换。根据规则,如果[
后面没有 并且参数以 指定,则将使用o
特殊字符串。-NoValue-
#1
你想要一个正常的m
andatory 参数,但这不是向 中添加动作的最佳方式\input
,因为它会破坏其他构造。为什么?因为原始\input
原语有点奇怪,因为它必须应对多个操作系统及其特性。原语期望无支架在其后查找文件名扩展标记,直到找到不可扩展且不是字符的东西(宏扩展后)。因此,LaTeX 重新定义\input
查找括号,如果找不到,LaTeX 会切换到原始基元。由于(不幸的是)包可能使用\input filename
,因此进一步重新定义\input
应该可以解决这个问题。
在引擎的最新实现中,原语\input
实际上会检查后面的括号,但这是我们无法依赖的行为。
作为一般建议,o
论点需要测试代码-NoValue-
:
\IfNoValueTF{#1}{%
do something when the optional argument is not present%
}{%
do something else with #1 when the optional argument is specified%
}
并要小心终点线。
已经有一个内置机制(不过,您需要一个较新版本的 LaTeX)。此机制还处理\input filename
。
\documentclass{scrbook}
\AddToHook{file/before}{\typeout{*** DEBUG: \CurrentFile}}
\usepackage{tikz}
\begin{document}
Just some random content.
\input{knuth}
\end{document}
但是,您可能希望在加载包后延迟添加 DEBUG 信息,因为您会得到很多关于文件输入的无用信息,例如,通过 Ti钾Z。
\documentclass{scrbook}
\usepackage{tikz}
\AddToHook{file/before}{\typeout{*** DEBUG: \CurrentFile}}
\begin{document}
Just some random content.
\input{knuth}
\end{document}
该文件knuth.tex
包含一些文本,对于此类实验很有用。
以下是控制台输出的摘录(Ti 加载的大量文件钾Z 被省略)
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./marc.tex
LaTeX2e <2023-06-01> patch level 1
L3 programming layer <2023-10-10>
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/scrbook.cls
Document Class: scrbook 2023/07/07 v3.41 KOMA-Script document class (book)
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/scrkbase.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/scrbase.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/scrlfile.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/scrlfile-hook.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/scrlogo.sty)))
(/usr/local/texlive/2023/texmf-dist/tex/latex/graphics/keyval.sty)))
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/tocbasic.sty)
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/scrsize11pt.clo)
(/usr/local/texlive/2023/texmf-dist/tex/latex/koma-script/typearea.sty))
(/usr/local/texlive/2023/texmf-dist/tex/latex/pgf/frontendlayer/tikz.sty
[...omissis...]
(/usr/local/texlive/2023/texmf-dist/tex/generic/pgf/frontendlayer/tikz/librarie
s/tikzlibrarytopaths.code.tex)))
*** DEBUG: l3backend-pdftex.def
(/usr/local/texlive/2023/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)
(./marc.aux)
*** DEBUG: supp-pdf.mkii
(/usr/local/texlive/2023/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
[Loading MPS to PDF converter (version 2006.09.02).]
)
*** DEBUG: epstopdf-base.sty
(/usr/local/texlive/2023/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty
*** DEBUG: epstopdf-sys.cfg
(/usr/local/texlive/2023/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg))
*** DEBUG: knuth.tex
(/usr/local/texlive/2023/texmf-dist/tex/context/sample/common/knuth.tex)
[1{/usr/local/texlive/2023/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
(./marc.aux) )</usr/local/texlive/2023/texmf-dist/fonts/type1/public/amsfonts/c
m/cmr10.pfb>
Output written on marc.pdf (1 page, 19830 bytes).
Transcript written on marc.log.