% DEFAULT.STY, version 1.3 July 1998, provides % 1. macro parameter-defaulting mechanism. % 2. user stack and dynamic array % Particularly useful if you have macros with many parameters, and you % don't want to remember all of them all the time. % % Author: Zhuhan Jiang, University of New England, Australia % Email: zhuhan@neumann.une.edu.au % % NOTES: % 1. This style file can be loaded in as many times as you want, % without overrunning the resources for such as counter % registers and etc. So different packages may all use it to % default their macro parameters, without causing any conflict. % 2. Macro parameters that can be defaulted through this style file % are those included in square brackets. E.g. #1, #2, #3 in % \foo[#1][#2][#3]#4#5 are defaultable while #4 and #5 here are % not. % 3. If \foo is a macro to be defaulted, the original macro \foo % will be renamed as ``\foo@ raw'' (yes, there is a space) and % the new macro \foo will be defined through the use of the % original ``\foo@ raw''. % % MAIN MACRO: % \setdefalut{cmdname}{n}{default1}{..}{default_n} % - gives defaults to \cmdname[p_1][p_2]..[p_n] % (the macro to be defaulted must be already defined % when \setdefault is executed) % EXAMPLES: % 1. Suppose \foo is defined for \foo[#1][#2][#3]{#4}, we may default % all (or some of) the parameters in the SQUARE BRACKETS to for % instance 'one', 'two' and 'three' via % \setdefault{foo}{3}{one}{two}{three} % This way, command \foo{stuff} or \foo[]{stuff} or \foo[][]{stuff} % or \foo[][][]{stuff} will all be translated as % \foo[one][two][three]{stuff}. Command \foo[][2]{stuff} will be % translated as \foo[one][2][three]{stuff}. % 2. See how \placebox is defined and redefined via \setdefault % in this file. % % TIP: % The best strategy to define (e.g.) \foo[#1][#2]{#3} so that % it has defaults for #1 and #2 % 1. define \foo@[#1][#2]#3 as normal (what you wish) % 2. define \foo[#1][#2]#{\foo@[#1][#2]} to make {#3} mandatory % 3. use \setdefault{foo}{2}{one}{two} to default #1=one and #2 to two % % MINOR MACROS: % \placebox[#1][#2][#3][#4][#5][#6]{#7} % - place stuff #7 in a box at the position specified % by parameters #1, ..., #6. (move mini page around) % #1: box position (default 0) % 1--6--2 <-- top of the box % | | % | | % | | % 9 5 7 0 is -5 <-- middle height of the box % | | % 10 11 12 <-height up <-- baseline % | | depth down % 4--8--3 <-- bottom of the box % #1<=0: box has no width, no height % #2: x shift (default 0pt) % #3: y shift (default 0pt) % #4,#5: extra x,y shift in multiple of box width/10, height/10 % #6: box type: v=vbox, otherwise=hbox % #7: content to be boxed % \push{ ... } - push stuff to stack; anything can be saved to % \pop - pop stack % \popnil - delete stack top element (pop to nil) % \fetch{#1} - fetch #1-th entry from the stack % (illegal number #1 will produce \relax) % if #1>0, fetch #1-th entry from bottom of stack % if #1>=0, fetch (-#1)-th element from top of stack % e.g. % fetch{0} - fetch the element of the top of stack % fetch{-1} - the element just below the top of stack % fetch{2} - 2nd element from the bottom of stack % \ifx\EntryDefault\undefined \message{1.3 13/7/98}% {\catcode`\@=11\relax \def\temp@macro{\space\space\space\space}% \wlog{\temp@macro DEFAULT.STY version 1.3 July 1998 By Z Jiang}% \wlog{\temp@macro University of New England, Australia}% \wlog{\temp@macro Email: zhuhan@neumann.une.edu.au}}% \fi \xdef\EntryDefault{\the\catcode`\@}\catcode`\@=11\relax % SAVE @'s STATUS % % % NEW MEASURES etc (parameter defaulting mechanism given by macros below) \def\new@measures{% \def\temp@@macro##1##2##3{\expandafter\ifx\csname ##3temp##2##1\endcsname \relax\edef\next{\noexpand\csname new##1\noexpand\endcsname \csname ##3temp##2##1\endcsname}% \else\let\next\relax\fi\next}% \def\temp@macro##1{% \temp@@macro{##1}{@}{}\temp@@macro{##1}{@@}{}\temp@@macro{##1}{@@@}{}}% \temp@macro{count}\temp@macro{toks}\temp@macro{box}\temp@macro{read}% \temp@@macro{if}{@}{if}\temp@@macro{if}{@@}{if}\temp@@macro{if}{@@@}{if}% \def\temp@@macro##1{\expandafter\ifx\csname temp##1dim\endcsname \relax\edef\next{\noexpand\csname newdimen\noexpand\endcsname \csname temp##1dim\endcsname}% \else\let\next\relax\fi\next}% \temp@@macro{@}\temp@@macro{@@}\temp@@macro{@@@}% }% \let\temp@@@macro=\wlog\def\wlog#1{}\new@measures % %%% GENERAL STACK \def\make@STKcount{\csname newcount\endcsname \STKcount\global\STKcount=0\relax}% \ifx\STKcount\undefined@ \def\next{\make@STKcount}\else\def\next{}\fi \next % ensures stack pointer not flushed if this piece of code % is loaded again % \long\def\push#1{\global\advance\STKcount1\relax \expandafter\gdef\csname STK\the\STKcount\string~\endcsname{#1}}% % \def\popnil{\expandafter\let\expandafter\temp@macro \csname STK\the\STKcount\string~\endcsname \ifnum\STKcount>0\global\expandafter\let \csname STK\the\STKcount\string~\endcsname=\undefined@ \global\advance\STKcount-1% \else \def\temp@macro{}\global\STKcount=0% \fi\relax % \temp@macro for pop }% % \def\pop{\popnil\temp@macro}% % \def\fetch@#1{\ifnum#1>0 \relax \temp@count=#1 \else \temp@count=\STKcount \advance\temp@count by #1 \fi \csname STK\the\temp@count\string~\endcsname }% \def\fetch#{\fetch@}% % %% GET PARAMETERS \long\def\get@nepara[#1][#2]{{\def\next@{#2}% \ifx\next@\empty\push{#1}\else\push{#2}\fi}\ag@in}% % \long\def\get@para\left@#1\right@{% \def\check@{% \ifx[\next@ \def\full@####1{\get@nepara[#1]####1}% \else \def\full@{\get@nepara[#1][#1]}\fi \full@}% \futurelet\next@\check@}% % \long\def\do@nepara\left@#1\right@#2\p@r@end{% \gdef\p@r@data{#2}\global\advance\p@r@count1\get@para\left@#1\right@}% % \def\ag@in{\ifx\p@r@data\empty \def\next@{\relax \getp@r@s\run@CMD}\else \def\next@{\expandafter\do@nepara\p@r@data\p@r@end}\fi \next@}% % \def\run@CMD{\csname STK\the\STKcount\string~\endcsname}% % \def\num@to@word#1{\ifcase #1 \or \def\temp@macro{one}\or \def\temp@macro{two}\or \def\temp@macro{three}\or \def\temp@macro{four}\or \def\temp@macro{five}\or \def\temp@macro{six}\or \def\temp@macro{seven}\or \def\temp@macro{eight}\or \def\temp@macro{nine}\else \def\temp@macro{}\fi \temp@toks=\expandafter{\temp@macro}}% % \temp@@count=1 % make nine newtoks, if they don't already exist \loop \num@to@word{\temp@@count}% \expandafter\ifx\csname p@r@\the\temp@toks\endcsname\relax \temp@@toks={newtoks}\expandafter\csname\expandafter\the \expandafter\temp@@toks\expandafter\endcsname \csname p@r@\the\temp@toks\endcsname\fi \advance\temp@@count by 1 \ifnum\temp@@count<10 \repeat % \ifx\p@r@count\undefined@ \csname newcount\endcsname\p@r@count\fi \long\def\st@ckparas#1\p@r@end{% \global\p@r@count=0\gdef\p@r@data{#1}\ag@in}% % % PARAMETER ASSIGNMENT % use \temp@count \def\getp@r@s{\temp@count=\p@r@count {\loop \ifnum\temp@count>0 % \expandafter\let\expandafter \temp@macro\csname STK\the\STKcount\string~\endcsname \ifcase\temp@count \or \global\p@r@one=\expandafter{\temp@macro}% \or \global\p@r@two=\expandafter{\temp@macro}% \or \global\p@r@three=\expandafter{\temp@macro}% \or \global\p@r@four=\expandafter{\temp@macro}% \or \global\p@r@five=\expandafter{\temp@macro}% \or \global\p@r@six=\expandafter{\temp@macro}% \or \global\p@r@seven=\expandafter{\temp@macro}% \or \global\p@r@eight=\expandafter{\temp@macro}% \or \global\p@r@nine=\expandafter{\temp@macro}% \else \errmessage{Parameter capacity exceeded.}% % this should never happen: TeX's max para no. is 9 \fi \global\expandafter\let \csname STK\the\STKcount\string~\endcsname=\undefined@% \global\advance\STKcount-1% \global\advance\temp@count-1\relax \fi \ifnum\temp@count>0 % \repeat}}% % \def\clrp@r@s{%GLOBALLY clear \global\p@r@one={}\global\p@r@two={}\global\p@r@three={}% \global\p@r@four={}\global\p@r@five={}\global\p@r@six={}% \global\p@r@seven={}\global\p@r@eight={}\global\p@r@nine={}}% % \def\read@paras#1{\temp@@@count=1 %use \temp@@@count and \temp@@count \loop \num@to@word{\the\temp@@@count}\csname p@r@\the\temp@toks\endcsname={}% \advance\temp@@@count by 1 \ifnum\temp@@@count<10 \repeat \temp@@@count=1 \temp@@count=#1 % \def\read@one@para##1{\num@to@word{\temp@@@count}% \def\temp@macro{\left@ ##1\right@}% \temp@@@toks=\expandafter{\temp@macro}% \csname p@r@\the\temp@toks\endcsname\expandafter{\temp@macro}% \advance\temp@@@count by 1 \read@continue}% \def\read@continue{\num@to@word{\temp@@@count}% which uses \temp@macro \ifnum\temp@@@count>\temp@@count \let\next@@\make@default \edef\temp@@macro{\the\p@r@one\the\p@r@two\the\p@r@three\the\p@r@four \the\p@r@five\the\p@r@six\the\p@r@seven\the\p@r@eight\the\p@r@nine}% \else \let\next@@\read@one@para \fi \next@@}\read@continue}% % \def\make@@default#1#2{\temp@count=#2\relax \temp@@count=1 %used \temp@@macro \loop \num@to@word{\temp@@count}% \ifnum\temp@@count>\temp@count \csname p@r@\the\temp@toks\endcsname={}% \else \csname p@r@\the\temp@toks\endcsname =\expandafter{\expandafter[\expandafter \the\csname p@r@\the\temp@toks\endcsname]}\fi \advance\temp@@count by 1 % \ifnum\temp@@count<10 \repeat \edef\temp@macro{\the\p@r@one\the\p@r@two\the\p@r@three\the\p@r@four \the\p@r@five\the\p@r@six\the\p@r@seven\the\p@r@eight\the\p@r@nine}% \temp@toks=\expandafter{\temp@macro}% \temp@@toks=\expandafter{\temp@@macro}% \expandafter\let\expandafter\temp@macro\csname #1\endcsname \expandafter\ifx\csname #1@ raw\endcsname\relax \expandafter\let\csname #1@ raw\endcsname\temp@macro\fi \expandafter\edef\csname#1\endcsname{% \noexpand\push{\noexpand\edef\noexpand\next@@{% \noexpand\noexpand \noexpand \csname \noexpand#1@ raw\noexpand\endcsname \the\temp@toks}% \noexpand\popnil\noexpand\clrp@r@s\noexpand\next@@}\noexpand\st@ckparas \the\temp@@toks \noexpand\p@r@end}}% % % \setdefalut{cmdname}{n}{default1}{..}{default_n} % then \cmdname[#1][..][#n] can be defaulted. \def\setdefault#1#2{\def\make@default{\make@@default{#1}{#2}}\read@paras{#2}} % % DEFAULT MECHANISM END: this piece of code can be included in any % package and can be reloaded any times without overruning the resources. % % Now an example to use \setdefault: % lower a box \long\def\xylower#1#2#3{\bgroup\hskip#1\hbox{% #1=x #2=y #3=content \ifmmode\let\SoftLower\undefined\else\def\SoftLower{}$\fi \mathop{\vtop{\ialign{##\crcr \noalign{\kern#2}#3\crcr}}}% \ifx\SoftLower\undefined\else $\fi}\egroup}% % % #1=box position(0) #2=x shift(0pt) #3=y shift(0pt) #6=v (vbox) % #4,#5=extra x,y shift in multiple of box width/10, height/10 #7=content \long\def\placebox[#1][#2][#3][#4][#5][#6]#7{\begingroup \def\temp@macro{#6}\def\temp@@macro{v}\ifx\temp@macro\temp@@macro \setbox\temp@box=\vbox{#7}\else \leavevmode % #1 (box position) \setbox\temp@box=\hbox{#7}\fi\temp@dim=-\wd\temp@box % 1--6--2 \temp@@dim=\ht\temp@box \temp@@@dim=\dp\temp@box % | | \ifnum#1<0 \temp@count=-#1 \else\temp@count=#1 \fi % | | \ifnum\temp@count=0 \temp@count=5 \fi % | | \ifcase\temp@count % 9 5 7 0 is -5 \or \temp@dim=0pt \temp@@dim=0pt % | | \or \temp@@dim=0pt % 10 11 12 <-height up \or \advance\temp@@dim by \temp@@@dim % | | depth down \temp@@dim=-\temp@@dim % 4--8--3 \or \temp@dim=0pt \advance\temp@@dim by % \temp@@@dim \temp@@dim=-\temp@@dim % -#1: box has no width etc \or \divide\temp@dim by 2 \advance\temp@@@dim by \temp@@dim \divide\temp@@@dim by 2 \temp@@dim=-\temp@@@dim \or \divide\temp@dim by 2 \temp@@dim=0pt \or \advance\temp@@dim by \temp@@@dim \temp@@dim=-\temp@@dim \divide\temp@@dim by 2 \or \advance\temp@@dim by \temp@@@dim \temp@@dim=-\temp@@dim \divide\temp@dim by 2 \or \temp@dim=0pt \advance\temp@@dim by \temp@@@dim \temp@@dim=-\temp@@dim \divide\temp@@dim by 2 \or \temp@dim=0pt \advance\temp@@@dim by \temp@@dim \temp@@dim=-\temp@@dim \or \divide\temp@dim by 2 \advance\temp@@@dim by \temp@@dim \temp@@dim=-\temp@@dim \or \advance\temp@@@dim by \temp@@dim \temp@@dim=-\temp@@dim \or \errmessage{Invalid range of first parameter: #1}\fi \advance\temp@dim by #2 \advance \temp@@dim by #3 \temp@@@dim=\wd\temp@box \divide \temp@@@dim by 10 \multiply\temp@@@dim by #4 \advance\temp@dim by \temp@@@dim \temp@@@dim=\ht\temp@box \advance\temp@@@dim by \dp\temp@box \divide \temp@@@dim by 10 \multiply\temp@@@dim by #5 \advance\temp@@dim by \temp@@@dim \setbox\temp@box=\hbox{\xylower{\temp@dim}{\temp@@dim}{\box\temp@box}}% \ifnum#1>0 \else \wd\temp@box=0pt \ht\temp@box=0pt \dp\temp@box=0pt \fi \box\temp@box\endgroup }% % \ifx\setdefault\undefined\else\setdefault{placebox}{6}{0}{0pt}{0pt}{0}{0}{h}\fi % example ends % \let\wlog\temp@@@macro\let\temp@@@macro\undefined@ \catcode`\@=\EntryDefault\relax \endinput % %ENDMACROS %