# Conditional string replacements in LuaLaTeX

I want to process whole tex file content with string replacements using lua. The following are the conditions

1. F, G, H should be replaced by P, Q, R respectively.
2. However if they aren't followed by a, e, i, o, u then replace them by Px, Qx, Rx respectively.
3. However if they are followed by letter Y then replace them by S, T, U.

So there are 3 conditions. If tex file is

\documentclass{article}
\begin{document}
FGH\\
FaGaHeF\\
FYGYHY
\end{document}


Then it should output to

PxQxRx
PQRPx
STU


How to write lua code to do this?

• Can you guarantee that the document won't contain words such as Figure, Garage, and Hotel? Or should they be converted to Pgure, Qrage, and Rtel, respectively? Please advise. – Mico Jul 17 at 16:47
• Figure, Garage and Hotel should be converted to Pgure, Qrage and Rtel respectively. – user61681 Jul 17 at 16:55
• Isn't this question, by any chance, related to this one? – Phelype Oleinik Jul 17 at 17:18

Your write-up of the substitution rules isn't very clear. I've interpreted them as follows:

1. If the letters F, G, and H are followed by a lowercase vowel (i.e., one of aeiou), the uppercase-lowercase letter pair should be replaced with P, Q, and R, respectively.

2. If the letters F, G, and H are followed by the uppercase letter Y, they (including the letter Y) should be replaced with S, T, and U, respectively.

3. If neither case 1 nor case 2 applies, the letters F, G, and H should be replaced with Px, Qx, and Rx, respectively.

4. All other material in the document should not be be affected by the preceding three substitution rules.

As long as the body of your document doesn't contain macros or environments whose names contain the letters F, G, and/or H, you can simply "turn on" the Lua function -- more precisely, assign it to LuaTeX's process_input_buffer callback, making the function act like a preprocessor on the input stream -- by running \fghOn after \begin{document}. It will then keep on running until it gets to \end{document}. The Lua function can be switched off via \fghOff. If you need to perform the substitution on just one string at a time, you could use the macro \fghSub -- cf. its use in the final row of the following working example.

\documentclass{article}
\usepackage{luacode}
%% Lua-side code:
\begin{luacode}

function fgh_sub ( s )
s = s:gsub ( "F[aeiou]" , "P")
s = s:gsub ( "G[aeiou]" , "Q")
s = s:gsub ( "H[aeiou]" , "R")
s = s:gsub ( "FY" , "S" )
s = s:gsub ( "GY" , "T" )
s = s:gsub ( "HY" , "U" )
s = s:gsub ( "F", "Px" )
s = s:gsub ( "G", "Qx" )
s = s:gsub ( "H", "Rx" )
return s
end

\end{luacode}

%% Three LaTeX macros to interface with the Lua function:
"process_input_buffer", fgh_sub, "fgh_sub" )}}
\newcommand\fghOff{\directlua{luatexbase.remove_from_callback(
"process_input_buffer", "fgh_sub" )}}
\newcommand\fghSub[1]{\directlua{%
tex.sprint(fgh_sub(\luastringN{#1}))}}

\begin{document}
\obeylines
\fghOn  % add Lua function to preprocessor stack
FGH
FaGaHeF
FYGYHY
\fghOff % remove Lua function from preprocessor stack
Figure, Garage, Hotel
\fghSub{Figure, Garage, Hotel} % run the function on a one-off basis
\end{document}

• Your interpretation of substitutions is absolutely right. – user61681 Jul 17 at 18:00
• @user61681 - No, this solution will not work under XeLaTeX. – Mico Jul 17 at 18:10
• Is it possible to modify code to replace say FY by \textbf{S} i.e. FY is to be replaced by boldface S. Does this need complete change of code or modification is possible? – user61681 Jul 18 at 5:03
• @user61681 - Just change ”S” to ”\\textbf{S}”. (Note the doubling of the backslash character.) – Mico Jul 18 at 5:37
• Thanks. It works. – user61681 Jul 18 at 5:54