You can use a lot of \name
both for defining and calling macros whose names also contain digits and/or spaces and/or the like - i elaborated on the macro \name
in the discussion Define a control sequence after that a space matters.
Perhaps something like this suits your needs? :
%%----------------------------------------------------------------------
%% \name{macro} -> \macro
%% \name\string{macro} -> \string\macro
%% \name\newcommand{macro}... -> \newcommand\macro...
%% (Instead of "macro" you can also use phrases that contain digits
%% and/or spaces and/or the like.)
%%......................................................................
\newcommand\name{}%
\long\def\name#1#{\romannumeral0\innername{#1}}%
\newcommand\innername[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%
\newcommand\exchange[2]{#2#1}%
%%......................................................................
\newcommand\CheckWhetherUndefined{}%
\name\global\let\CheckWhetherUndefined={@ifundefined}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\firstoftwo[2]{#1}%
\newcommand\secondoftwo[2]{#2}%
\newcommand\CheckWhetherNull[1]{%
\romannumeral0\expandafter\secondoftwo\string{\expandafter\secondoftwo
\expandafter{\expandafter{\string#1}\expandafter\secondoftwo\string}%
\expandafter\firstoftwo\expandafter{\expandafter\secondoftwo\string}%
\expandafter\expandafter\firstoftwo{ }{}\secondoftwo}{\expandafter
\expandafter\firstoftwo{ }{}\firstoftwo}%
}%
%%----------------------------------------------------------------------
%% Maintaining local commands:
%%......................................................................
\newcommand\genericSet[1]{%
\name\name{\CheckWhetherUndefined{#1}{}{re}newcommand}*{#1}%
}%
\newcommand{\setName}[2][]{%
\CheckWhetherNull{#1}{\genericSet{tokenName}{#2}}{\genericSet{tokenName}{#2 1--#1}}%
\ignorespaces
}%
\newcommand{\setEffect}[2][]{\genericSet{tokenEffect#1}{#2}\ignorespaces}%
\newcommand{\setRequirement}[2][]{\genericSet{tokenRequirement#1}{#2}\ignorespaces}%
% You must never define \UnDeFInED ;-)
\newenvironment{Description}{\let\tokenName=\UnDeFInED\ignorespaces}{%
\section{\tokenName}% <- This way you will get an undefined
% control-sequence-error in case of not
% having called \setName from within the environment.
\paragraph{Effects}%
\begin{enumerate}% At least one of the following should be defined!
\CheckWhetherUndefined{tokenEffect}{}{\item[]\name{tokenEffect}}%
\CheckWhetherUndefined{tokenEffectX}{}{\item[each:]\name{tokenEffectX}}%
\CheckWhetherUndefined{tokenEffect1}{}{\item\name{tokenEffect1}}%
\CheckWhetherUndefined{tokenEffect2}{}{\item\name{tokenEffect2}}%
\CheckWhetherUndefined{tokenEffect3}{}{\item\name{tokenEffect3}}%
\end{enumerate}%
\paragraph{Requirements}%
\begin{enumerate}% At least one of the following should be defined!
\CheckWhetherUndefined{tokenRequirement}{}{\item[]\name{tokenRequirement}}%
\CheckWhetherUndefined{tokenRequirement1}{}{\item\name{tokenRequirement1}}%
\CheckWhetherUndefined{tokenRequirement2}{}{\item\name{tokenRequirement2}}%
\CheckWhetherUndefined{tokenRequirement3}{}{\item\name{tokenRequirement3}}%
\end{enumerate}%
}%
%% Usage:
% \begin{Description}
% \setName[foo]{Bar}%
% \setEffect{Token Effect}%
% \setEffect[1]{Token Effect 1}%
% \setEffect[2]{Token Effect 2}%
% \setEffect[3]{Token Effect 3}%
% \setEffect[X]{Token Effect X}%
% \setRequirement{Token Requirement}%
% \setRequirement[1]{Token Requirement 1}%
% \setRequirement[2]{Token Requirement 2}%
% \setRequirement[3]{Token Requirement 3}%
% \end{Description}
Additionally one can add an \if..
-switch for starting and ending the enumerate-environment only in case there are items:
%%----------------------------------------------------------------------
%% \name{macro} -> \macro
%% \name\string{macro} -> \string\macro
%% \name\newcommand{macro}... -> \newcommand\macro...
%% (Instead of "macro" you can also use phrases that contain digits
%% and/or spaces and/or the like.)
%%......................................................................
\newcommand\name{}%
\long\def\name#1#{\romannumeral0\innername{#1}}%
\newcommand\innername[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%
\newcommand\exchange[2]{#2#1}%
%%......................................................................
\newcommand\CheckWhetherUndefined{}%
\name\global\let\CheckWhetherUndefined={@ifundefined}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\firstoftwo[2]{#1}%
\newcommand\secondoftwo[2]{#2}%
\newcommand\CheckWhetherNull[1]{%
\romannumeral0\expandafter\secondoftwo\string{\expandafter\secondoftwo
\expandafter{\expandafter{\string#1}\expandafter\secondoftwo\string}%
\expandafter\firstoftwo\expandafter{\expandafter\secondoftwo\string}%
\expandafter\expandafter\firstoftwo{ }{}\secondoftwo}{\expandafter
\expandafter\firstoftwo{ }{}\firstoftwo}%
}%
%%----------------------------------------------------------------------
%% Starting and ending enumerate-environment:
%%......................................................................
\newif\ifThereAlreadyIsAnItem\ThereAlreadyIsAnItemfalse
\newcommand\ProbablyStartEnumerate[1]{%
\ifThereAlreadyIsAnItem\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
{}{\ThereAlreadyIsAnItemtrue#1\begin{enumerate}}%
}%
\newcommand\ProbablyStopEnumerate{%
\ifThereAlreadyIsAnItem\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
{\end{enumerate}\ThereAlreadyIsAnItemfalse}{}%
}%
%%----------------------------------------------------------------------
%% Maintaining local commands:
%%......................................................................
\newcommand\genericSet[1]{%
\name\name{\CheckWhetherUndefined{#1}{}{re}newcommand}*{#1}%
}%
\newcommand{\setName}[2][]{%
\CheckWhetherNull{#1}{\genericSet{tokenName}{#2}}{\genericSet{tokenName}{#2 1--#1}}%
\ignorespaces
}%
\newcommand{\setEffect}[2][]{\genericSet{tokenEffect#1}{#2}\ignorespaces}%
\newcommand{\setRequirement}[2][]{\genericSet{tokenRequirement#1}{#2}\ignorespaces}%
% You must never define \UnDeFInED ;-)
\newenvironment{Description}{%
\ThereAlreadyIsAnItemfalse
\let\tokenName=\UnDeFInED
\ignorespaces
}{%
\section{\tokenName}% <- This way you will get an undefined
% control-sequence-error in case of not
% having called \setName from within the environment.
\CheckWhetherUndefined{tokenEffect}{}{\ProbablyStartEnumerate{\paragraph{Effects}}\item[]\name{tokenEffect}}%
\CheckWhetherUndefined{tokenEffectX}{}{\ProbablyStartEnumerate{\paragraph{Effects}}\item[each:]\name{tokenEffectX}}%
\CheckWhetherUndefined{tokenEffect1}{}{\ProbablyStartEnumerate{\paragraph{Effects}}\item\name{tokenEffect1}}%
\CheckWhetherUndefined{tokenEffect2}{}{\ProbablyStartEnumerate{\paragraph{Effects}}\item\name{tokenEffect2}}%
\CheckWhetherUndefined{tokenEffect3}{}{\ProbablyStartEnumerate{\paragraph{Effects}}\item\name{tokenEffect3}}%
\ProbablyStopEnumerate
\CheckWhetherUndefined{tokenRequirement}{}{\ProbablyStartEnumerate{\paragraph{Requirements}}\item[]\name{tokenRequirement}}%
\CheckWhetherUndefined{tokenRequirement1}{}{\ProbablyStartEnumerate{\paragraph{Requirements}}\item\name{tokenRequirement1}}%
\CheckWhetherUndefined{tokenRequirement2}{}{\ProbablyStartEnumerate{\paragraph{Requirements}}\item\name{tokenRequirement2}}%
\CheckWhetherUndefined{tokenRequirement3}{}{\ProbablyStartEnumerate{\paragraph{Requirements}}\item\name{tokenRequirement3}}%
\ProbablyStopEnumerate
}%
%% Usage:
% \begin{Description}
% \setName[foo]{Bar}%
% \setEffect{Token Effect}%
% \setEffect[1]{Token Effect 1}%
% \setEffect[2]{Token Effect 2}%
% \setEffect[3]{Token Effect 3}%
% \setEffect[X]{Token Effect X}%
% \setRequirement{Token Requirement}%
% \setRequirement[1]{Token Requirement 1}%
% \setRequirement[2]{Token Requirement 2}%
% \setRequirement[3]{Token Requirement 3}%
% \end{Description}
\setName
from within the environment, this will yield a\section
without a title. That seems weird. What do you wish to happen in case\setName
is not called from within the environment? If you don't call\setEffect
/\setRequirement
from within the environment, this might yield empty enumerate environments which also yields error-messages. What behavior do you wish in such cases?