%%
%% This is file `inlinedef.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% inlinedef.dtx  (with options: `package')
%% 
%% Copyright 2008 Stephen D. Hicks <sdh33@cornell.edu>.
%% 
%% This program may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   http://www.latex-project.org/lppl.txt and
%% version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%% 
%% This work has the LPPL maintenance status `maintained'.
%% 
%% The Current Maintainer of this work is Stephen D. Hicks
%% 
%% This work consists of the files
%%   README
%%   inlinedef.dtx
%%   inlinedef.ins
%%   inlinedef.pdf
%% and the derived files
%%   inlinedef.sty
%%   inlinetest.tex
%% 
%% Any modified versions of this file must be renamed
%% with new filenames distinct from those in this work.
%% 
%% This generated file may be distributed as long as the
%% original source files, as listed above, are part of the
%% same distribution. (The sources need not necessarily be
%% in the same archive or directory.)
%% 
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{inlinedef}%
           [2008/07/10 v1.0 Inlined expansions within definitions]
\makeatletter
\let\xa\expandafter
\newif\ifID@aborted
\newif\ifID@star
\newif\ifID@starstar
\newif\ifID@bang
\newtoks\ID@toks
\newcount\ID@count
\DeclareRobustCommand\Inline{%
  \begingroup
  % Define a few ``quarks''
  \def\Expand{\Expand}\def\Super{\Super}%
  \def\UnsafeExpand{\UnsafeExpand}\def\MultiExpand{\MultiExpand}%
  \def\Recurse{\Recurse}\def\NoExpand{\NoExpand}%
  \def\Q@END{\Q@END}%
  % Define a toks register
  \ID@toks{}%
  % Signal that we need to look for a star
  \@testtrue\ID@starfalse\ID@starstarfalse\ID@bangfalse
  % Start scanning for \def or \gdef
  \futurelet\@foo\ID@scandef
}
\newcommand\ID@scandef{%
  \let\next\ID@saveprefix % Default behavior
  % If this is the first few tokens after the \Inline, check for * or !
  \if@test
    \ifx\@foo*%
      \ifID@star
        \ifID@bang\let\next\ID@sd@lastcheck\else\let\next\ID@sd@checkagain\fi
        \ID@starstartrue
      \else
        \let\next\ID@sd@checkagain
        \ID@startrue
      \fi
    \fi
    \ifx\@foo!%
      \ifID@bang\else % two bangs - can this be anything but an error?
        \ID@bangtrue
        \xa\let\xa\next\ifID@starstar\ID@sd@lastcheck\else\ID@sd@checkagain\fi
      \fi
    \fi
  \fi
  % Now look for a \def or \gdef
  \ifx\@foo\def
    \def\next{\ID@start\def}%
  \fi
  \ifx\@foo\gdef
    \def\next{\ID@start\gdef}%
  \fi
  \ifcat\noexpand\@foo\space
    \def\next{\ID@toks\xa\xa\xa{\xa\the\xa\ID@toks\space}%
      \xa\futurelet\xa\@foo\xa\ID@scandef\ID@unspace}% copied from ID@space
  \fi
  % Error checking (minimal)
  \@testfalse
  \ifx\@foo\edef\@testtrue\fi\ifx\@foo\xdef\@testtrue\fi
  \ifx\@foo\newcommand\@testtrue\fi\ifx\@foo\renewcommand\@testtrue\fi
  \ifx\@foo\DeclareRobustCommand\@testtrue\fi
  \if@test\PackageError{inlinedef}{Only \protect\def\space and \protect\gdef\space are
    allowed after \protect\Inline,\MessageBreak but some other type of
    definition was found}\@eha\let\next\ID@abort\fi
  \@testfalse
  \ifx\@foo\bgroup\@testtrue\fi\ifx\@foo\let\@testtrue\fi
  \if@test\PackageError{inlinedef}{No \protect\def\space or \protect\gdef\space found
    after \protect\Inline}\@ehd\def\next{\ID@abort{}}\fi
  \next
}
\def\ID@sd@checkagain#1{\@testtrue\futurelet\@foo\ID@scandef}
\def\ID@sd@lastcheck#1{\futurelet\@foo\ID@scandef}
\newcommand*\ID@saveprefix[1]{%
  \ID@toks\xa{\the\ID@toks#1}%
  \futurelet\@foo\ID@scandef
}
\newcommand\ID@abort{}\def\ID@abort#1#{\endgroup\@gobble}
\newcommand\ID@start{}\def\ID@start#1#2#3#4#{%
  \xa\def\xa\ID@prefix\xa{\the\ID@toks#1}%
  \ID@def#3{#4}%
}
\newcommand*\ID@fixparams{\begingroup\ID@toks{}\futurelet\@foo\ID@fp@start}
\newcommand*\ID@fp@start{%
  \let\next\ID@fp@normal
  \ifx\@foo\Q@END\let\next\ID@fp@end\fi
 \ifcat\noexpand\@foo##\let\next\ID@fp@param\fi % was \ifx\@foo - broken?
  \ifcat\noexpand\@foo\space
    \def\next{\ID@toks\xa\xa\xa{\xa\the\xa\ID@toks\space}%
      \xa\futurelet\xa\@foo\xa\ID@fp@start\ID@unspace}% copied from ID@space
  \fi
  \next
}
\newcommand*\ID@fp@normal[1]{%
  \ID@toks\xa{\the\ID@toks#1}\futurelet\@foo\ID@fp@start
}
\newcommand*\ID@fp@param[2]{%
  % We used to just use ###2 but need two more now...
  % Need another doubling because we're now using it inside a def...
  \def\@arg{#########2}% assume delimited unless we find # or \Q@END
  \ifcat\noexpand\@foo##\def\@arg{{#########2}}\fi
  \ifx\@foo\Q@END\def\@arg{{#########2}}\fi
  \ID@toks\xa\xa\xa{\xa\the\xa\ID@toks\@arg}%
  \futurelet\@foo\ID@fp@start
}
\newcommand*\ID@fp@end[1]{%
  \xa\endgroup\xa\def\xa\ID@fixedparams\xa{\the\ID@toks}%
}
\newcommand\ID@def[3]{%
  % Other definitions
  \global\ID@abortedfalse
  \let\@reservedc#1%
  \def\@macroname{#1}% for error message
  \ID@fixparams#2\Q@END
  % These are used by \Super but easier to define here
  \def\@reservedb#2{}%
  \edef\@reservedb{\xa\ID@getprefix\meaning\@reservedb\Q@END}%
  \ifx#1\undefined % hopefully nobody's going around defining \undefined
    \let\@reserveda\undefined
  \else
    \edef\@reserveda{\xa\ID@getprefix\meaning#1\Q@END}%
  \fi
  % Scan it all into \ID@toks
  \ifID@bang\else\ID@checkusage\fi
  \ifID@aborted\else
    \ID@toks{}\ID@scan#3\Q@END{}% we need the {} so that the the #1# works...
  \fi
  \ifID@aborted
    \def\command{}% gracefully ignore
  \else
    \let#1\relax % don't want it expanded in the |\edef| below
    % We don't need to worry about scope anymore
    \toks0\ID@toks % likely redundant, but what if ID@toks=1 or 2?
    \toks1\xa{\ID@prefix}% (easiest way to avoid expansion...)
    \toks2{#2}%
    \edef\command{\the\toks1#1\the\toks2{\the\toks0}}%
    % We could also write this with 3 levels of \xa...
  \fi
  \global\ID@toks\xa{\ID@fixedparams}% just to test...
  \expandafter\endgroup\command
}
\newcommand\ID@scan{\futurelet\@foo\ID@switch}
\newcommand\ID@switch{%
  \let\next\ID@normal
  \ifx\@foo\Q@END
    \let\next\@gobble
  \fi
  \ifx\@foo\@reservedc % macro name... what to do?
    \ifID@star
      \ifID@starstar
        \let\next\ID@expandmacro
      \else
        \let\next\ID@expandsuper
      \fi
    \fi
  \fi
  \ifx\@foo\Super
    \let\next\ID@expandsuper
  \fi
  \ifx\@foo\Expand
    \let\next\ID@expandnext
  \fi
  \ifx\@foo\UnsafeExpand
    \let\next\ID@expandunsafe
  \fi
  \ifx\@foo\MultiExpand
    \let\next\ID@expandmulti
  \fi
  \ifx\@foo\NoExpand
    \let\next\ID@noexpandnext
  \fi
  \ifx\@foo\Recurse
    \def\next{\xa\xa\xa\ID@scan\xa\xa\xa\NoExpand\xa\@macroname\@gobble}%
  \fi
  \ifcat\noexpand\@foo\space
    \let\next\ID@space
  \fi
  \ifcat\noexpand\@foo\bgroup
    \let\next\ID@trygroup
  \fi
  \next
}
\newcommand\ID@space{%
  \ID@toks\xa\xa\xa{\xa\the\xa\ID@toks\space}%
  \xa\ID@scan\ID@unspace
}
\newcommand\ID@unspace{}
\xa\def\xa\ID@unspace\space{}
\newcommand\ID@trygroup{}
\long\def\ID@trygroup#1#{% check for explicit/implicit grouping!
  \def\@reservedd{#1}%
  \xa\let\xa\next
    \ifx\@reservedd\@empty\ID@recurse\else\ID@normal\fi
  \next#1%
}
\newcommand\ID@recurse[1]{%
  \begingroup\ID@toks{}% start a new level of grouping and empty \ID@toks
  \ID@scan#1\Q@END{}% % parse...
  \xa\endgroup\xa    % this fiasco should get the job done...!
  \ID@toks\xa\xa\xa{\xa\the\xa\ID@toks\xa{\the\ID@toks}}%
  \ID@scan
}
\newcommand\ID@normal[1]{\ID@toks\xa{\the\ID@toks#1}\ID@scan}
\newcommand\ID@noexpandnext[2]{\ID@toks\xa{\the\ID@toks#2}\ID@scan}
\newcommand*\ID@checkusage{%
  % Make sure parameter lists are the same, does nothing if undefined
  \ifx\@reserveda\@reservedb
  \else
    % Error messages
    \ifx\@reserveda\undefined % undefined - okay
    \else
      \global\ID@abortedtrue
      \ifx\@foo\Super
        \PackageError{inlinedef}{Cannot use \protect\Super\space in \expandafter
          \protect\@macroname\space because\MessageBreak
          parameter lists don't match:\MessageBreak
          `\@reservedb' (new) != `\@reserveda' (old)}\@eha
      \else
        \ifID@bang % auto-expansion forbidden
          \PackageError{inlinedef}{Cannot use \protect\Inline* auto-expansion in
            \expandafter\protect\@macroname\MessageBreak
            because parameter lists don't match:\MessageBreak
            `\@reservedb' (new) != `\@reserveda' (old)}\@eha
        \else
          \PackageError{inlinedef}{Parameter lists for
            \expandafter\protect\@macroname\space don't match:\MessageBreak
            `\@reservedb' (new) != `\@reserveda' (old)\MessageBreak
            Use !-form of \protect\Inline\space to ignore this}\@eha
        \fi
      \fi
    \fi
  \fi
}
\newcommand*\ID@checkredef{%
  \ifx\@reserveda\undefined % undefined - okay
    \PackageError{inlinedef}{Cannot use \ifx\@foo\Super\protect\Super\space
      \else\protect\Inline** \fi in \expandafter\protect\@macroname\space
      because \MessageBreak it hasn't been defined yet}%
      \@eha
    \global\ID@abortedtrue
  \fi
}
\newcommand*\ID@expandsuper[1]{%
  \ID@checkusage\ID@checkredef
  \ifID@aborted\else
    \ID@toks\xa\xa\xa\xa\xa\xa\xa
      {\xa\xa\xa\the\xa\xa\xa\ID@toks\xa\@reservedc\ID@fixedparams}%
  \fi
  \ID@scan
}
\newcommand\ID@expandnext[2]{%
  \ID@toks\xa\xa\xa{\xa\the\xa\ID@toks#2}\ID@scan
}
\newcommand\ID@expandmulti[3]{%
  \begingroup % #1 is the \MultiExpand...
    \ID@count#2\relax % this will need to be allocated too!
    \ID@toks{#3}%
    \@testtrue\ifnum\ID@count<\@ne\@testfalse\fi
    \@whilesw\if@test\fi{%
      \ID@toks\xa\xa\xa{\the\ID@toks}% one expansion...
      \advance\ID@count\m@ne\ifnum\ID@count<\@ne\@testfalse\fi
    }%
  \xa\endgroup\xa\ID@toks\xa\xa\xa{\xa\the\xa\ID@toks\the\ID@toks}\ID@scan
}

\newcommand*\ID@expandunsafe[1]{\expandafter\ID@scan}
\newcommand*\ID@expandmacro[1]{\expandafter\ID@scan\@reservedc}
\newcommand\ID@getprefix{}\long\def\ID@getprefix#1:#2->#3\Q@END{\detokenize{#2}}
\makeatother


\endinput
%%
%% End of file `inlinedef.sty'.
