xindy 具有任意位置(不是页码):无排序、无范围、超链接

xindy 具有任意位置(不是页码):无排序、无范围、超链接

我正在尝试使用不是页码而是某种节的“位置”来编写索引(也没有使用正确的节命令)。这些位置只是数字,后面可能有一个或两个字母,例如00337b(和00303不同)。

我正在使用 xindy,这对我来说很新,并且我正在努力:

  • 防止对位置编号进行排序:我希望它们按照在文档中出现的顺序出现。
  • 防止“压缩”范围。如果某个东西出现在位置003和中,我想要,004而不是。005003, 004, 005003-005
  • 与 hyperref 完美配合:我希望索引链接到“位置”开始的页面(可能)。

一份示例文档,这是我所得到的:

\documentclass{article}

\usepackage[xindy]{imakeidx}
\usepackage{hyperref}

\makeindex[options=-M foo]

\begin{filecontents}[overwrite,noheader]{foo.xdy}
(define-location-class "type"
                       ("arabic-numbers" :sep "" "alpha") :min-range-length 1000)
\end{filecontents}

\makeatletter

\def\current{}
\newcommand{\type}[1]{\def\current{#1}\textbf{#1}\par}

\renewcommand{\imki@wrindexentrysplit}[3]{%
  \expandafter\protected@write\csname#1@idxfile\endcsname{}%
    {\string\indexentry{#2}{\current}}%
}

\makeatother

\begin{document}

\type{003}

One\index{one}
Two\index{two}
Three\index{three}

\type{024}

Two\index{two}

\clearpage
\type{024b}

One\index{one}

\type{024v}

One\index{one}

\type{024f}

One\index{one}
Two\index{two}
Three\index{three}

\clearpage
\type{100}

Three\index{three}

\clearpage

One\index{one}
Three\index{three}

\clearpage
\type{01}

One\index{one}

\clearpage
\type{24}

One\index{one}
Four\index{four}

\clearpage
\type{25}

Four\index{four}

\clearpage
\type{26}

Four\index{four}

\clearpage
\type{29}

Two\index{two}

\printindex

\end{document}

请注意,four显示为24-26而不是24, 25, 26(尽管 似乎:min-range-length适用于页码)。位置按数字排序,并且包含字母的位置位于末尾。超链接全部损坏。

关于如何接近我的目标有什么提示或想法吗?

答案1

哦好吧...我想我明白了。

  1. alpha表示单个字母,而不是“任意数量的字母”。
  2. “标准”页码仍然定义为位置类,并且默认允许范围。
  3. 不同的位置类别是分开排序的,这就是为什么所有没有字母的位置都出现在有字母的位置之前。

因此,我决定采用另一种方法,编写一个更详细的“位置键”,其中包括:

  • 每个位置都有一个增加的计数器,因此排序将不再需要任何操作。
  • 地点名称
  • 页码,用于超链接。

位置名称有点困难,因为我找不到指定允许使用任意数量的小写字母的方法。在深入研究了 xindy 的源代码后,我发现了未记录的(据我所知)define-enumeration,它实际上用于定义arabic-numbers,然后我将其扩展为允许使用任意数量的字母数字字符。

一旦我搞定了,就只需要定义正确的格式化命令,这样当索引排版时,我只会看到位置名称(超链接到页面)。这个listofitems包非常有用。

作为奖励,我调整了范围格式,以便只打印第一页。位置是正确的,但链接指向该术语实际出现的页面(同一位置内不连续的页面可能是一个问题,但我没有这种情况)。

\documentclass{article}

\usepackage[xindy]{imakeidx}
\usepackage{listofitems}
\usepackage{hyperref}

\makeindex[options=-M foo]

\begin{filecontents}[overwrite,noheader]{foo.xdy}
;; copied from idxstyle.lsp
(defun prefix-match-for-radix-numbers (str radix)
  (let* ((n nil)
         (strlen (length str))
         (len-match (do ((i 0 (1+ i)))
                        ((or (>= i strlen)
                             (not (digit-char-p (char str i) radix)))
                           i)
                      (setq n (+ (* (if n n 0) radix)
                                 (digit-char-p (char str i) radix))))))
    (values (subseq str 0 len-match)
            (subseq str len-match)
            n)))

;; any number of alphanumeric characters
(define-enumeration "alphanum"
                    #'(lambda (str)
                        (prefix-match-for-radix-numbers str 36))
                    "0123456789abcdefghijklmnopqrstuvwxyz")

;; prefix indicates sort order, letter "a" should be removed
(define-location-class "loc-and-page"
                       ("arabic-numbers" :sep ":" "alphanum" :sep ":" "arabic-numbers") :min-range-length 1)

;; for page ranges, use only the first one
(markup-range :sep "" :ignore-end)

;; use a custom command for location formatting
(markup-locref :attr "hyperpage" :open "\locfmt{" :close "}")
\end{filecontents}

\makeatletter

\def\locidx{}
\newcounter{type}
\setcounter{type}{0}
\newcommand{\type}[1]{%
  % increase the counter
  \stepcounter{type}%
  % define the "index key"
  \def\locidx{\arabic{type}:#1}%
  % typeset the text
  \textbf{#1}\par}

% write the "index key" and the page number to the index
\renewcommand{\imki@wrindexentrysplit}[3]{%
  \expandafter\protected@write\csname#1@idxfile\endcsname{}%
    {\string\indexentry{#2}{\locidx:\thepage}}%
}

% define the formatting command
\newcommand{\locfmt}[1]{%
  % split the location at the colons
  \setsepchar{:}\readlist\parts{#1}%
  % 1 is a counter and can be ignored
  % 2 is the actual location
  % 3 is the page number
  \hyperlink{page.\parts[3]}{\parts[2]}%
}

\makeatother

\begin{document}

\type{003}

One\index{one}
Two\index{two}
Three\index{three}

\type{024}

Two\index{two}

\clearpage
\type{024b}

One\index{one}

\type{024v}

One\index{one}

\type{024f}

One\index{one}
Two\index{two}
Three\index{three}

\clearpage
\type{100}

Three\index{three}

\clearpage

One\index{one}
Three\index{three}

\clearpage
\type{01}

One\index{one}

\clearpage
\type{24}

One\index{one}
Four\index{four}

\clearpage
\type{25}

Four\index{four}

\clearpage
\type{26}

Four\index{four}

\clearpage
\type{29vf}

Two\index{two}

\printindex

\end{document}

相关内容