| 1 | %%% -*-latex-*- |
| 2 | %%% |
| 3 | %%% Styles and other hacking for the Sod manual |
| 4 | %%% |
| 5 | %%% (c) 2015 Straylight/Edgeware |
| 6 | %%% |
| 7 | |
| 8 | %%%----- Licensing notice --------------------------------------------------- |
| 9 | %%% |
| 10 | %%% This file is part of the Sensible Object Design, an object system for C. |
| 11 | %%% |
| 12 | %%% SOD is free software; you can redistribute it and/or modify |
| 13 | %%% it under the terms of the GNU General Public License as published by |
| 14 | %%% the Free Software Foundation; either version 2 of the License, or |
| 15 | %%% (at your option) any later version. |
| 16 | %%% |
| 17 | %%% SOD is distributed in the hope that it will be useful, |
| 18 | %%% but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | %%% GNU General Public License for more details. |
| 21 | %%% |
| 22 | %%% You should have received a copy of the GNU General Public License |
| 23 | %%% along with SOD; if not, write to the Free Software Foundation, |
| 24 | %%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 25 | |
| 26 | \ProvidesPackage{sod} |
| 27 | |
| 28 | %%%-------------------------------------------------------------------------- |
| 29 | %%% Basic style things. |
| 30 | |
| 31 | %% More reference types. |
| 32 | \defxref{p}{part} |
| 33 | |
| 34 | %% A gadget to include in `\xref': call as |
| 35 | %% |
| 36 | %% \xref[\instead{THING}]{LABEL} |
| 37 | %% |
| 38 | %% to replace the usual `section' or whatever with THING. |
| 39 | \def\instead#1#2{#1} |
| 40 | |
| 41 | %% Other languages with special typesetting. |
| 42 | \def\Cplusplus{C\kern-\p@++} |
| 43 | \def\Csharp{C\#} |
| 44 | |
| 45 | %% Special maths notation. |
| 46 | \def\chain#1#2{\mathsf{ch}_{#1}(#2)} |
| 47 | \def\chainhead#1#2{\mathsf{hd}_{#1}(#2)} |
| 48 | \def\chaintail#1#2{\mathsf{tl}_{#1}(#2)} |
| 49 | |
| 50 | %% Other mathematical tweaks. |
| 51 | \let\implies\Rightarrow |
| 52 | \let\epsilon\varepsilon |
| 53 | |
| 54 | %% A table heading cell. Clone and hack \multicolumn. |
| 55 | \def\thd{\omit\@ifnextchar[\thd@{\thd@[l]}} |
| 56 | \def\thd@[#1]#2{% |
| 57 | \begingroup |
| 58 | \tab@multicol \tab@initread \let\tab@looped\tab@err@multi |
| 59 | \tab@preamble{}\def\tab@midtext{\bfseries#2}\tab@readpreamble{#1}% |
| 60 | \the\tab@preamble |
| 61 | \endgroup \ignorespaces |
| 62 | } |
| 63 | |
| 64 | %% Unix manpage references. |
| 65 | \def\man#1#2{\textbf{#1}(#2)} |
| 66 | |
| 67 | %% Listings don't need to be small. |
| 68 | \let\listingsize\relax |
| 69 | |
| 70 | %% Notes for later. |
| 71 | \def\fixme#1{\leavevmode\marginpar{FIXME}\index{FIXME}[FIXME: #1]} |
| 72 | |
| 73 | %% Diagram settings. |
| 74 | \tikzset{ |
| 75 | every picture/.style={>=stealth, thick}, |
| 76 | lit/.style={font=\sffamily} |
| 77 | } |
| 78 | |
| 79 | %% Metavariables are italics without decoration. |
| 80 | \def\syntleft{\normalfont\itshape} |
| 81 | \let\syntright\empty |
| 82 | |
| 83 | %% Literal code is in sans face. |
| 84 | \def\codeface{\upshape\sffamily} |
| 85 | \DeclareRobustCommand\code[1]{% |
| 86 | \ifmmode\hbox\else\leavevmode\fi% |
| 87 | {\normalfont\codeface\/#1\/}% |
| 88 | } |
| 89 | \def\ulitleft{\normalfont\codeface} |
| 90 | \let\ulitright\empty |
| 91 | \def\lit@i#1#2#3{\ifmmode\leavevmode\hbox\fi{#1{#3\/}#2}} |
| 92 | |
| 93 | %% Conditionally enter maths mode. Can't use \ensuremath here because we |
| 94 | %% aren't necessarily sure where the maths will actually end. |
| 95 | \let\m@maybe@end\relax |
| 96 | \def\m@maybe{\ifmmode\else$\let\m@maybe@end$\fi} |
| 97 | |
| 98 | %% Standard syntax shortcuts. |
| 99 | \atdef <#1>{\synt{#1}\@scripts} |
| 100 | \atdef "#1"{\lit*{#1}\@scripts} |
| 101 | \atdef `#1'{\lit{#1}\@scripts} |
| 102 | \atdef |#1|{\lit*{#1}\@scripts} |
| 103 | |
| 104 | %% A handy abbreviation; `\\' itself is too good to steal. |
| 105 | \atdef \\{\textbackslash} |
| 106 | |
| 107 | %% Intercept grammar typesetting and replace the vertical bar with the |
| 108 | %% maths-font version. |
| 109 | \let\@@grammar\grammar |
| 110 | \def\grammar{\def\textbar{\hbox{$|$}}\@@grammar} |
| 111 | |
| 112 | %% Collect super- and subscripts. (Note that underscores are active for the |
| 113 | %% most part.) When we're done, end maths mode if we entered it |
| 114 | %% conditionally. |
| 115 | \def\@scripts{\futurelet\@ch\@scripts@i} |
| 116 | \begingroup\lccode`\~=`\_\lowercase{\endgroup |
| 117 | \def\@scripts@i{\if1\ifx\@ch~1\else\ifx\@ch_1\else\ifx\@ch^1\else0\fi\fi\fi% |
| 118 | \expandafter\@scripts@ii\else\expandafter\m@maybe@end\fi}} |
| 119 | \def\@scripts@ii#1#2{\m@maybe#1{#2}\@scripts} |
| 120 | |
| 121 | %% Doubling characters, maybe. Either way, chain onto \@scripts. |
| 122 | \def\dbl@maybe#1{\let\@tempa#1\futurelet\@ch\dbl@maybe@i} |
| 123 | \def\dbl@maybe@i{\m@maybe\ifx\@ch\@tempa\@tempa\!\@tempa% |
| 124 | \expandafter\@firstoftwo\expandafter\@scripts% |
| 125 | \else\@tempa\expandafter\@scripts\fi} |
| 126 | |
| 127 | %% Lookahead without eating spaces. |
| 128 | \def\@ifnextchar@preserve#1#2#3{% |
| 129 | \let\want@= #1\def\@tempa{#2}\def\@tempb{#3}% |
| 130 | \futurelet\nch@\@ifnch@p% |
| 131 | } |
| 132 | \def\@ifnch@p{% |
| 133 | \ifx\want@\nch@\expandafter\@tempa\else\expandafter\@tempb\fi} |
| 134 | |
| 135 | %% Extra syntax for Lisp templates. These produce the maths-font versions of |
| 136 | %% characters, which should contrast well against the sans face used for |
| 137 | %% literals. |
| 138 | \atdef [{\dbl@maybe[} |
| 139 | \atdef ]{\dbl@maybe]} |
| 140 | \atdef {{\m@maybe\{\@scripts} |
| 141 | \atdef }{\m@maybe\}\@scripts} |
| 142 | \atdef ({\m@maybe(\@scripts} |
| 143 | \atdef ){\m@maybe)\@scripts} |
| 144 | \atdef !{\m@maybe|\@scripts} |
| 145 | |
| 146 | \def\returns{\m@maybe\longrightarrow\m@maybe@end\hspace{0.5em}\ignorespaces} |
| 147 | \def\nlret{\\\hspace{4em}\returns} |
| 148 | \atdef >{\leavevmode\unskip\hspace{0.5em}\returns} |
| 149 | |
| 150 | %% Extra syntax for common tokens. |
| 151 | \atdef ~{\textasciitilde} |
| 152 | \atdef -{\leavevmode\hbox\bgroup\futurelet\ch@\@dash} |
| 153 | \def\@dash{% |
| 154 | \ifx\ch@>% |
| 155 | --\raisebox{.4pt}{>}% |
| 156 | \def\next@{\@firstoftwo{\egroup\penalty200\relax}}% |
| 157 | \else\ifx\ch@-% |
| 158 | --\,% |
| 159 | \def\next@{\@firstoftwo{\futurelet\ch@\@dash}}% |
| 160 | \else% |
| 161 | --% |
| 162 | \let\next@\egroup% |
| 163 | \fi\fi |
| 164 | \next@% |
| 165 | } |
| 166 | |
| 167 | %% Comment setting. |
| 168 | \def\comment#1{\mbox{\normalfont\itshape\/#1\/}} |
| 169 | \atdef /*#1*/{/*\comment{#1}*/} |
| 170 | \def\@semis;{\@ifnextchar@preserve;{;\@semis}\@semicomment} |
| 171 | \def\@semicomment#1\\{\comment{#1}\\} |
| 172 | \atdef ;{;\@semis;} |
| 173 | |
| 174 | %% Put a chunk of text in a box. |
| 175 | \newenvironment{boxy}[1][\q@]{% |
| 176 | \savenotes% |
| 177 | \dimen@\linewidth\advance\dimen@-1.2pt\advance\dimen@-2ex% |
| 178 | \medskip% |
| 179 | \vbox\bgroup\hrule\hbox\bgroup\vrule% |
| 180 | \vbox\bgroup\vskip1ex\hbox\bgroup\hskip1ex\minipage\dimen@% |
| 181 | \def\@temp{#1}\ifx\@temp\q@\else\leavevmode{\headfam\bfseries#1\quad}\fi% |
| 182 | }{% |
| 183 | \endminipage\hskip1ex\egroup\vskip1ex\egroup% |
| 184 | \vrule\egroup\hrule\egroup% |
| 185 | \medskip% |
| 186 | \spewnotes% |
| 187 | } |
| 188 | |
| 189 | %%%-------------------------------------------------------------------------- |
| 190 | %%% Environment for setting programs. |
| 191 | |
| 192 | %% Main guts of `prog' and `nprog'. |
| 193 | \def\@prog{\let\prog@@cr\@tabcr\let\@tabcr\@progcr\codeface\tabbing} |
| 194 | |
| 195 | %% Newlines: called by `\\' within a `prog'. |
| 196 | %% |
| 197 | %% \\ newline without following break |
| 198 | %% \\[SKIP] newline /with/ break and vertical glue |
| 199 | %% \\*[SKIP] newline without break, with optional glue |
| 200 | %% \\+ newline with break and a vertical gap |
| 201 | %% \\- newline without break, with a tiny gap |
| 202 | \def\@progcr{\futurelet\@tempa\@progcr@i} |
| 203 | \def\@progcr@i{% |
| 204 | \ifx\@tempa\@sptoken\let\next@\@progcr@sp\else |
| 205 | \if1\ifx\@tempa[1\else |
| 206 | \ifx\@tempa*1\else |
| 207 | 0\fi\fi |
| 208 | \let\next@\prog@@cr\else |
| 209 | \if1\ifx\@tempa+1\else |
| 210 | \ifx\@tempa-1\else |
| 211 | 0\fi\fi |
| 212 | \let\next@\@progcr@ii\else |
| 213 | \let\next@\@progcr@a\fi\fi\fi |
| 214 | \next@} |
| 215 | \def\@progcr@a{\prog@@cr*{}\ignorespaces} |
| 216 | \def\@progcr@ii#1{\csname @progcr@#1\endcsname\ignorespaces} |
| 217 | \@namedef{@progcr@+}{\prog@@cr[\medskipamount]} |
| 218 | \@namedef{@progcr@-}{\prog@@cr*[\jot]} |
| 219 | {\def\:{\gdef\@progcr@sp}\: {\@progcr}} % \@progcr@sp eats space and recurses |
| 220 | |
| 221 | %% Set a program in `codeface', with implicit tabbing and other toys. |
| 222 | %% Newlines are explicit, because otherwise I need comments in weird places |
| 223 | %% to make the vertical spacing come out properly. You can write |
| 224 | %% `\obeylines' if you really want to. |
| 225 | \def\prog{\quote\@prog} |
| 226 | \def\endprog{\endtabbing\endquote} |
| 227 | |
| 228 | %% Like `prog', but without indenting the code. Use this within environments |
| 229 | %% which already set their contents out from the body text in some |
| 230 | %% distinctive way. |
| 231 | \let\nprog\@prog |
| 232 | \let\endnprog\endtabbing |
| 233 | |
| 234 | %% Indent the following material. Cancel using `\-'. |
| 235 | \def\ind{\quad\=\+\kill} |
| 236 | |
| 237 | %% Show a backslash by the right-hand margin; for multiline macros etc. |
| 238 | \def\macsl{\`\textbackslash\hskip\leftmargin} |
| 239 | |
| 240 | %% \maplist{THING}{{ITEM}...}: Invoke THING{ITEM} for each ITEM in turn. |
| 241 | \def\maplist#1#2{\map@i{#1}#2\q@} |
| 242 | \def\map@i#1{\def\next@{\map@ii{#1}}\futurelet\ch@\next@} |
| 243 | \def\map@ii#1{\ifx\ch@\q@\expandafter\@gobble% |
| 244 | \else\def\next@{\map@iii{#1}}\expandafter\next@\fi} |
| 245 | \def\map@iii#1#2{#1{#2}\map@i{#1}} |
| 246 | |
| 247 | %% \crossproduct{THING}{{LIST}...} where each LIST is {ITEM}... |
| 248 | %% For each possible way of selecting one ITEM from each LIST, in order, |
| 249 | %% invoke THING{{ITEM}...} |
| 250 | \toksdef\cprod@new=0 |
| 251 | \toksdef\cprod@old=2 |
| 252 | \toksdef\cprod@head=4 |
| 253 | \toksdef\cprod@tail=6 |
| 254 | \def\crossproduct#1#2{% |
| 255 | \cprod@new{{}}% |
| 256 | \maplist{\cprod@f{#1}}{#2}% |
| 257 | \cprod@head{#1}% |
| 258 | \edef\next@{\noexpand\maplist{\the\cprod@head}{\the\cprod@new}} |
| 259 | \next@% |
| 260 | } |
| 261 | \def\cprod@f#1#2{% |
| 262 | \cprod@old\cprod@new\cprod@new{}% |
| 263 | \maplist\cprod@g{#2}% |
| 264 | } |
| 265 | \def\cprod@g#1{% |
| 266 | \cprod@head{#1}% |
| 267 | \expandafter\maplist\expandafter\cprod@h\expandafter{\the\cprod@old}% |
| 268 | } |
| 269 | \def\cprod@h#1{% |
| 270 | \cprod@tail{#1}% |
| 271 | \cprod@new\expandafter{\the\expandafter\cprod@new\expandafter{% |
| 272 | \the\expandafter\cprod@tail\the\cprod@head}}% |
| 273 | } |
| 274 | |
| 275 | %%%-------------------------------------------------------------------------- |
| 276 | %%% Machinery for describing functions, etc. |
| 277 | |
| 278 | %% \definedescribecategory{CAT}[KIND]{NAME} |
| 279 | %% |
| 280 | %% Define a category of things to document. CAT is a short label identifying |
| 281 | %% the category to `\describe', `\descref', and friends. The NAME is the |
| 282 | %% text to show in the description headline; it is a macro body which is |
| 283 | %% passed an argument `#1' that applies a modifier to some portion of the |
| 284 | %% text. |
| 285 | %% |
| 286 | %% The KIND allows additional arguments to be collected, included in label |
| 287 | %% strings, and mentioned in the index. The default is `plain'. |
| 288 | \def\definedescribecategory#1{% |
| 289 | \@ifnextchar[{\def@desc{#1}}{\def@desc{#1}[plain]}} |
| 290 | \def\def@desc#1[#2]#3{\@namedef{cat!#1}##1{#3}\@namedef{catsw!#1}{#2}} |
| 291 | |
| 292 | %% \describecategoryname[MOD]{CAT} |
| 293 | %% |
| 294 | %% Typeset the category name for CAT, modified by MOD. |
| 295 | \def\describecategoryname{\@ifnextchar[\@descname@i{\@descname@i[]}} |
| 296 | \def\@descname@i[#1]#2{% |
| 297 | \expandafter\let\expandafter\@tempa\csname cat!#2\endcsname% |
| 298 | \expandafter\let\expandafter\@tempb\csname modcat/#1\endcsname% |
| 299 | \ifx\@tempa\relax\@tempb{#2}\else\@tempa\@tempb\fi} |
| 300 | |
| 301 | %% Call a modifier method. |
| 302 | \def\@mod@dispatch#1#2{\csname #1/#2\endcsname} |
| 303 | |
| 304 | %% Call a description method given the category. |
| 305 | \def\@desc@dispatch#1#2{% |
| 306 | \csname #1/% |
| 307 | \expandafter\ifx\csname catsw!#2\endcsname\relax plain% |
| 308 | \else \csname catsw!#2\endcsname \fi% |
| 309 | \endcsname% |
| 310 | } |
| 311 | |
| 312 | %% Modifier methods for the default `plain' modifier. |
| 313 | \@namedef{modcat/plain}#1{#1} |
| 314 | \@namedef{modlabel/plain}#1{#1} |
| 315 | \@namedef{modindex/plain}#1{#1@\noexpand\code{#1}} |
| 316 | |
| 317 | %% Modifier methods for `setf'. The name text prefixes the relevant word |
| 318 | %% with `setf-'. |
| 319 | \@namedef{modcat/setf}#1{\code{setf}-#1} |
| 320 | \@namedef{modlabel/setf}#1{setf/#1} |
| 321 | \@namedef{modindex/setf}#1{#1@\noexpand\code{#1}} |
| 322 | |
| 323 | %% Modifier methods for words with *earmuffs*. Sort into the index without |
| 324 | %% the earmuffs. |
| 325 | \@namedef{modcat/muffs}#1{#1} |
| 326 | \@namedef{modlabel/muffs}#1{#1} |
| 327 | \@namedef{modindex/muffs}#1{\@unmuff#1@\noexpand\code{#1}} |
| 328 | \def\@unmuff*#1*{#1} |
| 329 | |
| 330 | %% Modifier methods for :keywords. Sort into the index without the `:'. |
| 331 | \@namedef{modcat/kwd}#1{#1} |
| 332 | \@namedef{modlabel/kwd}#1{#1} |
| 333 | \@namedef{modindex/kwd}#1{\@gobble#1@\noexpand\code{#1}} |
| 334 | |
| 335 | %% Category-kind methods for plain categories. |
| 336 | \@namedef{descargs/plain}#1{#1{}} |
| 337 | \@namedef{desclabel/plain}#1#2#3{#2:\@mod@dispatch{modlabel}{#1}{#3}} |
| 338 | \@namedef{descindex/plain}#1#2#3{% |
| 339 | \@mod@dispatch{modindex}{#1}{#3}!% |
| 340 | \protect\describecategoryname[#1]{#2}% |
| 341 | } |
| 342 | |
| 343 | %% Category-kind methods for `method' categories. Collect an extra argument |
| 344 | %% listing the specializers: include them in the label, and typeset them in |
| 345 | %% the index. |
| 346 | \def\fmtspecs#1#2{% |
| 347 | \if!#2!\else\count@\z@\toks@{}#1\fmtspecs@i#2,\q@,\fi} |
| 348 | \def\fmtspecs@i#1,{% |
| 349 | \def\@tempa{#1}% |
| 350 | \ifx\@tempa\q@% |
| 351 | \ifcase\count@(no args?!)% |
| 352 | \or% nothin' doin |
| 353 | \or \space and % |
| 354 | \else, and % |
| 355 | \fi% |
| 356 | \the\toks@% |
| 357 | \else% |
| 358 | \ifnum\count@>\@ne, \fi% |
| 359 | \the\toks@% |
| 360 | \toks@{\code{#1}}\advance\count@\@ne% |
| 361 | \expandafter\fmtspecs@i% |
| 362 | \fi% |
| 363 | } |
| 364 | \@namedef{descargs/method}#1#2{#1{{#2}}} |
| 365 | \@namedef{desclabel/method}#1#2#3#4% |
| 366 | {#2:\@mod@dispatch{modlabel}{#1}{#4}(#3)} |
| 367 | \@namedef{descindex/method}#1#2#3#4{% |
| 368 | \@mod@dispatch{modindex}{#1}{#4}!% |
| 369 | \protect\describecategoryname[#1]{#2}% |
| 370 | \protect\fmtspecs{ specialized at }{#3}% |
| 371 | } |
| 372 | |
| 373 | %% Some magic strings. |
| 374 | \def\q@{\q@} |
| 375 | \def\@setf{setf} |
| 376 | \def\@starstar{**} |
| 377 | |
| 378 | %% \parse@dhd{NEXT}[MOD]{CAT}{...}...[NAME]{SYNOPSIS} |
| 379 | %% |
| 380 | %% Parse the arguments for a description header, and call |
| 381 | %% |
| 382 | %% NEXT{MOD}{CAT}{{...}...}{NAME}{SYNOPSIS} |
| 383 | %% |
| 384 | %% Here, {...}... represents the additional category-kind arguments. See |
| 385 | %% `describe' for what all of this means. |
| 386 | \def\parse@dhd#1{% {NEXT} |
| 387 | \@ifnextchar[{\parse@dhd@a{#1}}{\parse@dhd@c{#1}}} |
| 388 | \def\parse@dhd@a#1[#2]#3{% {NEXT}[MOD]{CAT} |
| 389 | \@desc@dispatch{descargs}{#3}{\parse@dhd@ab{#1}{#2}{#3}}} |
| 390 | \def\parse@dhd@ab#1#2#3#4{% {NEXT}{MOD}{CAT}{{...}...} |
| 391 | \@ifnextchar[{\parse@dhd@ac{#1}{#2}{#3}{#4}}{\parse@dhd@ad{#1}{#2}{#3}{#4}}} |
| 392 | \def\parse@dhd@ac#1#2#3#4[#5]#6{% {NEXT}{MOD}{CAT}{{...}...}[NAME]{SYNOPSIS} |
| 393 | #1{#2}{#3}{#4}{#5}{#6}} |
| 394 | \def\parse@dhd@ad#1#2#3#4#5{% {NEXT}{MOD}{CAT}{{...}...}{NAME [ARGS...]} |
| 395 | \parse@dhd@ae{#1}{#2}{#3}{#4}{#5}#5 \q@} |
| 396 | \def\parse@dhd@ae#1#2#3#4#5#6 #7\q@{% |
| 397 | % {NEXT}{MOD}{CAT}{{...}...}{SYNSOPSIS}NAME [ARGS...]\q@ |
| 398 | #1{#2}{#3}{#4}{#6}{#5}} |
| 399 | |
| 400 | \def\parse@dhd@c#1#2{% {NEXT}{CAT} |
| 401 | \@desc@dispatch{descargs}{#2}{\parse@dhd@cb{#1}{#2}}} |
| 402 | \def\parse@dhd@cb#1#2#3{% {NEXT}{CAT}{{...}...} |
| 403 | \@ifnextchar[{\parse@dhd@cc{#1}{#2}{#3}}{\parse@dhd@cd{#1}{#2}{#3}}} |
| 404 | \def\parse@dhd@cc#1#2#3[#4]#5{% {NEXT}{CAT}{{...}...}[NAME]{SYNOPSIS} |
| 405 | #1{plain}{#2}{#3}{#4}{#5}} |
| 406 | \def\parse@dhd@cd#1#2#3#4{% {NEXT}{CAT}{{...}...}{SYNOPSIS} |
| 407 | \parse@dhd@ce{#1}{#2}{#3}{#4}#4 \q@} |
| 408 | \def\parse@dhd@ce#1#2#3#4#5 #6\q@{% |
| 409 | % {NEXT}{CAT}{{...}...}{SYNOPSIS}NAME [ARGS...]\q@ |
| 410 | \def\temp@{#5}% |
| 411 | \ifx\@setf\temp@\def\next@{\parse@dhd@csetf{#1}{#2}{#3}{#4}#6 \q@}% |
| 412 | \else\def\temp@##1##2*##3\q@{\def\temp@{##1##3}}\temp@#5*\q@% |
| 413 | \ifx\temp@\@starstar\def\next@{#1{muffs}{#2}{#3}{#5}{#4}}% |
| 414 | \else\def\temp@##1##2\q@{\def\temp@{##1}}\temp@#5\q@% |
| 415 | \if:\temp@\def\next@{#1{kwd}{#2}{#3}{#5}{#4}}% |
| 416 | \else\def\next@{#1{plain}{#2}{#3}{#5}{#4}}\fi\fi\fi% |
| 417 | \next@% |
| 418 | } |
| 419 | \def\parse@dhd@csetf#1#2#3#4(#5 #6\q@{% |
| 420 | % {NEXT}{CAT}{{...}...}{SYNOPSIS}(NAME [ARGS...])\q@ |
| 421 | #1{setf}{#2}{#3}{#5}{#4}} |
| 422 | |
| 423 | %% \dhead[MOD]{CAT}{...}...[NAME]{SYNOPSIS} |
| 424 | %% \dhead*[MOD]{CAT}{...}...[NAME]{SYNOPSIS} |
| 425 | %% |
| 426 | %% Typeset a description head. Use this within the first argument of |
| 427 | %% `describe*'; see `describe' for the details. |
| 428 | %% |
| 429 | %% With `*', don't set labels or add items to the index. |
| 430 | \newif\if@dheadfirst |
| 431 | \newif\if@dheadindex |
| 432 | \def\dhead{\@ifstar% |
| 433 | {\parse@dhd{\global\@dheadindexfalse\dhead@}}% |
| 434 | {\parse@dhd{\global\@dheadindextrue\dhead@}}} |
| 435 | \def\dhead@#1#2#3#4#5{% {MOD}{CAT}{{...}...}{NAME}{SYNOPSIS} |
| 436 | \if@dheadfirst\global\@dheadfirstfalse\else\relax\\*[\smallskipamount]\fi% |
| 437 | \if@dheadindex% |
| 438 | \phantomsection% |
| 439 | {\let\protect\@empty\let\@uscore\relax% |
| 440 | \edef\temp@{\@desc@dispatch{desclabel}{#2}{#1}{#2}#3{#4}}% |
| 441 | \def\@uscore{_\@gobble}\expandafter\message\expandafter{\temp@}% |
| 442 | \def\@uscore{-\@gobble}\expandafter\label\expandafter{\temp@}}% |
| 443 | {\begingroup\lccode`\~=`\_\lowercase{\endgroup\def~{_}}% |
| 444 | \protected@edef\@tempa##1{% |
| 445 | \noexpand\index{\@desc@dispatch{descindex}{#2}{#1}{#2}#3{#4}##1}}% |
| 446 | \toks@\expandafter{\@tempa{|)}}% |
| 447 | \toks\tw@\expandafter{\after@desc}% |
| 448 | \xdef\after@desc{\the\toks\tw@\the\toks@}% |
| 449 | \@tempa{|(}}% |
| 450 | \fi% |
| 451 | \rlap{\hb@xt@\linewidth{\hfil\normalfont\bfseries |
| 452 | [\describecategoryname[#1]{#2}]}}% |
| 453 | #5% |
| 454 | } |
| 455 | |
| 456 | %% Main guts of a description environment. The argument here typesets the |
| 457 | %% header line(s). |
| 458 | \def\desc@begin#1{% |
| 459 | \let\saved@after@desc\after@desc% |
| 460 | \gdef\after@desc{}% |
| 461 | \normalfont% |
| 462 | \if@nobreak\else\par\goodbreak\fi% |
| 463 | \global\@dheadfirsttrue% |
| 464 | \begingroup% |
| 465 | \let\@endparenv\relax% |
| 466 | \clubpenalty\@M \widowpenalty\@M \interlinepenalty50% |
| 467 | \@prog#1\endtabbing% |
| 468 | \endgroup% |
| 469 | \penalty\@M\@afterheading% |
| 470 | \list{}{\rightmargin\z@\topsep\z@}\item% |
| 471 | } |
| 472 | \def\desc@end{\endlist\after@desc\global\let\after@desc\saved@after@desc} |
| 473 | |
| 474 | %% \begin{describe}[MOD]{CAT}{...}...[NAME]{SYNOPSIS} |
| 475 | %% ... |
| 476 | %% \end{describe} |
| 477 | %% |
| 478 | %% Describe some kind of program object. The CAT names the category of thing |
| 479 | %% being described -- this will be shown in the header, and index. The |
| 480 | %% SYNOPSIS is an implicit `prog' environment in which invoking the thing can |
| 481 | %% be summarized. |
| 482 | %% |
| 483 | %% The {...}... are any additional arguments required by the category's kind |
| 484 | %% (e.g., method specializers). |
| 485 | %% |
| 486 | %% The NAME is the name of the thing, which ends up in the index and |
| 487 | %% cross-reference label. If omitted, it defaults to the first word of the |
| 488 | %% SYNOPSIS, except that there are some special cases. |
| 489 | %% |
| 490 | %% The MOD is the modifier to apply. If omitted, it will usually default to |
| 491 | %% `plain', but in the absence of a NAME, some kinds of synopses are |
| 492 | %% recognized specially: |
| 493 | %% |
| 494 | %% * `setf (NAME ...) ...': selects NAME, and defaults MOD to `setf'. |
| 495 | %% |
| 496 | %% * `*NAME*': defaults MOD to `muffs'. |
| 497 | %% |
| 498 | %% * `:NAME': defaults MOD to `kwd'. |
| 499 | \def\describe{\parse@dhd\desc@} |
| 500 | \def\desc@#1#2#3#4#5{% |
| 501 | \global\@dheadindextrue% |
| 502 | \desc@begin{\dhead@{#1}{#2}{#3}{#4}{#5}}% |
| 503 | } |
| 504 | \let\enddescribe\desc@end |
| 505 | |
| 506 | %% \begin{describe*} |
| 507 | %% {\dhead[MOD]{CAT}{...}...[NAME]{SYNOPSIS} |
| 508 | %% ...} |
| 509 | %% ... |
| 510 | %% \end{describe*} |
| 511 | %% |
| 512 | %% This is the fancy form of `describe' for describing several different |
| 513 | %% things at once. |
| 514 | \@namedef{describe*}#1{\desc@begin{#1}} |
| 515 | \expandafter\let\csname enddescribe*\endcsname\desc@end |
| 516 | |
| 517 | %% \parse@dlbl{NEXT}[MOD]{CAT}{...}...{LABEL} |
| 518 | %% |
| 519 | %% Parse a description label, and call |
| 520 | %% |
| 521 | %% NEXT{MOD}{CAT}{{...}...}{LABEL} |
| 522 | %% |
| 523 | %% This handles defaulting the MOD correctly, based on the LABEL text. See |
| 524 | %% `\descref' for the details. |
| 525 | \def\parse@dlbl#1{\@ifnextchar[{\parse@dlbl@a{#1}}{\parse@dlbl@c{#1}}} |
| 526 | \def\parse@dlbl@a#1[#2]#3{\@desc@dispatch{descargs}{#3}{#1{#2}{#3}}} |
| 527 | \def\parse@dlbl@c#1#2% |
| 528 | {\@desc@dispatch{descargs}{#2}{\parse@dlbl@cb{#1}{#2}}} |
| 529 | \def\parse@dlbl@cb#1#2#3#4{% |
| 530 | \def\temp@##1##2*##3\q@{\def\temp@{##1##3}}\temp@#4*\q@% |
| 531 | \ifx\temp@\@starstar\def\next@{#1{muffs}{#2}{#3}{#4}}% |
| 532 | \else\def\temp@##1##2\q@{\def\temp@{##1}}\temp@#4\q@% |
| 533 | \if:\temp@\def\next@{#1{kwd}{#2}{#3}{#4}} |
| 534 | \else\def\next@{#1{plain}{#2}{#3}{#4}}\fi\fi% |
| 535 | \next@% |
| 536 | } |
| 537 | |
| 538 | %% \descref[MOD]{CAT}{...}...{LABEL}[TEXT] |
| 539 | %% \descref*[MOD]{CAT}{...}...{LABEL} |
| 540 | %% |
| 541 | %% Typesets a cross-reference to a described thing. The CAT names the |
| 542 | %% category of thing being described, and the LABEL names the specific thing. |
| 543 | %% |
| 544 | %% The {...}... are any additional arguments required by the category's kind |
| 545 | %% (e.g., method specializers). |
| 546 | %% |
| 547 | %% The MOD is the modifier to apply, similar (but subtly different from) to |
| 548 | %% the `describe' environment. If omitted, it will usually default to |
| 549 | %% `plain', but in the absence of a NAME, some kinds of synopses are |
| 550 | %% recognized specially: |
| 551 | %% |
| 552 | %% * `*NAME*': defaults MOD to `muffs'. |
| 553 | %% |
| 554 | %% * `:NAME': defaults MOD to `kwd'. |
| 555 | %% |
| 556 | %% (`setf' is /not/ specially detected here. Write an explicit `setf' |
| 557 | %% modifier if necessary, because it's no more typing.) |
| 558 | %% |
| 559 | %% Usually a page-number cross-reference is included, so as to help readers |
| 560 | %% of a dead-tree copy; this is suppressed by the `*' version. |
| 561 | \def\descref{\@ifstar% |
| 562 | {\parse@dlbl{\descref@i\relax\@gobble\relax}}% |
| 563 | {\parse@dlbl{\descref@i{ (}\autopageref)}}} |
| 564 | \def\descref@i#1#2#3#4#5#6#7{\@ifnextchar@preserve[% |
| 565 | % {PGA}{PGB}{PGC}{MOD}{CAT}{{...}...}{LABEL} |
| 566 | {\descref@ii{#1}{#2}{#3}{#4}{#5}{#6}{#7}}% |
| 567 | {\descref@iii{#1}{#2}{#3}{#4}{#5}{#6}{#7}{}}} |
| 568 | \def\descref@ii#1#2#3#4#5#6#7[#8]% |
| 569 | % {PGA}{PGB}{PGC}{MOD}{CAT}{{...}...}{LABEL}[AFTER] |
| 570 | {\descref@iii{#1}{#2}{#3}{#4}{#5}{#6}{#7}{ #8}} |
| 571 | \def\descref@iii#1#2#3#4#5#6#7#8{% |
| 572 | % {PGA}{PGB}{PGC}{MOD}{CAT}{{...}...}{LABEL}{AFTER} |
| 573 | \begingroup% |
| 574 | \let\protect\@empty\def\@uscore{-\@gobble}% |
| 575 | \edef\temp@{\@desc@dispatch{desclabel}{#5}{#4}{#5}#6{#7}}% |
| 576 | \hyperref[\temp@]{\code{#7}}#8% |
| 577 | #1#2{\temp@}#3% |
| 578 | \endgroup% |
| 579 | } |
| 580 | |
| 581 | %% \descindex[MOD]{CAT}{...}...{LABEL}[SUFFIX] |
| 582 | %% |
| 583 | %% Set a label and index entry here, as if for a description. The CAT names |
| 584 | %% the category of thing being described, and the LABEL names the specific |
| 585 | %% thing, as for `\descref'. The {...}... are any additional arguments |
| 586 | %% required by the category's kind (e.g., method specializers). The MOD is |
| 587 | %% the modifier to apply; see `\descref' for the details. |
| 588 | %% |
| 589 | %% The SUFFIX is appended to the index-entry text; by default it is empty. |
| 590 | %% Useful values are `|(' and `|)' to set ranges. |
| 591 | \def\descindex{\parse@dlbl\descindex@i} |
| 592 | \def\descindex@i#1#2#3#4{\@ifnextchar[% |
| 593 | {\descindex@ii{#1}{#2}{#3}{#4}}% |
| 594 | {\descindex@ii{#1}{#2}{#3}{#4}[]}} |
| 595 | \def\descindex@ii#1#2#3#4[#5]{% |
| 596 | {\begingroup\lccode`\~=`\_\lowercase{\endgroup\def~{_}}% |
| 597 | \protected@edef\@tempa{% |
| 598 | \noexpand\index{\@desc@dispatch{descindex}{#2}{#1}{#2}#3{#4}#5}}% |
| 599 | \@tempa}% |
| 600 | } |
| 601 | |
| 602 | %% \desclabel[MOD]{CAT}{...}...{LABEL}[INDEX-SUFFIX] |
| 603 | %% |
| 604 | %% Set a label and index entry here, as if for a description. The CAT names |
| 605 | %% the category of thing being described, and the LABEL names the specific |
| 606 | %% thing, as for `\descref'. The {...}... are any additional arguments |
| 607 | %% required by the category's kind (e.g., method specializers). The MOD is |
| 608 | %% the modifier to apply; see `\descref' for the details. |
| 609 | %% |
| 610 | %% This will also add an index entry, as for `\descindex'; the INDEX-SUFFIX |
| 611 | %% argument has the same effect as its SUFFIX argument. |
| 612 | \def\desclabel{\parse@dlbl\desclabel@i} |
| 613 | \def\desclabel@i#1#2#3#4{% |
| 614 | \begingroup% |
| 615 | \let\protect\@empty\def\@uscore{-\@gobble}% |
| 616 | \edef\@tempa{\@desc@dispatch{desclabel}{#2}{#1}{#2}#3{#4}}% |
| 617 | \phantomsection\label{\@tempa}% |
| 618 | \endgroup% |
| 619 | \descindex@i{#1}{#2}{#3}{#4}% |
| 620 | } |
| 621 | |
| 622 | %% Description categories. |
| 623 | \definedescribecategory{sym}{symbol} |
| 624 | \definedescribecategory{fun}{#1{function}} |
| 625 | \definedescribecategory{gf}{generic #1{function}} |
| 626 | \definedescribecategory{msg}{message} |
| 627 | \definedescribecategory{var}{variable} |
| 628 | \definedescribecategory{modvar}{module variable} |
| 629 | \definedescribecategory{const}{constant} |
| 630 | \definedescribecategory{meth}[method]{primary #1{method}} |
| 631 | \definedescribecategory{ar-meth}[method]{\code{:around} #1{method}} |
| 632 | \definedescribecategory{be-meth}[method]{\code{:before} #1{method}} |
| 633 | \definedescribecategory{af-meth}[method]{\code{:after} #1{method}} |
| 634 | \definedescribecategory{cls}{class} |
| 635 | \definedescribecategory{rst}{restart} |
| 636 | \definedescribecategory{ty}{type} |
| 637 | \definedescribecategory{mac}{#1{macro}} |
| 638 | \definedescribecategory{feat}{feature macro} |
| 639 | \definedescribecategory{lmac}{local #1{macro}} |
| 640 | \definedescribecategory{parse}{parser spec} |
| 641 | \definedescribecategory{parseform}{parser form} |
| 642 | \definedescribecategory{opt}{option handler} |
| 643 | \definedescribecategory{optmac}{option macro} |
| 644 | \definedescribecategory{plug}{pluggable parser} |
| 645 | |
| 646 | %%%----- That's all, folks -------------------------------------------------- |
| 647 | \endinput |