7

Question on commands and control sequences. The following command

\newcommand{\startwiths}[1]{\csname s\expandafter\@gobble\string#1\endcsname}

adds the letter s the beginning of the sequence in the argument. For example, \startwiths{\plot} returns \splot.

I would like to define a similar command that makes the first letter of the original command uppercase on top of adding the initial s. Let us call this new command \startwithsUpper. For example, \startwithsUpper{\plot} returns \sPlot. I am not an expert in these manipulations and any help is very welcome :)

EDIT: \startwiths{\plot} and \startwithsUpper{\plot} are now correct (in the first version I forgot the backslash).

  • 2
    I'm curious: what's the broader purpose? – jon Nov 2 '16 at 22:07
  • 1
    the code you post would need input {\plot} not {plot} as you show. which do you need (it is always best to post complete test document to avoid such ambiguities) – David Carlisle Nov 2 '16 at 22:28
  • @jon: the purpose is to implement it for some manipulation after this question that was solved by egreg – Monte Carlo Nov 2 '16 at 23:48
4

It's possible in several ways. Here's a (non expandable) one:

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

Here's an expandable one, with expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\startwithsUpper}{m}
 {
  % \use:c is essentially \csname...\endcsname
  \use:c
   {
    s % add the initial s
    \tl_upper_case:f { \tl_head:n { #1 } } % make the initial uppercase
    \tl_tail:n { #1 } % the rest of the argument
   }
 }
\cs_generate_variant:Nn \tl_upper_case:n { f }
\ExplSyntaxOff

\newcommand{\sPlot}{Here it is}

\begin{document}

\startwithsUpper{plot}

\end{document}

The following (more complicated) version accepts either a string or a control sequence as argument.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\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:f { \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
    \tl_upper_case:f { \tl_head:n { #1 } }
    \tl_tail:n { #1 }
   }
 }
\cs_generate_variant:Nn \tl_upper_case:n { f }
\cs_generate_variant:Nn \__montecarlo_start_with_s_upper:n { f }
\ExplSyntaxOff

\newcommand{\sPlot}{Here it is}

\begin{document}

\startwithsUpper{plot}

\startwithsUpper{\plot}

\end{document}
9

The question is inconsistent, \expandafter\@gobble\string#1 indicates that the argument is a command sequence and the code strips the starting backslash. Then the usage cases are:

\startwiths{\plot} -> \splot
\startwithsUpper{\plot} -> \sPlot

Macro \startwithsUpper can be implemented in an expandable manner by using \@Alph instead of \uppercase for converting a simple ASCII letter to its uppercase version:

\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

Result:

\startwithsUpper{\plot} -> \sPlot
3

Here's a LuaLaTeX-based solution.

enter image description here

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.