对单词的字符范围应用命令

对单词的字符范围应用命令

这是我上一个问题的补充对单词的第 n 个字符应用命令,我需要为这样的一系列字符着色,\ColorRgChar{2-5}{examination}即为单词的第二个字符到第五个字符着色。

如果第一个数字大于单词的长度,则不进行着色。

字符着色应该用一个命令一次性完成,\textcolor而不是\textcolor每个字符都用一个命令。@David Carlisle

\documentclass{article}
\usepackage{xcolor}

\begin{document}

\makeatletter
\def\ColorRgChar#1#2{\xColorRgChar{#1}#2\@empty}
\def\xColorRgChar#1#2{\ifnum\ifx\@empty#21\else#1\fi=1 \textcolor{red}{#2}\expandafter\@gobbletwo
    \else#2\fi\xColorRgChar{\numexpr#1-1\relax}}
\makeatother

\ColorRgChar{2}{examination} 

%\ColorRgChar{2-5}{examination}  % desired macro 

\end{document}

答案1

代码的主要部分是管理输入。第二个参数可以是

  1. 一个数字,表示只有一个字符需要着色;
  2. -,意思是给一切事物涂上颜色;
  3. m-,表示从第m个字符到末尾的颜色;
  4. -n,表示从开始到第 n 个字符的颜色;
  5. m-n,表示从第 m 个字符到第 n 个字符的颜色。
\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}

允许输入错误。可以轻松添加使用可选参数更改颜色。

在此处输入图片描述

答案2

\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}

在此处输入图片描述

或者没有明确的反驳。

\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}

在此处输入图片描述

或者不将单个字符换行到\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}

在此处输入图片描述

答案3

这是一个基于 LuaLaTeX 的解决方案。它提供了一个执行实际工作的 Lua 函数和一个名为 的 LaTeX 实用程序宏\ColorRangeChar,该宏将其三个参数传递给 Lua 函数。这三个参数是 (a) 和 (b) 整数,它们指示要着色的第一个和最后一个字符的位置,以及 (c) 单词本身。

此解决方案满足了 OP 的要求,即“应使用单个命令一次性完成字符着色\textcolor”。 Lua 函数设置为处理非 ASCII 字符,例如öäüßÖÄÜ。 当然,如果第一个数字超出单词中的字符数,则不会进行着色。

在此处输入图片描述

% !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}

答案4

以下是 egreg 第一个代码的扩展这个答案支持以下形式的范围分钟-最大限度, 在哪里分钟如果没有给出,则表示“开始”,并且最大限度如果没有提供,则表示“结束”。我的代码用于l3regex解析范围表达式。

\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}

\ExplSyntaxOn

\msg_new:nnn { salim } { invalid-range-expression }
  { Invalid~range~expression:~'\exp_not:n {#1}'. }

\msg_new:nnn { salim } { zero-bound-in-range-expression }
  { Range~expression~contains~zero~bound:~'\exp_not:n {#1}'. }

\tl_new:N \l__salim_startexpr_tl
\tl_new:N \l__salim_endexpr_tl
\int_new:N \l__salim_start_int
\int_new:N \l__salim_end_int
\regex_const:Nn \l__salim_range_regex { \A (\d*) \- (\d*) \Z }

% Internal function that handles non-degenerate, ready-to-use input
\cs_new_protected:Npn \__salim_colorrange:nnn #1#2#3
  {
    % Deliver all characters before the chosen range
    \tl_range:nnn { #3 } { 1 } { \l__salim_start_int - 1 }
    % Deliver the characters in the chosen range with the desired color
    \textcolor {#1}
      { \tl_range:nnn { #3 } { \l__salim_start_int } { \l__salim_end_int } }
    % Deliver all characters after the chosen range
    \tl_range:nnn { #3 } { \l__salim_end_int + 1 } { -1 }
  }

\cs_new_protected:Npn \salim_colorrange:nnn #1#2#3
  {
    \regex_extract_once:NnNTF \l__salim_range_regex {#2} \l_tmpa_seq
      {
        \tl_set:Nx \l__salim_startexpr_tl { \seq_item:Nn \l_tmpa_seq { 2 } }
        \tl_set:Nx \l__salim_endexpr_tl { \seq_item:Nn \l_tmpa_seq { 3 } }

        \int_set:Nn \l__salim_start_int
          {
            \tl_if_empty:NTF \l__salim_startexpr_tl { 1 }
              { \l__salim_startexpr_tl }
          }
        \int_set:Nn \l__salim_end_int
          {
            \tl_if_empty:NTF \l__salim_endexpr_tl { -1 }
              { \l__salim_endexpr_tl }
          }

        \bool_lazy_any:nTF
          {
            { \int_compare_p:nNn { \l__salim_start_int } = { 0 } }
            { \int_compare_p:nNn { \l__salim_end_int } = { 0 } }
          }
          { \msg_error:nnn { salim } { zero-bound-in-range-expression } {#2} }
          {
            \bool_if:nTF
              {
                \int_compare_p:nNn
                  { \l__salim_start_int } > { \tl_count:n {#3} }
                ||
                ! \int_compare_p:nNn { \l__salim_end_int } = { -1 }
                && \int_compare_p:nNn { \l__salim_start_int } >
                                      { \l__salim_end_int }
              }
              {#3}
              { \__salim_colorrange:nnn {#1} {#2} {#3} }
          }
      }
      { \msg_error:nnn { salim } { invalid-range-expression } {#2} }
  }

\NewDocumentCommand \colorrange { O{red} m m }
  {% #1 = color to use, #2 = range, #3 = word
    \salim_colorrange:nnn {#1} {#2} {#3}
  }

\ExplSyntaxOff

\begin{document}

\colorrange{4-6}{examination}

\colorrange[blue]{1-3}{examination}

\colorrange[blue]{-3}{examination}

\colorrange[green!50!black]{4-11}{examination}

\colorrange[green!50!black]{4-}{examination}

\colorrange{-}{examination}

\bigskip

% Cases with degenerate input
\colorrange{5-4}{examination}

\colorrange{12-4}{examination}

\colorrange{12-}{examination}

\colorrange{-15}{examination}

\end{document}

在此处输入图片描述

相关内容