关于命令和控制序列的问题。以下命令
\newcommand{\startwiths}[1]{\csname s\expandafter\@gobble\string#1\endcsname}
将字母添加到s
参数中序列的开头。例如,\startwiths{\plot}
返回\splot
。
我想定义一个类似的命令,在添加首字母的基础上将原始命令的首字母变为大写s
。让我们将这个新命令称为\startwithsUpper
。例如,\startwithsUpper{\plot}
返回\sPlot
。我不是这些操作的专家,任何帮助都非常欢迎:)
编辑:\startwiths{\plot}
现在\startwithsUpper{\plot}
是正确的(在第一个版本中我忘记了反斜杠)。
答案1
有多种方法可以实现。以下是其中一种(不可扩展):
\documentclass{article}
\makeatletter
\newcommand{\startwithsUpper}[1]{%
\startwithsUpper@aux#1\relax
}
\def\startwithsUpper@aux#1#2\relax{%
\uppercase{\csname\initial@s #1}#2\endcsname
}
\def\initial@s{s}
\makeatother
\newcommand{\sPlot}{Here it is}
\begin{document}
\startwithsUpper{plot}
\end{document}
这是一个可扩展的,具有expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\startwithsUpper}{m}
{
% \use:c is essentially \csname...\endcsname
\use:c
{
s % add the initial s
\text_titlecase_first:n { #1 }
}
}
\ExplSyntaxOff
\newcommand{\sPlot}{Here it is}
\begin{document}
\startwithsUpper{plot}
\end{document}
以下(更复杂)版本接受字符串或控制序列作为参数。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\startwithsUpper}{m}
{
\montecarlo_start_with_s_upper:n { #1 }
}
\cs_new:Nn \montecarlo_start_with_s_upper:n
{
\tl_if_single:nTF { #1 }
{
\token_if_cs:NTF #1
{
\__montecarlo_start_with_s_upper:e { \cs_to_str:N #1 }
}
{
\__montecarlo_start_with_s_upper:n { #1 }
}
}
{
\__montecarlo_start_with_s_upper:n { #1 }
}
}
\cs_new:Nn \__montecarlo_start_with_s_upper:n
{
\use:c
{
s
\char_titlecase:N #1
}
}
\cs_generate_variant:Nn \__montecarlo_start_with_s_upper:n { e }
\ExplSyntaxOff
\newcommand{\sPlot}{Here it is}
\begin{document}
X\startwithsUpper{plot}X
X\startwithsUpper{\plot}X
\end{document}
答案2
问题不一致,\expandafter\@gobble\string#1
表明参数是命令序列,并且代码删除了起始反斜杠。那么使用情况是:
\startwiths{\plot} -> \splot
\startwithsUpper{\plot} -> \sPlot
宏可以通过使用而不是将简单 ASCII 字母转换为大写版本来\startwithsUpper
以可扩展的方式实现:\@Alph
\uppercase
\makeatletter
\newcommand*{\startwithsUpper}[1]{%
\csname
s%
\expandafter\expandafter\expandafter\FirstUpper
\expandafter\@gobble\string#1%
\endcsname
}
\def\FirstUpper#1{%
\ifnum`#1>`Z % case distinction between lowercase and uppercase letter
\@Alph{\numexpr`#1-`a+1\relax}% Convert lowercase letter
\else
#1% Keep uppercase letter
\fi
}
\makeatother
% Test
\edef\x{%
\unexpanded\expandafter\expandafter\expandafter{%
\startwithsUpper{\plot}%
}%
}
\makeatletter
\typeout{\string\startwithsUpper{\string\plot} -> \detokenize\expandafter{\x}}
\makeatother
\stop
结果:
\startwithsUpper{\plot} -> \sPlot
答案3
这是一个基于 LuaLaTeX 的解决方案。
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function startwithsUpper ( s )
tex.sprint ( "\\s" .. string.gsub( s , "^%l", string.upper) )
end
\end{luacode}
\newcommand\startwithsUpper[1]{\directlua{startwithsUpper(\luastring{#1})}}
\newcommand\sPlot{Hello World} % dummy definition of "\sPlot"
\begin{document}
\startwithsUpper{plot}
\end{document}