Индекс, который учитывает номера примеров, а не номера страниц

Индекс, который учитывает номера примеров, а не номера страниц

Я создаю несколько глоссированных лингвистических текстов на языке коренных американцев. Предложения помечены как, например, (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}

mwe, часть 1: нет движения


Одностороннее движение: замечания по 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}

mwe, часть 2: одностороннее движение


Двустороннее движение: замечания по mal-expex-3.texделу

Как только мы сможем что-то улучшить, мы это сделаем. Мы хотим иметь кликабельную версию документа с перекрестными ссылками, ведущими к нужным местам. Более того, мы можем попытаться иметь перекрестные ссылки с обоих направлений. Из \indexв индекс и из записей индекса в индексе обратно к их \indexаналогам. Мы должны иметь в виду, что записи индекса сгруппированы, и мы можем потерять некоторые гиперссылки в индексе, вообще говоря.

Для этого я использовал пару команд \hypertargetи \hyperlink, гарантируя, что я предоставлю им уникальные маркеры, см. строки 40-47 в коде ниже. Это исправленная версия, она переходит в исходное местоположение, но пути назад нет. Давайте сосредоточимся на этой функции.

Я подготовил новый файл для следующих экспериментов, чтобы отделить их от обычного idxфайла для целей этого поста. Я буду использовать myiрасширение (отражает idxфайл) и iymрасширение (отражает indфайл).

Суть этого метода заключается в использовании \hypertargetand \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}

mwe, часть 3: двустороннее движение

решение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}

индекс

Связанный контент