Apply command on range of characters of a word
\documentclass{article}
\usepackage{xcolor}
\newcounter{pft}
\begin{document}
\makeatletter
\def\pft#1-#2;{\edef\lower@pft{\the\numexpr#1-1}\edef\upper@pft{\the\numexpr#2+1}}%
\def\ColorRgChar#1#2{\pft#1;%
\setcounter{pft}{0}%
\@tfor\next:=#2\do{\stepcounter{pft}%
\ifnum\value{pft}>\lower@pft
\ifnum\value{pft}<\upper@pft
\textcolor{red}{\next}%
\else
\next
\fi
\else
\next
\fi
}}%
\makeatother
\ColorRgChar{2-5}{examination} \ColorRgChar{4-7}{hibernation} \ColorRgChar{1-3}{catcode}
\end{document}
Or without an explicit counter.
\documentclass{article}
\usepackage{xcolor}
\colorlet{SalimBouColor}{red}
\begin{document}
\makeatletter
\def\pft#1-#2;{\edef\lower@pft{\the\numexpr#1-1}\edef\upper@pft{\the\numexpr#2+1}}%
\def\ColorRgChar#1#2{\pft#1;%
\edef\n@pft{0}%
\@tfor\next:=#2\do{\edef\n@pft{\the\numexpr\n@pft+1}%
\ifnum\n@pft>\lower@pft
\ifnum\n@pft<\upper@pft
\textcolor{SalimBouColor}{\next}%
\else
\next
\fi
\else
\next
\fi
}}%
\makeatother
\ColorRgChar{2-5}{examination} \ColorRgChar{4-7}{hibernation} \ColorRgChar{1-3}{catcode}
This includes, of course, your case of just coloring one character: \ColorRgChar{3-3}{examination}
\colorlet{SalimBouColor}{blue}%
\ColorRgChar{2-5}{examination}
\end{document}
Or without wrapping single characters into \textcolor
.
\documentclass{article}
\usepackage{xcolor}
\colorlet{SalimBouColor}{red}
\begin{document}
\makeatletter
\def\pft#1-#2-#3;{\edef\lower@pft{#1}\edef\upper@pft{#2}}%
\def\ColorRgChar#1#2{\pft#1-0-0;%
\ifnum\upper@pft=0
\edef\upper@pft{\lower@pft}%
\fi
\colorlet{orig@color}{.}%
\edef\n@pft{0}%
\@tfor\next:=#2\do{\edef\n@pft{\the\numexpr\n@pft+1}%
\edef\tmp@pft{}%
\ifnum\n@pft=\lower@pft
\color{SalimBouColor}%
\fi
\next
\ifnum\n@pft=\upper@pft
\color{orig@color}%
\fi
}}%
\makeatother
\ColorRgChar{2-5}{examination} \ColorRgChar{4-7}{hibernation} \ColorRgChar{1-3}{catcode}
This includes, of course, your case of just coloring one character: \ColorRgChar{3}{examination}
\colorlet{SalimBouColor}{blue}%
\ColorRgChar{2-5}{examination}
\end{document}
Here's a LuaLaTeX-based solution. It provides a Lua function that does the actual work and a LaTeX utility macro, called \ColorRangeChar
, which passes its three arguments to the Lua function. The three arguments are (a) and (b) integers that indicate the positions of the first and last characters to be colored and (c) the word itself.
This solution satisfies the OP's requirement that "Coloring of characters should be done at one time with a single \textcolor
command." The Lua function is set up to handle non-ASCII characters, such as öäüßÖÄÜ
. Of course, no coloring is done if the first number exceeds the number of characters in the word.
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{xcolor}
%% set up the Lua function that does the actual work:
\directlua{
function color_range_char ( m , n , s )
local t
t = unicode.utf8.sub(s,1,m-1) ..
"\string\\textcolor{red}{" .. unicode.utf8.sub(s,m,n) .. "}" ..
unicode.utf8.sub(s,n+1)
tex.sprint ( t )
end
}
%% set up a LaTeX macro that invokes the Lua function:
\newcommand\ColorRangeChar[3]{\directlua{color_range_char(#1,#2,"#3")}}
\begin{document}
\ColorRangeChar{3}{5}{examination}
\ColorRangeChar{2}{4}{öäüßÖÄÜ}
\end{document}
The bulk of the code is managing the input. The second argument can be
- a single number, meaning just one character to color;
-
, meaning color everything;m-
, meaning color from the m-th character to the end;-n
, meaning color from the start up to the n-th character;m-n
, meaning color from the m-th up to the n-th character.
\documentclass{article}
\usepackage{xparse,xcolor}
\ExplSyntaxOn
\NewDocumentCommand{\colorrange}{>{\SplitArgument{1}{-}}mm}
{
% #1 is passed as two braced arguments
\salim_colorrange:nnn #1 { #2 }
}
\cs_new_protected:Nn \salim_colorrange:nnn
{
% let's analyze the first two args
\tl_if_novalue:nTF { #2 }
{% no hyphen in the argument
\__salim_colorrange:nnn { #1 } { #1 } { #3 }
}
{
\bool_lazy_or:nnTF { \tl_if_blank_p:n { #1 } } { \tl_if_blank_p:n { #2 } }
{% argument is -n or m- or -
\tl_if_blank:nTF { #1 }
{
\tl_if_blank:nTF { #2 }
{% argument is -
\textcolor{red}{#3}
}
{% argument is -n
\__salim_colorrange:nnn { 1 } { #2 } { #3 }
}
}
{% argument is m-
\__salim_colorrange:nnn { #1 } { -1 } { #3 }
}
}
{% argument is m-n
\__salim_colorrange:nnn { #1 } { #2 } { #3 }
}
}
}
\cs_new_protected:Nn \__salim_colorrange:nnn
{
\int_compare:nTF { #1 > #2 > 0 }
{
#3
}
{
\tl_range:nnn { #3 } { 1 } { #1 - 1 }
\textcolor{red}{ \tl_range:nnn { #3 } { #1 } { #2 } }
\tl_range:nnn { #3 } { #2 + 1 } { -1 }
}
}
\ExplSyntaxOff
\begin{document}
\colorrange{4}{examination} (4)
\colorrange{4-6}{examination} (4-6)
\colorrange{1-3}{examination} (1-3)
\colorrange{-3}{examination} (-3)
\colorrange{4-11}{examination} (4-11)
\colorrange{4-}{examination} (4-)
\colorrange{-}{examination} (-)
\colorrange{5-4}{examination} (5-4)
\colorrange{12-4}{examination} (12-4)
\colorrange{12-}{examination} (12-)
\colorrange{-15}{examination} (-15)
\end{document}
Wrong input is allowed. Changing the color with an optional argument can be easily added.