我为讲座编制了过去练习的目录(长达数百页),这使得一致的标签有点问题。
我的解决方案是使用形式为 的标签prb:problemname:locallabel
,其中locallabel
是形式为eq:ODE
或 的东西fig:convergence
。为了能够在实践中使用它(而不必每次都输入巨大的标签),我想出了一个生成本地函数的函数来处理这个问题(这已经是一年前的事了,我当然得到了 StackExchange 的帮助,但不记得现在应该参考的所有问题了——抱歉):
\AtBeginDocument{% hyperref changes the commands \AtBeginDocument, so this must come afterwards
\let\prblabel\label % define commands so that \prb... can be continually overwritten
\let\prbref\ref
\let\prbeqref\eqref
\let\prbautoref\autoref
\newcommand\locallabels[1]{%
\renewcommand\prblabel[1]{\label{#1:##1}}%
\renewcommand\prbref[1]{\ref{#1:##1}}%
\renewcommand\prbeqref[1]{\eqref{#1:##1}}%
\renewcommand\prbautoref[1]{\autoref{#1:##1}}%
}}
在问题开始时,它被称为。只要所有标记/引用命令都在其-version\locallabels{prb:problemname}
中使用,问题中的所有标签都可以像文件独立一样使用。prb
我无法理解的是,这种行为延伸到了listings
-environment ( \usepackage{listings}
) 中,它提供了自己的标签功能。因此,这些必须像这样调用
\lstinputlisting[label={prb:problemname:code:sample}]{matlab/sample.m}
如果在这个框架中编写新示例的人忘记正确使用它,或者甚至只是在标签的第一部分出现拼写错误(\prbref{code:sample}
当然,一旦正确创建标签,就会引用作品),这会增加另一个潜在错误来源。
我的问题是如何扩展我的\locallabels
命令,以便它也能处理listings
包,即我可以调用
\lstinputlisting[label={code:sample}]{matlab/sample.m}
而不是上面的。
我尝试过\label
直接更改 -command,但结果很奇怪。如果可行的解决方案是这样的,我必须添加进一步的限制(为了示例之间的交叉引用),即仍然必须能够调用例如\eqref{prb:otherproblemname:eq:PDE}
。
答案1
我仔细研究了一下listings.sty
,得出了以下解决方案。请注意,我是通过“bull-in-the-chinashop”方法发现这个问题的,如果有人知道他在做什么,可以检查/改进这个问题,我将不胜感激。
唯一的添加(除了处理之外@
)是倒数第三行。
\makeatletter
\AtBeginDocument{% hyperref changes the commands \AtBeginDocument, so this must come afterwards
\let\prblabel\label % define commands so that \prb... can be continually overwritten
\let\prbref\ref
\let\prbeqref\eqref
\let\prbautoref\autoref
\newcommand\locallabels[1]{%
\renewcommand\prblabel[1]{\label{#1:##1}}%
\renewcommand\prbref[1]{\ref{#1:##1}}%
\renewcommand\prbeqref[1]{\eqref{#1:##1}}%
\renewcommand\prbautoref[1]{\autoref{#1:##1}}%
\lst@Key{label}\relax{\def\lst@label{#1:##1}} %
}}
\makeatother
我可能应该补充一点,类似于其他命令的构造(使用\let\oldlst@label\lst@label
然后重新定义\lst@label
)不起作用,至少在我尝试过的变体中是这样。
此外,更改是永久性的(这并不困扰我,因为整个 pdf 由问题组成,每个问题都定义了其本地标签) - 但当然可以使用以下命令恢复正常
\lst@Key{label}\relax{\def\lst@label{#1}}
为了确保万无一失,我觉得我应该重申一下我无法解释为什么这是有效的- 需要您自担风险使用它。
附言:在 StackExchange 上发布问题所产生的心理影响非常有趣。我很高兴在一年中的大部分时间里都没有这个解决方案,但在我发布它之后24 小时内无人回复(太可怕了!),我只好亲自去找了。