【LaTeX Tips】如何确定某个宏定义的位置

我们在排错的时候,经常希望知道出错的宏是在哪里定义的,然后通过比对定义和现有情况判断错误原因。

LeoLiu 在 TeX.SX 给出了一个利用 filehook 宏包实现的方法,效果拔群!当然,方法有些讨巧。

代码:

demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
\documentclass{article}
\usepackage{filehook,currfile}
\newwrite\finder
\immediate\openout\finder=\jobname.fnd

\def\searchmacro#1{
\AtBeginOfFiles{\ifdefined#1
\expandafter\def\csname \currfilename:found\endcsname{}%
\fi}
\AtEndOfFiles{\ifdefined#1
\unless\ifcsname \currfilename:found\endcsname
\immediate\write\finder{found in '\currfilename'}%
\fi\fi}}

\searchmacro\url

\usepackage{hyperref}
\begin{document}
dummy
\end{document}

编译后,在 \jobname.fnd 里我们能找到

found in 'url.sty'
found in 'hyperref.sty'

也就是说,\url 是在 url.sty 里定义的,而 url.styhyperref.sty 调用。


We would be glad to know where a certain macro is defined, when we are debugging. LeoLiu provided a method by using the package filehook, on the website TeX.SX. It’s really great!

The code is somewhat tricky:

demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
\documentclass{article}
\usepackage{filehook,currfile}
\newwrite\finder
\immediate\openout\finder=\jobname.fnd

\def\searchmacro#1{
\AtBeginOfFiles{\ifdefined#1
\expandafter\def\csname \currfilename:found\endcsname{}%
\fi}
\AtEndOfFiles{\ifdefined#1
\unless\ifcsname \currfilename:found\endcsname
\immediate\write\finder{found in '\currfilename'}%
\fi\fi}}

\searchmacro\url

\usepackage{hyperref}
\begin{document}
dummy
\end{document}

After compiling, we will get

found in 'url.sty'
found in 'hyperref.sty'

in \jobname.fnd. That is to say, \url is defined in url.sty, which is inputed by hyperref.sty.


您的鼓励是我写作最大的动力

俗话说,投资效率是最好的投资。 如果您感觉我的文章质量不错,读后收获很大,预计能为您提高 10% 的工作效率,不妨小额捐助我一下,让我有动力继续写出更多好文章。


撰写评论

写了这么多年博客,收到的优秀评论少之又少。在这个属于 SNS 的时代也并不缺少向作者反馈的渠道。因此,如果你希望撰写评论,请发邮件至我的邮箱并注明文章标题,我会挑选对读者有价值的评论附加到文章末尾。