根据字母大小写更改字符串的宏

根据字母大小写更改字符串的宏

我想定义一个新的 mathmode 命令,例如:

  • 输入是一个字符串s;
  • 输出是相同的字符串,其中每个字符的字体根据字符是小写还是大写而改变。

用伪代码来说,它看起来像这样:

\newcommand{\cat}{
    forEach (character char in #1) {
        if (isLowerCase(char)) -> print \mathit{char}
        else -> print \mathcal{char}
    }
}

似乎我可以使用if/elseifthenelse包中的代码ifthen。我找不到如何操作:

  • 从字符串中提取字符;
  • 对每个字符进行循环;
  • 检查字符是否是小写。

顺便说一句,如果有人知道关于定义命令的可读但又详尽的参考,我将不胜感激(我只能找到太基础或“超出我理解范围”的参考)。

感谢您的帮助!

PS:如果有人需要一些背景信息,我正在研究范畴论,其中范畴的典型字体是 \mathcal。由于 mathcal 中的小写字母没有定义,所以我需要找到一种解决方法。


编辑:我在这里描述我对 Ulrike Fischer 解决方案的理解,因为它可能对其他人有用。

\ExplSyntaxOn
\NewDocumentCommand\cat{m}
 {
   \tl_set:Nn\l_tmpa_tl {#1}
   \regex_replace_all:nnN {[a-z]}{\c{mathit}\cB\{\0\cE\}}\l_tmpa_tl
   \regex_replace_all:nnN {[A-Z]}{\c{mathcal}\cB\{\0\cE\}}\l_tmpa_tl
   \l_tmpa_tl
 }
\ExplSyntaxOff
  • ExplSyntaxOn...ExplSyntaxOff:更改代码机制,其中空格被忽略,“:”和“_”被视为字母。访问函数和变量时需要。请参阅 interface3.pdf,第 7 页。
  • \NewDocumentCommand \cat {m} {...}:创建一个新的文档级函数。首先应描述函数名称(\cat)、参数集( ,一个在函数代码中{m}引用的参数)和函数代码本身( )。请参阅 xparse.pdf,第 7 页。#1{...}
  • \tl_set:Nn \l_tmpa_tl {#1}\tl_set:Nn设置某个变量(或“标记列表”,因此)的值tlNn定义此函数的通常参数类型,N代表单个标记和n括号之间的标记列表。\l_tmpa_tl是本地临时分配标记列表的标准名称。
  • 的第一个参数\regex_replace_all:nnN是要替换的标记列表,例如{[a-z]}。第二个参数是如何处理这些标记,例如{\c{mathit}\cB\{\0\cE\}}\c{mathit}相当于\mathit(出于某种原因,您不能只写\mathit)。\0代表通过第一个参数选择的所有内容。出于某种原因,它应该被 包围\cB\{...\cE\}。最后,第三个参数是应用该函数的标记列表。
  • 最后\l_tpma_tl只是显示结果标记。

答案1

Ulrike 的回答很好,但我们可以通过删除不需要的字距来改进它。

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\AtBeginDocument{$\mathcal{\global\chardef\calfam=\fam}$}

\ExplSyntaxOn

\cs_new_protected:Nn \__trynopsis_cat_neg:n
 {
  \mathchoice
   { \__trynopsis_cat_neg_aux:Nn \textfont { #1 } }
   { \__trynopsis_cat_neg_aux:Nn \textfont { #1 } }
   { \__trynopsis_cat_neg_aux:Nn \scriptfont { #1 } }
   { \__trynopsis_cat_neg_aux:Nn \scriptscriptfont { #1 } }
 }
\cs_new_protected:Nn \__trynopsis_cat_neg_aux:Nn
 {
  \kern -\fontcharic#1\calfam`#2
 }

\NewDocumentCommand{\cat}{m}
 {
  \trynopsis_cat:n { #1 }
 }

\tl_new:N \l__trynopsis_cat_tl

\cs_new_protected:Nn \trynopsis_cat:n
 {
  \tl_set:Nn \l__trynopsis_cat_tl { #1 }
  \regex_replace_all:nnN
   { ([A-Z]) ([a-z]) } % search uppercase letter followed by a lowercase letter
   { \1 \c{__trynopsis_cat_neg:n} \1 \2 } % add a negative space in between
   \l__trynopsis_cat_tl
  \regex_replace_all:nnN
   { [A-Z]+ } % search any run of uppercase letters
   { \c{mathcal}\cB\{\0\cE\} } % enclose it in \mathcal
   \l__trynopsis_cat_tl
  \regex_replace_all:nnN
   { [a-z]+ } % search any run of lowercase letters
   { \c{mathit}\cB\{\0\cE\} } % enclose it in \mathit
   \l__trynopsis_cat_tl
  \regex_replace_all:nnN
   { \c{__trynopsis_cat_neg:n} \c{mathcal} }
   { \c{__trynopsis_cat_neg:n} }
   \l__trynopsis_cat_tl
  % deliver the new token list
  \tl_use:N \l__trynopsis_cat_tl
 }

\cs_new_protected:Nn \__trynopsis_cat_neg:
 {
  \mspace{-2mu}
 }

\ExplSyntaxOff

\begin{document}

$\cat{Set}\quad\cat{Grp}\quad\cat{Abc\_def}$

$\scriptstyle\cat{Set}\quad\cat{Grp}\quad\cat{Abc\_def}$

\end{document}

第四次替换将不需要的转换\__trynopsis_cat_neg:n \mathcal {<letter>}\__trynopsis_cat_neg:n {<letter>}

的目的\__trynopsis_cat_neg:n是删除大写(书法)字母后面跟着小写(斜体)字母时的多余空格。

在此处输入图片描述

答案2

假设参数中只有 aZ:

\documentclass{article}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\mycal{m}
 {
   \tl_set:Nn\l_tmpa_tl {#1}
   \regex_replace_all:nnN {[a-z]}{\c{mathit}\cB\{\0\cE\}}\l_tmpa_tl
   \regex_replace_all:nnN {[A-Z]}{\c{mathcal}\cB\{\0\cE\}}\l_tmpa_tl
   \l_tmpa_tl
 }
\ExplSyntaxOff
\begin{document}
$\mycal{abcABC}$
\end{document}

在此处输入图片描述

相关内容