通过 pdflatex 进行纯文本索引

通过 pdflatex 进行纯文本索引

我想获得索引的纯文本版本,因此认为以某种方式从现有包中提取它可能更容易。下面的 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

相关内容