替换命令字母(控制序列)

替换命令字母(控制序列)

关于命令和控制序列的问题。以下命令

\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}

相关内容