From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/generic/misc/default.sty | 311 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 macros/generic/misc/default.sty (limited to 'macros/generic/misc/default.sty') diff --git a/macros/generic/misc/default.sty b/macros/generic/misc/default.sty new file mode 100644 index 0000000000..b2a0f0c023 --- /dev/null +++ b/macros/generic/misc/default.sty @@ -0,0 +1,311 @@ +% 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 +% -- cgit v1.2.3