文档包中的 CodelineIndex:对页面和代码行索引条目进行排序

文档包中的 CodelineIndex:对页面和代码行索引条目进行排序

\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:第一个条目来自第\DescribeMacro2 页,而其他三个是指文档后面的代码行号。

\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}

相关内容