关于上周提出的如何处理不同类型的索引条目的问题: Makeindex 和不同类型的引用
我想知道是否有可能提高赌注。我再次提到了 Makeindex 的部分:
在某些索引中,某些页码具有特殊格式 - 例如,斜体页码可能表示主要参考文献,页码后的 n 可能表示该项目出现在该页的脚注中。
只是如果该页面上没有主要参考,我只想显示注释参考。如果同一页面上有主要参考和注释参考,则使用索引的每个人都会对主要参考感到满意,因此无需重复。
输出(使用上周的 egregs 解决方案):
\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{makeidx}
\usepackage{xparse}
\makeindex
\ExplSyntaxOn
\NewDocumentCommand{\nn}{m}
{
% split the argument at commas
\seq_set_split:Nnn \l_martin_nn_in_seq { , } { #1 }
% add a trailing n to each item
\seq_set_map:NNn \l_martin_nn_out_seq \l_martin_nn_in_seq { ##1n }
% output the items separated, if necessary, by "comma space"
\seq_use:Nn \l_martin_nn_out_seq {,~}
}
\seq_new:N \l_martin_nn_in_seq
\seq_new:N \l_martin_nn_out_seq
\ExplSyntaxOff
\begin{document}
bla\index{Lahm} blablab\index{Lahm|nn}
bla\index{A} bla\index{A|nn}
bla\index{B} bla\index{B|nn}
\newpage
bla\index{Lahm|nn} blablab
bla\index{B|nn}
\newpage
bla\index{B|nn}
\printindex
\end{document}
不应该是:
1,1n
B 1–3n
拉姆 1,1n,2n
尽管:
答 1
B 1–3n
拉姆 1, 2n
那可能吗?
答案1
这里的问题是makeindex
无法处理同一位置的冲突封装(位置格式化命令)。例如,页面(位置)1 有一个空的封装(来自\index{Lahm}
)和封装nn
(来自\index{Lahm|nn}
)。由于makeindex
不知道如何解决这个问题,它将1
和都添加\nn{1}
到 的位置列表中,Lahm
并在抄本中发出警告。假设文件名为test.tex
,则抄本文件为test.ilg
并且包含三个这样的警告:
Generating output file test.ind....
## Warning (input = test.idx, line = 4; output = test.ind, line = 3):
-- Conflicting entries: multiple encaps for the same page under same key.
## Warning (input = test.idx, line = 6; output = test.ind, line = 7):
-- Conflicting entries: multiple encaps for the same page under same key.
## Warning (input = test.idx, line = 2; output = test.ind, line = 11):
-- Conflicting entries: multiple encaps for the same page under same key.
done (13 lines written, 3 warnings).
makeindex
除了使用某种形式的脚本在调用test.idx
后latex
和调用前进行处理外,没有其他简单的方法可以解决这个问题。(如果软件包附带的 perl 脚本检测到多重封装警告,它会执行此操作。)makeindex
makeglossaries
glossaries
makeindex
最简单的解决方案是切换到xindy
,它通过根据其在已定义属性列表中的位置优先使用格式化命令(封装值)来解决此冲突。您的 MWE 中有两个属性:(当中省略 部分default
时使用的默认值)和。这些需要在模块(文件)中定义。例如:|
\index
nn
xindy
.xdy
(define-attributes (( "default" "nn" )))
这使得默认属性具有更高的优先级。或者:
(define-attributes (( "nn" "default" )))
这赋予了nn
属性更高的优先级。不幸的是, (与 等包一起使用时texindy
通常的调用方法)在模块中定义了“default” ,因此上述两种情况都会导致警告:xindy
makeidx
latex-loc-fmts.xdy
Loading module "latex-loc-fmts.xdy"...
WARNING: ignoring redefinition of attribute "default" in
(DEFINE-ATTRIBUTES (("default" "textbf" "textit" "hyperpage")))
但是,如果我们确保自定义.xdy
模块首先加载,那么将确保自定义属性列表优先。
B
这里还有另一个问题。就您示例中的 而言,当属性覆盖 属性时\index{B|nn}
,条目将被丢弃,取而代之的是第 1 页上的条目。这意味着 的位置列表最终将为(由于 已被丢弃,因此无法与和形成范围)。这可以通过合并规则来解决:\index{B}
default
nn
B
1, \nn{2}, \nn{3}
\nn{1}
\nn{2}
\nn{3}
(merge-to "default" "nn" :drop)
您还需要说明xindy
如何处理该nn
属性:
(markup-locref :open "\nn{" :close "}" :attr "nn")
这只是用 封装了位置\nn
(这是makeindex
自动执行的)。默认属性不需要任何特殊格式。
最后,需要定义位置列表分隔符。例如,要大致复制makeindex
:
(markup-locref-list :sep ", ")
(markup-range :sep "--")
但是,在具有封装值的情况下,makeindex
和范围之间存在差异。使用,您的 MWE 封装范围(例如),而封装范围元素(例如)。连续封装也是如此(例如,使用和)。这意味着范围最终将显示为而不是。由于命令现在仅封装单个位置,因此定义要简单得多:xindy
makeindex
\nn{1--3}
xindy
\nn{1}--\nn{3}
\nn{1, 2}
makeindex
\nn{1}, \nn{2}
xindy
1n--3n
xindy
1--3n
\nn
\newcommand{\nn}[1]{#1n}
但范围形成需要调整以防止n
前缀应用于起始位置。
解决这个问题的一种方法是修改范围分隔符,以便--
使用格式化命令来分隔范围,而不是简单地使用\range{
开始}{
结尾}
:
(markup-range :open "\range{" :sep "}{" :close "}")
这将更改为\nn{1}--\nn{3}
。\range{\nn{1}}{\nn{3}}
现在\range
可以定义为\nn
在起始值范围内进行本地更改:
\newcommand{\range}[2]{{\def\nn##1{##1}#1}--#2}
以下是完整的 MWE:
\documentclass{scrartcl}
\usepackage{filecontents}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{makeidx}
\begin{filecontents*}{\jobname.xdy}
; list of allowed attributes
(define-attributes (( "default" "nn" )))
; define format to use for locations
(markup-locref :open "\nn{" :close "}" :attr "nn")
; location list separators
(markup-locref-list :sep ", ")
(markup-range :open "\range{" :sep "}{" :close "}")
(merge-to "default" "nn" :drop)
\end{filecontents*}
\makeindex
\newcommand{\nn}[1]{#1n}
\newcommand{\range}[2]{{\def\nn##1{##1}#1}--#2}
\begin{document}
bla\index{Lahm} blablab\index{Lahm|nn}
bla\index{A} bla\index{A|nn}
bla\index{B} bla\index{B|nn}
\newpage
bla\index{Lahm|nn} blablab
bla\index{B|nn}
\newpage
bla\index{B|nn}
\printindex
\end{document}
假设调用此文件test.tex
,则构建过程为:
pdflatex test
xindy -M test -M texindy -C utf8 -L english -t test.ilg test.idx
pdflatex test
或者(因为您正在使用ngerman
):
pdflatex test
xindy -M test -M texindy -C din5007-utf8 -L german -t test.ilg test.idx
pdflatex test
请注意,开关的顺序-M
很重要。这可确保 中的属性列表test.xdy
位于模块中的属性列表之前texindy
。(但是,这仅在您需要更改模块定义的属性的优先级时才重要texindy
。)
指数
A
A,1
乙
B、1–3n
大号
拉姆,1,2n
您可以通过将以下内容添加到文档来删除字母组标题:
\newcommand*\lettergroup[1]{}
如果您需要更多封装,您只需将它们添加到定义的属性列表中,以便ii
从您的评论中添加:
(define-attributes (( "default" "nn" "ii")))
(这会使默认和nn
封装覆盖ii
。)您甚至不需要定义\ii
(尽管如果您愿意,您仍然可以定义)。例如:
(markup-locref :open "\emph{" :close "}" :attr "ii")
(直接使用\emph
)或
(markup-locref :open "\ii{" :close "}" :attr "ii")
(使用\ii
)。