Let me present a small snippet in LuaTeX. We pass an argument and selected letters to the Lua core, where the snippet decomposes it at a character level and wraps the preselected letters only by the \malbf
command.
Words to be marked are tagged, I didn't expect a TeX command, I presumed plain text. I enclose a small example with English (requested letters by OP) and Czech text (all the graphemes).
We can also check out the output in the terminal, it writes:
H\malbf{e}ll\malbf{o} W\malbf{o}rld! Y\malbf{ou} c\malbf{a}n s\malbf{a}y H\malbf{i} \malbf{a}s H\malbf{e}ll\malbf{o}.
Č\malbf{au} d\malbf{ě}ck\malbf{a}, j\malbf{a}k s\malbf{e} d\malbf{a}ř\malbf{í}?
If we would like to see different strategy how to preserve ligatures and kerning pairs of the formatted letters (I remove all the }\malbf{
sequences in this example), please see Version 2 of this answer. I mentioned one other method of the possible strategies there (I used a variable for font switching). In this example, we've got Č\malbf{au}
instead of Č\malbf{a}\malbf{u}
, and Y\malbf{ou}
instead of Y\malbf{o}\malbf{u}
.
I enclose the source code of the snippet and a preview of the PDF file. We run lualatex mal-letters.tex
.
% lualatex mal-letters.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\usepackage{xcolor}
\usepackage{luatextra} % luacode
\begin{luacode*}
function boldme () -- the core function
letters=tex.toks[1] -- some more/other letters?
text=tex.toks[0] -- text taken from TeX
towrite="" -- an empty string
markerbegin="\\malbf{" -- a command to be used as a marker
markerend="}"
for i=1,unicode.utf8.len(text) do -- decomposition of text
s=unicode.utf8.sub(text, i, i) -- actual character
isthere=nil -- initial value, no, character is not among letters
for j=1,unicode.utf8.len(letters) do -- test if it is
if unicode.utf8.sub(letters, j, j)==s then isthere=1; break end
end -- for, j, is character between selected letters?
if isthere then -- to be bold, or not?
towrite=towrite..markerbegin..s..markerend -- yes, it is to be empasized in bold
else
towrite=towrite..s -- no, that character is not among selected letters
end -- if, isthere
end -- for, i, decomposition of input text
-- combine the commands together
-- e.g. \malbf{a}\malbf{e} -> \malbf{ae}
towrite=unicode.utf8.gsub(towrite, markerend..markerbegin, "")
-- writing result to the terminal and to the document
io.write(towrite) -- information shipped to the terminal
tex.sprint(towrite) -- information shipped to the document
end -- function, boldme
\end{luacode*}
\def\malbf#1{\textbf{\color{red}#1}}
\def\markit#1{\toks0{#1}\directlua{boldme()}}
\def\tomark#1{\toks1{#1}}
\begin{document}
% Text in English, selected letters.
\tomark{aeiou}
Some text before. \markit{Hello World! You can say Hi as Hello.} More text after.
% An example with Czech graphemes.
\tomark{aáeéěiíoóuúůyý}
Text in the middle. \markit{Čau děcka, jak se daří?} End of story.
\end{document}
