String in a macro - how to pass it to a command defined in another command as a default optional argument?
The following seems to be what you want:
\renewcommand*{\do}[1]{%
\StrCut{#1}{-}\csA\csB
% the next line is the "crucial one"
\edef\temp{\noexpand\providecommand\expandafter\noexpand\csname my\csA\endcsname[1][\csB]}%
\temp{%
\begin{enumerate}[##1]
\item one
\item two
\end{enumerate}
}
}
We first define a temporary command \temp
that fully expands the \providecommand
parameters, except for the \providecommand
macro itself which is prevented by \noexpand
. Then \temp
is executed to actually perform the command definition.
Here's a new version wrt. the extended question:
\renewcommand*{\do}[1]{%
\StrCut{#1}{-}\csA\csB
% the next line is the "crucial one"
\edef\temp{\noexpand\providecommand\expandafter\noexpand\csname my\csA\endcsname[1][\csB]{%
\noexpand\begin{enumerate}[####1]
\noexpand\item one
\noexpand\item two
\noexpand\end{enumerate}
The above list is of type \csB
}%
}\temp
}
The \edef
now spans the whole defintion, not only the parameters. This makes it necessary to prefix all used commands that should not be expanded by \noexpand
, though. Not sure if this is practical in your real code. The xparse
version suggested by egreg is more flexible here.
You should not use \providecommand
for this. Moreover, redefining \do
is quite dangerous, because several packages can use it. With etoolbox
you have \forcsvlist
, which accepts a different macro.
The main problem is passing \csB
expanded.
\documentclass{article}
\usepackage{xstring,etoolbox}
\usepackage[shortlabels]{enumitem}
\newcommand\lists{%
parts-a),
items-1)
}
\newcommand*{\mydo}[1]{%
\StrCut{#1}{-}\csA\csB
% build \newcommand one step at a time
\toks0=\expandafter{\expandafter\newcommand\csname my\csA\endcsname}%
\toks2=\expandafter{\csB}%
\begingroup\edef\x{\endgroup\the\toks0[1][\the\toks2]}\x{%
\begin{enumerate}[##1]
\item one
\item two
\end{enumerate}
}%
}
\expandafter\forcsvlist\expandafter\mydo\expandafter{\lists}
\begin{document}
\myparts[i)]
\myparts
\end{document}
With a different approach, based on xparse
:
\documentclass{article}
\usepackage{xparse}
\usepackage[shortlabels]{enumitem}
\NewDocumentCommand{\parselists}{>{\SplitList{,}}m}{%
\ProcessList{#1}{\makelist}%
}
\NewDocumentCommand{\makelist}{>{\SplitArgument{1}{-}}{m}}{%
\makelistsdo#1%
}
\NewDocumentCommand{\makelistsdo}{mm}{%
\NewDocumentNamedCommand{my#1}{O{#2}}{%
\begin{enumerate}[##1]
\item one
\item two
\end{enumerate}
}%
}
\ExplSyntaxOn
\cs_new_protected:Npn \NewDocumentNamedCommand #1
{
\exp_args:Nc \NewDocumentCommand { #1 }
}
\ExplSyntaxOff
\parselists{
parts-a),
items-1),
}
\begin{document}
\myparts[i)]
\myparts
\myitems[i)]
\myitems
\end{document}