我正在尝试使用不是页码而是某种节的“位置”来编写索引(也没有使用正确的节命令)。这些位置只是数字,后面可能有一个或两个字母,例如003
或37b
(和003
和03
不同)。
我正在使用 xindy,这对我来说很新,并且我正在努力:
- 防止对位置编号进行排序:我希望它们按照在文档中出现的顺序出现。
- 防止“压缩”范围。如果某个东西出现在位置
003
和中,我想要,004
而不是。005
003, 004, 005
003-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
哦好吧...我想我明白了。
alpha
表示单个字母,而不是“任意数量的字母”。- “标准”页码仍然定义为位置类,并且默认允许范围。
- 不同的位置类别是分开排序的,这就是为什么所有没有字母的位置都出现在有字母的位置之前。
因此,我决定采用另一种方法,编写一个更详细的“位置键”,其中包括:
- 每个位置都有一个增加的计数器,因此排序将不再需要任何操作。
- 地点名称
- 页码,用于超链接。
位置名称有点困难,因为我找不到指定允许使用任意数量的小写字母的方法。在深入研究了 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}