6

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.

3 Answers3

6

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}
\keywordslist{gmond, gmetad}{\bfseries}

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{boldlist}{gmond, gmetad}{bfseries}
\keywordslist{italiclist}{other, nope}{itshape}

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

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


\end{document}

enter image description here

  • +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 07 '16 at 20:52
  • @HenriMenke: Yes, I was in a hurry;-) I am updating this –  Jan 07 '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 07 '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 08 '16 at 03:38
  • @AntiEarth: That's the problem of any macro basically. –  Jan 08 '16 at 04:44
  • With your solution, define section, chapter, alpha, or document as keywords may be problematic! – Paul Gaborit Jan 09 '16 at 09:21
  • @PaulGaborit: Of course, but as long as no description of the 'language' is available ... and I have another solution in mind, I try to update this soon –  Jan 09 '16 at 09:32
3

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

\cs_new_protected:Npn \anti_add_keywords:nN #1#2
 {
  \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 }
 {
  \anti_add_keywords:nN { #1 } #2
 }

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

\ExplSyntaxOff

\begin{document}
\keywords{gmond, gmetad}{\textbf}
\keywords{blurst., gmetad.}{\textit}

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

enter image description here

Henri Menke
  • 109,596
  • 1
    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 07 '16 at 21:25
  • 2
    @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 07 '16 at 22:09
1
\documentclass[12pt,letterpaper,fleqn,parskip=half]{scrartcl}
\usepackage[T1]{fontenc} 
\usepackage[latin1]{inputenc} 
\usepackage{bookman} 
\newcommand{\gm}{\textbf{gmond}}
\newcommand{\gt}{\textbf{gmetad}}

\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}
\SearchList{advice}{\textit{#1}{productive,conductive,inductive}

  \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:

enter image description here

A Feldman
  • 3,930
  • 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 09 '16 at 23:21
  • Yes I know. Sometimes the simplest solutions are best. – A Feldman Jan 09 '16 at 23:45
  • @Anti Earth, per your suggestion, I changed the answer. – A Feldman Jan 27 '16 at 05:57
  • Is there any equivalent for PDFLatex? – Anti Earth Jan 27 '16 at 07:09
  • perhaps one can link to your question https://tex.stackexchange.com/questions/280532/is-there-a-way-to-have-xesearch-search-and-replace-a-term-and-have-the-replaceme –  Jan 27 '16 at 08:37
  • @Anti Earth I am not sure of that. Recently I have been using the abbrevs package, but I have not investigated whether it will do command substitution like xesearch does in xetex. – A Feldman Jan 27 '16 at 14:26
  • @jfbu great idea, how would I link a question like that. – A Feldman Jan 27 '16 at 14:26
  • @jfbu added a link to the answer. Is there a way to link otherwise? – A Feldman Jan 27 '16 at 14:36
  • @Anti Earth see http://tex.stackexchange.com/questions/289713/what-packages-provide-text-command-substitution-for-latex-xetex-and-luatex-lual – A Feldman Jan 27 '16 at 17:53
  • @jfbu see http://tex.stackexchange.com/questions/289713/what-packages-provide-text-command-substitution-for-latex-xetex-and-luatex-lual – A Feldman Jan 27 '16 at 17:53
  • ok, but I have no answer for your new question ;-) about links you probably already know that you can either paste directly the http://... thing or use [name](url) mark-up. Short links are provided by the "share" buttons. –  Jan 27 '16 at 18:17
  • Thanks @jfbu, I started out with xesearch, I use abbrevs when I have to use pdftex or luatex, then I ran into chickenize, did a search found xstring, and that's when I realized that I had no idea how many others were lurking out there. – A Feldman Jan 27 '16 at 18:21