你能写一个宏,让每个字符都变成彩虹的下一种颜色吗

你能写一个宏,让每个字符都变成彩虹的下一种颜色吗

我想编写一个 LaTeX 文件,其中每个字符都是彩虹的下一种颜色,但我不知道如何在新命令中对其进行编程。

因此,如果我想写文本“Hello World”,我希望“H”为红色,“e”为橙色,“l”为黄色,等等。

先感谢您!

答案1

欢迎来到 TeX.SX!以下是从“复杂示例”改编而来的方法之一这里, 用一个来自 egreg 的技巧处理空间:

\documentclass{article}
\usepackage[svgnames]{xcolor}
\usepackage{xparse}

\ExplSyntaxOn

\msg_new:nnn { myrainbowtext } { not-enough-elements-in-color-vector }
  { Not~enough~elements~in~color~vector. }

\seq_new:N \l_my_color_vector_seq
% We are going to copy \g__my_saved_color_vector_seq to this one before
% starting a set of color operations, then from pop from it as we need to get
% each next color.
\seq_new:N \g__my_work_color_vector_seq
\seq_new:N \g__my_saved_color_vector_seq

\cs_new_protected:Npn \my_set_local_color_vector:n #1
  {
    \seq_set_from_clist:Nn \l_my_color_vector_seq {#1}
  }

\cs_new_protected:Nn \my_use_current_color_vector:
  {
    \seq_gset_eq:NN \g__my_work_color_vector_seq \l_my_color_vector_seq
    \seq_gset_eq:NN \g__my_saved_color_vector_seq \l_my_color_vector_seq
  }

\cs_new_protected:Npn \my_set_color_vector:n #1
  {
    \my_set_local_color_vector:n {#1}
    \my_use_current_color_vector:
  }

\cs_generate_variant:Nn \my_set_color_vector:n { x }

\NewDocumentCommand \myUseCurrentColorVector { }
  {
    \my_use_current_color_vector:
  }

\NewDocumentCommand \mySetColorVector { m }
  {
    \my_set_color_vector:n {#1}
  }

% #1: a token (typically a control sequence)
\cs_new_protected:Npn \my_apply_current_vector_color:N #1
  {
    \seq_gpop_left:NN \g__my_work_color_vector_seq \l_tmpa_tl

    \tl_if_eq:NNTF \l_tmpa_tl \q_no_value
      {
        \msg_error:nn { myrainbowtext }
          { not-enough-elements-in-color-vector }
      }
      % Apply command #1 to the color contained in \l_tmpa_tl
      { \exp_args:NV #1 \l_tmpa_tl }
  }

% #1: a <boolean expression> indicating whether looping is enabled
% #2: a token (typically a control sequence) passed to
%     \my_apply_current_vector_color:N
\cs_new_protected:Npn \my_apply_current_vector_color:nN #1#2
  {
    \bool_if:nT {#1}
      {                         % looping allowed -> restore the work vector
        \seq_if_empty:NT \g__my_work_color_vector_seq
          {
            \seq_gset_eq:NN \g__my_work_color_vector_seq
                            \g__my_saved_color_vector_seq
          }
      }

    \my_apply_current_vector_color:N #2
  }

\prg_generate_conditional_variant:Nnn \tl_if_blank:n { x } { TF }

% #1: <boolean expression> indicating whether to loop
% #2: command to apply to each element of #3 (e.g., \textcolor)
% #3: token list
\cs_new_protected:Npn \my_tl_map_colorize:nNn #1#2#3
  {
    \tl_set:Nn \l_tmpa_tl {#3}
    % Trick from egreg <https://tex.stackexchange.com/a/491669/73317>
    \tl_replace_all:Nnn \l_tmpa_tl { ~ } { \c_space_tl }

    \tl_map_inline:Nn \l_tmpa_tl
      {
        \tl_if_blank:xTF {##1}
          { ~ }                 % don't use any color for spaces
          { \my_apply_current_vector_color:nN {#1} #2 {##1} }
      }
  }

\NewDocumentCommand \myColorize { s m }
  {
    \my_use_current_color_vector:
    \exp_args:Nx \my_tl_map_colorize:nNn
      { \IfBooleanTF {#1} { \c_true_bool } { \c_false_bool } }
    \textcolor {#2}
  }

% #1: color model
% #2: stem for color names
% #3: color specs (seq)
\cs_new_protected:Npn \my_define_color_series:nnN #1#2#3
  {
    \seq_set_eq:NN \l_tmpa_seq #3
    \int_step_inline:nnn { 1 } { \seq_count:N #3 }
      {
        \seq_gpop_left:NN \l_tmpa_seq \l_tmpa_tl
        \exp_args:Nnnx
          \definecolor { #2 ##1 } {#1} { \tl_use:N \l_tmpa_tl }
      }
  }

\seq_new:N \l__my_batch_define_colors_seq

% #1: color model
% #2: stem for color names
% #3: color specs (clist)
\cs_new_protected:Npn \my_batch_define_colors:nnn #1#2#3
  {
    \seq_set_from_clist:Nn \l__my_batch_define_colors_seq {#3}
    \my_define_color_series:nnN {#1} {#2} \l__my_batch_define_colors_seq
  }

\NewDocumentCommand \myBatchDefineColors { m m m }
  {
    \my_batch_define_colors:nnn {#1} {#2} {#3}
  }

% #1: first color index (default: 1)
% #2: last color index
% #3: stem for color names
\cs_new_protected:Npn \my_batch_set_color_vector:nnn #1#2#3
  {
    \seq_clear:N \l_tmpa_seq
    \int_step_inline:nnn {#1} {#2}
      { \seq_gput_right:Nn \l_tmpa_seq { #3 ##1 } }
    \my_set_color_vector:x { \seq_use:Nn \l_tmpa_seq { , } }
  }

\NewDocumentCommand \myBatchSetColorVector { O{1} m m }
  {
    \my_batch_set_color_vector:nnn {#1} {#2} {#3}
  }

\ExplSyntaxOff

% Define MyColor1, MyColor2, MyColor3, MyColor4, MyColor5 and MyColor6 in one
% go.
\myBatchDefineColors{rgb}{MyColor}{%
  {0.4,0.2,0.6},
  {0.2,1.0,0.1},
  {0.3,0.5,0.8},
  {0.9,0.4,0.5},
  {1.0,0.9,0.1},
  {0.1,0.8,0.7}
}

\begin{document}
% Simplest way to define the current color vector:
\mySetColorVector{gray!60, DarkSlateBlue, MediumVioletRed, DarkCyan}%
% The unstarred version wouldn't loop over the color vector, and thus would
% need at least as many elements in said vector as there are characters in the
% argument of \myColorize (not the case here).
\myColorize*{This is a test.}

{% The notion of “current color vector” respects grouping, as we are about to
 % demonstrate.
 %
 \myBatchSetColorVector{6}{MyColor}% this is a shortcut for
 % \mySetColorVector{MyColor1,MyColor2,MyColor3,MyColor4,MyColor5,MyColor6}%
 %
 \myColorize*{Once upon a time in a galaxy far, far away...}%
}

\myColorize*{Back to the first color vector.}
\end{document}

截屏

相关内容