在学习expl3
编程的过程中,我编写了一个函数来伪造“小型大写字母”,方法是循环遍历标记列表并放大所有大写字母的标记。代码目前“有效”,但我知道我经历了比需要的更多的麻烦。我的问题是:我怎样才能重写代码才能更好地利用所expl3
提供的功能?
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_if_eq:nnTF { VV }
\cs_generate_variant:Nn \tl_to_str:n { e }
\DeclareDocumentCommand\fakesmallcaps{m} {
\tl_new:N \__orig_tl
\tl_new:N \__modified_tl
\tl_set:Nn \__orig_tl {#1}
% Put all the spaces in groups so they don't get filtered out when we map over them.
\tl_replace_all:Nnn \__orig_tl { ~ } { {~} }
\tl_set:Nn \__modified_tl {
\tl_map_inline:Nn \__orig_tl {
\tl_set:Nn \__current_tl {##1}
\tl_set:NV \__uppercasecurrent_tl {\tl_upper_case:n {##1}}
\str_set:Nx \__orig_str {\tl_to_str:e {\__current_tl}}
\str_set:Nx \__uppercasecurrent_str {\tl_to_str:e {\__uppercasecurrent_tl}}
\tl_if_eq:VVTF {\__orig_str} {\__uppercasecurrent_str} {
{\Large \__orig_str}
}{
\__uppercasecurrent_str
}
}
}
\tl_use:N \__modified_tl
}
\ExplSyntaxOff
\fakesmallcaps{This Is Cool}
我知道使用正则表达式的解决方案这里,但我真的想“循环遍历标记”。我也尝试过但未能创建一个\bool__iscapital:n
可以在 内部使用的函数宏,因此,如果能提供这方面的指导,我将不胜感激!如果我能做类似的事情并保留颜色,\bool_if:nTF
那也将是一个巨大的优势。\fakesmallcaps{{\color{blue}The} Windy Road}
答案1
在这里,我没有使用 expl3,而是使用我的tokcycle
包来循环遍历标记。对于每个合适的标记,我应用\fauxsctok
,它模仿我在所引用的问题中的方法,使用 XeTeX/fontspec 伪造小型大写字母?。
使用引用问题中的方法的优点tokcycle
是,宏和空格可以回显,而无需尝试将小写字母应用于它们。此外,小写字母可以扩展进入环境内的群体。
困难在于,盲目地将每个 cat-11 标记小写化,但仅限于那些要排版的标记。因此,在 中\color{blue}
,我们希望避免将排版命令应用于blue
,因为它是一个宏参数,而不是用于排版的文本!
一般来说,TeX 无法知道宏是否与参数相关联(以及有多少个参数)。因此,在这里,我必须编写可能出现在环境中的宏名称列表,需要一个不可排版的参数。在此实现中,我将该列表限制为需要单个参数“保护”的宏。当前列表中编写的宏是\color
和\textcolor
。虽然后者接受两个参数,但只有第一个参数需要保护以免被排版。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor,tokcycle,graphicx}
\def\Hscale{.83}\def\Vscale{.72}\def\Cscale{1.00}
\newif\ifskiparg
\newcommand\fauxsctok[1]{%
\ifnum`#1>``\ifnum`#1<`\{\scalebox{\Hscale}[\Vscale]{\uppercase{#1}}\else%
\scalebox{\Cscale}[1]{#1}\fi\else\scalebox{\Cscale}[1]{#1}\fi}
\tokcycleenvironment\fauxsc
{\addcytoks{\fauxsctok{##1}}}% CHARACTER DIRECTIVE
{\ifskiparg\addcytoks{##1}\else\processtoks{##1}\fi\aftergroup
\skipargfalse}% GROUP DIRECTIVE
{\addcytoks{##1}%
\ifx\color##1\skipargtrue\fi
\ifx\textcolor##1\skipargtrue\fi
}% MACRO DIRECTIVE
{\addcytoks{##1}}% SPACE DIRECTIVE
\begin{document}
\fauxsc{\color{blue}The} Windy Road
\textcolor{blue}{The} Windy Road\endfauxsc
\ and back to normal.
\end{document}
伪环境通过循环环境的标记来 fauxsc
构建标记列表( )。\cytoks
人物(不是 catcode 0,1,2,10 的东西)已经\fauxsctok
应用于它们(在\cytoks
正在构建的令牌列表内)。
如果一个团体当\ifskiparg
设置为 true 时,则该组仅被回显\cytoks
而不发生改变。但是,当\ifskiparg
为 false 时,该组的每个标记都将通过标记循环进行处理。无论哪种情况,\ifskiparg
在组结束后都会将其重置为 false。
宏只是回显到 中\cytoks
。但是,必须将宏名称与编程列表进行比较,以查看是否\ifskiparg
需要设置为 true。最后,
空间所遇到的只是回响\cytoks
。