4

This question is a follow-up of Macro: Replace all occurrences of a word, but I would like the same for different colours, that is to have different pre-defined sets of text strings which will be coloured in a predefined way, where the colour depends on the set they are in.

Requirement:

  • Each string should be able to include spaces and/or punctuation marks (e.g. a string could be foo's foo doesn't foo).

Edit: I was asked to provide a MWE, and while I was making one, suddenly I achieved an answer which I failed in creating before. Trial-and-error-and-trial-and-success.

1
  • 1
    Please provide a proper Minimal Example which demonstrates how you envisage this working and takes account of Mico's comments regarding the limitations of Lua's search-and-replace routine.
    – cfr
    Apr 19, 2016 at 22:37

2 Answers 2

7

(Updated the answer after OP indicated that he/she uses the book document class and may have instances of search strings in the arguments of \chapter and \section.)

Here's a LuaLaTeX-based solution. In addition to the Lua fuction, named colorize, that does the colorizing work, the code also sets up two TeX-side macros, \colorizeOn and \colorizeOff. As their names suggest, the macros serve to switch the operation of the Lua function on and off.

Some comments on the TeX-side code:

  • If some of your search strings may occur in the arguments of \chapter and \section instructions, you'll need to provide all-uppercase aliases for the colors you'll be using. For instance, if the applicable colors are named red, blue, and orange, use \colorlet instructions to set up the aliased names RED, BLUE, and ORANGE.

  • As far as I can tell, there is no good reason or valid excuse for letting search strings occur in the arguments of \label and \ref.

Some comments on the Lua-side code:

  • \ (a single backslash) is a special character in Lua. To generate a backslash in a luacode environment, one must write \\.

  • The search and replacement patterns in the gsub function must be delimited by matching single (') or double (") quotes. If the search patterns contain quote characters of the same type as are used for the delimiters, the quotes inside the search pattern must be escaped by prefixing them with a \. (This isn't the case in the code below: there are two instances of ' in the first search string, but they need not be escaped as " is being used to delimit the search pattern.)

  • The characters . and ) that occur in the first search string have a special, so-called "magical", meaning in Lua if they occur in a search string. To treat them as ordinary characters, they must be escaped with a % character.

    The following are Lua's "magical" characters: ( ) . % + - * ? [ ^ $. E.g., to search for a % symbol, write it as %% in the search string.

    No escaping of these characters is needed in the replacement string (the third argument of gsub), as they have no "magical" quality in the replacement string.

  • The %0 term in the third argument of gsub represents the entire string that was found by the pattern match.

enter image description here


enter image description here


enter image description here

% !TEX TS-program = lualatex
\documentclass{book}

\usepackage{fontspec} 
\setmainfont{Latin Modern Roman} % choose various fonts, as needed

\usepackage{xcolor}  % for "\textcolor" and "\colorlet" macros
\colorlet{RED}{red}  % alias names for colors: use all-uppercase
\colorlet{BLUE}{blue}
\colorlet{ORANGE}{orange}

\usepackage{lipsum}  % filler text
\usepackage{luacode} % for "luacode" environment and "\luastring" macro

%% Lua-side code
\begin{luacode}
function colorize ( buff )
   buff = string.gsub ( buff, "foo's foo doesn't foo%.%)", "\\textcolor{red}{%0}" )
   buff = string.gsub ( buff, "The quick brown fox",       "\\textcolor{blue}{%0}" )
   buff = string.gsub ( buff, "jumps over the lazy dog",   "\\textcolor{orange}{%0}" )
   return buff
end
\end{luacode}
%% TeX-side code
\newcommand\colorizeOn{\directlua{luatexbase.add_to_callback 
   ( "process_input_buffer" , colorize , "colorize" )}}
\newcommand\colorizeOff{\directlua{luatexbase.remove_from_callback 
   ( "process_input_buffer" , "colorize" )}}
\AtBeginDocument{\colorizeOn} % turn Lua function on by default

\begin{document}

\chapter{The quick brown fox jumps}  

\section{Zorro jumps over the lazy dog}

(Every day, foo's foo doesn't foo.)

The quick brown fox jumps over the lazy dog.

\colorizeOff  % switch off the Lua function
The quick brown fox jumps over the lazy dog.

\colorizeOn   % switch Lua function back on
The quick brown fox jumps over the lazy dog.


\lipsum[1-12]  % filler text
\end{document}
1
0

The following is basicly just adapted from User Mico's answer in the mentioned post "Macro: Replace all occurrences of a word":

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{xcolor}
\usepackage{luacode,luatexbase} 

%%% RED SET %%%

\begin{luacode}
local function vartosrcvar ( line )
  return string.gsub(line, "colour it red" , " \\redder{colour it red} ") 
end
luatexbase.add_to_callback( "process_input_buffer",  vartosrcvar, "red1")
local function vartosrcvar ( line )
  return string.gsub(line, "very red" , " \\redder{very red} ") 
end
luatexbase.add_to_callback( "process_input_buffer",  vartosrcvar, "red2")
\end{luacode}

\newcommand\redder[1]{\textcolor{red}{#1}}

%%% GREEN SET %%%

\begin{luacode}
local function vartosrcvar ( line )
  return string.gsub(line, "coloured it green" , "\\greener{coloured it green}") 
end
luatexbase.add_to_callback( "process_input_buffer",  vartosrcvar, "green1")
\end{luacode}

\newcommand\greener[1]{\textcolor{green}{#1}}

\begin{document}

For example, here is a string which should be coloured red: colour it red.\\

Here is another string which should be ``coloured it red", it makes its very red.\\

Now, here should be a string, which should be ``coloured it green".

\end{document}
2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .