\foo
在以下使用该包的宏的示例“文档”中doc
,索引条目的\foo
顺序不自然。如何避免这种情况?
\documentclass{article}
\usepackage{doc}
\usepackage{lipsum}
\CodelineIndex
\begin{document}
\lipsum[1-10]
\DescribeMacro\foo
\lipsum
\begin{macrocode}
first line of code using \foo
second line of code using \foo
third line of code using \foo
% \end{macrocode}
\PrintIndex
\end{document}
正如从的文档中所预期的那样\CodelineIndex
,我们在文件中得到了四个索引条目.idx
:第一个条目来自第\DescribeMacro
2 页,而其他三个是指文档后面的代码行号。
\indexentry{foo=\verb!*+\foo+|usage}{2}
\indexentry{foo=\verb!*+\foo+}{1}
\indexentry{foo=\verb!*+\foo+}{2}
\indexentry{foo=\verb!*+\foo+}{3}
运行结果makeindex -s gind.ist test.idx
为以下ind
文件
\begin{theindex}
\makeatletter\scan@allowedfalse
{\bfseries\hfil F\hfil}\nopagebreak
\item \verb*+\foo+\pfill 1, 2, \usage{2}, 3
\end{theindex}
其中可以看到页面引用\usage{2}
位于代码行引用的中间。相关地,makeindex
日志文件包含有关与代码行 2.ilg
之间冲突的警告。\usage{2}
## Warning (input = test.idx, line = 1; output = test.ind, line = 6):
-- Conflicting entries: multiple encaps for the same page under same key.
当然,doc
将代码行号和页码以相同的方式传递给makeindex
,因此makeindex
无法区分它们并对其进行良好的排序。我看到了两种不好看的解决方法,但我希望有更好的方法:
将所有代码行号移位 1000000 后再传递给
makeindex
,排版时再移回在环境中重新定义
\item
(或\pfill
?)theindex
来解析页面和代码行列表并在 TeX 端重新排序
答案1
以下代码似乎可以解决问题。 makeindex
有对 ABC 等形式的复合页码进行排序的规则,其中 A、B、C 可以是阿拉伯数字、罗马数字或拉丁字母。我决定在代码行前加上前缀A-
(参见A-\number\c@CodelineNo
下面的代码),以便它们可以单独排序makeindex
(事实证明,是在页面引用之后排序)。然后需要更多代码来避免排版A-
:想法是\codeline@typeset
向每个代码行索引条目添加一个封装,同时保留原始封装。
运行pdflatex test ; makeindex -s gind.ist test ; pdflatex test ; pdflatex test
以下文件会产生一个索引条目,\foo
其内容\emph{3}, 1--3, \underline{4}, 7--9
为,对应于对第 3 页的引用、对第 1-3 行的引用范围、对代码第 4 行(对应于环境macro
)的“主要”引用以及另一行范围。我还为加载了的情况提供了更简单的代码hypdoc
;但是找不到代码行范围。
\documentclass{article}
\usepackage{doc}
\usepackage{lipsum}
\makeatletter
\@ifpackageloaded{hypdoc}
{
\def\codeline@wrindex#1{%
\if@filesw
\immediate\write\@indexfile
{\string\indexentry{#1}{A-\number\c@CodelineNo}}\fi
}
\def\hdclindex#1#2#3{%
\csname\ifx\\#2\\relax\else#2\fi\endcsname{%
\hyperlink{HD.#1}{\codeline@removeA #3\@gobble A-}%
\HD@savedest@add{#1}%
}%
}
}
{
\def\codeline@wrindex#1{%
\codeline@wrindex@tweak\empty#1\encapchar\encapchar\@nil
}
\def\codeline@wrindex@tweak #1\encapchar#2\encapchar#3\@nil{%
\codeline@wrindex@do{#1\encapchar codeline@typeset{#2}}%
}
\def\codeline@wrindex@do#1{%
\if@filesw
\immediate\write\@indexfile
{\string\indexentry{#1}{A-\number\c@CodelineNo}}\fi
}
\def\codeline@typeset#1#2{%
\csname\ifx\\#1\\relax\else #1\fi\endcsname
{\codeline@removeA #2\@gobble A-}%
}
}
\def\codeline@removeA#1A-{#1\codeline@removeA}
\makeatother
\CodelineIndex
\begin{document}
Early on
\begin{macrocode}
first line of code using \foo
second line of code using \foo
third line of code using \foo
% \end{macrocode}
\lipsum[1-10]
\DescribeMacro\foo
\lipsum
\begin{macro}{\foo}
\begin{macrocode}
first line
second line
using \foo not index because we're inside begin{macro}{\foo}...
% \end{macrocode}
\end{macro}
Later on
\begin{macrocode}
first line of code using \foo
second line of code using \foo
third line of code using \foo
% \end{macrocode}
\PrintIndex
\end{document}