%% %% 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 . %% %% 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'.