我想这只是一个简单的问题,但我被难住了。
我需要翻译工作来创建类似这样的内容:
\newcommand\dog{cane}
\newcommand\Dog{Cane}
我没有创建两个函数,而是问自己是否可以创建类似的东西
\aCustomFunction{dog}{cane}
\begin{document}
\dog
\Dog
\end{document}
这为我编译了字符串的大写版本和小写版本。
软件包xstring
给了我\StrLeft
并\StrGobbleLeft
取第一个字母,命令\uppercase{}
也很有用。但如果我尝试定义一个函数,我会在扩展时迷失方向\expandafter
:
%This is the uppercase string manipulation: dog -> Dog (or cane -> Cane)
\newcommand\FirstLetterUppercase[1]{\uppercase{\StrLeft{#1}{1}}\StrGobbleLeft{#1}{1}}
%This is the double define function
\newcommand\newUpperCommand[2]{%
%This is the lowercase function: \newcommand\dog{cane}
\expandafter\newcommand\csname#1\endcsname{#2}%
%This is the uppercase function: \newcommand\Dog{Cane}
\expandafter\newcommand\csname\FirstLetterUppercase{#1}\endcsname{\FirstLetterUppercase{#2}}%
}
这种方式当然是错误的。你能帮助我吗?
谢谢你!
答案1
一种方法stringstrings
\documentclass{article}
\usepackage{stringstrings}
\newcommand\aCustomFunction[2]{%
\expandafter\def\csname #1\endcsname{#2}%
\capitalizewords[q]{#1}%
\expandafter\def\csname\thestring\endcsname{\capitalizewords{#2}}%
}
\begin{document}
\aCustomFunction{dog}{cane}
\dog
\Dog
\end{document}
事实上,上述方法\capitalizewords
对 的每个实例都会重新调用\Dog
。可以通过以下方式避免这种情况,因此\Dog
确实包含字符串“Cane”:
\documentclass{article}
\usepackage{stringstrings}
\newcommand\aCustomFunction[2]{%
\expandafter\def\csname #1\endcsname{#2}%
\capitalizewords[q]{#1}%
\edef\tmp{\thestring}%
\capitalizewords[q]{#2}%
\expandafter\edef\csname\tmp\endcsname{\thestring}%
}
\begin{document}
\aCustomFunction{dog}{cane}
\dog
\Dog
\end{document}
请注意,这两种方法都允许间接语法,例如
\def\blah{this is a test}
\aCustomFunction{cat}{\blah}
\cat
\Cat
\blah
然而,只有原始方法才能在中途重新定义时跟踪事物。
答案2
和expl3
:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\CustomFunction}{mom}
{% #1 = command name, #2 = optional initial, #3 = string
\IfNoValueTF{#2}
{
\verdoja_custom_function:ffff
{ \tl_head:n {#1} } { \tl_tail:n {#1} }
{ \tl_head:n {#3} } { \tl_tail:n {#3} }
}
{
\verdoja_custom_function:ffnn
{ \tl_head:n {#1} } { \tl_tail:n {#1} }
{ #2 } { #3 }
}
}
\cs_new_protected:Nn \verdoja_custom_function:nnnn
{
\tl_new:c { #1 #2 }
\tl_set:cn { #1 #2 }{ #3 #4 }
\tl_new:c { \text_uppercase:n { #1 } #2 }
\tl_set:cx { \text_uppercase:n { #1 } #2 } { \text_uppercase:n { #3 } #4 }
}
\cs_generate_variant:Nn \verdoja_custom_function:nnnn { ff , ffff }
\ExplSyntaxOff
\CustomFunction{dog}{cane}
\CustomFunction{elite}[é]{lite}
\begin{document}
\dog
\Dog
\elite
\Elite
\end{document}
如果第一个字符是特殊字符,则需要使用可选字符(为了兼容pdflatex
,如果使用 XeLaTeX 或 LuaLaTeX,则不需要可选参数)。
实际上,通过最近的添加和改进expl3
,我们可以大大简化代码。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\CustomFunction}{mm}
{% #1 = command name, #2 = string
\verdoja_custom_function:nn { #1 } { #2 }
}
\cs_new_protected:Nn \verdoja_custom_function:nn
{
\tl_const:cn { #1 } { #2 }
\tl_const:cx { \char_titlecase:N #1 } { \text_titlecase:n { #2 } }
}
\ExplSyntaxOff
\CustomFunction{dog}{cane}
\CustomFunction{elite}{élite}
\begin{document}
\dog
\Dog
\elite
\Elite
\end{document}
如果“特殊”的话,我们不再需要将首字母放在可选参数中。