\def\doind#1#2{} \def\obeylinez{} \def\inENV{\relax} \message{defuns,} % Define formatter for defuns % First, allow user to change definition object font (\df) internally \def\setdeffont#1{\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deftypemargin \deftypemargin=12pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % define \functionparens, which makes ( and ) and & do special things. % \functionparens affects the group it is contained in. \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active} {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1{{\rm\char`\(}#1 \bf \let(=\opnested % \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1{{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&} \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % First, defname, which formats the header line itself. %#1 should be the function name. % #2 should be the type of definition, such as "Function". \def\defname#1#2{% % Get the values of \leftskip and \rightskip as they were % outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent \dimen3=\rightskip \advance\dimen3 by -\defbodyindent \noindent % \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % % Now output arg 2 ("Function" or some such) % ending at \deftypemargin from the right margin, % but stuck inside a box of width 0 so it does not interfere with linebreaking {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \advance \hsize by -\dimen3 \rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}% % Make all lines underfull and no complaints: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent {\df#1}\enskip % Generate function name } % Actually process the body of a definition %#1 should be the terminating control sequence, such as \Edefun. % #2 should be the "another name" control sequence, such as \defunx. % #3 should be the control sequence that actually processes the header, % such as \defunheader. \def\defparsebody#1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylinez\activeparens\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \begingroup % \catcode 61=\active % \obeylinez\activeparens\spacesplit#3} \def\defmethparsebody#1#2#3#4{\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1{\begingroup\obeylinez\activeparens\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \begingroup\obeylinez\activeparens\spacesplit{#3{#4}}} \def\defopparsebody#1#2#3#4#5{\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylinez\activeparens\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \begingroup\obeylinez\activeparens\spacesplit{#3{#5}}} % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. \def\defvarparsebody#1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylinez\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \begingroup % \catcode 61=\active % \obeylinez\spacesplit#3} \def\defvrparsebody#1#2#3#4{\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1{\begingroup\obeylinez\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \begingroup\obeylinez\spacesplit{#3{#4}}} \def\defopvarparsebody#1#2#3#4#5{\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylinez\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \begingroup\obeylinez\spacesplit{#3{#5}}} % Split up #2 at the first space token. % call#1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. {\obeylinez \gdef\spacesplit#1#2{\endgroup\spacesplitfoo{#1}{#2}\relax\spacesplitfoo}% \long\gdef\spacesplitfoo#1#2#3#4\spacesplitfoo{% \ifx\relax #3% #1{#2}{}\else#1{#2}{#3#4}\fi}} \def\spacesplit#1#2{\endgroup\spacesplitbar{#1}{#2}} \def\spacesplitbar#1#2#3{#1{#2}{#3}} % So much for the things common to all kinds of definitions. % Define @defun. % First, define the processing that is wanted for arguments of \defun % Use this to expand the args and terminate the paragraph they make up \def\defunargs#1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. \hyphenchar\tensl=0 #1% \hyphenchar\tensl=45 \ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\penalty 10000\vskip -\parskip\penalty 10000% } \def\deftypefunargs#1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. \functionparens \code{#1}% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\penalty 10000\vskip -\parskip\penalty 10000% } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\enddeffn\deffnx\deffnheader} \def\deffnheader#1#2#3{\fnindexbold{#2}% \begingroup\defname{#2}{#1}\defunargs{#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\enddefun\defunx\defunheader} \def\defunheader#1#2{\fnindexbold{#1}% Make entry in function index \begingroup\defname{#1}{Function}% \defunargs{#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\enddeftypefun\deftypefunx\deftypefunheader} %#1 is the data type. #2 is the name and args. \def\deftypefunheader#1#2{\deftypefunheaderx{#1}{#2}} %#1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx#1#2#3{% \fnindexbold{#2}% Make entry in function index \begingroup\defname{\code{#1} #2}{Function}% \deftypefunargs{#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\enddeftypefn\deftypefnx\deftypefnheader} %#1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader#1#2#3{\deftypefnheaderx{#1}{#2}{#3}} %#1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx#1#2#3#4{% \fnindexbold{#3}% Make entry in function index \begingroup\defname{\code{#2} #3}{#1}% \deftypefunargs{#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\enddefmac\defmacx\defmacheader} \def\defmacheader#1#2{\fnindexbold{#1}% Make entry in function index \begingroup\defname{#1}{Macro}% \defunargs{#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\enddefspec\defspecx\defspecheader} \def\defspecheader#1#2{\fnindexbold{#1}% Make entry in function index \begingroup\defname{#1}{Special Form}% \defunargs{#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % This definition is run if you use @defunx % anywhere other than immediately after a @defun or @defunx. \def\deffnx#1{\errmessage{@deffnx in invalid context}} \def\defunx#1{\errmessage{@defunx in invalid context}} \def\defmacx#1{\errmessage{@defmacx in invalid context}} \def\defspecx#1{\errmessage{@defspecx in invalid context}} \def\deftypefnx#1{\errmessage{@deftypefnx in invalid context}} \def\deftypeunx#1{\errmessage{@deftypeunx in invalid context}} % @defmethod, and so on % @defop {Funny Method} foo-class frobnicate argument \def\defop#1{\def\defoptype{#1}% \defopparsebody\enddefop\defopx\defopheader\defoptype} \def\defopheader#1#2#3{% \dosubind {fn}{\code{#2}}{on#1}% Make entry in function index \begingroup\defname{#2}{\defoptype{} on#1}% \defunargs{#3}\endgroup % } % @defmethod == @defop Method \def\defmethod{\defmethparsebody\enddefmethod\defmethodx\defmethodheader} \def\defmethodheader#1#2#3{% \dosubind {fn}{\code{#2}}{on#1}% entry in function index \begingroup\defname{#2}{Method on#1}% \defunargs{#3}\endgroup % } % @defcv {Class Option} foo-class foo-flag \def\defcv#1{\def\defcvtype{#1}% \defopvarparsebody\enddefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader#1#2#3{% \dosubind {vr}{\code{#2}}{of#1}% Make entry in var index \begingroup\defname{#2}{\defcvtype{} of#1}% \defvarargs {#3}\endgroup % } % @defivar == @defcv {Instance Variable} \def\defivar{\defvrparsebody\enddefivar\defivarx\defivarheader} \def\defivarheader#1#2#3{% \dosubind {vr}{\code{#2}}{of#1}% Make entry in var index \begingroup\defname{#2}{Instance Variable of#1}% \defvarargs {#3}\endgroup % } % These definitions are run if you use @defmethodx, etc., % anywhere other than immediately after a @defmethod, etc. \def\defopx#1{\errmessage{@defopx in invalid context}} \def\defmethodx#1{\errmessage{@defmethodx in invalid context}} \def\defcvx#1{\errmessage{@defcvx in invalid context}} \def\defivarx#1{\errmessage{@defivarx in invalid context}} % Now @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs#1{\normalparens#1% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000} % @defvr Counter foo-count \def\defvr{\defvrparsebody\enddefvr\defvrx\defvrheader} \def\defvrheader#1#2#3{\vrindexbold{#2}% \begingroup\defname{#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\enddefvar\defvarx\defvarheader} \def\defvarheader#1#2{\vrindexbold{#1}% Make entry in var index \begingroup\defname{#1}{Variable}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\enddefopt\defoptx\defoptheader} \def\defoptheader#1#2{\vrindexbold{#1}% Make entry in var index \begingroup\defname{#1}{User Option}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\enddeftypevar\deftypevarx\deftypevarheader} %#1 is the data type. #2 is the name. \def\deftypevarheader#1#2{% \vrindexbold{#2}% Make entry in variables index \begingroup\defname{\code{#1} #2}{Variable}% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\enddeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader#1#2#3{\vrindexbold{#3}% \begingroup\defname{\code{#2} #3}{#1} \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} % This definition is run if you use @defvarx % anywhere other than immediately after a @defvar or @defvarx. \def\defvrx#1{\errmessage{@defvrx in invalid context}} \def\defvarx#1{\errmessage{@defvarx in invalid context}} \def\defoptx#1{\errmessage{@defoptx in invalid context}} \def\deftypevarx#1{\errmessage{@deftypevarx in invalid context}} \def\deftypevrx#1{\errmessage{@deftypevrx in invalid context}} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs#1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\defvrparsebody\enddeftp\deftpx\deftpheader} \def\deftpheader#1#2#3{\tpindexbold{#2}% \begingroup\defname{#2}{#1}\deftpargs{#3}\endgroup} % This definition is run if you use @deftpx, etc % anywhere other than immediately after a @deftp, etc. \def\deftpx#1{\errmessage{@deftpx in invalid context}}