考虑这个例子:
\documentclass{article}
\usepackage{ifthen}
\newcommand{\deftitle}[1]{%
\ifthenelse{\equal{#1}{Aa}}{aaa}{}%
\ifthenelse{\equal{#1}{Bb}}{bbb}{}%
}%
\begin{document}
\MakeUppercase sffdfd
\MakeUppercase \deftitle{Aa}
\end{document}
虽然\MakeUppercase sffdfd
运行完美,但\MakeUppercase \deftitle{Aa}
结果却出错。如何应用于\MakeUppercase
的输出\newcommand
?
答案1
您的设置失败,因为\MakeUppercase
将抓取一个参数,如果您不使用括号,这将是它看到的第一个标记。代码中的第一个标记是\deftitle
。下一步\MakeUppercase
尝试尽可能扩展其参数,但由于它是在没有参数的情况下被抓取的,因此\deftitle
这将失败!正确的方法是先\deftitle
用其参数进行扩展,然后应用于\MakeUppercase
由此产生的第一个字符。如果不更改您的设置,则无法完成此操作。
以下假设您\deftitle
实际上可以完全扩展工作(这对于您的 MWE 来说是正确的)。
此处的代码可能非常不稳定,具体取决于输入(非常适合\deftitle
生成 ASCII 输出)。请参阅下文以了解更好的方法。
由于\ifthenelse
不可扩展,您无法直接使用它来产生所需的结果。因此,下面定义了两个测试(这样做而不是加载定义所有测试的包,仅用于教育目的)。
第一个测试是针对空参数 ( ) 的测试\myifempty
。它的工作原理是首先将参数转换为字符串,然后\relax
使用进行比较\if
。如果参数不为空,\relax
将与 other 类别的字符进行比较,因此结果为 false。如果它为空,\relax
将与第二个进行比较\relax
,结果为 true。
第二个测试比较两个字符串(\myifeq
),如果它们确实相同,则结果为 true。为此,我使用该包在未内置宏的引擎中pdftexcmds
获取宏。\pdf@strcmp
接下来我们需要一个宏,它在将输入交给之前将其完全展开\MakeUppercase
。为此,我使用\edef
扩展并使用检查结果是否为空\ifx\mytmp\@empty
。之后\MakeUppercase
获取完全展开的第一个标记\mytmp
作为其参数。
\documentclass[]{article}
\usepackage{pdftexcmds}
\makeatletter
\newcommand\myifempty[1]
{%
\if\relax\detokenize{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\newcommand\myifeq[2]
{%
\ifnum\pdf@strcmp{\detokenize{#1}}{\detokenize{#2}}=0
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\newcommand\ExpandAndUppercaseFirst[1]
{%
\begingroup
\edef\mytmp{#1}%
\unless\ifx\mytmp\@empty
\expandafter\MakeUppercase\mytmp
\fi
\endgroup
}
\makeatletter
\newcommand\deftitle[1]
{%
\myifeq{#1}{Aa}{aaa}{}%
\myifeq{#1}{Bb}{bbb}{}%
}
\begin{document}
\ExpandAndUppercaseFirst{\deftitle{Aa}}
\end{document}
使用编程层,相同的宏,但更加稳定expl3
:
\documentclass[]{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \ExpandAndUppercaseFirst { m }
{
\text_titlecase_first:n { #1 }
}
\NewExpandableDocumentCommand \deftitle { m }
{%
\str_if_eq:nnT { #1 } { Aa } { aaa }
\str_if_eq:nnT { #1 } { Bb } { bbb }
}
\ExplSyntaxOff
\begin{document}
\ExpandAndUppercaseFirst{\deftitle{Aa}}
\end{document}