更改大写字母的颜色

更改大写字母的颜色

有没有办法定义一个命令来改变输入字符串中任何大写字母的颜色?

当我输入“LaTeX 字符串大写”时,找到的大多数结果都是将每个单词的首字母大写的结果。这里我想处理字符串的所有大写字母。

我知道 TeX 确实很棒,原因有很多,但当涉及到实际编程时,我真的觉得没有其他东西能与之媲美。我希望我不会冒犯任何人,尽管我非常感激 LaTeX 的存在,但有时我希望 TeX 的语法在实际编程时更传统。

答案1

如果您有输入字符串作为参数,您可以使用正则表达式来完成此操作。

\documentclass{article}
\usepackage{xparse}
%\usepackage{l3regex} % only with expl3 before June 2017
\usepackage{xcolor}


\ExplSyntaxOn
\NewDocumentCommand{\colorcap}{ O{blue} m }
 {
  \sheljohn_colorcap:nn { #1 } { #2 }
 }

\tl_new:N \l__sheljohn_colorcap_input_tl
\cs_new_protected:Npn \sheljohn_colorcap:nn #1 #2
 {
  % store the string in a variable for usage with \regex_replace_all:nnN
  \tl_set:Nn \l__sheljohn_colorcap_input_tl { #2 }
  \regex_replace_all:nnN
   { ([A-Z]+) } % search a capital letter (or more)
   { \c{textcolor}\cB\{#1\cE\}\cB\{\1\cE\} } % replace the match with \textcolor{#1}{<match>}
   \l__sheljohn_colorcap_input_tl
  \tl_use:N \l__sheljohn_colorcap_input_tl
 }
\ExplSyntaxOff

\begin{document}
\colorcap{Once Upon a Time}

\colorcap[red]{Once Upon a Time}
\end{document}

在此处输入图片描述

笔记

替换字符串的语法有点复杂,但并不难:

  • \c{textcolor}表示“控制序列\textcolor
  • \cB\{意思是“一个具有正常功能的开口括号⁣egin 集团
  • \cE\}表示“具有正常功能的右括号和组

因此,替换文本可以理解为

\textcolor{#1}{<match>}

其中#1是 的可选参数\colorcap

该版本还支持重音,只要使用宏以“传统”方式输入即可。

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

\ExplSyntaxOn
\NewDocumentCommand{\colorcap}{ O{blue} m }
 {
  \sheljohn_colorcap:nn { #1 } { #2 }
 }

\tl_new:N \l__sheljohn_colorcap_input_tl
\cs_new_protected:Npn \sheljohn_colorcap:nn #1 #2
 {
  % store the string in a variable
  \tl_set:Nn \l__sheljohn_colorcap_input_tl { #2 }
  \regex_replace_all:nnN
    % search a capital letter (or more)
    { ([A-Z]+|\cC.\{?[A-Z]+\}?) }
    % replace the match with \textcolor{#1}{<match>}
    { \c{textcolor}\cB\{#1\cE\}\cB\{\1\cE\} }
    \l__sheljohn_colorcap_input_tl
  \tl_use:N \l__sheljohn_colorcap_input_tl
 }
\ExplSyntaxOff

\begin{document}
\colorcap{\`Once \r{U}pon a Time}

\colorcap[red]{Once Upon a Time}
\end{document}

在此处输入图片描述

这里\cC.匹配任何控制序列、\{?零个或一个左括号、\}?零个或一个右括号,因此\`O\r{U}输入都会被捕获。

答案2

此解决方案展示了一种主动字符方法,该方法(尽管设置繁琐)可让大写字母自动着色。但由于主动字母往往会破坏宏,因此我提供了禁用它的方法。此修订解决方案提供了以下宏:

\capcoloron[color]将所有大写字母变为此颜色(默认为红色)

\capcoloroff关闭活动字符并恢复原始大写字母定义

\coloron{letter}{color}仅将此 [非活动] 字母变为活动字母,并将其设置为指定颜色

\coloroff{letter}仅关闭这个活动字符,并恢复其原始定义。

唯一的怪癖是,要更改已激活的大写字母的颜色,必须先关闭颜色,然后再打开。这是我的 MWE:

\documentclass{article}
\usepackage{xcolor}
\usepackage{stringstrings}

\let\sva A\let\svb B\let\svc C\let\svd D\let\sve E\let\svf F\let\svg G
\let\svh H\let\svi I\let\svj J\let\svk K\let\svl L\let\svm M\let\svn N
\let\svo O\let\svp P\let\svq Q\let\svr R\let\svs S\let\svt T\let\svu U
\let\svv V\let\svw W\let\svx X\let\svy Y\let\svz Z
\catcode`A=\active\catcode`B=\active\catcode`C=\active\catcode`D=\active
\catcode`E=\active\catcode`F=\active\catcode`G=\active\catcode`H=\active
\catcode`I=\active\catcode`J=\active\catcode`K=\active\catcode`L=\active
\catcode`M=\active\catcode`N=\active\catcode`O=\active\catcode`P=\active
\catcode`Q=\active\catcode`R=\active\catcode`S=\active\catcode`T=\active
\catcode`U=\active\catcode`V=\active\catcode`W=\active\catcode`X=\active
\catcode`Y=\active\catcode`Z=\active
\newcommand\colorcapon[1][red]{%
  \catcode`A=\active\def A{\textcolor{#1}{\sva}}%
  \catcode`B=\active\def B{\textcolor{#1}{\svb}}%
  \catcode`C=\active\def C{\textcolor{#1}{\svc}}%
  \catcode`D=\active\def D{\textcolor{#1}{\svd}}%
  \catcode`E=\active\def E{\textcolor{#1}{\sve}}%
  \catcode`F=\active\def F{\textcolor{#1}{\svf}}%
  \catcode`G=\active\def G{\textcolor{#1}{\svg}}%
  \catcode`H=\active\def H{\textcolor{#1}{\svh}}%
  \catcode`I=\active\def I{\textcolor{#1}{\svi}}%
  \catcode`J=\active\def J{\textcolor{#1}{\svj}}%
  \catcode`K=\active\def K{\textcolor{#1}{\svk}}%
  \catcode`L=\active\def L{\textcolor{#1}{\svl}}%
  \catcode`M=\active\def M{\textcolor{#1}{\svm}}%
  \catcode`N=\active\def N{\textcolor{#1}{\svn}}%
  \catcode`O=\active\def O{\textcolor{#1}{\svo}}%
  \catcode`P=\active\def P{\textcolor{#1}{\svp}}%
  \catcode`Q=\active\def Q{\textcolor{#1}{\svq}}%
  \catcode`R=\active\def R{\textcolor{#1}{\svr}}%
  \catcode`S=\active\def S{\textcolor{#1}{\svs}}%
  \catcode`T=\active\def T{\textcolor{#1}{\svt}}%
  \catcode`U=\active\def U{\textcolor{#1}{\svu}}%
  \catcode`V=\active\def V{\textcolor{#1}{\svv}}%
  \catcode`W=\active\def W{\textcolor{#1}{\svw}}%
  \catcode`X=\active\def X{\textcolor{#1}{\svx}}%
  \catcode`Y=\active\def Y{\textcolor{#1}{\svy}}%
  \catcode`Z=\active\def Z{\textcolor{#1}{\svz}}%
}
\def\colorcapoff{%
  \catcode`A=11\let A\sva%
  \catcode`B=11\let B\svb%
  \catcode`C=11\let C\svc%
  \catcode`D=11\let D\svd%
  \catcode`E=11\let E\sve%
  \catcode`F=11\let F\svf%
  \catcode`G=11\let G\svg%
  \catcode`H=11\let H\svh%
  \catcode`I=11\let I\svi%
  \catcode`J=11\let J\svj%
  \catcode`K=11\let K\svk%
  \catcode`L=11\let L\svl%
  \catcode`M=11\let M\svm%
  \catcode`N=11\let N\svn%
  \catcode`O=11\let O\svo%
  \catcode`P=11\let P\svp%
  \catcode`Q=11\let Q\svq%
  \catcode`R=11\let R\svr%
  \catcode`S=11\let S\svs%
  \catcode`T=11\let T\svt%
  \catcode`U=11\let U\svu%
  \catcode`V=11\let V\svv%
  \catcode`W=11\let W\svw%
  \catcode`X=11\let X\svx%
  \catcode`Y=11\let Y\svy%
  \catcode`Z=11\let Z\svz%
}
\newcommand\coloron[2]{%
  \if\sva#1\catcode`A=\active\def A{\textcolor{#2}{\sva}}\else%
  \if\svb#1\catcode`B=\active\def B{\textcolor{#2}{\svb}}\else%
  \if\svc#1\catcode`C=\active\def C{\textcolor{#2}{\svc}}\else%
  \if\svd#1\catcode`D=\active\def D{\textcolor{#2}{\svd}}\else%
  \if\sve#1\catcode`E=\active\def E{\textcolor{#2}{\sve}}\else%
  \if\svf#1\catcode`F=\active\def F{\textcolor{#2}{\svf}}\else%
  \if\svg#1\catcode`G=\active\def G{\textcolor{#2}{\svg}}\else%
  \if\svh#1\catcode`H=\active\def H{\textcolor{#2}{\svh}}\else%
  \if\svi#1\catcode`I=\active\def I{\textcolor{#2}{\svi}}\else%
  \if\svj#1\catcode`J=\active\def J{\textcolor{#2}{\svj}}\else%
  \if\svk#1\catcode`K=\active\def K{\textcolor{#2}{\svk}}\else%
  \if\svl#1\catcode`L=\active\def L{\textcolor{#2}{\svl}}\else%
  \if\svm#1\catcode`M=\active\def M{\textcolor{#2}{\svm}}\else%
  \if\svn#1\catcode`N=\active\def N{\textcolor{#2}{\svn}}\else%
  \if\svo#1\catcode`O=\active\def O{\textcolor{#2}{\svo}}\else%
  \if\svp#1\catcode`P=\active\def P{\textcolor{#2}{\svp}}\else%
  \if\svq#1\catcode`Q=\active\def Q{\textcolor{#2}{\svq}}\else%
  \if\svr#1\catcode`R=\active\def R{\textcolor{#2}{\svr}}\else%
  \if\svs#1\catcode`S=\active\def S{\textcolor{#2}{\svs}}\else%
  \if\svt#1\catcode`T=\active\def T{\textcolor{#2}{\svt}}\else%
  \if\svu#1\catcode`U=\active\def U{\textcolor{#2}{\svu}}\else%
  \if\svv#1\catcode`V=\active\def V{\textcolor{#2}{\svv}}\else%
  \if\svw#1\catcode`W=\active\def W{\textcolor{#2}{\svw}}\else%
  \if\svx#1\catcode`X=\active\def X{\textcolor{#2}{\svx}}\else%
  \if\svy#1\catcode`Y=\active\def Y{\textcolor{#2}{\svy}}\else%
  \if\svz#1\catcode`Z=\active\def Z{\textcolor{#2}{\svz}}\else%
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
}
\newcommand\coloroff[1]{\catcode`#1=11%
  \edef\tmp{\detokenize{#1}}%
  \caselower[q]{\tmp}%
  \expandafter\let\expandafter#1\csname sv\thestring\endcsname%
}
\catcode`A=11\catcode`B=11\catcode`C=11\catcode`D=11\catcode`E=11
\catcode`F=11\catcode`G=11\catcode`H=11\catcode`I=11\catcode`J=11
\catcode`K=11\catcode`L=11\catcode`M=11\catcode`N=11\catcode`O=11
\catcode`P=11\catcode`Q=11\catcode`R=11\catcode`S=11\catcode`T=11
\catcode`U=11\catcode`V=11\catcode`W=11\catcode`X=11\catcode`Y=11
\catcode`Z=11

\parskip 1em

\begin{document}

\colorcapon[cyan]
\verb|\colorcapon[color]| will change all caps to the specified color\\
A Test of The Active Method (\verb|Even in \Verbatim|)

\colorcapoff
\verb|\colorcapoff| will restore all things to the original LaTeX setting\\
A Test of The Active Method

\coloron{M}{blue}\coloron{A}{red}\coloron{T}{orange}
\verb|\coloron{letter}{color}| will turn an inactive letter active with the
specified color, done here to letters ``M'', ``A'', and ``T'':\\
A Test of The Active Method

\coloroff{A}
\verb|\coloroff{letter}| will restore that letter to the original LaTeX
setting, here done to the letter ``A'':\\
A Test of The Active Method

To change The color an already active letter, one must first turn the color off
and then set the color anew, as done here to the letter ``T'':\\
\coloroff{T}\coloron{T}{green}
A Test of The Active Method
\end{document}

在此处输入图片描述


原始解决方案:

这表明传统和危险的主动字符方法。主动方法需要相当多的“设置”代码,但在使用时会自动更改大写字母的颜色。

因为它是危险的\colorcapon,我提供了使用 和 进入和退出主动方法的方法\colorcapoff。我只设置了 3 个字母……但其他 23 个字母也以类似的方式设置。

\documentclass{article}
\usepackage{xcolor}
\begin{document}
TRADITIONAL APPROACH:

\textcolor{red}{A} letter can have its color \textcolor{blue!60}{C}hanged
with the \textcolor{cyan!80}{U}se of \verb|\textcolor|.\vspace{2em}

ACTIVE CHARACTER APPROACH

\let\sva A
\let\svc C
\let\svu U
\catcode`A=\active
\catcode`C=\active
\catcode`U=\active
\def\colorcapon{%
  \catcode`A=\active\def A{\textcolor{red}{\sva}}%
  \catcode`C=\active\def C{\textcolor{blue!60}{\svc}}%
  \catcode`U=\active\def U{\textcolor{cyan!80}{\svu}}%
}
\def\colorcapoff{%
  \catcode`A=11\let A\sva%
  \catcode`C=11\let C\svc%
  \catcode`U=11\let U\svu%
}
\catcode`A=11
\catcode`C=11
\catcode`U=11

\colorcapon
A letter can have its color Changed with the Use of\\
\verb|\textcolor.  Wow.  And I can Use it in verbatim|.\vspace{2em}\colorcapoff


RESTORED TO ORIGINAL

A letter can have its color Changed with the Use of \verb|\textcolor|.

\end{document}

在此处输入图片描述

答案3

这是用 LuaLaTeX 编写的一段代码,新命令\capme接受参数,使用 Lua 并通过正则表达式和unicode.utf8.gsub函数将预选字符转换为新命令\colorme。我尝试实现常用单词以及标记单词(以字母开头的单词{,例如\textit{Ňouma})的更改。我已经用一些带变音符号的字母扩展了一系列常见的大写字母(A 到 Z),以展示其附加功能。

\noexpand我找到了一种不遵守我在之前的 LuaTeX 示例中经常使用的命令的方法。我正在扩展本地组中的各个命令,在本例中它是\textit命令。但是,如果这是节省打字时间的正确方法,则需要更复杂的示例和数据。

我们运行lualatex mal-capitalization.tex,我附上文件和结果预览。

% lualatex mal-capitalization.tex
\documentclass[a4paper]{article}
%\usepackage{fontspec} % It also loads Latin Modern.
%\usepackage{luacode}
\usepackage{luatextra} % a recommended way of loading luacode (and fontspec) package
\pagestyle{empty}
\usepackage{xcolor}

\begin{document}
\begin{luacode*}
selection="[%uČĎŇŘŠŤŽ]" -- the characters we consider to be coloured
function capme(text)
text=" "..text -- the first letter of a string is also considered for change
text=unicode.utf8.gsub(text, "([%s{])("..selection..")", "%1\\colorme{%2}")
text=unicode.utf8.sub(text,2) -- delete that extra space
print(text) -- a new text written to the terminal
tex.print(text) -- deliver the result back to TeX
end -- function capme
\end{luacode*}

\def\capme#1{%
    % We neither need \noexpand\textit nor \noexpand{#1} and \\textit.
    \begingroup % Let's redefining begin!
    \let\oldtextit=\textit
    \def\textit##1{\noexpand\oldtextit{##1}}
    \directlua{capme([[#1]])}
      \endgroup % \textit returns to its common definition.
    }
\def\colorme#1{{\color{red}\bfseries#1}}

% A small demonstration of using it.
Hello World! \capme{Hello Capitalized WORLD!} 
Several words with diacritics: \capme{Čenich. \textit{Ňouma.} 
Ďagilev. Šiška. Živočich.} I'm back in \textit{common} text.
\end{document}

这是使用此代码片段的示例:常用词和以变音字母开头的几个单词。

答案4

使用 OPmac 宏是可能的:

\input opmac

\def\setupclr #1{\ifx\relax#1\else \replacestrings{#1}{\clr{#1}}\expandafter\setupclr\fi}
\def\clrstring#1{\def\tmpb{#1}\setupclr ABCDEFGHIJKLMNOPQRSTUVWXYZ\relax \tmpb}
\def\clr#1{{\localcolor\Red#1}}

\clrstring{Once Upon a Time.}

\bye

编辑:如果也必须处理组中的大写字母,那么可以使用\repl来自\tl_replace_all:Nnn 递归子组并定义

\def\replX#1{\ifnum\uccode`#1=`#1 \clr{#1}\else #1\fi}

相关内容