[Tex/LaTex] How to insert a symbol to the beginning of a line for which a word appears

formattingrules

This is to indicate changes for a LaTeX file. Say, I wanted to add a vertical line to the beginning of a line whenever"word 1", "word 2", …", or "word 100" appears. Manually this can be done in order to determine where "word 1" appears, but it can be tedious if there are many "word" and if the process needs to be repeated again. So what is the intelligent way to do this?

I use this as an example to add vertical line 
| when word 1 appears and another vertical line
| word 2 appears.

Best Answer

I use an adaptation of my titlecaps package, normally used for capitalizing the first letter of each word, given a string of words (with user-specified exceptions). Therefore, instead of capping words, I leave them unchanged. However, I use the code that searches for the user-specified exceptions to both place a rule in the left margin and to change the color of the highlighted word (those two features operate independently and either can be disabled without affecting the other).

I use the tabto package to facilitate the marginal line notation.

Words to be searched for are specified by the macro \WordsToNote{word1 word2 word3}, a space-separated list. Subsequent invocations are cumulative, so that \WordsToNote{word1 word2}\WordsToNote{word3} is functionally equivalent to the former invocation. The list of words may be reset with \Resetlcwords.

The macro invocation on the paragraph is simply \NoteWords{<text>}.

As with the titlecaps package, it can handle a limited subset of macro invocations including text size changes and style changes.

EDITED to handle multiple paragraphs at a time. FIXED so that a new \par is not automatically issued at the end of the macro.

\documentclass{article}
\usepackage{titlecaps}
\makeatletter
\renewcommand\titlecap[2][P]{%
  \digest@sizes%
  \if T\converttilde\def~{ }\fi%
  \redefine@tertius%
  \get@argsC{#2}%
  \seek@lcwords{#1}%
  \if P#1%
    \redefine@primus%
    \get@argsC{#2}%
    \protected@edef\primus@argi{\argi}%
  \else%
  \fi%
  \setcounter{word@count}{0}%
  \redefine@secundus%
  \def\@thestring{}%
  \get@argsC{#2}%
  \if P#1\protected@edef\argi{\primus@argi}\fi%
  \whiledo{\value{word@count} < \narg}{%
    \addtocounter{word@count}{1}%
    \if F\csname found@word\roman{word@count}\endcsname%
      \notitle@word{\csname arg\roman{word@count}\endcsname}%
      \expandafter\protected@edef\csname%
           arg\roman{word@count}\endcsname{\@thestring}%
    \else
      \notitle@word{\csname arg\roman{word@count}\endcsname}%
      \expandafter\protected@edef\csname%
           arg\roman{word@count}\endcsname{%
            \protect\MPAR\color{red}\@thestring\color{black}{}}%
    \fi%
  }%
  \def\@thestring{}%
  \setcounter{word@count}{0}%
  \whiledo{\value{word@count} < \narg}{%
    \addtocounter{word@count}{1}%
    \ifthenelse{\value{word@count} = 1}%
   {}{\add@space}%
    \protected@edef\@thestring{\@thestring%
      \csname arg\roman{word@count}\endcsname}%
  }%
  \let~\SaveHardspace%
  \@thestring%
  \restore@sizes%
\un@define}
\makeatother
\usepackage{tabto,xcolor}
\def\margrule{\protect\rule[-\dp\strutbox]{1pt}{\baselineskip}}
\def\MPAR{\protect\tabto*{-.2cm}%
  \margrule\protect\tabto*{\TabPrevPos}}
\let\WordsToNote\Addlcwords
\newcommand\NoteWords[1]{\NoteWordsHelp#1\par\relax}
\long\def\NoteWordsHelp#1\par#2\relax{%
  \titlecap{#1}%
  \ifx\relax#2\else\par\NoteWordsHelp#2\relax\fi%
}
\textwidth4in\relax\sloppy
\begin{document}
\WordsToNote{word1 word2 word3}
\NoteWords{
This is a test of finding  word1 and others like word2 and to see if
a marking can be placed in the \textit{margin when they} are found.
I also include word3 in the list.  \"Unfortunately, this only does
a single paragraph at a time.  \tiny Multiple ocurrences in a 
single row only result in a single\normalsize mark, with this word1 implementation.

For my second paragraph,
this is a test of finding  word1 and others like word2 and to see if
a marking can be placed in the \textit{margin when they} are found.
I also include word3 in the list.  \"Unfortunately, this only does
a single paragraph at a time.  \tiny Multiple ocurrences in a 
single row only result in a single\normalsize mark, with this word1 implementation.
}
Look Mom, no new paragraph.
\end{document}

enter image description here

Please note: the line \textwidth4in\relax\sloppy I purposefully placed in the MWE code to reduce the margins and eliminate overfull boxes. Please remove them before using this code in other venues.