调整 listings 包的标签功能

调整 listings 包的标签功能

我为讲座编制了过去练习的目录(长达数百页),这使得一致的标签有点问题。

我的解决方案是使用形式为 的标签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 小时内无人回复(太可怕了!),我只好亲自去找了。

相关内容