texinfo.tex
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:279k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. % By default, they are off at the start of a document,
  2. % and turned `on' after @end titlepage.
  3. defheadings #1 {csname HEADINGS#1endcsname}
  4. defHEADINGSoff{%
  5. globalevenheadline={hfil} globalevenfootline={hfil}
  6. globaloddheadline={hfil} globaloddfootline={hfil}}
  7. HEADINGSoff
  8. % When we turn headings on, set the page number to 1.
  9. % For double-sided printing, put current file name in lower left corner,
  10. % chapter name on inside top of right hand pages, document
  11. % title on inside top of left hand pages, and page numbers on outside top
  12. % edge of all pages.
  13. defHEADINGSdouble{%
  14. globalpageno=1
  15. globalevenfootline={hfil}
  16. globaloddfootline={hfil}
  17. globalevenheadline={line{foliohfilthistitle}}
  18. globaloddheadline={line{thischapterhfilfolio}}
  19. globalletcontentsalignmacro = chapoddpage
  20. }
  21. letcontentsalignmacro = chappager
  22. % For single-sided printing, chapter title goes across top left of page,
  23. % page number on top right.
  24. defHEADINGSsingle{%
  25. globalpageno=1
  26. globalevenfootline={hfil}
  27. globaloddfootline={hfil}
  28. globalevenheadline={line{thischapterhfilfolio}}
  29. globaloddheadline={line{thischapterhfilfolio}}
  30. globalletcontentsalignmacro = chappager
  31. }
  32. defHEADINGSon{HEADINGSdouble}
  33. defHEADINGSafter{letHEADINGShook=HEADINGSdoublex}
  34. letHEADINGSdoubleafter=HEADINGSafter
  35. defHEADINGSdoublex{%
  36. globalevenfootline={hfil}
  37. globaloddfootline={hfil}
  38. globalevenheadline={line{foliohfilthistitle}}
  39. globaloddheadline={line{thischapterhfilfolio}}
  40. globalletcontentsalignmacro = chapoddpage
  41. }
  42. defHEADINGSsingleafter{letHEADINGShook=HEADINGSsinglex}
  43. defHEADINGSsinglex{%
  44. globalevenfootline={hfil}
  45. globaloddfootline={hfil}
  46. globalevenheadline={line{thischapterhfilfolio}}
  47. globaloddheadline={line{thischapterhfilfolio}}
  48. globalletcontentsalignmacro = chappager
  49. }
  50. % Subroutines used in generating headings
  51. % This produces Day Month Year style of output.
  52. % Only define if not already defined, in case a txi-??.tex file has set
  53. % up a different format (e.g., txi-cs.tex does this).
  54. ifxtodayundefined
  55. deftoday{%
  56.   numberdayspace
  57.   ifcasemonth
  58.   orputwordMJanorputwordMFeborputwordMMarorputwordMApr
  59.   orputwordMMayorputwordMJunorputwordMJulorputwordMAug
  60.   orputwordMSeporputwordMOctorputwordMNovorputwordMDec
  61.   fi
  62.   spacenumberyear}
  63. fi
  64. % @settitle line...  specifies the title of the document, for headings.
  65. % It generates no output of its own.
  66. defthistitle{putwordNoTitle}
  67. defsettitle{parsearg{gdefthistitle}}
  68. message{tables,}
  69. % Tables -- @table, @ftable, @vtable, @item(x).
  70. % default indentation of table text
  71. newdimentableindent tableindent=.8in
  72. % default indentation of @itemize and @enumerate text
  73. newdimenitemindent  itemindent=.3in
  74. % margin between end of table item and start of table text.
  75. newdimenitemmargin  itemmargin=.1in
  76. % used internally for itemindent minus itemmargin
  77. newdimenitemmax
  78. % Note @table, @ftable, and @vtable define @item, @itemx, etc., with
  79. % these defs.
  80. % They also define itemindex
  81. % to index the item name in whatever manner is desired (perhaps none).
  82. newififitemxneedsnegativevskip
  83. defitemxpar{parifitemxneedsnegativevskipnobreakvskip-parskipnobreakfi}
  84. definternalBitem{smallbreak parseargitemzzz}
  85. definternalBitemx{itemxpar parseargitemzzz}
  86. defitemzzz #1{begingroup %
  87.   advancehsize by -rightskip
  88.   advancehsize by -tableindent
  89.   setbox0=hbox{itemindicate{#1}}%
  90.   itemindex{#1}%
  91.   nobreak % This prevents a break before @itemx.
  92.   %
  93.   % If the item text does not fit in the space we have, put it on a line
  94.   % by itself, and do not allow a page break either before or after that
  95.   % line.  We do not start a paragraph here because then if the next
  96.   % command is, e.g., @kindex, the whatsit would get put into the
  97.   % horizontal list on a line by itself, resulting in extra blank space.
  98.   ifdim wd0>itemmax
  99.     %
  100.     % Make this a paragraph so we get the parskip glue and wrapping,
  101.     % but leave it ragged-right.
  102.     begingroup
  103.       advanceleftskip by-tableindent
  104.       advancehsize bytableindent
  105.       advancerightskip by0pt plus1fil
  106.       leavevmodeunhbox0par
  107.     endgroup
  108.     %
  109.     % We're going to be starting a paragraph, but we don't want the
  110.     % parskip glue -- logically it's part of the @item we just started.
  111.     nobreak vskip-parskip
  112.     %
  113.     % Stop a page break at the parskip glue coming up.  However, if
  114.     % what follows is an environment such as @example, there will be no
  115.     % parskip glue; then the negative vskip we just inserted would
  116.     % cause the example and the item to crash together.  So we use this
  117.     % bizarre value of 10001 as a signal to aboveenvbreak to insert
  118.     % parskip glue after all.  Section titles are handled this way also.
  119.     % 
  120.     penalty 10001
  121.     endgroup
  122.     itemxneedsnegativevskipfalse
  123.   else
  124.     % The item text fits into the space.  Start a paragraph, so that the
  125.     % following text (if any) will end up on the same line.
  126.     noindent
  127.     % Do this with kerns and unhbox so that if there is a footnote in
  128.     % the item text, it can migrate to the main vertical list and
  129.     % eventually be printed.
  130.     nobreakkern-tableindent
  131.     dimen0 = itemmax  advancedimen0 by itemmargin advancedimen0 by -wd0
  132.     unhbox0
  133.     nobreakkerndimen0
  134.     endgroup
  135.     itemxneedsnegativevskiptrue
  136.   fi
  137. }
  138. defitem{errmessage{@item while not in a list environment}}
  139. defitemx{errmessage{@itemx while not in a list environment}}
  140. % @table, @ftable, @vtable.
  141. envdeftable{%
  142.   letitemindexgobble
  143.   tablecheck{table}%
  144. }
  145. envdefftable{%
  146.   defitemindex ##1{doind {fn}{code{##1}}}%
  147.   tablecheck{ftable}%
  148. }
  149. envdefvtable{%
  150.   defitemindex ##1{doind {vr}{code{##1}}}%
  151.   tablecheck{vtable}%
  152. }
  153. deftablecheck#1{%
  154.   ifnum thecatcode`^^M=active
  155.     endgroup
  156.     errmessage{This command won't work in this context; perhaps the problem is
  157.       that we are inenvironmentthisenv}%
  158.     defnext{doignore{#1}}%
  159.   else
  160.     letnexttablex
  161.   fi
  162.   next
  163. }
  164. deftablex#1{%
  165.   defitemindicate{#1}%
  166.   parseargtabley
  167. }
  168. deftabley#1{%
  169.   {%
  170.     makevalueexpandable
  171.     edeftemp{noexpandtablez #1spacespacespace}%
  172.     expandafter
  173.   }temp endtablez
  174. }
  175. deftablez #1 #2 #3 #4endtablez{%
  176.   aboveenvbreak
  177.   ifnum 0#1>0 advance leftskip by #1mil fi
  178.   ifnum 0#2>0 tableindent=#2mil fi
  179.   ifnum 0#3>0 advance rightskip by #3mil fi
  180.   itemmax=tableindent
  181.   advance itemmax by -itemmargin
  182.   advance leftskip by tableindent
  183.   exdentamount=tableindent
  184.   parindent = 0pt
  185.   parskip = smallskipamount
  186.   ifdim parskip=0pt parskip=2pt fi
  187.   letitem = internalBitem
  188.   letitemx = internalBitemx
  189. }
  190. defEtable{endgrafafterenvbreak}
  191. letEftableEtable
  192. letEvtableEtable
  193. letEitemizeEtable
  194. letEenumerateEtable
  195. % This is the counter used by @enumerate, which is really @itemize
  196. newcount itemno
  197. envdefitemize{parseargdoitemize}
  198. defdoitemize#1{%
  199.   aboveenvbreak
  200.   itemmax=itemindent
  201.   advanceitemmax by -itemmargin
  202.   advanceleftskip by itemindent
  203.   exdentamount=itemindent
  204.   parindent=0pt
  205.   parskip=smallskipamount
  206.   ifdimparskip=0pt parskip=2pt fi
  207.   defitemcontents{#1}%
  208.   % @itemize with no arg is equivalent to @itemize @bullet.
  209.   ifxitemcontentsemptydefitemcontents{bullet}fi
  210.   letitem=itemizeitem
  211. }
  212. % Definition of @item while inside @itemize and @enumerate.
  213. %
  214. defitemizeitem{%
  215.   advanceitemno by 1  % for enumerations
  216.   {letpar=endgraf smallbreak}% reasonable place to break
  217.   {%
  218.    % If the document has an @itemize directly after a section title, a
  219.    % nobreak will be last on the list, and sectionheading will have
  220.    % done a vskip-parskip.  In that case, we don't want to zero
  221.    % parskip, or the item text will crash with the heading.  On the
  222.    % other hand, when there is normal text preceding the item (as there
  223.    % usually is), we do want to zero parskip, or there would be too much
  224.    % space.  In that case, we won't have a nobreak before.  At least
  225.    % that's the theory.
  226.    ifnumlastpenalty<10000 parskip=0in fi
  227.    noindent
  228.    hbox to 0pt{hss itemcontents kernitemmargin}%
  229.    vadjust{penalty 1200}}% not good to break after first line of item.
  230.   flushcr
  231. }
  232. % splitoff TOKENSendmark defines first to be the first token in
  233. % TOKENS, and rest to be the remainder.
  234. %
  235. defsplitoff#1#2endmark{deffirst{#1}defrest{#2}}%
  236. % Allow an optional argument of an uppercase letter, lowercase letter,
  237. % or number, to specify the first label in the enumerated list.  No
  238. % argument is the same as `1'.
  239. %
  240. envparseargdefenumerate{enumeratey #1  endenumeratey}
  241. defenumeratey #1 #2endenumeratey{%
  242.   % If we were given no argument, pretend we were given `1'.
  243.   defthearg{#1}%
  244.   ifxtheargempty defthearg{1}fi
  245.   %
  246.   % Detect if the argument is a single token.  If so, it might be a
  247.   % letter.  Otherwise, the only valid thing it can be is a number.
  248.   % (We will always have one token, because of the test we just made.
  249.   % This is a good thing, since splitoff doesn't work given nothing at
  250.   % all -- the first parameter is undelimited.)
  251.   expandaftersplitofftheargendmark
  252.   ifxrestempty
  253.     % Only one token in the argument.  It could still be anything.
  254.     % A ``lowercase letter'' is one whose lccode is nonzero.
  255.     % An ``uppercase letter'' is one whose lccode is both nonzero, and
  256.     %   not equal to itself.
  257.     % Otherwise, we assume it's a number.
  258.     %
  259.     % We need the relax at the end of the ifnum lines to stop TeX from
  260.     % continuing to look for a <number>.
  261.     %
  262.     ifnumlccodeexpandafter`thearg=0relax
  263.       numericenumerate % a number (we hope)
  264.     else
  265.       % It's a letter.
  266.       ifnumlccodeexpandafter`thearg=expandafter`theargrelax
  267.         lowercaseenumerate % lowercase letter
  268.       else
  269.         uppercaseenumerate % uppercase letter
  270.       fi
  271.     fi
  272.   else
  273.     % Multiple tokens in the argument.  We hope it's a number.
  274.     numericenumerate
  275.   fi
  276. }
  277. % An @enumerate whose labels are integers.  The starting integer is
  278. % given in thearg.
  279. %
  280. defnumericenumerate{%
  281.   itemno = thearg
  282.   startenumeration{theitemno}%
  283. }
  284. % The starting (lowercase) letter is in thearg.
  285. deflowercaseenumerate{%
  286.   itemno = expandafter`thearg
  287.   startenumeration{%
  288.     % Be sure we're not beyond the end of the alphabet.
  289.     ifnumitemno=0
  290.       errmessage{No more lowercase letters in @enumerate; get a bigger
  291.                   alphabet}%
  292.     fi
  293.     charlccodeitemno
  294.   }%
  295. }
  296. % The starting (uppercase) letter is in thearg.
  297. defuppercaseenumerate{%
  298.   itemno = expandafter`thearg
  299.   startenumeration{%
  300.     % Be sure we're not beyond the end of the alphabet.
  301.     ifnumitemno=0
  302.       errmessage{No more uppercase letters in @enumerate; get a bigger
  303.                   alphabet}
  304.     fi
  305.     charuccodeitemno
  306.   }%
  307. }
  308. % Call doitemize, adding a period to the first argument and supplying the
  309. % common last two arguments.  Also subtract one from the initial value in
  310. % itemno, since @item increments itemno.
  311. %
  312. defstartenumeration#1{%
  313.   advanceitemno by -1
  314.   doitemize{#1.}flushcr
  315. }
  316. % @alphaenumerate and @capsenumerate are abbreviations for giving an arg
  317. % to @enumerate.
  318. %
  319. defalphaenumerate{enumerate{a}}
  320. defcapsenumerate{enumerate{A}}
  321. defEalphaenumerate{Eenumerate}
  322. defEcapsenumerate{Eenumerate}
  323. % @multitable macros
  324. % Amy Hendrickson, 8/18/94, 3/6/96
  325. %
  326. % @multitable ... @end multitable will make as many columns as desired.
  327. % Contents of each column will wrap at width given in preamble.  Width
  328. % can be specified either with sample text given in a template line,
  329. % or in percent of hsize, the current width of text on page.
  330. % Table can continue over pages but will only break between lines.
  331. % To make preamble:
  332. %
  333. % Either define widths of columns in terms of percent of hsize:
  334. %   @multitable @columnfractions .25 .3 .45
  335. %   @item ...
  336. %
  337. %   Numbers following @columnfractions are the percent of the total
  338. %   current hsize to be used for each column. You may use as many
  339. %   columns as desired.
  340. % Or use a template:
  341. %   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
  342. %   @item ...
  343. %   using the widest term desired in each column.
  344. % Each new table line starts with @item, each subsequent new column
  345. % starts with @tab. Empty columns may be produced by supplying @tab's
  346. % with nothing between them for as many times as empty columns are needed,
  347. % ie, @tab@tab@tab will produce two empty columns.
  348. % @item, @tab do not need to be on their own lines, but it will not hurt
  349. % if they are.
  350. % Sample multitable:
  351. %   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
  352. %   @item first col stuff @tab second col stuff @tab third col
  353. %   @item
  354. %   first col stuff
  355. %   @tab
  356. %   second col stuff
  357. %   @tab
  358. %   third col
  359. %   @item first col stuff @tab second col stuff
  360. %   @tab Many paragraphs of text may be used in any column.
  361. %
  362. %         They will wrap at the width determined by the template.
  363. %   @item@tab@tab This will be in third column.
  364. %   @end multitable
  365. % Default dimensions may be reset by user.
  366. % @multitableparskip is vertical space between paragraphs in table.
  367. % @multitableparindent is paragraph indent in table.
  368. % @multitablecolmargin is horizontal space to be left between columns.
  369. % @multitablelinespace is space to leave between table items, baseline
  370. %                                                            to baseline.
  371. %   0pt means it depends on current normal line spacing.
  372. %
  373. newskipmultitableparskip
  374. newskipmultitableparindent
  375. newdimenmultitablecolspace
  376. newskipmultitablelinespace
  377. multitableparskip=0pt
  378. multitableparindent=6pt
  379. multitablecolspace=12pt
  380. multitablelinespace=0pt
  381. % Macros used to set up halign preamble:
  382. %
  383. letendsetuptablerelax
  384. defxendsetuptable{endsetuptable}
  385. letcolumnfractionsrelax
  386. defxcolumnfractions{columnfractions}
  387. newififsetpercent
  388. % #1 is the @columnfraction, usually a decimal number like .5, but might
  389. % be just 1.  We just use it, whatever it is.
  390. %
  391. defpickupwholefraction#1 {%
  392.   globaladvancecolcount by 1
  393.   expandafterxdefcsname colthecolcountendcsname{#1hsize}%
  394.   setuptable
  395. }
  396. newcountcolcount
  397. defsetuptable#1{%
  398.   deffirstarg{#1}%
  399.   ifxfirstargxendsetuptable
  400.     letgo = relax
  401.   else
  402.     ifxfirstargxcolumnfractions
  403.       globalsetpercenttrue
  404.     else
  405.       ifsetpercent
  406.          letgopickupwholefraction
  407.       else
  408.          globaladvancecolcount by 1
  409.          setbox0=hbox{#1unskipspace}% Add a normal word space as a
  410.                    % separator; typically that is always in the input, anyway.
  411.          expandafterxdefcsname colthecolcountendcsname{thewd0}%
  412.       fi
  413.     fi
  414.     ifxgopickupwholefraction
  415.       % Put the argument back for the pickupwholefraction call, so
  416.       % we'll always have a period there to be parsed.
  417.       defgo{pickupwholefraction#1}%
  418.     else
  419.       letgo = setuptable
  420.     fi%
  421.   fi
  422.   go
  423. }
  424. % multitable-only commands.
  425. %
  426. % @headitem starts a heading row, which we typeset in bold.
  427. % Assignments have to be global since we are inside the implicit group
  428. % of an alignment entry.  Note that everycr resets everytab.
  429. defheaditem{checkenvmultitable crcr globaleverytab={bf}theeverytab}%
  430. %
  431. % A tab used to include hskip1sp.  But then the space in a template
  432. % line is not enough.  That is bad.  So let's go back to just `&' until
  433. % we encounter the problem it was intended to solve again.
  434. % --karl, nathan@acm.org, 20apr99.
  435. deftab{checkenvmultitable &theeverytab}%
  436. % @multitable ... @end multitable definitions:
  437. %
  438. newtokseverytab  % insert after every tab.
  439. %
  440. envdefmultitable{%
  441.   vskipparskip
  442.   startsavinginserts
  443.   %
  444.   % @item within a multitable starts a normal row.
  445.   % We use def instead of let so that if one of the multitable entries
  446.   % contains an @itemize, we don't choke on the item (seen as crcr aka
  447.   % endtemplate) expanding doitemize.
  448.   defitem{crcr}%
  449.   %
  450.   tolerance=9500
  451.   hbadness=9500
  452.   setmultitablespacing
  453.   parskip=multitableparskip
  454.   parindent=multitableparindent
  455.   overfullrule=0pt
  456.   globalcolcount=0
  457.   %
  458.   everycr = {%
  459.     noalign{%
  460.       globaleverytab={}%
  461.       globalcolcount=0 % Reset the column counter.
  462.       % Check for saved footnotes, etc.
  463.       checkinserts
  464.       % Keeps underfull box messages off when table breaks over pages.
  465.       %filbreak
  466. % Maybe so, but it also creates really weird page breaks when the
  467. % table breaks over pages. Wouldn't vfil be better?  Wait until the
  468. % problem manifests itself, so it can be fixed for real --karl.
  469.     }%
  470.   }%
  471.   %
  472.   parseargdomultitable
  473. }
  474. defdomultitable#1{%
  475.   % To parse everything between @multitable and @item:
  476.   setuptable#1 endsetuptable
  477.   %
  478.   % This preamble sets up a generic column definition, which will
  479.   % be used as many times as user calls for columns.
  480.   % vtop will set a single line and will also let text wrap and
  481.   % continue for many paragraphs if desired.
  482.   halignbgroup &%
  483.     globaladvancecolcount by 1
  484.     multistrut
  485.     vtop{%
  486.       % Use the current colcount to find the correct column width:
  487.       hsize=expandaftercsname colthecolcountendcsname
  488.       %
  489.       % In order to keep entries from bumping into each other
  490.       % we will add a leftskip of multitablecolspace to all columns after
  491.       % the first one.
  492.       %
  493.       % If a template has been used, we will add multitablecolspace
  494.       % to the width of each template entry.
  495.       %
  496.       % If the user has set preamble in terms of percent of hsize we will
  497.       % use that dimension as the width of the column, and the leftskip
  498.       % will keep entries from bumping into each other.  Table will start at
  499.       % left margin and final column will justify at right margin.
  500.       %
  501.       % Make sure we don't inherit rightskip from the outer environment.
  502.       rightskip=0pt
  503.       ifnumcolcount=1
  504. % The first column will be indented with the surrounding text.
  505. advancehsize byleftskip
  506.       else
  507. ifsetpercent else
  508.   % If user has not set preamble in terms of percent of hsize
  509.   % we will advance hsize by multitablecolspace.
  510.   advancehsize by multitablecolspace
  511. fi
  512.        % In either case we will make leftskip=multitablecolspace:
  513.       leftskip=multitablecolspace
  514.       fi
  515.       % Ignoring space at the beginning and end avoids an occasional spurious
  516.       % blank line, when TeX decides to break the line at the space before the
  517.       % box from the multistrut, so the strut ends up on a line by itself.
  518.       % For example:
  519.       % @multitable @columnfractions .11 .89
  520.       % @item @code{#}
  521.       % @tab Legal holiday which is valid in major parts of the whole country.
  522.       % Is automatically provided with highlighting sequences respectively
  523.       % marking characters.
  524.       noindentignorespaces##unskipmultistrut
  525.     }cr
  526. }
  527. defEmultitable{%
  528.   crcr
  529.   egroup % end the halign
  530.   globalsetpercentfalse
  531. }
  532. defsetmultitablespacing{%
  533.   defmultistrut{strut}% just use the standard line spacing
  534.   %
  535.   % Compute multitablelinespace (if not defined by user) for use in
  536.   % multitableparskip calculation.  We used define multistrut based on
  537.   % this, but (ironically) that caused the spacing to be off.
  538.   % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
  539. ifdimmultitablelinespace=0pt
  540. setbox0=vbox{X}globalmultitablelinespace=thebaselineskip
  541. globaladvancemultitablelinespace by-ht0
  542. fi
  543. %% Test to see if parskip is larger than space between lines of
  544. %% table. If not, do nothing.
  545. %%        If so, set to same dimension as multitablelinespace.
  546. ifdimmultitableparskip>multitablelinespace
  547. globalmultitableparskip=multitablelinespace
  548. globaladvancemultitableparskip-7pt %% to keep parskip somewhat smaller
  549.                                       %% than skip between lines in the table.
  550. fi%
  551. ifdimmultitableparskip=0pt
  552. globalmultitableparskip=multitablelinespace
  553. globaladvancemultitableparskip-7pt %% to keep parskip somewhat smaller
  554.                                       %% than skip between lines in the table.
  555. fi}
  556. message{conditionals,}
  557. % @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
  558. % @ifnotxml always succeed.  They currently do nothing; we don't
  559. % attempt to check whether the conditionals are properly nested.  But we
  560. % have to remember that they are conditionals, so that @end doesn't
  561. % attempt to close an environment group.
  562. %
  563. defmakecond#1{%
  564.   expandafterletcsname #1endcsname = relax
  565.   expandafterletcsname iscond.#1endcsname = 1
  566. }
  567. makecond{iftex}
  568. makecond{ifnotdocbook}
  569. makecond{ifnothtml}
  570. makecond{ifnotinfo}
  571. makecond{ifnotplaintext}
  572. makecond{ifnotxml}
  573. % Ignore @ignore, @ifhtml, @ifinfo, and the like.
  574. %
  575. defdirentry{doignore{direntry}}
  576. defdocumentdescription{doignore{documentdescription}}
  577. defdocbook{doignore{docbook}}
  578. defhtml{doignore{html}}
  579. defifdocbook{doignore{ifdocbook}}
  580. defifhtml{doignore{ifhtml}}
  581. defifinfo{doignore{ifinfo}}
  582. defifnottex{doignore{ifnottex}}
  583. defifplaintext{doignore{ifplaintext}}
  584. defifxml{doignore{ifxml}}
  585. defignore{doignore{ignore}}
  586. defmenu{doignore{menu}}
  587. defxml{doignore{xml}}
  588. % Ignore text until a line `@end #1', keeping track of nested conditionals.
  589. %
  590. % A count to remember the depth of nesting.
  591. newcountdoignorecount
  592. defdoignore#1{begingroup
  593.   % Scan in ``verbatim'' mode:
  594.   obeylines
  595.   catcode`@ = other
  596.   catcode`{ = other
  597.   catcode`} = other
  598.   %
  599.   % Make sure that spaces turn into tokens that match what doignoretext wants.
  600.   spaceisspace
  601.   %
  602.   % Count number of #1's that we've seen.
  603.   doignorecount = 0
  604.   %
  605.   % Swallow text until we reach the matching `@end #1'.
  606.   dodoignore{#1}%
  607. }
  608. { catcode`_=11 % We want to use _STOP_ which cannot appear in texinfo source.
  609.   obeylines %
  610.   %
  611.   gdefdodoignore#1{%
  612.     % #1 contains the command name as a string, e.g., `ifinfo'.
  613.     %
  614.     % Define a command to find the next `@end #1'.
  615.     longdefdoignoretext##1^^M@end #1{%
  616.       doignoretextyyy##1^^M@#1_STOP_}%
  617.     %
  618.     % And this command to find another #1 command, at the beginning of a
  619.     % line.  (Otherwise, we would consider a line `@c @ifset', for
  620.     % example, to count as an @ifset for nesting.)
  621.     longdefdoignoretextyyy##1^^M@#1##2_STOP_{doignoreyyy{##2}_STOP_}%
  622.     %
  623.     % And now expand that command.
  624.     doignoretext ^^M%
  625.   }%
  626. }
  627. defdoignoreyyy#1{%
  628.   deftemp{#1}%
  629.   ifxtempempty % Nothing found.
  630.     letnextdoignoretextzzz
  631.   else % Found a nested condition, ...
  632.     advancedoignorecount by 1
  633.     letnextdoignoretextyyy % ..., look for another.
  634.     % If we're here, #1 ends with ^^Mifinfo (for example).
  635.   fi
  636.   next #1% the token _STOP_ is present just after this macro.
  637. }
  638. % We have to swallow the remaining "_STOP_".
  639. %
  640. defdoignoretextzzz#1{%
  641.   ifnumdoignorecount = 0 % We have just found the outermost @end.
  642.     letnextenddoignore
  643.   else % Still inside a nested condition.
  644.     advancedoignorecount by -1
  645.     letnextdoignoretext      % Look for the next @end.
  646.   fi
  647.   next
  648. }
  649. % Finish off ignored text.
  650. { obeylines%
  651.   % Ignore anything after the last `@end #1'; this matters in verbatim
  652.   % environments, where otherwise the newline after an ignored conditional
  653.   % would result in a blank line in the output.
  654.   gdefenddoignore#1^^M{endgroupignorespaces}%
  655. }
  656. % @set VAR sets the variable VAR to an empty value.
  657. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
  658. %
  659. % Since we want to separate VAR from REST-OF-LINE (which might be
  660. % empty), we can't just use parsearg; we have to insert a space of our
  661. % own to delimit the rest of the line, and then take it out again if we
  662. % didn't need it.
  663. % We rely on the fact that parsearg sets catcode` =10.
  664. %
  665. parseargdefset{setyyy#1 endsetyyy}
  666. defsetyyy#1 #2endsetyyy{%
  667.   {%
  668.     makevalueexpandable
  669.     deftemp{#2}%
  670.     edefnext{gdefmakecsname{SET#1}}%
  671.     ifxtempempty
  672.       next{}%
  673.     else
  674.       setzzz#2endsetzzz
  675.     fi
  676.   }%
  677. }
  678. % Remove the trailing space setxxx inserted.
  679. defsetzzz#1 endsetzzz{next{#1}}
  680. % @clear VAR clears (i.e., unsets) the variable VAR.
  681. %
  682. parseargdefclear{%
  683.   {%
  684.     makevalueexpandable
  685.     globalexpandafterletcsname SET#1endcsname=relax
  686.   }%
  687. }
  688. % @value{foo} gets the text saved in variable foo.
  689. defvalue{begingroupmakevalueexpandablevaluexxx}
  690. defvaluexxx#1{expandablevalue{#1}endgroup}
  691. {
  692.   catcode`- = active catcode`_ = active
  693.   %
  694.   gdefmakevalueexpandable{%
  695.     letvalue = expandablevalue
  696.     % We don't want these characters active, ...
  697.     catcode`-=other catcode`_=other
  698.     % ..., but we might end up with active ones in the argument if
  699.     % we're called from @code, as @code{@value{foo-bar_}}, though.
  700.     % So let them to their normal equivalents.
  701.     let-realdash let_normalunderscore
  702.   }
  703. }
  704. % We have this subroutine so that we can handle at least some @value's
  705. % properly in indexes (we call makevalueexpandable in indexdummies).
  706. % The command has to be fully expandable (if the variable is set), since
  707. % the result winds up in the index file.  This means that if the
  708. % variable's value contains other Texinfo commands, it's almost certain
  709. % it will fail (although perhaps we could fix that with sufficient work
  710. % to do a one-level expansion on the result, instead of complete).
  711. %
  712. defexpandablevalue#1{%
  713.   expandafterifxcsname SET#1endcsnamerelax
  714.     {[No value for ``#1'']}%
  715.     message{Variable `#1', used in @value, is not set.}%
  716.   else
  717.     csname SET#1endcsname
  718.   fi
  719. }
  720. % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
  721. % with @set.
  722. %
  723. % To get special treatment of `@end ifset,' call makeond and the redefine.
  724. %
  725. makecond{ifset}
  726. defifset{parsearg{doifset{letnext=ifsetfail}}}
  727. defdoifset#1#2{%
  728.   {%
  729.     makevalueexpandable
  730.     letnext=empty
  731.     expandafterifxcsname SET#2endcsnamerelax
  732.       #1% If not set, redefine next.
  733.     fi
  734.     expandafter
  735.   }next
  736. }
  737. defifsetfail{doignore{ifset}}
  738. % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
  739. % defined with @set, or has been undefined with @clear.
  740. %
  741. % The `else' inside the `doifset' parameter is a trick to reuse the
  742. % above code: if the variable is not set, do nothing, if it is set,
  743. % then redefine next to ifclearfail.
  744. %
  745. makecond{ifclear}
  746. defifclear{parsearg{doifset{else letnext=ifclearfail}}}
  747. defifclearfail{doignore{ifclear}}
  748. % @dircategory CATEGORY  -- specify a category of the dir file
  749. % which this file should belong to.  Ignore this in TeX.
  750. letdircategory=comment
  751. % @defininfoenclose.
  752. letdefinfoenclose=comment
  753. message{indexing,}
  754. % Index generation facilities
  755. % Define newwrite to be identical to plain tex's newwrite
  756. % except not outer, so it can be used within macros and if's.
  757. edefnewwrite{makecsname{ptexnewwrite}}
  758. % newindex {foo} defines an index named foo.
  759. % It automatically defines fooindex such that
  760. % fooindex ...rest of line... puts an entry in the index foo.
  761. % It also defines fooindfile to be the number of the output channel for
  762. % the file that accumulates this index.  The file's extension is foo.
  763. % The name of an index should be no more than 2 characters long
  764. % for the sake of vms.
  765. %
  766. defnewindex#1{%
  767.   iflinks
  768.     expandafternewwrite csname#1indfileendcsname
  769.     openout csname#1indfileendcsname jobname.#1 % Open the file
  770.   fi
  771.   expandafterxdefcsname#1indexendcsname{%     % Define @#1index
  772.     noexpanddoindex{#1}}
  773. }
  774. % @defindex foo  ==  newindex{foo}
  775. %
  776. defdefindex{parseargnewindex}
  777. % Define @defcodeindex, like @defindex except put all entries in @code.
  778. %
  779. defdefcodeindex{parseargnewcodeindex}
  780. %
  781. defnewcodeindex#1{%
  782.   iflinks
  783.     expandafternewwrite csname#1indfileendcsname
  784.     openout csname#1indfileendcsname jobname.#1
  785.   fi
  786.   expandafterxdefcsname#1indexendcsname{%
  787.     noexpanddocodeindex{#1}}%
  788. }
  789. % @synindex foo bar    makes index foo feed into index bar.
  790. % Do this instead of @defindex foo if you don't want it as a separate index.
  791. %
  792. % @syncodeindex foo bar   similar, but put all entries made for index foo
  793. % inside @code.
  794. %
  795. defsynindex#1 #2 {dosynindexdoindex{#1}{#2}}
  796. defsyncodeindex#1 #2 {dosynindexdocodeindex{#1}{#2}}
  797. % #1 is doindex or docodeindex, #2 the index getting redefined (foo),
  798. % #3 the target index (bar).
  799. defdosynindex#1#2#3{%
  800.   % Only do closeout if we haven't already done it, else we'll end up
  801.   % closing the target index.
  802.   expandafter ifxcsname donesynindex#2endcsname undefined
  803.     % The closeout helps reduce unnecessary open files; the limit on the
  804.     % Acorn RISC OS is a mere 16 files.
  805.     expandaftercloseoutcsname#2indfileendcsname
  806.     expandafterletcsnamedonesynindex#2endcsname = 1
  807.   fi
  808.   % redefine fooindfile:
  809.   expandafterletexpandaftertempexpandafter=csname#3indfileendcsname
  810.   expandafterletcsname#2indfileendcsname=temp
  811.   % redefine fooindex:
  812.   expandafterxdefcsname#2indexendcsname{noexpand#1{#3}}%
  813. }
  814. % Define doindex, the driver for all fooindex macros.
  815. % Argument #1 is generated by the calling fooindex macro,
  816. %  and it is "foo", the name of the index.
  817. % doindex just uses parsearg; it calls doind for the actual work.
  818. % This is because doind is more useful to call from other macros.
  819. % There is also dosubind {index}{topic}{subtopic}
  820. % which makes an entry in a two-level index such as the operation index.
  821. defdoindex#1{edefindexname{#1}parseargsingleindexer}
  822. defsingleindexer #1{doind{indexname}{#1}}
  823. % like the previous two, but they put @code around the argument.
  824. defdocodeindex#1{edefindexname{#1}parseargsinglecodeindexer}
  825. defsinglecodeindexer #1{doind{indexname}{code{#1}}}
  826. % Take care of Texinfo commands that can appear in an index entry.
  827. % Since there are some commands we want to expand, and others we don't,
  828. % we have to laboriously prevent expansion for those that we don't.
  829. %
  830. defindexdummies{%
  831.   escapechar = `\     % use backslash in output files.
  832.   def@{@}% change to @@ when we switch to @ as escape char in index files.
  833.   def {realbackslashspace }%
  834.   %
  835.   % Need these in case tex is in effect and { is a delimiter again.
  836.   % But can't use lbracecmd and rbracecmd because texindex assumes
  837.   % braces and backslashes are used only as delimiters.
  838.   let{ = mylbrace
  839.   let} = myrbrace
  840.   %
  841.   % I don't entirely understand this, but when an index entry is
  842.   % generated from a macro call, the endinput which scanmacro inserts
  843.   % causes processing to be prematurely terminated.  This is,
  844.   % apparently, because indexsorttmp is fully expanded, and endinput
  845.   % is an expandable command.  The redefinition below makes endinput
  846.   % disappear altogether for that purpose -- although logging shows that
  847.   % processing continues to some further point.  On the other hand, it
  848.   % seems endinput does not hurt in the printed index arg, since that
  849.   % is still getting written without apparent harm.
  850.   % 
  851.   % Sample source (mac-idx3.tex, reported by Graham Percival to
  852.   % help-texinfo, 22may06):
  853.   % @macro funindex {WORD}
  854.   % @findex xyz
  855.   % @end macro
  856.   % ...
  857.   % @funindex commtest
  858.   % 
  859.   % The above is not enough to reproduce the bug, but it gives the flavor.
  860.   % 
  861.   % Sample whatsit resulting:
  862.   % .@write3{entry{xyz}{@folio }{@code {xyz@endinput }}}
  863.   % 
  864.   % So:
  865.   letendinput = empty
  866.   %
  867.   % Do the redefinitions.
  868.   commondummies
  869. }
  870. % For the aux and toc files, @ is the escape character.  So we want to
  871. % redefine everything using @ as the escape character (instead of
  872. % realbackslash, still used for index files).  When everything uses @,
  873. % this will be simpler.
  874. %
  875. defatdummies{%
  876.   def@{@@}%
  877.   def {@ }%
  878.   let{ = lbraceatcmd
  879.   let} = rbraceatcmd
  880.   %
  881.   % Do the redefinitions.
  882.   commondummies
  883.   otherbackslash
  884. }
  885. % Called from indexdummies and atdummies.
  886. %
  887. defcommondummies{%
  888.   %
  889.   % definedummyword defines #1 as string#1space, thus effectively
  890.   % preventing its expansion.  This is used only for control% words,
  891.   % not control letters, because the space would be incorrect for
  892.   % control characters, but is needed to separate the control word
  893.   % from whatever follows.
  894.   %
  895.   % For control letters, we have definedummyletter, which omits the
  896.   % space.
  897.   %
  898.   % These can be used both for control words that take an argument and
  899.   % those that do not.  If it is followed by {arg} in the input, then
  900.   % that will dutifully get written to the index (or wherever).
  901.   %
  902.   defdefinedummyword  ##1{def##1{string##1space}}%
  903.   defdefinedummyletter##1{def##1{string##1}}%
  904.   letdefinedummyaccentdefinedummyletter
  905.   %
  906.   commondummiesnofonts
  907.   %
  908.   definedummyletter_%
  909.   %
  910.   % Non-English letters.
  911.   definedummywordAA
  912.   definedummywordAE
  913.   definedummywordL
  914.   definedummywordOE
  915.   definedummywordO
  916.   definedummywordaa
  917.   definedummywordae
  918.   definedummywordl
  919.   definedummywordoe
  920.   definedummywordo
  921.   definedummywordss
  922.   definedummywordexclamdown
  923.   definedummywordquestiondown
  924.   definedummywordordf
  925.   definedummywordordm
  926.   %
  927.   % Although these internal commands shouldn't show up, sometimes they do.
  928.   definedummywordbf
  929.   definedummywordgtr
  930.   definedummywordhat
  931.   definedummywordless
  932.   definedummywordsf
  933.   definedummywordsl
  934.   definedummywordtclose
  935.   definedummywordtt
  936.   %
  937.   definedummywordLaTeX
  938.   definedummywordTeX
  939.   %
  940.   % Assorted special characters.
  941.   definedummywordbullet
  942.   definedummywordcomma
  943.   definedummywordcopyright
  944.   definedummywordregisteredsymbol
  945.   definedummyworddots
  946.   definedummywordenddots
  947.   definedummywordequiv
  948.   definedummyworderror
  949.   definedummywordeuro
  950.   definedummywordguillemetleft
  951.   definedummywordguillemetright
  952.   definedummywordguilsinglleft
  953.   definedummywordguilsinglright
  954.   definedummywordexpansion
  955.   definedummywordminus
  956.   definedummywordpounds
  957.   definedummywordpoint
  958.   definedummywordprint
  959.   definedummywordquotedblbase
  960.   definedummywordquotedblleft
  961.   definedummywordquotedblright
  962.   definedummywordquoteleft
  963.   definedummywordquoteright
  964.   definedummywordquotesinglbase
  965.   definedummywordresult
  966.   definedummywordtextdegree
  967.   %
  968.   % We want to disable all macros so that they are not expanded by write.
  969.   macrolist
  970.   %
  971.   normalturnoffactive
  972.   %
  973.   % Handle some cases of @value -- where it does not contain any
  974.   % (non-fully-expandable) commands.
  975.   makevalueexpandable
  976. }
  977. % commondummiesnofonts: common to commondummies and indexnofonts.
  978. %
  979. defcommondummiesnofonts{%
  980.   % Control letters and accents.
  981.   definedummyletter!%
  982.   definedummyaccent"%
  983.   definedummyaccent'%
  984.   definedummyletter*%
  985.   definedummyaccent,%
  986.   definedummyletter.%
  987.   definedummyletter/%
  988.   definedummyletter:%
  989.   definedummyaccent=%
  990.   definedummyletter?%
  991.   definedummyaccent^%
  992.   definedummyaccent`%
  993.   definedummyaccent~%
  994.   definedummywordu
  995.   definedummywordv
  996.   definedummywordH
  997.   definedummyworddotaccent
  998.   definedummywordringaccent
  999.   definedummywordtieaccent
  1000.   definedummywordubaraccent
  1001.   definedummywordudotaccent
  1002.   definedummyworddotless
  1003.   %
  1004.   % Texinfo font commands.
  1005.   definedummywordb
  1006.   definedummywordi
  1007.   definedummywordr
  1008.   definedummywordsc
  1009.   definedummywordt
  1010.   %
  1011.   % Commands that take arguments.
  1012.   definedummywordacronym
  1013.   definedummywordcite
  1014.   definedummywordcode
  1015.   definedummywordcommand
  1016.   definedummyworddfn
  1017.   definedummywordemph
  1018.   definedummywordenv
  1019.   definedummywordfile
  1020.   definedummywordkbd
  1021.   definedummywordkey
  1022.   definedummywordmath
  1023.   definedummywordoption
  1024.   definedummywordpxref
  1025.   definedummywordref
  1026.   definedummywordsamp
  1027.   definedummywordstrong
  1028.   definedummywordtie
  1029.   definedummyworduref
  1030.   definedummywordurl
  1031.   definedummywordvar
  1032.   definedummywordverb
  1033.   definedummywordw
  1034.   definedummywordxref
  1035. }
  1036. % indexnofonts is used when outputting the strings to sort the index
  1037. % by, and when constructing control sequence names.  It eliminates all
  1038. % control sequences and just writes whatever the best ASCII sort string
  1039. % would be for a given command (usually its argument).
  1040. %
  1041. defindexnofonts{%
  1042.   % Accent commands should become @asis.
  1043.   defdefinedummyaccent##1{let##1asis}%
  1044.   % We can just ignore other control letters.
  1045.   defdefinedummyletter##1{let##1empty}%
  1046.   % Hopefully, all control words can become @asis.
  1047.   letdefinedummyworddefinedummyaccent
  1048.   %
  1049.   commondummiesnofonts
  1050.   %
  1051.   % Don't no-op tt, since it isn't a user-level command
  1052.   % and is used in the definitions of the active chars like <, >, |, etc.
  1053.   % Likewise with the other plain tex font commands.
  1054.   %lettt=asis
  1055.   %
  1056.   def { }%
  1057.   def@{@}%
  1058.   % how to handle braces?
  1059.   def_{normalunderscore}%
  1060.   %
  1061.   % Non-English letters.
  1062.   defAA{AA}%
  1063.   defAE{AE}%
  1064.   defL{L}%
  1065.   defOE{OE}%
  1066.   defO{O}%
  1067.   defaa{aa}%
  1068.   defae{ae}%
  1069.   defl{l}%
  1070.   defoe{oe}%
  1071.   defo{o}%
  1072.   defss{ss}%
  1073.   defexclamdown{!}%
  1074.   defquestiondown{?}%
  1075.   defordf{a}%
  1076.   defordm{o}%
  1077.   %
  1078.   defLaTeX{LaTeX}%
  1079.   defTeX{TeX}%
  1080.   %
  1081.   % Assorted special characters.
  1082.   % (The following {} will end up in the sort string, but that's ok.)
  1083.   defbullet{bullet}%
  1084.   defcomma{,}%
  1085.   defcopyright{copyright}%
  1086.   defregisteredsymbol{R}%
  1087.   defdots{...}%
  1088.   defenddots{...}%
  1089.   defequiv{==}%
  1090.   deferror{error}%
  1091.   defeuro{euro}%
  1092.   defguillemetleft{<<}%
  1093.   defguillemetright{>>}%
  1094.   defguilsinglleft{<}%
  1095.   defguilsinglright{>}%
  1096.   defexpansion{==>}%
  1097.   defminus{-}%
  1098.   defpounds{pounds}%
  1099.   defpoint{.}%
  1100.   defprint{-|}%
  1101.   defquotedblbase{"}%
  1102.   defquotedblleft{"}%
  1103.   defquotedblright{"}%
  1104.   defquoteleft{`}%
  1105.   defquoteright{'}%
  1106.   defquotesinglbase{,}%
  1107.   defresult{=>}%
  1108.   deftextdegree{degrees}%
  1109.   %
  1110.   % We need to get rid of all macros, leaving only the arguments (if present).
  1111.   % Of course this is not nearly correct, but it is the best we can do for now.
  1112.   % makeinfo does not expand macros in the argument to @deffn, which ends up
  1113.   % writing an index entry, and texindex isn't prepared for an index sort entry
  1114.   % that starts with .
  1115.   % 
  1116.   % Since macro invocations are followed by braces, we can just redefine them
  1117.   % to take a single TeX argument.  The case of a macro invocation that
  1118.   % goes to end-of-line is not handled.
  1119.   % 
  1120.   macrolist
  1121. }
  1122. letindexbackslash=0  %overridden during printindex.
  1123. letSETmarginindex=relax % put index entries in margin (undocumented)?
  1124. % Most index entries go through here, but dosubind is the general case.
  1125. % #1 is the index name, #2 is the entry text.
  1126. defdoind#1#2{dosubind{#1}{#2}{}}
  1127. % Workhorse for all fooindexes.
  1128. % #1 is name of index, #2 is stuff to put there, #3 is subentry --
  1129. % empty if called from doind, as we usually are (the main exception
  1130. % is with most defuns, which call us directly).
  1131. %
  1132. defdosubind#1#2#3{%
  1133.   iflinks
  1134.   {%
  1135.     % Store the main index entry text (including the third arg).
  1136.     toks0 = {#2}%
  1137.     % If third arg is present, precede it with a space.
  1138.     defthirdarg{#3}%
  1139.     ifxthirdargempty else
  1140.       toks0 = expandafter{thetoks0 space #3}%
  1141.     fi
  1142.     %
  1143.     edefwriteto{csname#1indfileendcsname}%
  1144.     %
  1145.     safewhatsitdosubindwrite
  1146.   }%
  1147.   fi
  1148. }
  1149. % Write the entry in toks0 to the index file:
  1150. %
  1151. defdosubindwrite{%
  1152.   % Put the index entry in the margin if desired.
  1153.   ifxSETmarginindexrelaxelse
  1154.     insertmargin{hbox{vrule height8pt depth3pt width0pt thetoks0}}%
  1155.   fi
  1156.   %
  1157.   % Remember, we are within a group.
  1158.   indexdummies % Must do this here, since bf, etc expand at this stage
  1159.   defbackslashcurfont{indexbackslash}% indexbackslash isn't defined now
  1160.       % so it will be output as is; and it will print as backslash.
  1161.   %
  1162.   % Process the index entry with all font commands turned off, to
  1163.   % get the string to sort by.
  1164.   {indexnofonts
  1165.    edeftemp{thetoks0}% need full expansion
  1166.    xdefindexsorttmp{temp}%
  1167.   }%
  1168.   %
  1169.   % Set up the complete index entry, with both the sort key and
  1170.   % the original text, including any font commands.  We write
  1171.   % three arguments to entry to the .?? file (four in the
  1172.   % subentry case), texindex reduces to two when writing the .??s
  1173.   % sorted result.
  1174.   edeftemp{%
  1175.     writewriteto{%
  1176.       stringentry{indexsorttmp}{noexpandfolio}{thetoks0}}%
  1177.   }%
  1178.   temp
  1179. }
  1180. % Take care of unwanted page breaks/skips around a whatsit:
  1181. %
  1182. % If a skip is the last thing on the list now, preserve it
  1183. % by backing up by lastskip, doing the write, then inserting
  1184. % the skip again.  Otherwise, the whatsit generated by the
  1185. % write or pdfdest will make lastskip zero.  The result is that
  1186. % sequences like this:
  1187. % @end defun
  1188. % @tindex whatever
  1189. % @defun ...
  1190. % will have extra space inserted, because the medbreak in the
  1191. % start of the @defun won't see the skip inserted by the @end of
  1192. % the previous defun.
  1193. %
  1194. % But don't do any of this if we're not in vertical mode.  We
  1195. % don't want to do a vskip and prematurely end a paragraph.
  1196. %
  1197. % Avoid page breaks due to these extra skips, too.
  1198. %
  1199. % But wait, there is a catch there:
  1200. % We'll have to check whether lastskip is zero skip.  ifdim is not
  1201. % sufficient for this purpose, as it ignores stretch and shrink parts
  1202. % of the skip.  The only way seems to be to check the textual
  1203. % representation of the skip.
  1204. %
  1205. % The following is almost like defzeroskipmacro{0.0pt} except that
  1206. % the ``p'' and ``t'' characters have catcode other, not 11 (letter).
  1207. %
  1208. edefzeroskipmacro{expandafterthecsname z@skipendcsname}
  1209. %
  1210. newskipwhatsitskip
  1211. newcountwhatsitpenalty
  1212. %
  1213. % ..., ready, GO:
  1214. %
  1215. defsafewhatsit#1{%
  1216. ifhmode
  1217.   #1%
  1218. else
  1219.   % lastskip and lastpenalty cannot both be nonzero simultaneously.
  1220.   whatsitskip = lastskip
  1221.   edeflastskipmacro{thelastskip}%
  1222.   whatsitpenalty = lastpenalty
  1223.   %
  1224.   % If lastskip is nonzero, that means the last item was a
  1225.   % skip.  And since a skip is discardable, that means this
  1226.   % -whatsitskip glue we're inserting is preceded by a
  1227.   % non-discardable item, therefore it is not a potential
  1228.   % breakpoint, therefore no nobreak needed.
  1229.   ifxlastskipmacrozeroskipmacro
  1230.   else
  1231.     vskip-whatsitskip
  1232.   fi
  1233.   %
  1234.   #1%
  1235.   %
  1236.   ifxlastskipmacrozeroskipmacro
  1237.     % If lastskip was zero, perhaps the last item was a penalty, and
  1238.     % perhaps it was >=10000, e.g., a nobreak.  In that case, we want
  1239.     % to re-insert the same penalty (values >10000 are used for various
  1240.     % signals); since we just inserted a non-discardable item, any
  1241.     % following glue (such as a parskip) would be a breakpoint.  For example:
  1242.     % 
  1243.     %   @deffn deffn-whatever
  1244.     %   @vindex index-whatever
  1245.     %   Description.
  1246.     % would allow a break between the index-whatever whatsit
  1247.     % and the "Description." paragraph.
  1248.     ifnumwhatsitpenalty>9999 penaltywhatsitpenalty fi
  1249.   else
  1250.     % On the other hand, if we had a nonzero lastskip,
  1251.     % this make-up glue would be preceded by a non-discardable item
  1252.     % (the whatsit from the write), so we must insert a nobreak.
  1253.     nobreakvskipwhatsitskip
  1254.   fi
  1255. fi
  1256. }
  1257. % The index entry written in the file actually looks like
  1258. %  entry {sortstring}{page}{topic}
  1259. % or
  1260. %  entry {sortstring}{page}{topic}{subtopic}
  1261. % The texindex program reads in these files and writes files
  1262. % containing these kinds of lines:
  1263. %  initial {c}
  1264. %     before the first topic whose initial is c
  1265. %  entry {topic}{pagelist}
  1266. %     for a topic that is used without subtopics
  1267. %  primary {topic}
  1268. %     for the beginning of a topic that is used with subtopics
  1269. %  secondary {subtopic}{pagelist}
  1270. %     for each subtopic.
  1271. % Define the user-accessible indexing commands
  1272. % @findex, @vindex, @kindex, @cindex.
  1273. deffindex {fnindex}
  1274. defkindex {kyindex}
  1275. defcindex {cpindex}
  1276. defvindex {vrindex}
  1277. deftindex {tpindex}
  1278. defpindex {pgindex}
  1279. defcindexsub {begingroupobeylinescindexsub}
  1280. {obeylines %
  1281. gdefcindexsub "#1" #2^^M{endgroup %
  1282. dosubind{cp}{#2}{#1}}}
  1283. % Define the macros used in formatting output of the sorted index material.
  1284. % @printindex causes a particular index (the ??s file) to get printed.
  1285. % It does not print any chapter heading (usually an @unnumbered).
  1286. %
  1287. parseargdefprintindex{begingroup
  1288.   dobreak chapheadingskip{10000}%
  1289.   %
  1290.   smallfonts rm
  1291.   tolerance = 9500
  1292.   plainfrenchspacing
  1293.   everypar = {}% don't want the kern-parindent from indentation suppression.
  1294.   %
  1295.   % See if the index file exists and is nonempty.
  1296.   % Change catcode of @ here so that if the index file contains
  1297.   % initial {@}
  1298.   % as its first line, TeX doesn't complain about mismatched braces
  1299.   % (because it thinks @} is a control sequence).
  1300.   catcode`@ = 11
  1301.   openin 1 jobname.#1s
  1302.   ifeof 1
  1303.     % enddoublecolumns gets confused if there is no text in the index,
  1304.     % and it loses the chapter title and the aux file entries for the
  1305.     % index.  The easiest way to prevent this problem is to make sure
  1306.     % there is some text.
  1307.     putwordIndexNonexistent
  1308.   else
  1309.     %
  1310.     % If the index file exists but is empty, then openin leaves ifeof
  1311.     % false.  We have to make TeX try to read something from the file, so
  1312.     % it can discover if there is anything in it.
  1313.     read 1 to temp
  1314.     ifeof 1
  1315.       putwordIndexIsEmpty
  1316.     else
  1317.       % Index files are almost Texinfo source, but we use  as the escape
  1318.       % character.  It would be better to use @, but that's too big a change
  1319.       % to make right now.
  1320.       defindexbackslash{backslashcurfont}%
  1321.       catcode`\ = 0
  1322.       escapechar = `\
  1323.       begindoublecolumns
  1324.       input jobname.#1s
  1325.       enddoublecolumns
  1326.     fi
  1327.   fi
  1328.   closein 1
  1329. endgroup}
  1330. % These macros are used by the sorted index file itself.
  1331. % Change them to control the appearance of the index.
  1332. definitial#1{{%
  1333.   % Some minor font changes for the special characters.
  1334.   lettentt=sectt lettt=sectt letsf=sectt
  1335.   %
  1336.   % Remove any glue we may have, we'll be inserting our own.
  1337.   removelastskip
  1338.   %
  1339.   % We like breaks before the index initials, so insert a bonus.
  1340.   nobreak
  1341.   vskip 0pt plus 3baselineskip
  1342.   penalty 0
  1343.   vskip 0pt plus -3baselineskip
  1344.   %
  1345.   % Typeset the initial.  Making this add up to a whole number of
  1346.   % baselineskips increases the chance of the dots lining up from column
  1347.   % to column.  It still won't often be perfect, because of the stretch
  1348.   % we need before each entry, but it's better.
  1349.   %
  1350.   % No shrink because it confuses balancecolumns.
  1351.   vskip 1.67baselineskip plus .5baselineskip
  1352.   leftline{secbf #1}%
  1353.   % Do our best not to break after the initial.
  1354.   nobreak
  1355.   vskip .33baselineskip plus .1baselineskip
  1356. }}
  1357. % entry typesets a paragraph consisting of the text (#1), dot leaders, and
  1358. % then page number (#2) flushed to the right margin.  It is used for index
  1359. % and table of contents entries.  The paragraph is indented by leftskip.
  1360. %
  1361. % A straightforward implementation would start like this:
  1362. % defentry#1#2{...
  1363. % But this freezes the catcodes in the argument, and can cause problems to
  1364. % @code, which sets - active.  This problem was fixed by a kludge---
  1365. % ``-'' was active throughout whole index, but this isn't really right.
  1366. %
  1367. % The right solution is to prevent entry from swallowing the whole text.
  1368. %                                 --kasal, 21nov03
  1369. defentry{%
  1370.   begingroup
  1371.     %
  1372.     % Start a new paragraph if necessary, so our assignments below can't
  1373.     % affect previous text.
  1374.     par
  1375.     %
  1376.     % Do not fill out the last line with white space.
  1377.     parfillskip = 0in
  1378.     %
  1379.     % No extra space above this paragraph.
  1380.     parskip = 0in
  1381.     %
  1382.     % Do not prefer a separate line ending with a hyphen to fewer lines.
  1383.     finalhyphendemerits = 0
  1384.     %
  1385.     % hangindent is only relevant when the entry text and page number
  1386.     % don't both fit on one line.  In that case, bob suggests starting the
  1387.     % dots pretty far over on the line.  Unfortunately, a large
  1388.     % indentation looks wrong when the entry text itself is broken across
  1389.     % lines.  So we use a small indentation and put up with long leaders.
  1390.     %
  1391.     % hangafter is reset to 1 (which is the value we want) at the start
  1392.     % of each paragraph, so we need not do anything with that.
  1393.     hangindent = 2em
  1394.     %
  1395.     % When the entry text needs to be broken, just fill out the first line
  1396.     % with blank space.
  1397.     rightskip = 0pt plus1fil
  1398.     %
  1399.     % A bit of stretch before each entry for the benefit of balancing
  1400.     % columns.
  1401.     vskip 0pt plus1pt
  1402.     %
  1403.     % Swallow the left brace of the text (first parameter):
  1404.     afterassignmentdoentry
  1405.     lettemp =
  1406. }
  1407. defdoentry{%
  1408.     bgroup % Instead of the swallowed brace.
  1409.       noindent
  1410.       aftergroupfinishentry
  1411.       % And now comes the text of the entry.
  1412. }
  1413. deffinishentry#1{%
  1414.     % #1 is the page number.
  1415.     %
  1416.     % The following is kludged to not output a line of dots in the index if
  1417.     % there are no page numbers.  The next person who breaks this will be
  1418.     % cursed by a Unix daemon.
  1419.     setboxboxA = hbox{#1}%
  1420.     ifdimwdboxA = 0pt
  1421.        %
  1422.     else
  1423.       %
  1424.       % If we must, put the page number on a line of its own, and fill out
  1425.       % this line with blank space.  (The hfil is overwhelmed with the
  1426.       % fill leaders glue in indexdotfill if the page number does fit.)
  1427.       hfilpenalty50
  1428.       nullnobreakindexdotfill % Have leaders before the page number.
  1429.       %
  1430.       % The ` ' here is removed by the implicit unskip that TeX does as
  1431.       % part of (the primitive) par.  Without it, a spurious underfull
  1432.       % hbox ensues.
  1433.       ifpdf
  1434. pdfgettoks#1.%
  1435.  thetoksA
  1436.       else
  1437.  #1%
  1438.       fi
  1439.     fi
  1440.     par
  1441.   endgroup
  1442. }
  1443. % Like plain.tex's dotfill, except uses up at least 1 em.
  1444. defindexdotfill{cleaders
  1445.   hbox{$mathsurround=0pt mkern1.5mu.mkern1.5mu$}hskip 1em plus 1fill}
  1446. defprimary #1{line{#1hfil}}
  1447. newskipsecondaryindent secondaryindent=0.5cm
  1448. defsecondary#1#2{{%
  1449.   parfillskip=0in
  1450.   parskip=0in
  1451.   hangindent=1in
  1452.   hangafter=1
  1453.   noindenthskipsecondaryindenthbox{#1}indexdotfill
  1454.   ifpdf
  1455.     pdfgettoks#2. thetoksA % The page number ends the paragraph.
  1456.   else
  1457.     #2
  1458.   fi
  1459.   par
  1460. }}
  1461. % Define two-column mode, which we use to typeset indexes.
  1462. % Adapted from the TeXbook, page 416, which is to say,
  1463. % the manmac.tex format used to print the TeXbook itself.
  1464. catcode`@=11
  1465. newboxpartialpage
  1466. newdimendoublecolumnhsize
  1467. defbegindoublecolumns{begingroup % ended by enddoublecolumns
  1468.   % Grab any single-column material above us.
  1469.   output = {%
  1470.     %
  1471.     % Here is a possibility not foreseen in manmac: if we accumulate a
  1472.     % whole lot of material, we might end up calling this output
  1473.     % routine twice in a row (see the doublecol-lose test, which is
  1474.     % essentially a couple of indexes with @setchapternewpage off).  In
  1475.     % that case we just ship out what is in partialpage with the normal
  1476.     % output routine.  Generally, partialpage will be empty when this
  1477.     % runs and this will be a no-op.  See the indexspread.tex test case.
  1478.     ifvoidpartialpage else
  1479.       onepageout{pagecontentspartialpage}%
  1480.     fi
  1481.     %
  1482.     globalsetboxpartialpage = vbox{%
  1483.       % Unvbox the main output page.
  1484.       unvboxPAGE
  1485.       kern-topskip kernbaselineskip
  1486.     }%
  1487.   }%
  1488.   eject % run that output routine to set partialpage
  1489.   %
  1490.   % Use the double-column output routine for subsequent pages.
  1491.   output = {doublecolumnout}%
  1492.   %
  1493.   % Change the page size parameters.  We could do this once outside this
  1494.   % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
  1495.   % format, but then we repeat the same computation.  Repeating a couple
  1496.   % of assignments once per index is clearly meaningless for the
  1497.   % execution time, so we may as well do it in one place.
  1498.   %
  1499.   % First we halve the line length, less a little for the gutter between
  1500.   % the columns.  We compute the gutter based on the line length, so it
  1501.   % changes automatically with the paper format.  The magic constant
  1502.   % below is chosen so that the gutter has the same value (well, +-<1pt)
  1503.   % as it did when we hard-coded it.
  1504.   %
  1505.   % We put the result in a separate register, doublecolumhsize, so we
  1506.   % can restore it in pagesofar, after hsize itself has (potentially)
  1507.   % been clobbered.
  1508.   %
  1509.   doublecolumnhsize = hsize
  1510.     advancedoublecolumnhsize by -.04154hsize
  1511.     dividedoublecolumnhsize by 2
  1512.   hsize = doublecolumnhsize
  1513.   %
  1514.   % Double the vsize as well.  (We don't need a separate register here,
  1515.   % since nobody clobbers vsize.)
  1516.   vsize = 2vsize
  1517. }
  1518. % The double-column output routine for all double-column pages except
  1519. % the last.
  1520. %
  1521. defdoublecolumnout{%
  1522.   splittopskip=topskip splitmaxdepth=maxdepth
  1523.   % Get the available space for the double columns -- the normal
  1524.   % (undoubled) page height minus any material left over from the
  1525.   % previous page.
  1526.   dimen@ = vsize
  1527.   dividedimen@ by 2
  1528.   advancedimen@ by -htpartialpage
  1529.   %
  1530.   % box0 will be the left-hand column, box2 the right.
  1531.   setbox0=vsplit255 todimen@ setbox2=vsplit255 todimen@
  1532.   onepageoutpagesofar
  1533.   unvbox255
  1534.   penaltyoutputpenalty
  1535. }
  1536. %
  1537. % Re-output the contents of the output page -- any previous material,
  1538. % followed by the two boxes we just split, in box0 and box2.
  1539. defpagesofar{%
  1540.   unvboxpartialpage
  1541.   %
  1542.   hsize = doublecolumnhsize
  1543.   wd0=hsize wd2=hsize
  1544.   hbox topagewidth{box0hfilbox2}%
  1545. }
  1546. %
  1547. % All done with double columns.
  1548. defenddoublecolumns{%
  1549.   % The following penalty ensures that the page builder is exercised
  1550.   % _before_ we change the output routine.  This is necessary in the
  1551.   % following situation:
  1552.   %
  1553.   % The last section of the index consists only of a single entry.
  1554.   % Before this section, pagetotal is less than pagegoal, so no
  1555.   % break occurs before the last section starts.  However, the last
  1556.   % section, consisting of initial and the single entry, does not
  1557.   % fit on the page and has to be broken off.  Without the following
  1558.   % penalty the page builder will not be exercised until eject
  1559.   % below, and by that time we'll already have changed the output
  1560.   % routine to the balancecolumns version, so the next-to-last
  1561.   % double-column page will be processed with balancecolumns, which
  1562.   % is wrong:  The two columns will go to the main vertical list, with
  1563.   % the broken-off section in the recent contributions.  As soon as
  1564.   % the output routine finishes, TeX starts reconsidering the page
  1565.   % break.  The two columns and the broken-off section both fit on the
  1566.   % page, because the two columns now take up only half of the page
  1567.   % goal.  When TeX sees eject from below which follows the final
  1568.   % section, it invokes the new output routine that we've set after
  1569.   % balancecolumns below; onepageout will try to fit the two columns
  1570.   % and the final section into the vbox of pageheight (see
  1571.   % pagebody), causing an overfull box.
  1572.   %
  1573.   % Note that glue won't work here, because glue does not exercise the
  1574.   % page builder, unlike penalties (see The TeXbook, pp. 280-281).
  1575.   penalty0
  1576.   %
  1577.   output = {%
  1578.     % Split the last of the double-column material.  Leave it on the
  1579.     % current page, no automatic page break.
  1580.     balancecolumns
  1581.     %
  1582.     % If we end up splitting too much material for the current page,
  1583.     % though, there will be another page break right after this output
  1584.     % invocation ends.  Having called balancecolumns once, we do not
  1585.     % want to call it again.  Therefore, reset output to its normal
  1586.     % definition right away.  (We hope balancecolumns will never be
  1587.     % called on to balance too much material, but if it is, this makes
  1588.     % the output somewhat more palatable.)
  1589.     globaloutput = {onepageout{pagecontentsPAGE}}%
  1590.   }%
  1591.   eject
  1592.   endgroup % started in begindoublecolumns
  1593.   %
  1594.   % pagegoal was set to the doubled vsize above, since we restarted
  1595.   % the current page.  We're now back to normal single-column
  1596.   % typesetting, so reset pagegoal to the normal vsize (after the
  1597.   % endgroup where vsize got restored).
  1598.   pagegoal = vsize
  1599. }
  1600. %
  1601. % Called at the end of the double column material.
  1602. defbalancecolumns{%
  1603.   setbox0 = vbox{unvbox255}% like box255 but more efficient, see p.120.
  1604.   dimen@ = ht0
  1605.   advancedimen@ by topskip
  1606.   advancedimen@ by-baselineskip
  1607.   dividedimen@ by 2 % target to split to
  1608.   %debugmessage{final 2-column material height=theht0, target=thedimen@.}%
  1609.   splittopskip = topskip
  1610.   % Loop until we get a decent breakpoint.
  1611.   {%
  1612.     vbadness = 10000
  1613.     loop
  1614.       globalsetbox3 = copy0
  1615.       globalsetbox1 = vsplit3 to dimen@
  1616.     ifdimht3>dimen@
  1617.       globaladvancedimen@ by 1pt
  1618.     repeat
  1619.   }%
  1620.   %debugmessage{split to thedimen@, column heights: theht1, theht3.}%
  1621.   setbox0=vbox todimen@{unvbox1}%
  1622.   setbox2=vbox todimen@{unvbox3}%
  1623.   %
  1624.   pagesofar
  1625. }
  1626. catcode`@ = other
  1627. message{sectioning,}
  1628. % Chapters, sections, etc.
  1629. % unnumberedno is an oxymoron, of course.  But we count the unnumbered
  1630. % sections so that we can refer to them unambiguously in the pdf
  1631. % outlines by their "section number".  We avoid collisions with chapter
  1632. % numbers by starting them at 10000.  (If a document ever has 10000
  1633. % chapters, we're in trouble anyway, I'm sure.)
  1634. newcountunnumberedno unnumberedno = 10000
  1635. newcountchapno
  1636. newcountsecno        secno=0
  1637. newcountsubsecno     subsecno=0
  1638. newcountsubsubsecno  subsubsecno=0
  1639. % This counter is funny since it counts through charcodes of letters A, B, ...
  1640. newcountappendixno  appendixno = `@
  1641. %
  1642. % defappendixletter{chartheappendixno}
  1643. % We do the following ugly conditional instead of the above simple
  1644. % construct for the sake of pdftex, which needs the actual
  1645. % letter in the expansion, not just typeset.
  1646. %
  1647. defappendixletter{%
  1648.   ifnumappendixno=`A A%
  1649.   elseifnumappendixno=`B B%
  1650.   elseifnumappendixno=`C C%
  1651.   elseifnumappendixno=`D D%
  1652.   elseifnumappendixno=`E E%
  1653.   elseifnumappendixno=`F F%
  1654.   elseifnumappendixno=`G G%
  1655.   elseifnumappendixno=`H H%
  1656.   elseifnumappendixno=`I I%
  1657.   elseifnumappendixno=`J J%
  1658.   elseifnumappendixno=`K K%
  1659.   elseifnumappendixno=`L L%
  1660.   elseifnumappendixno=`M M%
  1661.   elseifnumappendixno=`N N%
  1662.   elseifnumappendixno=`O O%
  1663.   elseifnumappendixno=`P P%
  1664.   elseifnumappendixno=`Q Q%
  1665.   elseifnumappendixno=`R R%
  1666.   elseifnumappendixno=`S S%
  1667.   elseifnumappendixno=`T T%
  1668.   elseifnumappendixno=`U U%
  1669.   elseifnumappendixno=`V V%
  1670.   elseifnumappendixno=`W W%
  1671.   elseifnumappendixno=`X X%
  1672.   elseifnumappendixno=`Y Y%
  1673.   elseifnumappendixno=`Z Z%
  1674.   % The the is necessary, despite appearances, because appendixletter is
  1675.   % expanded while writing the .toc file.  charappendixno is not
  1676.   % expandable, thus it is written literally, thus all appendixes come out
  1677.   % with the same letter (or @) in the toc without it.
  1678.   elsechartheappendixno
  1679.   fififififififififififififi
  1680.   fififififififififififififi}
  1681. % Each @chapter defines these (using marks) as the number+name, number
  1682. % and name of the chapter.  Page headings and footings can use
  1683. % these.  @section does likewise.
  1684. defthischapter{}
  1685. defthischapternum{}
  1686. defthischaptername{}
  1687. defthissection{}
  1688. defthissectionnum{}
  1689. defthissectionname{}
  1690. newcountabsseclevel % used to calculate proper heading level
  1691. newcountsecbasesecbase=0 % @raisesections/@lowersections modify this count
  1692. % @raisesections: treat @section as chapter, @subsection as section, etc.
  1693. defraisesections{globaladvancesecbase by -1}
  1694. letup=raisesections % original BFox name
  1695. % @lowersections: treat @chapter as section, @section as subsection, etc.
  1696. deflowersections{globaladvancesecbase by 1}
  1697. letdown=lowersections % original BFox name
  1698. % we only have subsub.
  1699. chardefmaxseclevel = 3
  1700. %
  1701. % A numbered section within an unnumbered changes to unnumbered too.
  1702. % To achieve this, remember the "biggest" unnum. sec. we are currently in:
  1703. chardefunmlevel = maxseclevel
  1704. %
  1705. % Trace whether the current chapter is an appendix or not:
  1706. % chapheadtype is "N" or "A", unnumbered chapters are ignored.
  1707. defchapheadtype{N}
  1708. % Choose a heading macro
  1709. % #1 is heading type
  1710. % #2 is heading level
  1711. % #3 is text for heading
  1712. defgenhead#1#2#3{%
  1713.   % Compute the abs. sec. level:
  1714.   absseclevel=#2
  1715.   advanceabsseclevel by secbase
  1716.   % Make sure absseclevel doesn't fall outside the range:
  1717.   ifnum absseclevel < 0
  1718.     absseclevel = 0
  1719.   else
  1720.     ifnum absseclevel > 3
  1721.       absseclevel = 3
  1722.     fi
  1723.   fi
  1724.   % The heading type:
  1725.   defheadtype{#1}%
  1726.   if headtype U%
  1727.     ifnum absseclevel < unmlevel
  1728.       chardefunmlevel = absseclevel
  1729.     fi
  1730.   else
  1731.     % Check for appendix sections:
  1732.     ifnum absseclevel = 0
  1733.       edefchapheadtype{headtype}%
  1734.     else
  1735.       if headtype Aif chapheadtype N%
  1736. errmessage{@appendix... within a non-appendix chapter}%
  1737.       fifi
  1738.     fi
  1739.     % Check for numbered within unnumbered:
  1740.     ifnum absseclevel > unmlevel
  1741.       defheadtype{U}%
  1742.     else
  1743.       chardefunmlevel = 3
  1744.     fi
  1745.   fi
  1746.   % Now print the heading:
  1747.   if headtype U%
  1748.     ifcaseabsseclevel
  1749. unnumberedzzz{#3}%
  1750.     or unnumberedseczzz{#3}%
  1751.     or unnumberedsubseczzz{#3}%
  1752.     or unnumberedsubsubseczzz{#3}%
  1753.     fi
  1754.   else
  1755.     if headtype A%
  1756.       ifcaseabsseclevel
  1757.   appendixzzz{#3}%
  1758.       or appendixsectionzzz{#3}%
  1759.       or appendixsubseczzz{#3}%
  1760.       or appendixsubsubseczzz{#3}%
  1761.       fi
  1762.     else
  1763.       ifcaseabsseclevel
  1764.   chapterzzz{#3}%
  1765.       or seczzz{#3}%
  1766.       or numberedsubseczzz{#3}%
  1767.       or numberedsubsubseczzz{#3}%
  1768.       fi
  1769.     fi
  1770.   fi
  1771.   suppressfirstparagraphindent
  1772. }
  1773. % an interface:
  1774. defnumhead{genhead N}
  1775. defapphead{genhead A}
  1776. defunnmhead{genhead U}
  1777. % @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
  1778. % all lower-level sectioning counters to zero.
  1779. %
  1780. % Also set chaplevelprefix, which we prepend to @float sequence numbers
  1781. % (e.g., figures), q.v.  By default (before any chapter), that is empty.
  1782. letchaplevelprefix = empty
  1783. %
  1784. outerparseargdefchapter{numhead0{#1}} % normally numhead0 calls chapterzzz
  1785. defchapterzzz#1{%
  1786.   % section resetting is global in case the chapter is in a group, such
  1787.   % as an @include file.
  1788.   globalsecno=0 globalsubsecno=0 globalsubsubsecno=0
  1789.     globaladvancechapno by 1
  1790.   %
  1791.   % Used for float.
  1792.   gdefchaplevelprefix{thechapno.}%
  1793.   resetallfloatnos
  1794.   %
  1795.   message{putwordChapterspace thechapno}%
  1796.   %
  1797.   % Write the actual heading.
  1798.   chapmacro{#1}{Ynumbered}{thechapno}%
  1799.   %
  1800.   % So @section and the like are numbered underneath this chapter.
  1801.   globalletsection = numberedsec
  1802.   globalletsubsection = numberedsubsec
  1803.   globalletsubsubsection = numberedsubsubsec
  1804. }
  1805. outerparseargdefappendix{apphead0{#1}} % normally apphead0 calls appendixzzz
  1806. defappendixzzz#1{%
  1807.   globalsecno=0 globalsubsecno=0 globalsubsubsecno=0
  1808.     globaladvanceappendixno by 1
  1809.   gdefchaplevelprefix{appendixletter.}%
  1810.   resetallfloatnos
  1811.   %
  1812.   defappendixnum{putwordAppendixspace appendixletter}%
  1813.   message{appendixnum}%
  1814.   %
  1815.   chapmacro{#1}{Yappendix}{appendixletter}%
  1816.   %
  1817.   globalletsection = appendixsec
  1818.   globalletsubsection = appendixsubsec
  1819.   globalletsubsubsection = appendixsubsubsec
  1820. }
  1821. outerparseargdefunnumbered{unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
  1822. defunnumberedzzz#1{%
  1823.   globalsecno=0 globalsubsecno=0 globalsubsubsecno=0
  1824.     globaladvanceunnumberedno by 1
  1825.   %
  1826.   % Since an unnumbered has no number, no prefix for figures.
  1827.   globalletchaplevelprefix = empty
  1828.   resetallfloatnos
  1829.   %
  1830.   % This used to be simply message{#1}, but TeX fully expands the
  1831.   % argument to message.  Therefore, if #1 contained @-commands, TeX
  1832.   % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
  1833.   % expanded @cite (which turns out to cause errors because cite is meant
  1834.   % to be executed, not expanded).
  1835.   %
  1836.   % Anyway, we don't want the fully-expanded definition of @cite to appear
  1837.   % as a result of the message, we just want `@cite' itself.  We use
  1838.   % the<toks register> to achieve this: TeX expands the<toks> only once,
  1839.   % simply yielding the contents of <toks register>.  (We also do this for
  1840.   % the toc entries.)
  1841.   toks0 = {#1}%
  1842.   message{(thetoks0)}%
  1843.   %
  1844.   chapmacro{#1}{Ynothing}{theunnumberedno}%
  1845.   %
  1846.   globalletsection = unnumberedsec
  1847.   globalletsubsection = unnumberedsubsec
  1848.   globalletsubsubsection = unnumberedsubsubsec
  1849. }
  1850. % @centerchap is like @unnumbered, but the heading is centered.
  1851. outerparseargdefcenterchap{%
  1852.   % Well, we could do the following in a group, but that would break
  1853.   % an assumption that chapmacro is called at the outermost level.
  1854.   % Thus we are safer this way: --kasal, 24feb04
  1855.   letcenterparametersmaybe = centerparameters
  1856.   unnmhead0{#1}%
  1857.   letcenterparametersmaybe = relax
  1858. }
  1859. % @top is like @unnumbered.
  1860. lettopunnumbered
  1861. % Sections.
  1862. outerparseargdefnumberedsec{numhead1{#1}} % normally calls seczzz
  1863. defseczzz#1{%
  1864.   globalsubsecno=0 globalsubsubsecno=0  globaladvancesecno by 1
  1865.   sectionheading{#1}{sec}{Ynumbered}{thechapno.thesecno}%
  1866. }
  1867. outerparseargdefappendixsection{apphead1{#1}} % normally calls appendixsectionzzz
  1868. defappendixsectionzzz#1{%
  1869.   globalsubsecno=0 globalsubsubsecno=0  globaladvancesecno by 1
  1870.   sectionheading{#1}{sec}{Yappendix}{appendixletter.thesecno}%
  1871. }
  1872. letappendixsecappendixsection
  1873. outerparseargdefunnumberedsec{unnmhead1{#1}} % normally calls unnumberedseczzz
  1874. defunnumberedseczzz#1{%
  1875.   globalsubsecno=0 globalsubsubsecno=0  globaladvancesecno by 1
  1876.   sectionheading{#1}{sec}{Ynothing}{theunnumberedno.thesecno}%
  1877. }
  1878. % Subsections.
  1879. outerparseargdefnumberedsubsec{numhead2{#1}} % normally calls numberedsubseczzz
  1880. defnumberedsubseczzz#1{%
  1881.   globalsubsubsecno=0  globaladvancesubsecno by 1
  1882.   sectionheading{#1}{subsec}{Ynumbered}{thechapno.thesecno.thesubsecno}%
  1883. }
  1884. outerparseargdefappendixsubsec{apphead2{#1}} % normally calls appendixsubseczzz
  1885. defappendixsubseczzz#1{%
  1886.   globalsubsubsecno=0  globaladvancesubsecno by 1
  1887.   sectionheading{#1}{subsec}{Yappendix}%
  1888.                  {appendixletter.thesecno.thesubsecno}%
  1889. }
  1890. outerparseargdefunnumberedsubsec{unnmhead2{#1}} %normally calls unnumberedsubseczzz
  1891. defunnumberedsubseczzz#1{%
  1892.   globalsubsubsecno=0  globaladvancesubsecno by 1
  1893.   sectionheading{#1}{subsec}{Ynothing}%
  1894.                  {theunnumberedno.thesecno.thesubsecno}%
  1895. }
  1896. % Subsubsections.
  1897. outerparseargdefnumberedsubsubsec{numhead3{#1}} % normally numberedsubsubseczzz
  1898. defnumberedsubsubseczzz#1{%
  1899.   globaladvancesubsubsecno by 1
  1900.   sectionheading{#1}{subsubsec}{Ynumbered}%
  1901.                  {thechapno.thesecno.thesubsecno.thesubsubsecno}%
  1902. }
  1903. outerparseargdefappendixsubsubsec{apphead3{#1}} % normally appendixsubsubseczzz
  1904. defappendixsubsubseczzz#1{%
  1905.   globaladvancesubsubsecno by 1
  1906.   sectionheading{#1}{subsubsec}{Yappendix}%
  1907.                  {appendixletter.thesecno.thesubsecno.thesubsubsecno}%
  1908. }
  1909. outerparseargdefunnumberedsubsubsec{unnmhead3{#1}} %normally unnumberedsubsubseczzz
  1910. defunnumberedsubsubseczzz#1{%
  1911.   globaladvancesubsubsecno by 1
  1912.   sectionheading{#1}{subsubsec}{Ynothing}%
  1913.                  {theunnumberedno.thesecno.thesubsecno.thesubsubsecno}%
  1914. }
  1915. % These macros control what the section commands do, according
  1916. % to what kind of chapter we are in (ordinary, appendix, or unnumbered).
  1917. % Define them by default for a numbered chapter.
  1918. letsection = numberedsec
  1919. letsubsection = numberedsubsec
  1920. letsubsubsection = numberedsubsubsec
  1921. % Define @majorheading, @heading and @subheading
  1922. % NOTE on use of vbox for chapter headings, section headings, and such:
  1923. %       1) We use vbox rather than the earlier line to permit
  1924. %          overlong headings to fold.
  1925. %       2) hyphenpenalty is set to 10000 because hyphenation in a
  1926. %          heading is obnoxious; this forbids it.
  1927. %       3) Likewise, headings look best if no parindent is used, and
  1928. %          if justification is not attempted.  Hence raggedright.
  1929. defmajorheading{%
  1930.   {advancechapheadingskip by 10pt chapbreak }%
  1931.   parseargchapheadingzzz
  1932. }
  1933. defchapheading{chapbreak parseargchapheadingzzz}
  1934. defchapheadingzzz#1{%
  1935.   {chapfonts vbox{hyphenpenalty=10000tolerance=5000
  1936.                     parindent=0ptraggedright
  1937.                     rm #1hfill}}%
  1938.   bigskip parpenalty 200relax
  1939.   suppressfirstparagraphindent
  1940. }
  1941. % @heading, @subheading, @subsubheading.
  1942. parseargdefheading{sectionheading{#1}{sec}{Yomitfromtoc}{}
  1943.   suppressfirstparagraphindent}
  1944. parseargdefsubheading{sectionheading{#1}{subsec}{Yomitfromtoc}{}
  1945.   suppressfirstparagraphindent}
  1946. parseargdefsubsubheading{sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
  1947.   suppressfirstparagraphindent}
  1948. % These macros generate a chapter, section, etc. heading only
  1949. % (including whitespace, linebreaking, etc. around it),
  1950. % given all the information in convenient, parsed form.
  1951. %%% Args are the skip and penalty (usually negative)
  1952. defdobreak#1#2{parifdimlastskip<#1removelastskippenalty#2vskip#1fi}
  1953. %%% Define plain chapter starts, and page on/off switching for it
  1954. % Parameter controlling skip before chapter headings (if needed)
  1955. newskipchapheadingskip
  1956. defchapbreak{dobreak chapheadingskip {-4000}}
  1957. defchappager{parvfillsupereject}
  1958. % Because domark is called before chapoddpage, the filler page will
  1959. % get the headings for the next chapter, which is wrong.  But we don't
  1960. % care -- we just disable all headings on the filler page.
  1961. defchapoddpage{%
  1962.   chappager
  1963.   ifoddpageno else
  1964.     begingroup
  1965.       evenheadline={hfil}evenfootline={hfil}%
  1966.       oddheadline={hfil}oddfootline={hfil}%
  1967.       hbox to 0pt{}%
  1968.       chappager
  1969.     endgroup
  1970.   fi
  1971. }
  1972. defsetchapternewpage #1 {csname CHAPPAG#1endcsname}
  1973. defCHAPPAGoff{%
  1974. globalletcontentsalignmacro = chappager
  1975. globalletpchapsepmacro=chapbreak
  1976. globalletpagealignmacro=chappager}
  1977. defCHAPPAGon{%
  1978. globalletcontentsalignmacro = chappager
  1979. globalletpchapsepmacro=chappager
  1980. globalletpagealignmacro=chappager
  1981. globaldefHEADINGSon{HEADINGSsingle}}
  1982. defCHAPPAGodd{%
  1983. globalletcontentsalignmacro = chapoddpage
  1984. globalletpchapsepmacro=chapoddpage
  1985. globalletpagealignmacro=chapoddpage
  1986. globaldefHEADINGSon{HEADINGSdouble}}
  1987. CHAPPAGon
  1988. % Chapter opening.
  1989. %
  1990. % #1 is the text, #2 is the section type (Ynumbered, Ynothing,
  1991. % Yappendix, Yomitfromtoc), #3 the chapter number.
  1992. %
  1993. % To test against our argument.
  1994. defYnothingkeyword{Ynothing}
  1995. defYomitfromtockeyword{Yomitfromtoc}
  1996. defYappendixkeyword{Yappendix}
  1997. %
  1998. defchapmacro#1#2#3{%
  1999.   % Insert the first mark before the heading break (see notes for domark).
  2000.   letprevchapterdefs=lastchapterdefs
  2001.   letprevsectiondefs=lastsectiondefs
  2002.   gdeflastsectiondefs{gdefthissectionname{}gdefthissectionnum{}%
  2003.                         gdefthissection{}}%
  2004.   %
  2005.   deftemptype{#2}%
  2006.   ifxtemptypeYnothingkeyword
  2007.     gdeflastchapterdefs{gdefthischaptername{#1}gdefthischapternum{}%
  2008.                           gdefthischapter{thischaptername}}%
  2009.   elseifxtemptypeYomitfromtockeyword
  2010.     gdeflastchapterdefs{gdefthischaptername{#1}gdefthischapternum{}%
  2011.                           gdefthischapter{}}%
  2012.   elseifxtemptypeYappendixkeyword
  2013.     toks0={#1}%
  2014.     xdeflastchapterdefs{%
  2015.       gdefnoexpandthischaptername{thetoks0}%
  2016.       gdefnoexpandthischapternum{appendixletter}%
  2017.       gdefnoexpandthischapter{putwordAppendix{} noexpandthischapternum:
  2018.                                  noexpandthischaptername}%
  2019.     }%
  2020.   else
  2021.     toks0={#1}%
  2022.     xdeflastchapterdefs{%
  2023.       gdefnoexpandthischaptername{thetoks0}%
  2024.       gdefnoexpandthischapternum{thechapno}%
  2025.       gdefnoexpandthischapter{putwordChapter{} noexpandthischapternum:
  2026.                                  noexpandthischaptername}%
  2027.     }%
  2028.   fififi
  2029.   %
  2030.   % Output the mark.  Pass it through safewhatsit, to take care of
  2031.   % the preceding space.
  2032.   safewhatsitdomark
  2033.   %
  2034.   % Insert the chapter heading break.
  2035.   pchapsepmacro
  2036.   %
  2037.   % Now the second mark, after the heading break.  No break points
  2038.   % between here and the heading.
  2039.   letprevchapterdefs=lastchapterdefs
  2040.   letprevsectiondefs=lastsectiondefs
  2041.   domark
  2042.   %
  2043.   {%
  2044.     chapfonts rm
  2045.     %
  2046.     % Have to define lastsection before calling donoderef, because the
  2047.     % xref code eventually uses it.  On the other hand, it has to be called
  2048.     % after pchapsepmacro, or the headline will change too soon.
  2049.     gdeflastsection{#1}%
  2050.     %
  2051.     % Only insert the separating space if we have a chapter/appendix
  2052.     % number, and don't print the unnumbered ``number''.
  2053.     ifxtemptypeYnothingkeyword
  2054.       setbox0 = hbox{}%
  2055.       deftoctype{unnchap}%
  2056.     elseifxtemptypeYomitfromtockeyword
  2057.       setbox0 = hbox{}% contents like unnumbered, but no toc entry
  2058.       deftoctype{omit}%
  2059.     elseifxtemptypeYappendixkeyword
  2060.       setbox0 = hbox{putwordAppendix{} #3enspace}%
  2061.       deftoctype{app}%
  2062.     else
  2063.       setbox0 = hbox{#3enspace}%
  2064.       deftoctype{numchap}%
  2065.     fififi
  2066.     %
  2067.     % Write the toc entry for this chapter.  Must come before the
  2068.     % donoderef, because we include the current node name in the toc
  2069.     % entry, and donoderef resets it to empty.
  2070.     writetocentry{toctype}{#1}{#3}%
  2071.     %
  2072.     % For pdftex, we have to write out the node definition (aka, make
  2073.     % the pdfdest) after any page break, but before the actual text has
  2074.     % been typeset.  If the destination for the pdf outline is after the
  2075.     % text, then jumping from the outline may wind up with the text not
  2076.     % being visible, for instance under high magnification.
  2077.     donoderef{#2}%
  2078.     %
  2079.     % Typeset the actual heading.
  2080.     nobreak % Avoid page breaks at the interline glue.
  2081.     vbox{hyphenpenalty=10000 tolerance=5000 parindent=0pt raggedright
  2082.           hangindent=wd0 centerparametersmaybe
  2083.           unhbox0 #1par}%
  2084.   }%
  2085.   nobreakbigskip % no page break after a chapter title
  2086.   nobreak
  2087. }
  2088. % @centerchap -- centered and unnumbered.
  2089. letcenterparametersmaybe = relax
  2090. defcenterparameters{%
  2091.   advancerightskip by 3rightskip
  2092.   leftskip = rightskip
  2093.   parfillskip = 0pt
  2094. }
  2095. % I don't think this chapter style is supported any more, so I'm not
  2096. % updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
  2097. %
  2098. defsetchapterstyle #1 {csname CHAPF#1endcsname}
  2099. %
  2100. defunnchfopen #1{%
  2101. chapoddpage {chapfonts vbox{hyphenpenalty=10000tolerance=5000
  2102.                        parindent=0ptraggedright
  2103.                        rm #1hfill}}bigskip parnobreak
  2104. }
  2105. defchfopen #1#2{chapoddpage {chapfonts
  2106. vbox to 3in{vfil hbox tohsize{hfil #2} hbox tohsize{hfil #1} vfil}}%
  2107. parpenalty 5000 %
  2108. }
  2109. defcenterchfopen #1{%
  2110. chapoddpage {chapfonts vbox{hyphenpenalty=10000tolerance=5000
  2111.                        parindent=0pt
  2112.                        hfill {rm #1}hfill}}bigskip parnobreak
  2113. }
  2114. defCHAPFopen{%
  2115.   globalletchapmacro=chfopen
  2116.   globalletcenterchapmacro=centerchfopen}
  2117. % Section titles.  These macros combine the section number parts and
  2118. % call the generic sectionheading to do the printing.
  2119. %
  2120. newskipsecheadingskip
  2121. defsecheadingbreak{dobreak secheadingskip{-1000}}
  2122. % Subsection titles.
  2123. newskipsubsecheadingskip
  2124. defsubsecheadingbreak{dobreak subsecheadingskip{-500}}
  2125. % Subsubsection titles.
  2126. defsubsubsecheadingskip{subsecheadingskip}
  2127. defsubsubsecheadingbreak{subsecheadingbreak}
  2128. % Print any size, any type, section title.
  2129. %
  2130. % #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
  2131. % the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
  2132. % section number.
  2133. %
  2134. defseckeyword{sec}
  2135. %
  2136. defsectionheading#1#2#3#4{%
  2137.   {%
  2138.     % Switch to the right set of fonts.
  2139.     csname #2fontsendcsname rm
  2140.     %
  2141.     defsectionlevel{#2}%
  2142.     deftemptype{#3}%
  2143.     %
  2144.     % Insert first mark before the heading break (see notes for domark).
  2145.     letprevsectiondefs=lastsectiondefs
  2146.     ifxtemptypeYnothingkeyword
  2147.       ifxsectionlevelseckeyword
  2148.         gdeflastsectiondefs{gdefthissectionname{#1}gdefthissectionnum{}%
  2149.                               gdefthissection{thissectionname}}%
  2150.       fi
  2151.     elseifxtemptypeYomitfromtockeyword
  2152.       % Don't redefine thissection.
  2153.     elseifxtemptypeYappendixkeyword
  2154.       ifxsectionlevelseckeyword
  2155.         toks0={#1}%
  2156.         xdeflastsectiondefs{%
  2157.           gdefnoexpandthissectionname{thetoks0}%
  2158.           gdefnoexpandthissectionnum{#4}%
  2159.           gdefnoexpandthissection{putwordSection{} noexpandthissectionnum:
  2160.                                      noexpandthissectionname}%
  2161.         }%
  2162.       fi
  2163.     else
  2164.       ifxsectionlevelseckeyword
  2165.         toks0={#1}%
  2166.         xdeflastsectiondefs{%
  2167.           gdefnoexpandthissectionname{thetoks0}%
  2168.           gdefnoexpandthissectionnum{#4}%
  2169.           gdefnoexpandthissection{putwordSection{} noexpandthissectionnum:
  2170.                                      noexpandthissectionname}%
  2171.         }%
  2172.       fi
  2173.     fififi
  2174.     %
  2175.     % Output the mark.  Pass it through safewhatsit, to take care of
  2176.     % the preceding space.
  2177.     safewhatsitdomark
  2178.     %
  2179.     % Insert space above the heading.
  2180.     csname #2headingbreakendcsname
  2181.     %
  2182.     % Now the second mark, after the heading break.  No break points
  2183.     % between here and the heading.
  2184.     letprevsectiondefs=lastsectiondefs
  2185.     domark
  2186.     %
  2187.     % Only insert the space after the number if we have a section number.
  2188.     ifxtemptypeYnothingkeyword
  2189.       setbox0 = hbox{}%
  2190.       deftoctype{unn}%
  2191.       gdeflastsection{#1}%
  2192.     elseifxtemptypeYomitfromtockeyword
  2193.       % for @headings -- no section number, don't include in toc,
  2194.       % and don't redefine lastsection.
  2195.       setbox0 = hbox{}%
  2196.       deftoctype{omit}%
  2197.       letsectionlevel=empty
  2198.     elseifxtemptypeYappendixkeyword
  2199.       setbox0 = hbox{#4enspace}%
  2200.       deftoctype{app}%
  2201.       gdeflastsection{#1}%
  2202.     else
  2203.       setbox0 = hbox{#4enspace}%
  2204.       deftoctype{num}%
  2205.       gdeflastsection{#1}%
  2206.     fififi
  2207.     %
  2208.     % Write the toc entry (before donoderef).  See comments in chapmacro.
  2209.     writetocentry{toctypesectionlevel}{#1}{#4}%
  2210.     %
  2211.     % Write the node reference (= pdf destination for pdftex).
  2212.     % Again, see comments in chapmacro.
  2213.     donoderef{#3}%
  2214.     %
  2215.     % Interline glue will be inserted when the vbox is completed.
  2216.     % That glue will be a valid breakpoint for the page, since it'll be
  2217.     % preceded by a whatsit (usually from the donoderef, or from the
  2218.     % writetocentry if there was no node).  We don't want to allow that
  2219.     % break, since then the whatsits could end up on page n while the
  2220.     % section is on page n+1, thus toc/etc. are wrong.  Debian bug 276000.
  2221.     nobreak
  2222.     %
  2223.     % Output the actual section heading.
  2224.     vbox{hyphenpenalty=10000 tolerance=5000 parindent=0pt raggedright
  2225.           hangindent=wd0  % zero if no section number
  2226.           unhbox0 #1}%
  2227.   }%
  2228.   % Add extra space after the heading -- half of whatever came above it.
  2229.   % Don't allow stretch, though.
  2230.   kern .5 csname #2headingskipendcsname
  2231.   %
  2232.   % Do not let the kern be a potential breakpoint, as it would be if it
  2233.   % was followed by glue.
  2234.   nobreak
  2235.   %
  2236.   % We'll almost certainly start a paragraph next, so don't let that
  2237.   % glue accumulate.  (Not a breakpoint because it's preceded by a
  2238.   % discardable item.)
  2239.   vskip-parskip
  2240.   % 
  2241.   % This is purely so the last item on the list is a known penalty >
  2242.   % 10000.  This is so startdefun can avoid allowing breakpoints after
  2243.   % section headings.  Otherwise, it would insert a valid breakpoint between:
  2244.   % 
  2245.   %   @section sec-whatever
  2246.   %   @deffn def-whatever
  2247.   penalty 10001
  2248. }
  2249. message{toc,}
  2250. % Table of contents.
  2251. newwritetocfile
  2252. % Write an entry to the toc file, opening it if necessary.
  2253. % Called from @chapter, etc.
  2254. %
  2255. % Example usage: writetocentry{sec}{Section Name}{thechapno.thesecno}
  2256. % We append the current node name (if any) and page number as additional
  2257. % arguments for the {chap,sec,...}entry macros which will eventually
  2258. % read this.  The node name is used in the pdf outlines as the
  2259. % destination to jump to.
  2260. %
  2261. % We open the .toc file for writing here instead of at @setfilename (or
  2262. % any other fixed time) so that @contents can be anywhere in the document.
  2263. % But if #1 is `omit', then we don't do anything.  This is used for the
  2264. % table of contents chapter openings themselves.
  2265. %
  2266. newififtocfileopened
  2267. defomitkeyword{omit}%
  2268. %
  2269. defwritetocentry#1#2#3{%
  2270.   edefwritetoctype{#1}%
  2271.   ifxwritetoctypeomitkeyword else
  2272.     iftocfileopenedelse
  2273.       immediateopenouttocfile = jobname.toc
  2274.       globaltocfileopenedtrue
  2275.     fi
  2276.     %
  2277.     iflinks
  2278.       {atdummies
  2279.        edeftemp{%
  2280.          writetocfile{@#1entry{#2}{#3}{lastnode}{noexpandfolio}}}%
  2281.        temp
  2282.       }%
  2283.     fi
  2284.   fi
  2285.   %
  2286.   % Tell shipout to create a pdf destination on each page, if we're
  2287.   % writing pdf.  These are used in the table of contents.  We can't
  2288.   % just write one on every page because the title pages are numbered
  2289.   % 1 and 2 (the page numbers aren't printed), and so are the first
  2290.   % two pages of the document.  Thus, we'd have two destinations named
  2291.   % `1', and two named `2'.
  2292.   ifpdf globalpdfmakepagedesttrue fi
  2293. }
  2294. % These characters do not print properly in the Computer Modern roman
  2295. % fonts, so we must take special care.  This is more or less redundant
  2296. % with the Texinfo input format setup at the end of this file.
  2297. defactivecatcodes{%
  2298.   catcode`"=active
  2299.   catcode`$=active
  2300.   catcode`<=active
  2301.   catcode`>=active
  2302.   catcode`\=active
  2303.   catcode`^=active
  2304.   catcode`_=active
  2305.   catcode`|=active
  2306.   catcode`~=active
  2307. }
  2308. % Read the toc file, which is essentially Texinfo input.
  2309. defreadtocfile{%
  2310.   setupdatafile
  2311.   activecatcodes
  2312.   input tocreadfilename
  2313. }
  2314. newskipcontentsrightmargin contentsrightmargin=1in
  2315. newcountsavepageno
  2316. newcountlastnegativepageno lastnegativepageno = -1
  2317. % Prepare to read what we've written to tocfile.
  2318. %
  2319. defstartcontents#1{%
  2320.   % If @setchapternewpage on, and @headings double, the contents should
  2321.   % start on an odd page, unlike chapters.  Thus, we maintain
  2322.   % contentsalignmacro in parallel with pagealignmacro.
  2323.   % From: Torbjorn Granlund <tege@matematik.su.se>
  2324.   contentsalignmacro
  2325.   immediatecloseouttocfile
  2326.   %
  2327.   % Don't need to put `Contents' or `Short Contents' in the headline.
  2328.   % It is abundantly clear what they are.
  2329.   chapmacro{#1}{Yomitfromtoc}{}%
  2330.   %
  2331.   savepageno = pageno
  2332.   begingroup                  % Set up to handle contents files properly.
  2333.     raggedbottom              % Worry more about breakpoints than the bottom.
  2334.     advancehsize by -contentsrightmargin % Don't use the full line length.
  2335.     %
  2336.     % Roman numerals for page numbers.
  2337.     ifnum pageno>0 globalpageno = lastnegativepageno fi
  2338. }
  2339. % redefined for the two-volume lispref.  We always output on
  2340. % jobname.toc even if this is redefined.
  2341. deftocreadfilename{jobname.toc}
  2342. % Normal (long) toc.
  2343. %
  2344. defcontents{%
  2345.   startcontents{putwordTOC}%
  2346.     openin 1 tocreadfilenamespace
  2347.     ifeof 1 else
  2348.       readtocfile
  2349.     fi
  2350.     vfill eject
  2351.     contentsalignmacro % in case @setchapternewpage odd is in effect
  2352.     ifeof 1 else
  2353.       pdfmakeoutlines
  2354.     fi
  2355.     closein 1
  2356.   endgroup
  2357.   lastnegativepageno = pageno
  2358.   globalpageno = savepageno
  2359. }
  2360. % And just the chapters.
  2361. defsummarycontents{%
  2362.   startcontents{putwordShortTOC}%
  2363.     %
  2364.     letnumchapentry = shortchapentry
  2365.     letappentry = shortchapentry
  2366.     letunnchapentry = shortunnchapentry
  2367.     % We want a true roman here for the page numbers.
  2368.     secfonts
  2369.     letrm=shortcontrm letbf=shortcontbf
  2370.     letsl=shortcontsl lettt=shortconttt
  2371.     rm
  2372.     hyphenpenalty = 10000
  2373.     advancebaselineskip by 1pt % Open it up a little.
  2374.     defnumsecentry##1##2##3##4{}
  2375.     letappsecentry = numsecentry
  2376.     letunnsecentry = numsecentry
  2377.     letnumsubsecentry = numsecentry
  2378.     letappsubsecentry = numsecentry
  2379.     letunnsubsecentry = numsecentry
  2380.     letnumsubsubsecentry = numsecentry
  2381.     letappsubsubsecentry = numsecentry
  2382.     letunnsubsubsecentry = numsecentry
  2383.     openin 1 tocreadfilenamespace
  2384.     ifeof 1 else
  2385.       readtocfile
  2386.     fi
  2387.     closein 1
  2388.     vfill eject
  2389.     contentsalignmacro % in case @setchapternewpage odd is in effect
  2390.   endgroup
  2391.   lastnegativepageno = pageno
  2392.   globalpageno = savepageno
  2393. }
  2394. letshortcontents = summarycontents
  2395. % Typeset the label for a chapter or appendix for the short contents.
  2396. % The arg is, e.g., `A' for an appendix, or `3' for a chapter.
  2397. %
  2398. defshortchaplabel#1{%
  2399.   % This space should be enough, since a single number is .5em, and the
  2400.   % widest letter (M) is 1em, at least in the Computer Modern fonts.
  2401.   % But use hss just in case.
  2402.   % (This space doesn't include the extra space that gets added after
  2403.   % the label; that gets put in by shortchapentry above.)
  2404.   %
  2405.   % We'd like to right-justify chapter numbers, but that looks strange
  2406.   % with appendix letters.  And right-justifying numbers and
  2407.   % left-justifying letters looks strange when there is less than 10
  2408.   % chapters.  Have to read the whole toc once to know how many chapters
  2409.   % there are before deciding ...
  2410.   hbox to 1em{#1hss}%
  2411. }
  2412. % These macros generate individual entries in the table of contents.
  2413. % The first argument is the chapter or section name.
  2414. % The last argument is the page number.
  2415. % The arguments in between are the chapter number, section number, ...
  2416. % Chapters, in the main contents.
  2417. defnumchapentry#1#2#3#4{dochapentry{#2labelspace#1}{#4}}
  2418. %
  2419. % Chapters, in the short toc.
  2420. % See comments in dochapentry re vbox and related settings.
  2421. defshortchapentry#1#2#3#4{%
  2422.   tocentry{shortchaplabel{#2}labelspace #1}{doshortpagenobgroup#4egroup}%
  2423. }
  2424. % Appendices, in the main contents.
  2425. % Need the word Appendix, and a fixed-size box.
  2426. %
  2427. defappendixbox#1{%
  2428.   % We use M since it's probably the widest letter.
  2429.   setbox0 = hbox{putwordAppendix{} M}%
  2430.   hbox to wd0{putwordAppendix{} #1hss}}
  2431. %
  2432. defappentry#1#2#3#4{dochapentry{appendixbox{#2}labelspace#1}{#4}}
  2433. % Unnumbered chapters.
  2434. defunnchapentry#1#2#3#4{dochapentry{#1}{#4}}
  2435. defshortunnchapentry#1#2#3#4{tocentry{#1}{doshortpagenobgroup#4egroup}}
  2436. % Sections.
  2437. defnumsecentry#1#2#3#4{dosecentry{#2labelspace#1}{#4}}
  2438. letappsecentry=numsecentry
  2439. defunnsecentry#1#2#3#4{dosecentry{#1}{#4}}
  2440. % Subsections.
  2441. defnumsubsecentry#1#2#3#4{dosubsecentry{#2labelspace#1}{#4}}
  2442. letappsubsecentry=numsubsecentry
  2443. defunnsubsecentry#1#2#3#4{dosubsecentry{#1}{#4}}
  2444. % And subsubsections.
  2445. defnumsubsubsecentry#1#2#3#4{dosubsubsecentry{#2labelspace#1}{#4}}
  2446. letappsubsubsecentry=numsubsubsecentry
  2447. defunnsubsubsecentry#1#2#3#4{dosubsubsecentry{#1}{#4}}
  2448. % This parameter controls the indentation of the various levels.
  2449. % Same as defaultparindent.
  2450. newdimentocindent tocindent = 15pt
  2451. % Now for the actual typesetting. In all these, #1 is the text and #2 is the
  2452. % page number.
  2453. %
  2454. % If the toc has to be broken over pages, we want it to be at chapters
  2455. % if at all possible; hence the penalty.
  2456. defdochapentry#1#2{%
  2457.    penalty-300 vskip1baselineskip plus.33baselineskip minus.25baselineskip
  2458.    begingroup
  2459.      chapentryfonts
  2460.      tocentry{#1}{dopagenobgroup#2egroup}%
  2461.    endgroup
  2462.    nobreakvskip .25baselineskip plus.1baselineskip
  2463. }
  2464. defdosecentry#1#2{begingroup
  2465.   secentryfonts leftskip=tocindent
  2466.   tocentry{#1}{dopagenobgroup#2egroup}%
  2467. endgroup}
  2468. defdosubsecentry#1#2{begingroup
  2469.   subsecentryfonts leftskip=2tocindent
  2470.   tocentry{#1}{dopagenobgroup#2egroup}%
  2471. endgroup}
  2472. defdosubsubsecentry#1#2{begingroup
  2473.   subsubsecentryfonts leftskip=3tocindent
  2474.   tocentry{#1}{dopagenobgroup#2egroup}%
  2475. endgroup}
  2476. % We use the same entry macro as for the index entries.
  2477. lettocentry = entry
  2478. % Space between chapter (or whatever) number and the title.
  2479. deflabelspace{hskip1em relax}
  2480. defdopageno#1{{rm #1}}
  2481. defdoshortpageno#1{{rm #1}}
  2482. defchapentryfonts{secfonts rm}
  2483. defsecentryfonts{textfonts}
  2484. defsubsecentryfonts{textfonts}
  2485. defsubsubsecentryfonts{textfonts}
  2486. message{environments,}
  2487. % @foo ... @end foo.
  2488. % @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
  2489. %
  2490. % Since these characters are used in examples, they should be an even number of
  2491. % tt widths. Each tt character is 1en, so two makes it 1em.
  2492. %
  2493. defpoint{$star$}
  2494. defarrow{leavevmoderaise.05exhbox to 1em{hfil$rightarrow$hfil}}
  2495. defresult{leavevmoderaise.05exhbox to 1em{hfil$Rightarrow$hfil}}
  2496. defexpansion{leavevmodehbox to 1em{hfil$mapsto$hfil}}
  2497. defprint{leavevmodelower.1exhbox to 1em{hfil$dashv$hfil}}
  2498. defequiv{leavevmodehbox to 1em{hfil$ptexequiv$hfil}}
  2499. % The @error{} command.
  2500. % Adapted from the TeXbook's boxit.
  2501. %
  2502. newboxerrorbox
  2503. %
  2504. {tentt globaldimen0 = 3em}% Width of the box.
  2505. dimen2 = .55pt % Thickness of rules
  2506. % The text. (`r' is open on the right, `e' somewhat less so on the left.)
  2507. setbox0 = hbox{kern-.75pt reducedsf errorkern-1.5pt}
  2508. %
  2509. setboxerrorbox=hbox to dimen0{hfil
  2510.    hsize = dimen0 advancehsize by -5.8pt % Space to left+right.
  2511.    advancehsize by -2dimen2 % Rules.
  2512.    vbox{%
  2513.       hrule heightdimen2
  2514.       hbox{vrule widthdimen2 kern3pt          % Space to left of text.
  2515.          vtop{kern2.4pt box0 kern2.4pt}% Space above/below.
  2516.          kern3ptvrule widthdimen2}% Space to right.
  2517.       hrule heightdimen2}
  2518.     hfil}
  2519. %
  2520. deferror{leavevmodelower.7excopyerrorbox}
  2521. % @tex ... @end tex    escapes into raw Tex temporarily.
  2522. % One exception: @ is still an escape character, so that @end tex works.
  2523. % But @ or @@ will get a plain tex @ character.
  2524. envdeftex{%
  2525.   catcode `\=0 catcode `{=1 catcode `}=2
  2526.   catcode `$=3 catcode `&=4 catcode `#=6
  2527.   catcode `^=7 catcode `_=8 catcode `~=active let~=tie
  2528.   catcode `%=14
  2529.   catcode `+=other
  2530.   catcode `"=other
  2531.   catcode `|=other
  2532.   catcode `<=other
  2533.   catcode `>=other
  2534.   escapechar=`\
  2535.   %
  2536.   letb=ptexb
  2537.   letbullet=ptexbullet
  2538.   letc=ptexc
  2539.   let,=ptexcomma
  2540.   let.=ptexdot
  2541.   letdots=ptexdots
  2542.   letequiv=ptexequiv
  2543.   let!=ptexexclam
  2544.   leti=ptexi
  2545.   letindent=ptexindent
  2546.   letnoindent=ptexnoindent
  2547.   let{=ptexlbrace
  2548.   let+=tabalign
  2549.   let}=ptexrbrace
  2550.   let/=ptexslash
  2551.   let*=ptexstar
  2552.   lett=ptext
  2553.   expandafter letcsname topendcsname=ptextop  % outer
  2554.   letfrenchspacing=plainfrenchspacing
  2555.   %
  2556.   defendldots{mathinner{ldotsldotsldotsldots}}%
  2557.   defenddots{relaxifmmodeendldotselse$mathsurround=0pt endldots,$fi}%
  2558.   def@{@}%
  2559. }
  2560. % There is no need to define Etex.
  2561. % Define @lisp ... @end lisp.
  2562. % @lisp environment forms a group so it can rebind things,
  2563. % including the definition of @end lisp (which normally is erroneous).
  2564. % Amount to narrow the margins by for @lisp.
  2565. newskiplispnarrowing lispnarrowing=0.4in
  2566. % This is the definition that ^^M gets inside @lisp, @example, and other
  2567. % such environments.  null is better than a space, since it doesn't
  2568. % have any width.
  2569. deflisppar{nullendgraf}
  2570. % This space is always present above and below environments.
  2571. newskipenvskipamount envskipamount = 0pt
  2572. % Make spacing and below environment symmetrical.  We use parskip here
  2573. % to help in doing that, since in @example-like environments parskip
  2574. % is reset to zero; thus the afterenvbreak inserts no space -- but the
  2575. % start of the next paragraph will insert parskip.
  2576. %
  2577. defaboveenvbreak{{%
  2578.   % =10000 instead of <10000 because of a special case in itemzzz and
  2579.   % sectionheading, q.v.
  2580.   ifnum lastpenalty=10000 else
  2581.     advanceenvskipamount by parskip
  2582.     endgraf
  2583.     ifdimlastskip<envskipamount
  2584.       removelastskip
  2585.       % it's not a good place to break if the last penalty was nobreak
  2586.       % or better ...
  2587.       ifnumlastpenalty<10000 penalty-50 fi
  2588.       vskipenvskipamount
  2589.     fi
  2590.   fi
  2591. }}
  2592. letafterenvbreak = aboveenvbreak
  2593. % nonarrowing is a flag.  If "set", @lisp etc don't narrow margins; it will
  2594. % also clear it, so that its embedded environments do the narrowing again.
  2595. letnonarrowing=relax
  2596. % @cartouche ... @end cartouche: draw rectangle w/rounded corners around
  2597. % environment contents.
  2598. fontcircle=lcircle10
  2599. newdimencircthick
  2600. newdimencartouternewdimencartinner
  2601. newskipnormbskipnewskipnormpskipnewskipnormlskip
  2602. circthick=fontdimen8circle
  2603. %
  2604. defctl{{circlechar'013hskip -6pt}}% 6pt from pl file: 1/2charwidth
  2605. defctr{{hskip 6ptcirclechar'010}}
  2606. defcbl{{circlechar'012hskip -6pt}}
  2607. defcbr{{hskip 6ptcirclechar'011}}
  2608. defcarttop{hbox to cartouter{hskiplskip
  2609.         ctlleadershrule heightcircthickhfilctr
  2610.         hskiprskip}}
  2611. defcartbot{hbox to cartouter{hskiplskip
  2612.         cblleadershrule heightcircthickhfilcbr
  2613.         hskiprskip}}
  2614. %
  2615. newskiplskipnewskiprskip
  2616. envdefcartouche{%
  2617.   ifhmodeparfi  % can't be in the midst of a paragraph.
  2618.   startsavinginserts
  2619.   lskip=leftskip rskip=rightskip
  2620.   leftskip=0ptrightskip=0pt % we want these *outside*.
  2621.   cartinner=hsize advancecartinner by-lskip
  2622.   advancecartinner by-rskip
  2623.   cartouter=hsize
  2624.   advancecartouter by 18.4pt % allow for 3pt kerns on either
  2625. % side, and for 6pt waste from
  2626. % each corner char, and rule thickness
  2627.   normbskip=baselineskip normpskip=parskip normlskip=lineskip
  2628.   % Flag to tell @lisp, etc., not to narrow margin.
  2629.   letnonarrowing = t%
  2630.   vboxbgroup
  2631.       baselineskip=0ptparskip=0ptlineskip=0pt
  2632.       carttop
  2633.       hboxbgroup
  2634.   hskiplskip
  2635.   vrulekern3pt
  2636.   vboxbgroup
  2637.       kern3pt
  2638.       hsize=cartinner
  2639.       baselineskip=normbskip
  2640.       lineskip=normlskip
  2641.       parskip=normpskip
  2642.       vskip -parskip
  2643.       comment % For explanation, see the end of defgroup.
  2644. }
  2645. defEcartouche{%
  2646.               ifhmodeparfi
  2647.       kern3pt
  2648.   egroup
  2649.   kern3ptvrule
  2650.   hskiprskip
  2651.       egroup
  2652.       cartbot
  2653.   egroup
  2654.   checkinserts
  2655. }
  2656. % This macro is called at the beginning of all the @example variants,
  2657. % inside a group.
  2658. defnonfillstart{%
  2659.   aboveenvbreak
  2660.   hfuzz = 12pt % Don't be fussy
  2661.   sepspaces % Make spaces be word-separators rather than space tokens.
  2662.   letpar = lisppar % don't ignore blank lines
  2663.   obeylines % each line of input is a line of output
  2664.   parskip = 0pt
  2665.   parindent = 0pt
  2666.   emergencystretch = 0pt % don't try to avoid overfull boxes
  2667.   ifxnonarrowingrelax
  2668.     advance leftskip by lispnarrowing
  2669.     exdentamount=lispnarrowing
  2670.   else
  2671.     letnonarrowing = relax
  2672.   fi
  2673.   letexdent=nofillexdent
  2674. }
  2675. % If you want all examples etc. small: @set dispenvsize small.
  2676. % If you want even small examples the full size: @set dispenvsize nosmall.
  2677. % This affects the following displayed environments:
  2678. %    @example, @display, @format, @lisp
  2679. %
  2680. defsmallword{small}
  2681. defnosmallword{nosmall}
  2682. letSETdispenvsizerelax
  2683. defsetnormaldispenv{%
  2684.   ifxSETdispenvsizesmallword
  2685.     % end paragraph for sake of leading, in case document has no blank
  2686.     % line.  This is redundant with what happens in aboveenvbreak, but
  2687.     % we need to do it before changing the fonts, and it's inconvenient
  2688.     % to change the fonts afterward.
  2689.     ifnum lastpenalty=10000 else endgraf fi
  2690.     smallexamplefonts rm
  2691.   fi
  2692. }
  2693. defsetsmalldispenv{%
  2694.   ifxSETdispenvsizenosmallword
  2695.   else
  2696.     ifnum lastpenalty=10000 else endgraf fi
  2697.     smallexamplefonts rm
  2698.   fi
  2699. }
  2700. % We often define two environments, @foo and @smallfoo.
  2701. % Let's do it by one command:
  2702. defmakedispenv #1#2{
  2703.   expandafterenvdefcsname#1endcsname {setnormaldispenv #2}
  2704.   expandafterenvdefcsname small#1endcsname {setsmalldispenv #2}
  2705.   expandafterletcsname E#1endcsname afterenvbreak
  2706.   expandafterletcsname Esmall#1endcsname afterenvbreak
  2707. }
  2708. % Define two synonyms:
  2709. defmaketwodispenvs #1#2#3{
  2710.   makedispenv{#1}{#3}
  2711.   makedispenv{#2}{#3}
  2712. }
  2713. % @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
  2714. %
  2715. % @smallexample and @smalllisp: use smaller fonts.
  2716. % Originally contributed by Pavel@xerox.
  2717. %
  2718. maketwodispenvs {lisp}{example}{%
  2719.   nonfillstart
  2720.   ttquoteexpand
  2721.   letkbdfont = kbdexamplefont % Allow @kbd to do something special.
  2722.   gobble       % eat return
  2723. }
  2724. % @display/@smalldisplay: same as @lisp except keep current font.
  2725. %
  2726. makedispenv {display}{%
  2727.   nonfillstart
  2728.   gobble
  2729. }
  2730. % @format/@smallformat: same as @display except don't narrow margins.
  2731. %
  2732. makedispenv{format}{%
  2733.   letnonarrowing = t%
  2734.   nonfillstart
  2735.   gobble
  2736. }
  2737. % @flushleft: same as @format, but doesn't obey SETdispenvsize.
  2738. envdefflushleft{%
  2739.   letnonarrowing = t%
  2740.   nonfillstart
  2741.   gobble
  2742. }
  2743. letEflushleft = afterenvbreak
  2744. % @flushright.
  2745. %
  2746. envdefflushright{%
  2747.   letnonarrowing = t%
  2748.   nonfillstart
  2749.   advanceleftskip by 0pt plus 1fill
  2750.   gobble
  2751. }
  2752. letEflushright = afterenvbreak
  2753. % @quotation does normal linebreaking (hence we can't use nonfillstart)
  2754. % and narrows the margins.  We keep parskip nonzero in general, since
  2755. % we're doing normal filling.  So, when using aboveenvbreak and
  2756. % afterenvbreak, temporarily make parskip 0.
  2757. %
  2758. envdefquotation{%
  2759.   {parskip=0pt aboveenvbreak}% because aboveenvbreak inserts parskip
  2760.   parindent=0pt
  2761.   %
  2762.   % @cartouche defines nonarrowing to inhibit narrowing at next level down.
  2763.   ifxnonarrowingrelax
  2764.     advanceleftskip by lispnarrowing
  2765.     advancerightskip by lispnarrowing
  2766.     exdentamount = lispnarrowing
  2767.   else
  2768.     letnonarrowing = relax
  2769.   fi
  2770.   parseargquotationlabel
  2771. }
  2772. % We have retained a nonzero parskip for the environment, since we're
  2773. % doing normal filling.
  2774. %
  2775. defEquotation{%
  2776.   par
  2777.   ifxquotationauthorundefinedelse
  2778.     % indent a bit.
  2779.     leftline{kern 2leftskip sl ---quotationauthor}%
  2780.   fi
  2781.   {parskip=0pt afterenvbreak}%
  2782. }
  2783. % If we're given an argument, typeset it in bold with a colon after.