我想获得索引的纯文本版本,因此认为以某种方式从现有包中提取它可能更容易。下面的 MWE 产生:
我想要的是一个包含以下内容的文本文件:
Fiction:
Star Trek,
Jedi:
Star Wars,
Science:
Star Trek,
Science Fiction:
Star Trek,
Star Wars,
Spock:
Star Trek,
笔记:
- 我有许多文件,每个文件都会以类似以下方式生成临时文件。我想对所有临时文件进行后处理并获得单个组合索引。
- 根本不关心页码。
- 我考虑编写一个脚本来
greps
包含适当宏的文件,但我认为可能有更优雅的方法,要么使用现有的\index
功能,要么使用其他技术。 - 不要拘泥于输出的语法。任何可以轻松解析的内容都可以。
- 我不知道为什么我会在每个条目的开头出现一个方括号,但当其他人运行类似代码时显然不会出现。
代码:
\documentclass{article}
\usepackage{lipsum}
\usepackage{imakeidx}
\makeindex[columns=2]
\newcommand*{\Index}[2]{%
\newpage\lipsum[1]% just for this MWE
\index{#2!#1}%
}%
\begin{document}
\Index{Star Trek}{Spock}
\Index{Star Trek}{Science}
\Index{Star Trek}{Science Fiction}
\Index{Star Wars}{Jedi}
\Index{Star Trek}{Fiction}
\Index{Star Wars}{Science Fiction}
\printindex
\end{document}
答案1
1. 合并未排序的索引文件
您的示例生成一个未分类的.idx
文件:
\indexentry{Spock!Star Trek}{1}
\indexentry{Science!Star Trek}{2}
\indexentry{Science Fiction!Star Trek}{3}
\indexentry{Jedi!Star Wars}{4}
\indexentry{Fiction!Star Trek}{5}
\indexentry{Science Fiction!Star Wars}{6}
因为您想忽略页码,.idx
可以通过简单连接文件来合并多个文件,例如 Linux/bash:
$ rm all.idx
$ cat *.idx >all.idx
或者在 Windows 的命令窗口中:
> del all.idx
> type *.idx >all.idx
结果我们得到一个all.idx
包含所有未排序的索引条目的文件。
2. 运行 makeindex
由于 makeindex 总是会写入页码,因此必须将其过滤掉。以下 makeindex 样式文件 `plain.ist 将项目名称和页码包装在 TeX 命令中,以便在后续的 TeX 运行中格式化或忽略它们:
preamble "\\catcode`\{=1
\\catcode`\}=2
\\catcode`\#=6
\\expandafter\\ifx\\csname newwrite\\endcsname\\relax
\\chardef\\OUT=10\\relax
\\else
\\csname newwrite\\endcsname\\OUT
\\fi
\\immediate\\openout\\OUT=\\jobname.txt\\relax
\\def\\outaux#1{\\immediate\\write\\OUT{#1}}
\\def\\out#1{\\let\\out\\outaux}
\\def\\gobble#1{}
\\def\\space{ }
\\def\\spaces{\\space\\space\\space\\space}
"
postamble "\n\\immediate\\closeout\\OUT
\\csname @@end\\endcsname\\end\n"
setpage_prefix "\n\\gobble{"
setpage_suffix "}\n"
group_skip ""
headings_flag 0
item_0 "\n\\out{}\\out{"
item_1 "\n\\out{\\spaces "
item_2 "\n\\out{\\spaces\\spaces "
item_01 "\n\\out{\\spaces "
item_x1 ":}\n\\out{\\spaces "
item_x2 "}\n\\out{\\spaces\\spaces "
delim_0 ":}\\gobble{"
delim_1 "}\\gobble{"
delim_2 "}\\gobble{"
delim_t "}"
line_max 1000
使用指定的样式文件运行 makeindex:
makeindex -s plain.ist all.idx
结果为文件all.ind
:
\catcode`{=1
\catcode`}=2
\catcode`#=6
\expandafter\ifx\csname newwrite\endcsname\relax
\chardef\OUT=10\relax
\else
\csname newwrite\endcsname\OUT
\fi
\immediate\openout\OUT=\jobname.txt\relax
\def\outaux#1{\immediate\write\OUT{#1}}
\def\out#1{\let\out\outaux}
\def\gobble#1{}
\def\space{ }
\def\spaces{\space\space\space\space}
\out{}\out{Fiction:}
\out{\spaces Star Trek}\gobble{5}
\out{}\out{Jedi:}
\out{\spaces Star Wars}\gobble{4}
\out{}\out{Science:}
\out{\spaces Star Trek}\gobble{2}
\out{}\out{Science Fiction:}
\out{\spaces Star Trek}\gobble{3}
\out{\spaces Star Wars}\gobble{6}
\out{}\out{Spock:}
\out{\spaces Star Trek}\gobble{1}
\immediate\closeout\OUT
\csname @@end\endcsname\end
3.运行 TeX
生成文件的前言和后记的某些行可能看起来有点吓人,它们只是确保该文件可以被不同的 TeX 格式(纯 TeX、LaTeX)甚至 ini-TeX 处理。
该代码打开一个文件
\\jobname.txt
并使用宏将行写入该文件\out
。只有 ini-TeX 才需要 catcode 设置。
\out
重新定义via的技巧\outaux
有助于忽略第一个项目的第一个空行。
现在我们可以运行 TeX:
tex all.ind
4. 结果
结果为文件all.txt
:
Fiction:
Star Trek
Jedi:
Star Wars
Science:
Star Trek
Science Fiction:
Star Trek
Star Wars
Spock:
Star Trek