简短答案

简短答案

我想知道哪些是本质区别makeindexxindy(或)之间texindy,其含义如下:

  • 哪些事情我们能做而xindy哪些不能做makeindex?反之亦然。
  • 它们每个的主要用途是什么?
  • 它们之间的句法差异样式文件. (.ist對比.xdy

答案1

简短答案

xindy比 灵活得多makeindex。与 不同makeindexxindy支持 UTF8,可以根据不同的语言规则进行排序,并且可以支持欧洲和罗马数字系统之外的枚举系统。 UTF8 支持与 配合使用效果最佳,xindy -I xindy而不是与texindy( xindy -I latex) 配合使用。

长答案

哪些事情我们可以做而哪些事情xindy我们不能做makeindex

xindy 常见问题解答xindy提供了有用的摘要,说明了可以做但 不能做的事情makeindex。以下是该摘要的节选版:

国际化

xindy可以配置为处理具有不同字母集和不同排序规则的多种语言的索引。[makeindex针对英文字母进行硬编码。]

位置类

makeindex能够识别和处理阿拉伯数字、罗马数字和字母表作为索引位置的说明符。这些的简单复合结构也可以处理。xindy提供了一个强大的声明方案,称为 位置类别。[这意味着您可以采用完全不同的编号方案来表示位置(例如,象形文字数字)。]

属性的概念

可以makeindex使用封装器为每个索引条目分配一个标记(通常在索引条目命令中位于竖线符号后面)。例如在规范中

\index{xindy|bold}

封装器是粗体,它在标记阶段封装页码。必须提供额外的 TeX 宏才能为某些标记分配页码。这个概念已被完全放弃,取而代之的xindy是更强大的方案,即属性。属性可用于 (i) 定义几个具有位置的分组和排序规则,我们可以定义 (ii) 文档准备系统的标记标签。

交叉引用

交叉引用是在 中makeindex通过封装机制实现的,该机制仅用于标记目的。在 中已将其完全分离xindy

除了上述情况之外,还有一件事您可以做xindy但不能做,makeindex那就是拥有任意子级别。makeindex您只能使用主级别(级别 0)、第一个子级别和第二个子级别条目。

或相反亦然。

我能想到的唯一优点makeindex是:xindy

  • makeindex应与所有 TeX 安装一起安装。没有安装的 TeX 安装makeindex很可能非常旧。但是,xindy仅包含在 TeX Live 中,因此 MikTeX 用户需要单独安装它。
  • xindy是 Perl 脚本,因此您必须在计算机上安装 Perl 解释器。这对某些 Windows 用户来说是一个障碍。类 Unix 系统往往预装了 Perl。
  • makeindex通常与受限模式配合使用\write18,但上次我尝试使用xindy受限模式调用\write18时,它被禁用了。我预计它最终会被添加到允许的应用程序列表中。(我看不出有什么理由不允许它。)

它们每个的主要用途是什么?

排序和整理。两者都读取包含一组术语及其相关位置(或交叉引用)的文件。这些术语根据指定的字母表(英文字母表makeindex,或所选的字母表)进行排序。xindy)进行排序。术语可能具有应该用于实际排序比较的对应键。然后,将每个术语的多次出现合并为具有排序的单个条目位置列表。位置列表中的连续编号可以压缩为一个数字范围。然后将此信息写入另一个文件,该文件可以由应用程序(例如tex或 )输入latex。(输出标记可以通过样式文件或模块更改,这意味着虽然makeindexxindy经常与 TeX/LaTeX 一起使用,但它们也可以与其他系统一起使用。)

它们的样式文件之间的语法差异。(.istvs .xdy

该格式的语法.ist比该格式简单得多.xdy,但这是因为它具有更强的限制性。

makeindex样式格式 ( .ist)

这只是一份清单⟨说明符⟩ ⟨属性⟩对。说明符分为两组:输入说明符和输出说明符。

输入说明makeindex符指示输入的格式。请考虑以下文档:

\documentclass{article}

\usepackage{makeidx}

\makeindex

\begin{document}

Duck\index{duck|textbf}.
Zebra\index{zebra}\index{stripy|see{zebra}}

\newpage

Aardvark\index{aardvark}
Zebra\index{zebra}
\emph{The Rise and Fall of the Duck Empire}%
\index{Rise and Fall of Duck Empire@\emph{The Rise and Fall of the Duck Empire}}%

\newpage

Zebra\index{zebra}
Duck\index{duck}
Aardvark\index{aardvark}
Mallard\index{duck!mallard}

\printindex

\end{document}

第一次运行 LaTeX 时,将创建一个扩展名为的文件.idx,运行结束时该文件包含:

\indexentry{duck|textbf}{1}
\indexentry{zebra}{1}
\indexentry{stripy|see{zebra}}{1}
\indexentry{aardvark}{2}
\indexentry{zebra}{2}
\indexentry{Rise and Fall of Duck Empire@\emph{The Rise and Fall of the Duck Empire}}{2}
\indexentry{zebra}{3}
\indexentry{duck}{3}
\indexentry{aardvark}{3}
\indexentry{duck!mallard}{3}

这是默认格式,makeindex但可以使用以下文件明确设置.ist

actual '@'
arg_close '}'
arg_open '{'
encap '|'
keyword '\\indexentry'
level '!'

还有一些其他输入说明符。(参见指数编制与处理.) 这些说明符能够makeindex正确解析输入文件。

输出说明符指示makeindex如何格式化输出。如果运行makeindex上述示例,则生成的.ind文件将如下所示:

\begin{theindex}

  \item aardvark, 2, 3

  \indexspace

  \item duck, \textbf{1}, 3
    \subitem mallard, 3

  \indexspace

  \item \emph{The Rise and Fall of the Duck Empire}, 2

  \indexspace

  \item stripy, \see{zebra}{1}

  \indexspace

  \item zebra, 1--3

\end{theindex}

这将使用默认输出说明符,其中包括:

preamble "\\begin{theindex}\n"
postamble "\n\n\\end{theindex}\n"
group_skip "\n\n  \\indexspace\n"
item_0 "\n  \\item "
item_1 "\n     \\subitem "
delim_0 ", "
delim_1 ", "

.ind现在可以通过 LaTeX 输入此文件(通过\printindex)。生成的索引如下所示:

索引图像

如果我想在每个字母组的开头添加标题,我可以创建一个名为的文件,test.ist其中包含:

headings_flag 1
heading_prefix "  \\item\\textbf{"
heading_suffix "}\n  \\indexspace\n"

现在我需要运行makeindex它将-s test.ist把以下内容写入文件.ind

\begin{theindex}
  \item\textbf{A}
  \indexspace

  \item aardvark, 2, 3

  \indexspace
  \item\textbf{D}
  \indexspace

  \item duck, \textbf{1}, 3
    \subitem mallard, 3

  \indexspace
  \item\textbf{R}
  \indexspace

  \item \emph{The Rise and Fall of the Duck Empire}, 2

  \indexspace
  \item\textbf{S}
  \indexspace

  \item stripy, \see{zebra}{1}

  \indexspace
  \item\textbf{Z}
  \indexspace

  \item zebra, 1--3

\end{theindex}

下一次运行 LaTeX 将会生成索引:

索引图像

之所以《鸭子帝国的兴衰》这个条目被列在“R”类而不是“T”类,是因为我把这个条目的排序键设置为“鸭子帝国的兴衰”。

xindy样式格式 ( .xdy)

与 不同makeindexxindy具有模块,可以加载其他模块,因此您可以在现有样式的基础上进行构建。此外,xindy具有--input-markup( -I) 命令行开关,用于指示输入标记。支持的标记设置有三种:latexomegaxindy

xindy -I latex

使用texindy相当于xindy使用和 使用启用解析使用默认输入说明符编写的文件-I latex的模块来调用。因此,例如,上述由 LaTeX 创建的文件可以直接由 处理。如果调用该文件,则将创建一个包含以下内容的文件:xindymakeindex.idxtexindytest.idxtexindy test.idx.ind

\begin{theindex}
  \providecommand*\lettergroupDefault[1]{}
  \providecommand*\lettergroup[1]{%
      \par\textbf{#1}\par
      \nopagebreak
  }

  \lettergroup{A}
  \item aardvark, 2, 3

  \indexspace

  \lettergroup{D}
  \item duck, \textbf{1}, 3
    \subitem mallard, 3

  \indexspace

  \lettergroup{R}
  \item \emph{The Rise and Fall of the Duck Empire}, 2

  \indexspace

  \lettergroup{S}
  \item stripy, \see{zebra}{}

  \indexspace

  \lettergroup{Z}
  \item zebra, 1--3

\end{theindex}

.ind这与创建的文件类似,makeindex只是它用于\lettergroup标记类别标题。如果尚未定义此命令,则将通过文件\providecommand开头的进行定义.ind。如果您想更改标题的格式,只需在\lettergroup之前定义 即可\printindex。这使得它比上面显示的示例更简单,makeindex该示例需要自定义.ist文件才能显示标题。

编写xindy模块相当复杂,在这个(已经很长的)答案中讨论起来太长了,但是xindy常问问题给出了介绍。但是,有许多模块满足了xindy常见需求,特别是语言模块。这些模块位于泰克思/xindy/modules/在哪里泰克思是 TEXMF 树的基础。语言模块位于泰克思/xindy/modules/lang/-L并通过命令行选项进行识别。

假设我的.idx文件现在看起来像这样:

\indexentry{ænder|textbf}{1}
\indexentry{zebra}{1}
\indexentry{aardvark}{2}
\indexentry{zebra}{2}
\indexentry{zebra}{3}
\indexentry{ænder}{3}
\indexentry{aardvark}{3}
\indexentry{ænder!gråand}{3}

makeindex创建以下.ind文件:

\begin{theindex}

  \item aardvark, 2, 3

  \indexspace

  \item zebra, 1--3

  \indexspace

  \item ænder, \textbf{1}, 3
    \subitem gråand, 3

\end{theindex}

这里makeindex将“ænder”放在了“zebra”后面。如果这是您语言的正确位置,乍一看可能还不错,但现在尝试通过创建.ist包含以下内容的文件来添加标题:

headings_flag 1
heading_prefix "  \\item\\textbf{"
heading_suffix "}\n  \\indexspace\n"

采用这种风格运行makeindex会导致:

\begin{theindex}
  \item\textbf{A}
  \indexspace

  \item aardvark, 2, 3

  \indexspace
  \item\textbf{Z}
  \indexspace

  \item zebra, 1--3

  \indexspace
  \item\textbf{Ã}
  \indexspace

  \item Ênder, \textbf{1}, 3
    \subitem gråand, 3

\end{theindex}

UTF8 字符已变得混乱,因为makeindex只抓取了 æ 的第一个八位字节作为标题。这破坏了文件编码。

理论上,如果我想使用,我需要使用开关(在本例中为)texindy指定语言,并使用开关(在本例中为)指定编码。不幸的是,这会导致错误:-L-L danish-C-C utf8

(require "tex/inputenc/utf8.xdy")
ERROR: Could not find file "tex/inputenc/utf8.xdy" !

并且没有.ind生成任何文件。

如果我使用,错误就会消失-M lang/danish/utf8。这会导致文件.ind包含:

\begin{theindex}
  \providecommand*\lettergroupDefault[1]{}
  \providecommand*\lettergroup[1]{%
      \par\textbf{#1}\par
      \nopagebreak
  }

  \lettergroup{A}
  \item aardvark, 2, 3
  \item ænder, \textbf{1}, 3
    \subitem gråand, 3

  \indexspace

  \lettergroup{Z}
  \item zebra, 1--3

\end{theindex}

将“ænder”放入“A”字母组中(这对于丹麦字母表来说是不正确的,请参阅下面的评论)。

.idx文件转换为上面显示的格式有些困难。以下 XeLaTeX 文档运行良好:

\documentclass{article}

\usepackage{fontspec}

\usepackage{makeidx}

\makeindex

\begin{document}

Ænder\index{ænder|textbf}
Zebra\index{zebra}

\newpage

Aardvark\index{aardvark}
Zebra\index{zebra}

\newpage

Zebra\index{zebra}
Ænder\index{ænder}
Aardvark\index{aardvark}
Gråand\index{ænder!gråand}

\printindex

\end{document}

等效的 LaTeX 文档:

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[danish]{babel}

\usepackage{makeidx}

\makeindex

\begin{document}

Ænder\index{ænder|textbf}
Zebra\index{zebra}

\newpage

Aardvark\index{aardvark}
Zebra\index{zebra}

\newpage

Zebra\index{zebra}
Ænder\index{ænder}
Aardvark\index{aardvark}
Gråand\index{ænder!gråand}

\printindex

\end{document}

生成:

\indexentry{\IeC {\ae }nder|textbf}{1}
\indexentry{zebra}{1}
\indexentry{aardvark}{2}
\indexentry{zebra}{2}
\indexentry{zebra}{3}
\indexentry{\IeC {\ae }nder}{3}
\indexentry{aardvark}{3}
\indexentry{\IeC {\ae }nder!gr\IeC {\r a}and}{3}

这让人困惑texindy

xindy -I xindy

通过xindy输入标记,该.idx文件具有以下格式的条目:

(indexentry :tkey (("sort" "term") ) :locref "location" :attr "attribute" )

其中sort,是比较函数在排序时使用的文本,term是条目在文件中的排版方式.indlocation是此条目的关联位置(页码),attribute是关联属性。这是glossaries与 package 选项一起使用时xindy

通过检查使用该包创建的文件,可以说明makeindex和所使用的语法之间的差异。xindyglossaries

考虑以下 LaTeX 文档:

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[danish]{babel}

\usepackage[index,style=indexgroup]{glossaries}

\makeglossaries

\newterm[name={æ}nder]{aender}
\newterm{zebra}
\newterm{aardvark}
\newterm[parent=aender,name=gråand]{graand}

\begin{document}

\Gls[format=textbf]{aender}
\Gls{zebra}

\newpage

\Gls{aardvark}
\Gls{zebra}

\newpage

\Gls{zebra}
\Gls{aender}
\Gls{aardvark}
\Gls{graand}

\printindex

\end{document}

这类似于前面的makeidx示例。默认情况下,本文档假定makeindex将使用。这将创建.idx包含以下内容的文件:

\glossaryentry{{æ}nder?\glossentry{aender}|setentrycounter[]{page}\textbf}{1}
\glossaryentry{zebra?\glossentry{zebra}|setentrycounter[]{page}\glsnumberformat}{1}
\glossaryentry{aardvark?\glossentry{aardvark}|setentrycounter[]{page}\glsnumberformat}{2}
\glossaryentry{zebra?\glossentry{zebra}|setentrycounter[]{page}\glsnumberformat}{2}
\glossaryentry{zebra?\glossentry{zebra}|setentrycounter[]{page}\glsnumberformat}{3}
\glossaryentry{{æ}nder?\glossentry{aender}|setentrycounter[]{page}\glsnumberformat}{3}
\glossaryentry{aardvark?\glossentry{aardvark}|setentrycounter[]{page}\glsnumberformat}{3}
\glossaryentry{{æ}nder?\glossentry{aender}!gråand?\subglossentry{1}{graand}|setentrycounter[]{page}\glsnumberformat}{3}

这使用\glossaryentry而不是\indexentry并且封装字符是?而不是@,因此glossaries创建一个makeindex .ist包含以下内容的文件:

actual '?'
encap '|'
level '!'
quote '"'
keyword "\\glossaryentry"
preamble "\\glossarysection[\\glossarytoctitle]{\\glossarytitle}\\glossarypreamble\n\\begin{theglossary}\\glossaryheader\n"
postamble "\%\n\\end{theglossary}\\glossarypostamble\n"
group_skip "\\glsgroupskip\n"
item_0 "\%\n"
item_1 "\%\n"
item_2 "\%\n"
item_01 "\%\n"
item_x1 "\\relax \\glsresetentrylist\n"
item_12 "\%\n"
item_x2 "\\relax \\glsresetentrylist\n"
delim_0 "\{\\glossaryentrynumbers\{\\relax "
delim_1 "\{\\glossaryentrynumbers\{\\relax "
delim_2 "\{\\glossaryentrynumbers\{\\relax "
delim_t "\}\}"
delim_n "\\delimN "
delim_r "\\delimR "
headings_flag 1
heading_prefix "\\glsgroupheading\{"
heading_suffix "\}\\relax \\glsresetentrylist "
symhead_positive "glssymbols"
numhead_positive "glsnumbers"
page_compositor "."
suffix_2p ""
suffix_3p ""

另一方面,如果xindy您在加载时添加了包选项glossaries

\usepackage[index,xindy]{glossaries}

.idx文件现在如下所示:

(indexentry :tkey (("{æ}nder" "\\glossentry{aender}") ) :locref "{}{1}" :attr "pagetextbf" ) 
(indexentry :tkey (("zebra" "\\glossentry{zebra}") ) :locref "{}{1}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("aardvark" "\\glossentry{aardvark}") ) :locref "{}{2}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("zebra" "\\glossentry{zebra}") ) :locref "{}{2}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("zebra" "\\glossentry{zebra}") ) :locref "{}{3}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("{æ}nder" "\\glossentry{aender}") ) :locref "{}{3}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("aardvark" "\\glossentry{aardvark}") ) :locref "{}{3}" :attr "pageglsnumberformat" ) 
(indexentry :tkey (("{æ}nder" "\\glossentry{aender}") ("gråand" "\\subglossentry{1}{graand}") ) :locref "{}{3}" :attr "pageglsnumberformat" ) 

扩展的拉丁字符(例如 å)没有像前面的makeidx示例那样被扩展,因为默认情况下,它们glossaries会“净化”排序键。(在 æ 周围使用括号的原因在 UTF8 部分中进行了讨论mfirstuc手动的

这次,不是创建附带.ist文件,而是glossaries创建一个xindy .xdy相当大的文件,并且太大了,无法在此重现,而不会超出 StackExchange 答案的最大长度。但是,如果您亲自尝试上述示例,您将能够看到语法差异。

运行 Perl 脚本makeglossaries test(示例文件名为test.tex)相当于运行xindy以下命令:

xindy  -L danish -C utf8 -I xindy -M "test" -t "test.ilg" -o "test.ind" "test.idx"

尽管-L danish -C utf8已使用,但现在不会产生先前的错误,因为texindy不再xindy尝试输入tex/inputenc/utf8.xdy。索引现在如下所示:

斑马 灰色 土豚

再次,切换到 XeLaTeX 可以使文档更简单:

\documentclass{article}

\usepackage{fontspec}
\usepackage{polyglossia}
\setmainlanguage{danish}

\usepackage[index,style=indexgroup,xindy]{glossaries}

\makeglossaries

\newterm{ænder}
\newterm{zebra}
\newterm{aardvark}
\newterm[parent=ænder]{gråand}

\begin{document}

\Gls[format=textbf]{ænder}
\Gls{zebra}

\newpage

\Gls{aardvark}
\Gls{zebra}

\newpage

\Gls{zebra}
\Gls{ænder}
\Gls{aardvark}
\Gls{gråand}

\printindex

\end{document}

相关内容