\bibhyperref
因此,我尝试对软件包中的命令进行一些黑客攻击biblatex
。我想修改此命令,因为在文件的第 552 行中biblatex.def
我们会发现
\DeclareFieldFormat{bibhyperref}{\bibhyperref{#1}}
以我的简单理解,我认为这意味着基本上所有超级引用都由该命令通过一些其他命令(如或)biblatex
处理,然后可以将其扩展为。\bibhyperref
\printfield[bibhyperref]{...}
\printtext[bibhyperref]{...}
\bibhyperref{...}
因此,接下来我尝试找到命令的定义(源代码),\bibhyperref
以便对其进行破解。我搜索了tex
目录,但似乎不存在任何看起来像定义\def\bibhyperref...
或\newcommand\bibhyperref...
等人。
所以我很困惑具体位置(哪个文件的哪一行)这个命令是否已定义?或者我对超级引用工作原理的理解可能biblatex
不正确,我应该找到其他命令来破解它?
另外,当我将来再次需要查找命令的定义时,是否有一个好的策略可以做到这一点?是否存在某种索引或手册来记录这些信息?
答案1
一般来说,搜索\def<commandname>
, \let<commandname>
, \newcommand<commandname>
, \NewDocumentCommand<commandname>
(后两种情况可能带有或不带有花括号<commandname>
)是了解命令的一个良好开始,但 LaTeX 在定义命令的方式上相当灵活,因此不可能给出一个有限的搜索字符串列表来识别所有可能的<commandname>
定义方式。
具体来说\bibhyperref
,Ulrike 已经在评论中给出了正确的提示。该命令仅在上下文中定义biblatex
,并且在这些上下文之外具有不同的名称。这确保了该命令在无意义时无法使用,并避免与其他包发生名称冲突。
有人可能会认为该命令定义在biblatex.sty
(v3.16)的第 11635-11636 行
\blx@regimcs{%
\bibhyperref \bibhyperlink \bibhypertarget \ifhyperref}
粗略地说,\blx@regimcs
确保在上下文中\<commandname>
具有的含义。因此是根据来定义的。\blx@imc@<commandname>
biblatex
bibhyperref
\blx@imc@bibhyperref
\blx@imc@bibhyperref
根据是否hyperref
加载有两种可能的定义(biblatex.sty
(v3.16)的第 11588-11633 行)
% hyperref interface
\appto\blx@mkhyperref{%
\protected\def\blx@imc@bibhyperref{%
\@ifnextchar[%]
{\blx@bibhyperref}
{\blx@bibhyperref[\abx@field@entrykey]}}%
\ifundef\hyper@natanchorstart
{\long\def\blx@bibhyperref[#1]#2{%
\blx@sfsave\hyperlink{cite.\the\c@refsection @#1}{\blx@sfrest
#2%
\blx@sfsave}\blx@sfrest}%
\protected\long\def\blx@imc@bibhyperlink#1#2{%
\blx@sfsave\hyperlink{cite.\the\c@refsection:#1}{\blx@sfrest
#2%
\blx@sfsave}\blx@sfrest}%
\protected\long\def\blx@imc@bibhypertarget#1#2{%
\blx@sfsave\hypertarget{cite.\the\c@refsection:#1}{\blx@sfrest
#2%
\blx@sfsave}\blx@sfrest}}%
{\long\def\blx@bibhyperref[#1]#2{%
\blx@sfsave\hyper@natlinkstart{\the\c@refsection @#1}\blx@sfrest
#2%
\blx@sfsave\hyper@natlinkend\blx@sfrest}%
\protected\long\def\blx@imc@bibhyperlink#1#2{%
\blx@sfsave\hyper@natlinkstart{\the\c@refsection:#1}\blx@sfrest
#2%
\blx@sfsave\hyper@natlinkend\blx@sfrest}%
\protected\long\def\blx@imc@bibhypertarget#1#2{%
\blx@sfsave\hyper@natanchorstart{\the\c@refsection:#1}\blx@sfrest
#2%
\blx@sfsave\hyper@natanchorend\blx@sfrest}}
\let\blx@imc@ifhyperref\@firstoftwo
\def\blx@sf{\spacefactor}%
\def\blx@sfsave{%
\blx@leavevmode
\numgdef\blx@sf{\spacefactor}}%
\def\blx@sfrest{%
\ifhmode\spacefactor\blx@sf\relax\fi
\gdef\blx@sf{\spacefactor}}}
\appto\blx@mknohyperref{%
\protected\def\blx@imc@bibhyperref{\@ifnextchar[\blx@nohyperref\@firstofone}%
\def\blx@nohyperref[#1]#2{#2}%
\let\blx@imc@bibhyperlink\@secondoftwo
\let\blx@imc@bibhypertarget\@secondoftwo
\let\blx@imc@ifhyperref\@secondoftwo}
我同意 Ulrike 的观点,尝试直接操纵这个命令可能不是一个好主意。
\def
我认为这类问题没有灵丹妙药。如果你只寻找、\let
和朋友,大部分情况可能都可以处理\newcommand
。但包总是有可能使用复杂的结构来定义你感兴趣的宏。像latexdef
(在哪里可以找到命令/环境是如何定义的?) 可能会有所帮助,但可能无法捕捉到包定义命令的所有奇怪方式。
如果您知道哪个包定义了您的宏(例如,因为您可以通过文档进行验证),那么您可以将对该宏的搜索范围缩小到属于该包的文件。因此,对于\bibhyperref
,您可以检查biblatex
定义该命令的位置,您可能希望仅在 中开始 grep,tex/latex/biblatex
而不是在 之类的样式目录中tex/latex/biblatex-chicago
。
从那时起,就没有保证的方法了。我通常\<commandname>
先搜索,然后尝试过滤出哪些匹配项是宏的使用,哪些匹配项看起来像是定义。但有时搜索<commandname>
不带前导反斜杠的 也会有所帮助,因为有几种方法可以在定义中不给出反斜杠的情况下定义宏。这也可能出现类似名称的辅助宏,这可能会或可能不会让您知道该在哪里查找。
在整个biblatex
子树中,只有 有三次命中\bibhyperref
。其中两个看起来像是宏的明显用途。因此, 中的第三个\blx@regimcs
是定义的候选。要检查它是否正确,您需要检查 的定义\blx@regimcs
并查看它的作用。从那里您将找到\blx@imc@bibhyperref
。但这可能需要一段时间,如果您对正在处理的包有一些整体经验,这肯定会有所帮助。