% eparam.tex
%%%%%%%%%%%%%%%%%%%%
% Petr Olsak 2014

% This macro enables full expansion during parameter scanning. 
% The usage:
% \def\macro#1{macro with #1}
% \eparam\macro prameter-text
%
% The delimiters for the parameter are {...} or \start...\stop or
% combination {...\stop, \start...}, where \start is declared by \eparamopen
% and \stop is declared by \eparamclose. See more information at the end of
% this file or at
% http://tex.stackexchange.com/questions/196776/arguments-possibly-delimited-by-bgroup-and-egroup


\def\tmp{% all expandable primitives (only from classical TeX, you can add others):
  \botmark \csname \else \endcsname \endinput \expandafter \fi \firstmark \fontname
  \if \ifcase \ifcat \ifdim \ifeof \iffalse \ifhbox \ifhmode \ifinner 
  \ifmmode \ifnum \ifodd \iftrue \ifvbox \ifvmode \ifvoid \ifx
  \input \jobname \meaning \noexpand \number \or \romannumeral
  \splitbotmark \splitfirstmark \string \the \topmark
}
\def\skipmm#1->{}  \def\showmm#1->{#1}
\edef\textmm{\expandafter\showmm\meaning\empty}
\edef\expandprimitives{\expandafter\skipmm\meaning\tmp}

\def\isinlist#1#2#3{% from opmac.tex
   \def\tmp##1#2##2\end{\def\tmp{##2}%
   \ifx\tmp\empty \csname iffalse\expandafter\endcsname \else
                  \csname iftrue\expandafter\endcsname \fi}% end of \def\tmp
   \expandafter\tmp#1\endlistsep#2\end
}
\def\isexpanded#1#2{% \isexpanded X\iftrue the X is expandable primitive or macro\fi
   \edef\tmpb{\meaning#1\space}%
   \expandafter\isinlist\expandafter\tmpb\expandafter{\textmm}%
   \iftrue \csname iftrue\expandafter\endcsname\else
      \def\nexxt{\expandafter\isinlist\expandafter\expandprimitives\expandafter{\tmpb}.}%
      \expandafter\nexxt\fi
}
\def\eparamopen#1{\def\eparamopenA{\let#1=\eparamopenA}}
\def\eparamclose#1{\def\eparamcloseA{\let#1=\eparamcloseA}}

\newtoks\eparamT
\def\eparam#1{\begingroup
  \toks0={#1}\let\bgroup=\relax \let\egroup=\relax
  \let\ifIamInGroup=\iffalse
  \ifx\eparamopenA\undefined \def\eparamopenA{^\eparam^}\else \eparamopenA\fi
  \ifx\eparamcloseA\undefined \def\eparamcloseA{^\eparam^}\else \eparamcloseA\fi
  \eparamT={}\eparamA
}
\def\eparamA{\futurelet\tmpc\eparamB}
\def\eparamB{\let\next=\eparamD
   \isexpanded\tmpc\iftrue \def\next{\expandafter\eparamA}\fi
   \ifx\tmpc\bgroupOri \let\next=\eparamC \let\nexxt=\eparamD \fi
   \ifx\tmpc\eparamopenA  \let\next=\eparamC \let\nexxt=\eparamD \fi
   \next
}
\def\eparamC{\afterassignment\nexxt \let\next= }
\def\eparamD{\futurelet\tmpc\eparamE}
\def\eparamE{\let\next=\eparamN
   \isexpanded\tmpc\iftrue \def\next{\expandafter\eparamD}\fi
   \ifx\tmpc\spacetoken \let\next=\eparamC \let\nexxt=\eparamD \eparamX{ }\fi
   \ifx\tmpc\eparamcloseA \ifIamInGroup \let\next=\eparamN
                          \else \let\next=\eparamC \let\nexxt=\eparamF \fi\fi
   \ifx\tmpc\egroupOri \let\next=\eparamC \let\nexxt=\eparamF \fi
   \ifx\tmpc\bgroupOri \let\next=\eparamC \let\nexxt=\eparamG \fi
   \next
}
\def\eparamN#1{\eparamX#1\eparamD}
\def\eparamG{\begingroup \let\ifIamInGroup=\iftrue \eparamT={}\eparamD}
\def\eparamF{\ifIamInGroup \let\next=\eparamY \else \let\next=\eparamZ \fi \next}
\long\def\eparamX#1{\eparamT\expandafter{\the\eparamT#1}}
\def\eparamY{\expandafter\endgroup
   \expandafter\eparamT\expandafter\expandafter\expandafter
      {\expandafter\the\expandafter\eparamT\expandafter{\the\eparamT}}%
   \eparamD
}
\def\eparamZ{\expandafter\endgroup\the\toks0\expandafter{\the\eparamT}}

\let\bgroupOri=\bgroup
\let\egroupOri=\egroup
\def\tmp/{\let\spacetoken= }\tmp/ %

\endinput

tests:

\def\macro#1{\toks0={#1}\message{the parameter is "\the\toks0"}}

\eparam\macro {abc}  % the parameter is "abc"

\def\x{ww}
\eparam\macro {ab\x c}          % the parameter is "abwwc"
\eparam\macro {a b\the\pageno c} % the parameter is "ab1c"
\eparam\macro {ab\ifx\x\x true\else false\fi c}        % the parameter is "abtruec"
\eparam\macro {ab\ifnum\folio=1 true\else false\fi c}  % the parameter is "abtruec"
\eparam\macro {ab\ifcase\pageno oo\or one\or two\fi c} % the parameter is "abonec"

\eparamopen\start \eparamclose\stop

\eparam\macro {abc\stop        % the parameter is "abc"
\eparam\macro \start abc\stop  % the parameter is "abc"
\eparam\macro \start abc}      % the parameter is "abc"

\eparam\macro abc}     % the parameter is "abc"
\eparam\macro abc\stop % the parameter is "abc"

\eparam\macro \start abc{uf\stop fu}ee\stop  % the parameter is "abc{uf\stop fu}ee"

\def\y{end\stop}

\eparam\macro {a\x\y   % the parameter is "awwend"

\eparam {\def\aha#1#2}\start params: #1 and #2\stop

\eparamopen\bgroup \eparamclose\egroup
\eparam {\def\foo#1#2}\bgroup Something with #1 and #2\egroup

\message{\meaning\foo}

\end

The question gives me a sense if it is read from its end: *give
the possibility of creating a macro which expands its parameter during
parameter scanning*. Then the variants `}` or `\egroup` as a delimiter of the
parameter is serviceable.

I've created the `\eparam` macro with this syntax:

    \def\mymacro #1{the #1 parameter is declared as undelimited}
    ...
    \eparam\mymacro parameter-text

The `parameter-text` is equal to `real-parameter-text` enclosed by braces or  
by another control sequences declared by `\eparamopen` and \eparamclose`.
Example:

    \eparamopen\start  \eparamclose\stop
    \eparam\mymacro {real-parameter-text}
    \eparam\mymacro \start real-parameter-text\stop
    \eparam\mymacro \start real-parameter-text}
    \eparam\mymacro {real-parameter-text\stop

The main point of the `\eparam` is that this is **Expanded Parameter**. 
The `real-parameter-text` is expanded during parameter scanning like
by `\edef`. This means that all expandable primitives and macros are
expanded during the parameter is read. Unexpandable primitives does nothing
in this time (like `\edef`) so you can do reassigmnent of registers/macros
inside this parameter but without any effect for parameter scaninng.
This is main difference between this case and the `\hbox {...}` primitive
syntax.

There is one difference between `\edef` and parameter scanning:
undefined control sequences do nothing (like unexpandable primitives)
during parameter scanning. The error can be occur only when the parameter is
used (no during parameter scanning).

The separator declared by `\eparamclose` can be hidden in a macro. Example:

    \def\x{-text\stop}
    \eparam\mymacro {real-parameter\x

The first open brace or delimiter given by `\eparamopen` is optional. I.e.
you can omit it:

    \eparam\mymacro real-parameter-text\stop

The parameter is always balanced. This means that the delimiter declared by
`\eparamclose` does no effect inside inner braces pair (like normal
parameter scanning):

    \eparam \start text{inside \stop braces}text\stop
    % the parameter is: "text{inside \stop braces}text"

The implementation (or wipet's sorcery :) and little tests follow.
 