Makeindex,索引中不同类型的引用和排序

Makeindex,索引中不同类型的引用和排序

关于上周提出的如何处理不同类型的索引条目的问题: 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.idxlatex和调用前进行处理外,没有其他简单的方法可以解决这个问题。(如果软件包附带的 perl 脚本检测到多重封装警告,它会执行此操作。)makeindexmakeglossariesglossariesmakeindex

最简单的解决方案是切换到xindy,它通过根据其在已定义属性列表中的位置优先使用格式化命令(封装值)来解决此冲突。您的 MWE 中有两个属性:(当中省略 部分default时使用的默认值)和。这些需要在模块(文件)中定义。例如:|\indexnnxindy.xdy

(define-attributes (( "default" "nn" )))

这使得默认属性具有更高的优先级。或者:

(define-attributes (( "nn" "default" )))

这赋予了nn属性更高的优先级。不幸的是, (与 等包一起使用时texindy通常的调用方法)在模块中定义了“default” ,因此上述两种情况都会导致警告:xindymakeidxlatex-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}defaultnnB1, \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 封装范围(例如),而封装范围元素(例如)。连续封装也是如此(例如,使用和)。这意味着范围最终将显示为而不是。由于命令现在仅封装单个位置,因此定义要简单得多:xindymakeindex\nn{1--3}xindy\nn{1}--\nn{3}\nn{1, 2}makeindex\nn{1}, \nn{2}xindy1n--3nxindy1--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)。

相关内容