# How to make a list of indexed words defined directly in text?

Is there any way to mark words in a text for the use of them in a list later on?

Example:

Hi my name is \addmark{Kris}, I need a \addmark{list} of words containing all the
\begin{itemize}
\end{itemize}

\printmark


to look like this:

Hi my name is Kris, I need a list of words containing all the marked words by the end of the document.

• fancy list

Kris, list, marked words, document and fancy list.

• Welcome to TeX.SX! Do you mean something like an index? The glossaries package can do something like that for you. – mafp Nov 3 '13 at 8:39
• But as far as I understood the glossaries package only allows predefined terms right? I would like to be able to define the terms for indexing in the text. – Khaurum Nov 3 '13 at 8:45
• You can use makeidx. – Marco Daniel Nov 3 '13 at 8:48
• makeidxseems good, but the \makeindex gives a list with index as title and I only need the indexed words in a paragraph as shown in my example - is there any workarround? – Khaurum Nov 3 '13 at 9:07

How about something with expl3 and sequences? :)

\documentclass{article}

\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn
\seq_new:N \g_khaurum_wordlist_seq

\seq_gput_right:Nn \g_khaurum_wordlist_seq { #1 }
#1
}

\NewDocumentCommand{ \printmarks }{s}{
\seq_gremove_duplicates:N \g_khaurum_wordlist_seq
\seq_use:Nnnn \g_khaurum_wordlist_seq { ~ and ~ } { , ~ } { ~ and ~ }
\IfBooleanT { #1 } {
\seq_gclear:N \g_khaurum_wordlist_seq
}
}

\ExplSyntaxOff

\begin{document}

containing all the \addmark{marked words} by the end of the

\begin{itemize}
\item I'm a list of \addmark{items}
\end{itemize}

\vspace{1em}

\printmarks

\vspace{1em}

\vspace{1em}

\printmarks*

\vspace{1em}

The starred version cleared the \addmark{sequence}, so now

\vspace{1em}

\printmarks

\end{document}


When using \printmarks*, the sequence is printed and then cleared; so we can start a fresh sequence and add new entries afterwards.

Hope it helps. :)

Thanks to Marco Daniel and egreg for providing improvements to the code. :)

• Exactly what I needed! – Khaurum Nov 3 '13 at 9:45
• I just figured out that I can not add marks in a list - why is that? – Khaurum Nov 3 '13 at 10:21
• Maybe you should use a global sequence. So you can use inside a table too. – Marco Daniel Nov 3 '13 at 10:39
• @Marco: ah. I replaced \seq_put_right:Nn by \seq_gput_right:Nn. Do you believe is that enough? – Paulo Cereda Nov 3 '13 at 11:31
• @Khaurum: I changed the code slightly, so now it might work. I'll just wait for the L3 wizards to check if it's correct. :) – Paulo Cereda Nov 3 '13 at 11:32

Since Paulo has already presented a LaTeX3 version, I'll stick to a classical approach. I only add a switch for printing red the marked words in the text, that may reveal useful during document writing.

\documentclass{article}
\usepackage{xcolor}

\newif\ifshowmarked
\makeatletter
\newtoks\mark@toks
\mark@toks={\@gobble}
\newcommand{\mark@comma}{, }
{% New marked word
}
{
% Already marked word, do nothing
}%
\ifshowmarked
\textcolor{red}{#1}%
\else
#1%
\fi
}

\newcommand{\printmarks}{%
\the\mark@toks\relax
\@ifstar{\global\mark@toks{\@gobble}}{}%
}
\makeatletter

\begin{document}

containing all the \addmark{marked words} by the end of the

\begin{itemize}
\item I'm a list of \addmark{items}
\end{itemize}

\vspace{1em}

\printmarks

\vspace{1em}

\vspace{1em}

\printmarks*

\vspace{1em}

\showmarkedtrue

The starred version cleared the \addmark{sequence}, so now

\vspace{1em}

\printmarks

\end{document}


The argument to \addmark is used to build a control sequence; if this command is already defined, we do nothing, otherwise define the control sequence and add it to a token register preceded by a comma and a space. The token register is initialized to contain \@gobble, so the first comma will not be printed. Finally, the word is printed (in red if the switch is on).

The \printmarked macro works in the same way: the token register's content is delivered; if the *-variant is used, the token register is reinitialized.

Note that the LaTeX3 is superior, because it allows for using the list of marked words in many different ways. It's doable also in the “classical” version, but reinventing the wheel many times. Also, no \detokenize trick is necessary with LaTeX3 to cope with special characters in the marked words, since the word is simply stored as is.

Just comparing the code clearly shows the superiority of the LaTeX3 approach.

\bool_new:N \g_khaurum_highlight_bool
\NewDocumentCommand{\showmarkedtrue}{}
{
\bool_gset_true:N \g_khaurum_highlight_bool
}
\NewDocumentCommand{\showmarkedfalse}{}
{
\bool_gset_false:N \g_khaurum_highlight_bool
}


and change the definition of \addmark to

\NewDocumentCommand{ \addmark }{ m }
{
\seq_gput_right:Nn \g_khaurum_wordlist_seq { #1 }
\bool_if:NTF \g_khaurum_highlight_bool { \textcolor}{red}{#1} } { #1 }
}