
Я создаю несколько глоссированных лингвистических текстов на языке коренных американцев. Предложения помечены как, например, (2.3) — что означает «текст 2, предложение 3» — и я хотел бы, чтобы индекс отслеживал эти номера, а не номера страниц. В терминах рисунка ниже, я хотел бы:
Братвурст, (2.1)
Квашеная капуста, (2.2)
в отличие от того, что показано (колбаски, 2; квашеная капуста, 2).
Как мне этого добиться?
Я использую версию expex для примеров чисел. Это слишком длинно, чтобы включить сюда, но я могу отправить это по электронной почте всем заинтересованным лицам.
*Пояснение. Я знаю, как маркировать примеры (помещая eg, <label>
после \ex
) и как вызывать метки в более поздней точке ( \getref{label}
). Однако этот вопрос не о маркировке примеров: я не хочу вручную связыватькапустаскажем, \getref{Sauerkraut}
, \getref{Kohl}
, \getref{Wirsing}
. Я хочу объединить усилия makeindex
, чтобы создать индекс, в котором вместо номеров страниц перечислены примеры номеров.
\documentclass{report}
\usepackage{expex-x2}
\usepackage{expexchapno}
\lingset{aboveexskip=0pt,glspace=1em plus .5em minus.2em,
glrightskip=0pt plus 8em,aboveglftskip=0pt,glneveryline={\it},
glstyle=nlevel,everygl={\hangindent=1.2em \hangafter=1},
exnotype=chapter.arabic}
\usepackage{makeidx}
\makeindex
\begin{document}
\gathertags
\chapter{First chapter}
\chapter{Second chapter}
\ex Bratwurst --- this example is followed by \verb"\index{Bratwurst}"
\xe \index{Bratwurst}
\ex Sauerkraut --- this example is followed by
\verb"\index{Sauerkraut}" \xe \index{Sauerkraut}
\printindex
\end{document}
решение1
Более длинный пост
Позвольте мне поделиться с вами своими выводами. Я разделил свой ответ на три части: без движения, с односторонним движением и с двусторонним движением, каждая часть приводит к созданию собственного компилируемого файла TeX.
я использовалСиндипотому чтоMakeIndexдовольно ограничен для неанглийских языков. С другой стороны, я использую довольно старыйmakeidx
пакет, но я бы рекомендовал использоватьimakeidx
пакет, потому что мы могли бы сохранить один слот записи ввода-вывода в последней части. Я хотел сравнить методы, я использовал этот способ.
Я использую lualatex
для обработки файлов TeX, но latex
можно использовать любой другой популярный движок.
Никакого транспорта: замечания по
mal-expex-1.tex
делу
Как уже было указано на нем, мы можем переопределить, \@wrindex
поскольку это ключевая часть, вызываемая командой \index
. Мы можем сохранить информацию напрямую, вызвав \ep@rawexnoprint
, см. строку 19 в первом файле. Это командаexpex
пакет используется для хранения информации.
Следующая проблема — как уведомить процессор индекса о расположении числа точка номер. Xindy использует для этой цели класс расположения, он использует несколько из них, и мы можем создать новый. Это можно сделать, добавив, что define-location-class
мы определяем сопутствующее markup-locref
для этого нового класса, в дополнение к этому мы добавляем скобки. Последним шагом будет определение порядка новых классов расположения, с вашего разрешения, я покажу вам позже, как это можно сделать.
Мы бегаем:
lualatex mal-expex-1.tex
xindy -M texindy -M expex-1 -L general -C utf8 mal-expex-1.idx
lualatex mal-expex-1.tex
Содержимое файла mal-expex-1.idx
следующее:
\indexentry{Bratwurst}{2.1}
\indexentry{Sauerkraut}{2.2}
\indexentry{Striz}{2.3}
\indexentry{Oldman}{2.4}
\indexentry{Sauerkraut}{2.5}
Прилагаю код TeX и предварительный просмотр трех обрезанных страниц. Как мы видим на последней странице, это запрошенная форма, ноХьюстон у нас проблема!Как только нам понадобится кликабельная версия нашего документа, перекрестные ссылки индекса перестанут работать.
% run: *latex mal-expex-1.tex
\documentclass{report}
\pagestyle{empty}
\usepackage{expex}
\lingset{aboveexskip=0pt,glspace=1em plus .5em minus.2em,
glrightskip=0pt plus 8em,aboveglftskip=0pt,glneveryline={\it},
glstyle=nlevel,everygl={\hangindent=1.2em \hangafter=1},
exnotype=chapter.arabic}
\usepackage{makeidx}
\makeindex
\usepackage{filecontents}
\begin{filecontents*}{expex-1.xdy}
;; expex-1.xdy
(define-location-class "expexnumber" ("arabic-numbers" :sep "." "arabic-numbers"))
(markup-locref :open "(" :close ")" :class "expexnumber")
\end{filecontents*}
\makeatletter
\def\@wrindex#1{%
\protected@write\@indexfile{}%
{\string\indexentry{#1}{\ep@rawexnoprint}}%
\endgroup
\@esphack#1%
}%End of \def\@wrindex...
\makeatother
\begin{document}
%\gathertags
\chapter{First chapter}
Some initial text.
\chapter{Second chapter}
The first approach.
\ex Bratwurst --- this example is followed by \index{Bratwurst} \xe
\ex Sauerkraut --- this example is followed by \index{Sauerkraut} \xe
\ex By \index{Striz} \xe
\ex By \index{Oldman} \xe
\ex Again \index{Sauerkraut} \xe
%\begingroup
%\def\thispagestyle#1{}%
\printindex
%\endgroup
\end{document}
Одностороннее движение: замечания по
mal-expex-2.tex
делу
Ну, я уже открыл этот ящик Пандоры, позвольте мне рассказать вам, как мы можем спасти наши души. Эта главная проблема заставляет меня загрузитьhyperref
упаковать и изучить наши дальнейшие возможности.
Идея заключалась в использовании обычных перекрестных ссылок, известных нам по комбинации \label
+ \ref
+ \pageref
, независимо от того, что будет набрано в индексном месте записей индекса.
Я переопределил \@wrindex
, добавил, |myhyperlink{\ep@rawexnoprint}
что помогает нам контролировать вывод. Ключевым шагом было добавление \label{\ep@rawexnoprint}#1
в эту команду. Она сохраняет справочную информацию и выводит ссылку для нас, поэтому нам не нужно вводить ее дважды.
Мы уведомляем процессор индекса о новой команде define-attributes
и определяем новый класс, как в первом примере. Результатом наших усилий является то, что число кликабельно, а скобки — нет.
Есть небольшая проблема, какhyperref
переопределяет команды, которые кликабельны, но ведут нас на страницу, а не на строку, где \index
была вызвана команда. Если мы исследуем mal-expex-2.aux
файл дальше, то увидим, что происходит:
\newlabel{2.1}{{1}{2}{Second chapter}{chapter.2}{}}
Он сохранил всю необходимую информацию, но ведет ко второй главе. Это не лучший результат, которого мы можем здесь добиться, так как само название могло быть набрано на несколько страниц раньше, чемexpex
примеры. Ну, у нас есть некоторые улучшения. Мы получаем сообщения об ошибках отxindy
о несуществующих перекрестных ссылках-целях, но мы можем их игнорировать, мы управляем этой частью сами.
Запускаем эти три строки:
lualatex mal-expex-2.tex
xindy -M texindy -M expex-2 -L general -C utf8 mal-expex-2.idx
lualatex mal-expex-2.tex
Содержимое файла mal-expex-2.idx
следующее:
\indexentry{Bratwurst|myhyperlink{2.1}}{2.1}
\indexentry{Sauerkraut|myhyperlink{2.2}}{2.2}
\indexentry{Striz|myhyperlink{2.3}}{2.3}
\indexentry{Oldman|myhyperlink{2.4}}{2.4}
\indexentry{Sauerkraut|myhyperlink{2.5}}{2.5}
Прилагаю код TeX и предварительный просмотр результата.
% run: *latex mal-expex-2.tex
\documentclass{report}
\pagestyle{empty}
\usepackage{expex}
\lingset{aboveexskip=0pt,glspace=1em plus .5em minus.2em,
glrightskip=0pt plus 8em,aboveglftskip=0pt,glneveryline={\it},
glstyle=nlevel,everygl={\hangindent=1.2em \hangafter=1},
exnotype=chapter.arabic}
\usepackage{makeidx}
\makeindex
\usepackage[colorlinks]{hyperref}
\usepackage{filecontents}
\begin{filecontents*}{expex-2.xdy}
;; expex-2.xdy
(define-attributes (("default" "textbf" "textit" "myhyperlink")))
(define-crossref-class "myhyperlink")
(markup-crossref-list :class "myhyperlink" :sep ",\,")
(markup-crossref-layer :open "(\myhyperlink{" :close "})" :class "myhyperlink")
\end{filecontents*}
\def\myhyperlink#1{\hyperref[#1]{#1}}
\makeatletter
\def\@wrindex#1{%
\protected@write\@indexfile{}%
{\string\indexentry{#1|myhyperlink{\ep@rawexnoprint}}{\ep@rawexnoprint}}%
\endgroup
\@esphack\label{\ep@rawexnoprint}#1}%
\makeatother%End of \def\@wrindex...
\begin{document}
%\gathertags
\chapter{First chapter}
Some initial text.
\chapter{Second chapter}
The first approach.
\ex Bratwurst --- this example is followed by \index{Bratwurst} \xe
\ex Sauerkraut --- this example is followed by \index{Sauerkraut} \xe
\ex By \index{Striz} \xe
\ex By \index{Oldman} \xe
\ex Again \index{Sauerkraut} \xe
%\begingroup
%\def\thispagestyle#1{}%
\printindex
%\endgroup
\end{document}
Двустороннее движение: замечания по
mal-expex-3.tex
делу
Как только мы сможем что-то улучшить, мы это сделаем. Мы хотим иметь кликабельную версию документа с перекрестными ссылками, ведущими к нужным местам. Более того, мы можем попытаться иметь перекрестные ссылки с обоих направлений. Из \index
в индекс и из записей индекса в индексе обратно к их \index
аналогам. Мы должны иметь в виду, что записи индекса сгруппированы, и мы можем потерять некоторые гиперссылки в индексе, вообще говоря.
Для этого я использовал пару команд \hypertarget
и \hyperlink
, гарантируя, что я предоставлю им уникальные маркеры, см. строки 40-47 в коде ниже. Это исправленная версия, она переходит в исходное местоположение, но пути назад нет. Давайте сосредоточимся на этой функции.
Я подготовил новый файл для следующих экспериментов, чтобы отделить их от обычного idx
файла для целей этого поста. Я буду использовать myi
расширение (отражает idx
файл) и iym
расширение (отражает ind
файл).
Суть этого метода заключается в использовании \hypertarget
and \hyperlink
дважды: одна пара обрабатывает один путь, другая пара обрабатывает обратный путь. Пожалуйста, посмотрите строки 50-65 в коде. Мне нужно было использовать , \raisebox
чтобы получить местоположение от левой базовой линии поля до левого верхнего угла.
Я также подготовил новый набор команд для регулярного использования. Мы можем хранить номера страниц (это распространенный метод; простые арабские цифры), мы можем хранить количествоexpex
пример (арабская цифра точка арабская цифра в скобках) и номер главы (арабская цифра в скобках). Используя этот подход, см. строки 68-70, мы можем хранить там почти все, что угодно.
Единственное, что нам осталось сделать, это уведомитьxindy
обо всем этом. Давайте расширим наш xdy
файл стилей, см. строки 20-36 в коде TeX.
Чтобы облегчить нам работу, я сделал еще одно улучшение. Я переопределил операторы \ex...\xe
в форму, просто \ex...
определив конец строки ( ^^M
) как команду и использовав ее впоследствии. Этот шаг, конечно, не является необходимым в производстве, я просто хотел показать вам, что это можно сделать, и мы можем сэкономить на вводе \xe
.
Мы запускаем следующие четыре строки:
lualatex mal-expex-3.tex
xindy -M texindy -M expex-3 -L общий -C utf8 -o mal-expex-3.ind mal-expex-3.idx
xindy -M texindy -M expex-3 -L общий -C utf8 -o mal-expex-3.iym mal-expex-3.myi
lualatex mal-expex-3.tex
Содержимое файла mal-expex-3.idx
такое же, как и во второй части, потому что мы переопределили команды на уровне TeX. Содержимое файла mal-expex-3.myi
для нас новое и выглядит так:
\indexentry{on purpose|malchapter{2-2-1}}{2}
\indexentry{paja|malpage{2-2-2}}{2}
\indexentry{malipivo|malpage{2-2-3}}{2}
\indexentry{next a|malexpex{2.8-2-4}}{2}
\indexentry{more a|malexpex{2.9-2-5}}{2}
\indexentry{next b|malchapter{2-2-6}}{2}
\indexentry{more b|malchapter{2-2-7}}{2}
\indexentry{paja|malexpex{2.12-2-8}}{2}
\indexentry{paja|malchapter{2-2-9}}{2}
Прилагаю последний пример и предварительный обзор наших усилий.
% run: *latex mal-expex-3.tex
\documentclass{report}
\pagestyle{empty}
\usepackage{expex}
\lingset{aboveexskip=0pt,glspace=1em plus .5em minus.2em,
glrightskip=0pt plus 8em,aboveglftskip=0pt,glneveryline={\it},
glstyle=nlevel,everygl={\hangindent=1.2em \hangafter=1},
exnotype=chapter.arabic}
\usepackage{makeidx}
\makeindex
\usepackage[colorlinks=true]{hyperref}
\usepackage{filecontents}
\begin{filecontents*}{expex-3.xdy}
;; expex-3.xdy
(define-location-class "expexnumber" ("arabic-numbers" :sep "." "arabic-numbers"))
(define-location-class "expexchapter" ("arabic-numbers" :sep "."))
(define-location-class-order ("expexnumber" "expexchapter" "arabic-numbers"))
(define-attributes (("malpage" "malexpex" "malchapter" "myhyperlink")))
(define-crossref-class "myhyperlink")
(markup-crossref-list :class "myhyperlink" :sep ",\,")
(markup-crossref-list :open "(\myhyperlink{" :close "})" :class "myhyperlink")
(define-crossref-class "malpage")
(markup-crossref-list :class "malpage" :sep ",\,")
(markup-crossref-layer :open "\myhyper{" :close "}" :class "malpage")
(define-crossref-class "malexpex")
(markup-crossref-list :class "malexpex" :sep ",\,")
(markup-crossref-layer :open "(\myhyper{" :close "})" :class "malexpex")
(define-crossref-class "malchapter")
(markup-crossref-list :class "malchapter" :sep ",\,")
(markup-crossref-layer :open "[\myhyper{" :close "}]" :class "malchapter")
\end{filecontents*}
% Redefinition in common index... (one-way approach)
\def\myhyperlink#1{\hyperlink{#1}{#1}}
\makeatletter
\def\@wrindex#1{%
\protected@write\@indexfile{}%
{\string\indexentry{#1|myhyperlink{\ep@rawexnoprint}}{\ep@rawexnoprint}}%
\endgroup
\@esphack\raisebox{\baselineskip}[0pt][0pt]{\hypertarget{\ep@rawexnoprint}{\raisebox{-\baselineskip}[0pt][0pt]{#1}}}}%
\makeatother
% A new index file...
\makeatletter
\let\temphere=\ep@rawexnoprint
\makeatother
\newwrite\myindexfile
\immediate\openout\myindexfile=\jobname.myi
\def\myhyper#1{\myhypertemp #1 }
\def\myhypertemp #1-#2-#3 {\hyperlink{#3}{\raisebox{\baselineskip}[0pt][0pt]{\hypertarget{#3-to-index}}#1}}
% Two-way approach...
\newcount\mycounter
\mycounter=0
\def\myshipping#1#2{%
\global\advance\mycounter by 1%
\raisebox{\baselineskip}[0pt][0pt]{\hypertarget{\the\mycounter}{}}%
\hyperlink{\the\mycounter-to-index}{#1}%
\immediate\write\myindexfile{\string\indexentry{#1|\material{#2-\thepage-\the\mycounter}}{\thepage}}%
}% End of \myshipping...
% Regular definitions to be used in document body...
\def\pageindex#1{\def\material{malpage}\myshipping{#1}{\thepage}}
\def\expexindex#1{\def\material{malexpex}\myshipping{#1}{\temphere}}
\def\chapterindex#1{\def\material{malchapter}\myshipping{#1}{\thechapter}}
\begin{document}
% The form of \ex...\xe rewritten to the form of \ex... only
% We are hacking the end of the line...
\catcode`\^^M=13
\def^^M{\par}
\let\extemp=\ex
\def\ex#1^^M{\extemp#1\xe}
%\gathertags
\chapter{First chapter}
Some initial text.
\chapter{Second chapter}
The first approach.
\ex Bratwurst --- this example is followed by \index{Bratwurst}
\ex Sauerkraut --- this example is followed by \index{Sauerkraut}
\ex By \index{Striz}
\ex By \index{Oldman}
\ex an experiment \chapterindex{on purpose}
\ex hello 1 \pageindex{paja}
\ex hello 2 \pageindex{malipivo}
\ex hello 3 \expexindex{next a}
\ex hello 4 \expexindex{more a}
\ex hello 5 \chapterindex{next b}
\ex hello 6 \chapterindex{more b}
\ex hello 7 \expexindex{paja}
\ex hello 8 \chapterindex{paja}
\ex finish \index{Sleep}
% A common index...
%\begingroup % Redefinition of \indexname...
%\def\thispagestyle#1{}%
\def\indexname{Common index\\ with example numbers\\(one-way traffic)}
\printindex
% An improved version of index...
\def\indexname{Index of\\ page, (exercise), [chapter]\\(two-way traffic)}
\immediate\closeout\myindexfile
\IfFileExists{\jobname.iym}{\input \jobname.iym}{}%
%\endgroup
\end{document}
решение2
Я хотел опубликовать решение, которое сводится к тому же, но может быть немного проще. Оно использует пакет index
. Вы можете указать index
использовать определенный макрос (ниже, \PageExample
) для генерации ссылки в индексе. Ниже я печатаю записи в формате "Страница-Пример" (например, 2-7). Другой формат обсуждается ниже.
\documentclass{book}
\usepackage{expex,lipsum,index}
% use this definition if using makeindex
\newcommand{\PageExample}{\thepage-\the\excnt}
% use this definition if using xindy
% \newcommand{\PageExample}{\thepage (\the\excnt)}
\newindex[PageExample]{my-index}{idx}{ind}{My Custom Index}
\makeindex
\begin{document}
\ex \lipsum[1]\index[my-index]{First example} \xe
\ex \lipsum[2] \index[my-index]{Second example}\xe
\ex \lipsum[3] \index[my-index]{Third example}\xe
\ex \lipsum[4] \index[my-index]{Fourth example}\xe
\ex \lipsum[5] \index[my-index]{Fifth example}\xe
\ex \lipsum[6] \index[my-index]{Sixth example}\xe
\ex \lipsum[6] \index[my-index]{Seventh example}\xe
\printindex[my-index]
\end{document}
Пунктуация, которая может встречаться в ссылках индекса, ограничена makeindex
. Если вас устраивает формат "2-7", приведенный выше пример работает идеально.
Если вы используете xindy
для обработки индекса, то есть больше гибкости. Я хотел ссылки типа "Page-number (Example-number)", т. е. 2(7). Это легко сгенерировать с помощью альтернативного определения \PageExample
выше, но тогда файл индекса должен быть обработан xindy
.
После компиляции с помощью latex
я вызываю xindy
следующим образом:
texindy -L english example.idx -M page-example.xdy
Файл page-example.xdy
инструктирует xindy
о моем формате "Page-number (Example-number)". Он содержит всего одну строку:
(define-location-class "page-example" ("arabic-numbers" :sep "(" "arabic-numbers" :sep ")" ))
решение3
Изменение \thepage оказалось не очень хорошей идеей по причинам, указанным ниже. Поэтому вместо этого я теперь пишу в файл .idx напрямую.
Основная проблема заключается в том, что makeindex распознает в качестве разделителя только {-}, а не {.}. Кроме того, счетчик \excnt увеличивается ПОСЛЕ его использования, а не ДО его использования.
Следуя совету Никола Тальбота, я смог исправить проблему с разделителем. Обратите внимание, что у меня Windows установлена на диске G, чего, вероятно, нет у кого-то еще.
Сначала я скопировал и переименовал ist-файл из G:\programfiles\MikTex 2.9\makeindex в "period.ist". Подойдет любой подкаталог. Я также отредактировал его так, чтобы он состоял из
page_compositor "."
Затем я использовал меню Build/Define Output Profiles из TeXnic Center, чтобы добавить -s "period.ist" в список аргументов Makeindex. Если какой-либо из этих шагов выполнен неправильно (для вашей установки), то Makeindex работать не будет.
\documentclass{report}
\usepackage{expex}
\lingset{aboveexskip=0pt,glspace=1em plus .5em minus.2em,
glrightskip=0pt plus 8em,aboveglftskip=0pt,glneveryline={\it},
glstyle=nlevel,everygl={\hangindent=1.2em \hangafter=1},
exnotype=chapter.arabic}
\usepackage{makeidx}
\makeindex
\makeatletter
\newcommand{\ExIndex}[1]% same as \index
{%
\immediate\write\@indexfile
{\string\indexentry{#1}%
{\thechapter.\the\excnt}}%
}%
\makeatother
\begin{document}
\gathertags
\chapter{First chapter}
\chapter{Second chapter}
\ExIndex{Bratwurst}
\ex Bratwurst --- this example is preceded by \verb"\ExIndex{Bratwurst}"
\xe
\ExIndex{Sauerkraut}
\ex Sauerkraut --- this example is preceded by \verb"\ExIndex{Sauerkraut}"
\xe
\printindex
\end{document}