# Automatically format words in a PDFLaTeX document which are in a keyword list

When writing technical documents, I often want to format 'technical phrases' (such as the name of some technology) in a particular way, which becomes annoying when I type the phrases frequently.

I'm wondering if there's a way I could define a list of 'keywords' in my LaTeX document which, when encountered else in the document, are automatically formatted in a particular way (which I would define).

For example, instead of the current method of:

The \textbf{gmond} daemon is the blurst. I hate \textbf{gmond} and \textbf{gmetad}.


I could write something which could look like

\keywords{gmond, gmetad}{\textbf}

The gmond daemon is the blurst. I hate gmond and gmetad.


which would produce identical output as above.

Is this at all possible? I'm happy to have to write \gmond, as long as I don't have to define the command for each word in my keywords list.

• if you are prepared to use the \gmond\ daemon is the blurst. I hate \gmond\ and \gmetad. then it is easy to set up, if you want it without markup then it's possible (there are some answers on site) but more fragile and possibly easier with lualatex than classic latex. – David Carlisle Jan 7 '16 at 20:35
• – Torbjørn T. Jan 7 '16 at 20:59
• See also Macro for typesetting acronyms. – Christian Lindig Jan 7 '16 at 21:11
• – Per Alexandersson Jan 12 '16 at 1:41
• – user4686 Jan 27 '16 at 8:42

Here's a keywordmarkup generator way with expl3 (note: Keywords, not key phrases)

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\clist_new:N \l_antiearth_keywords_clist

\newcommand{\keywordslist}[2]{%
\clist_set:Nn \l_antiearth_keywords_clist {#1}
\clist_map_inline:Nn \l_antiearth_keywords_clist {%
\expandafter\newcommand\csname ##1\endcsname{{#2 ##1}}
}
}
\ExplSyntaxOff

\begin{document}

Here is an example with \gmond\ and \gmetad.

\end{document}


Update

Use different lists (the style handling is not very well yet)

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\keywordslist}{mmm}{%
\clist_new:c {l_antiearth_#1_clist}
\clist_set:cn {l_antiearth_#3_clist} {#2}
\clist_map_inline:cn {l_antiearth_#3_clist} {%
\expandafter\NewDocumentCommand\csname ##1\endcsname{}{{\csname #3\endcsname ##1}}
}
}
\ExplSyntaxOff

\begin{document}
\keywordslist{italiclist}{other, nope}{itshape}

Here is an example with \gmond\ and \gmetad.

Here is an example with \other\  and \nope.

\end{document}


• +1, but please use \NewDocumentCommand for the document level function \keywordslist to have it automatically e-TeX protected and call a code level function from there rather than doing everything inside the document level function. – Henri Menke Jan 7 '16 at 20:52
• @HenriMenke: Yes, I was in a hurry;-) I am updating this – user31729 Jan 7 '16 at 20:53
• This seems to remove the space after gmond on Ubuntu, and I can't add the space back after \bfseries. Will I have to write \gmond{}? That stinks – Anti Earth Jan 7 '16 at 21:57
• (+1.) @AntiEarth -- Load the package xspace, and change \endcsname ##1}} to \endcsname ##1}\xspace}. However, xspace can have some (fairly minor but) unfortunate kerning side effects. – jon Jan 8 '16 at 3:38
• @AntiEarth: That's the problem of any macro basically. – user31729 Jan 8 '16 at 4:44

You can add items to a list and replace the words in the argument to a command. You can add items with

\keywords{comma separated list}{\text…}


where \text… has to be one single command which takes exactly one parameter. The replacement is done with

\applykeywords{text}


Because text is split at the spaces one has to take punctuation into account, see example below.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\tl_new:N \g_anti_keywords

{
\clist_map_inline:nn { #1 }
{
\tl_gput_right:Nn \g_anti_keywords {{##1}{#2{##1}}}
}
}

\cs_new_protected:Npn \anti_apply_keywords:n #1
{
\seq_set_split:Nnn \l_tmpa_seq { ~ } { #1 }
\seq_map_inline:Nn \l_tmpa_seq
{
\str_case:nVF { ##1 } \g_anti_keywords { ##1 } ~
}
\tex_unskip:D
}

\NewDocumentCommand \keywords { m m }
{
}

\NewDocumentCommand \applykeywords { m }
{
\anti_apply_keywords:n { #1 }
}

\ExplSyntaxOff

\begin{document}

\applykeywords{The gmond daemon is the blurst. I hate gmond and gmetad.}
\end{document}


• What purpose is served by having the document level command call a combo-command sequence rather than just using the commands in that combo directly? I guess I don't quite understand the idea behind this split since, to the uninformed, it just seems to make the code (1) longer and (2) more opaque as it is that much more difficult to figure out what a document command does and how it does it. (First find the command in the source. Then find the combo-thing the command calls. Then figure out what the combined things combine to do.) Is the extra layer more efficient (faster) or safer or...? – cfr Jan 7 '16 at 21:25
• @cfr The point is, that you can't patch or \let xparse defined commands. Thus a person who wants to extend \keywords has to do a \RenewDcoumentCommand \keywords { m m } { \anti_add_keywords:nN { #1 } #2 … do more stuff … }. This is more convenient than having to copy a huge code block. – Henri Menke Jan 7 '16 at 22:09
\documentclass[12pt,letterpaper,fleqn,parskip=half]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}
\usepackage{bookman}
\newcommand{\gm}{\textbf{gmond}}

\begin{document}

The \gm\ daemon is the blurst. I hate \gm\ and \gt.

\end{document}


However, and responding to @Anti Earth's just criticism of the above, xelatex (thanks to @jfbu) seems to do this quite well in a minimalist sort of way:

\documentclass {article}
\usepackage {fontspec}
\setmainfont {TeX Gyre Schola}
\usepackage{soul}
\usepackage{color}
\sethlcolor{yellow}
\usepackage{xesearch}
\UndoBoundary{-}
\SearchList{phrases}{\hl{#1}}{555-222-1212,Fido,Tinkerbell}
\robustify{\hl}
\SearchList{poems}{\textbf{#1}}{theatre,convention,Timbuktu}

\begin{document}

Once upon a time Tinkerbell called the Fairy Princess, at 555-222-1212, to complain that Fido was tinkling on the pretty flowers.
\bigskip

Away from the town of Timbuktu

The theatre of the wise

And the convention of the poor

Combined to make the party
\bigskip

Your counsel is to only be seen as productive if conductive to proper inductive reasoning.

\end{document}


which produces:

• See "I'm happy to have to write \gmond, as long as I don't have to define the command for each word in my keywords list." – Anti Earth Jan 9 '16 at 23:21
• Yes I know. Sometimes the simplest solutions are best. – A Feldman Jan 9 '16 at 23:45
• @Anti Earth, per your suggestion, I changed the answer. – A Feldman Jan 27 '16 at 5:57
• Is there any equivalent for PDFLatex? – Anti Earth Jan 27 '16 at 7:09
• perhaps one can link to your question tex.stackexchange.com/questions/280532/… – user4686 Jan 27 '16 at 8:37