texinfo.tex
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:184k
源码类别:

网络

开发平台:

Unix_Linux

  1.   % don't both fit on one line.  In that case, bob suggests starting the
  2.   % dots pretty far over on the line.  Unfortunately, a large
  3.   % indentation looks wrong when the entry text itself is broken across
  4.   % lines.  So we use a small indentation and put up with long leaders.
  5.   %
  6.   % hangafter is reset to 1 (which is the value we want) at the start
  7.   % of each paragraph, so we need not do anything with that.
  8.   hangindent = 2em
  9.   %
  10.   % When the entry text needs to be broken, just fill out the first line
  11.   % with blank space.
  12.   rightskip = 0pt plus1fil
  13.   %
  14.   % A bit of stretch before each entry for the benefit of balancing columns.
  15.   vskip 0pt plus1pt
  16.   %
  17.   % Start a ``paragraph'' for the index entry so the line breaking
  18.   % parameters we've set above will have an effect.
  19.   noindent
  20.   %
  21.   % Insert the text of the index entry.  TeX will do line-breaking on it.
  22.   #1%
  23.   % The following is kludged to not output a line of dots in the index if
  24.   % there are no page numbers.  The next person who breaks this will be
  25.   % cursed by a Unix daemon.
  26.   deftempa{{rm }}%
  27.   deftempb{#2}%
  28.   edeftempc{tempa}%
  29.   edeftempd{tempb}%
  30.   ifxtempctempd else%
  31.     %
  32.     % If we must, put the page number on a line of its own, and fill out
  33.     % this line with blank space.  (The hfil is overwhelmed with the
  34.     % fill leaders glue in indexdotfill if the page number does fit.)
  35.     hfilpenalty50
  36.     nullnobreakindexdotfill % Have leaders before the page number.
  37.     %
  38.     % The ` ' here is removed by the implicit unskip that TeX does as
  39.     % part of (the primitive) par.  Without it, a spurious underfull
  40.     % hbox ensues.
  41.      #2% The page number ends the paragraph.
  42.   fi%
  43.   par
  44. endgroup}
  45. % Like dotfill except takes at least 1 em.
  46. defindexdotfill{cleaders
  47.   hbox{$mathsurround=0pt mkern1.5mu ${it .}$ mkern1.5mu$}hskip 1em plus 1fill}
  48. defprimary #1{line{#1hfil}}
  49. newskipsecondaryindent secondaryindent=0.5cm
  50. defsecondary #1#2{
  51. {parfillskip=0in parskip=0in
  52. hangindent =1in hangafter=1
  53. noindenthskipsecondaryindenthbox{#1}indexdotfill #2par
  54. }}
  55. % Define two-column mode, which we use to typeset indexes.
  56. % Adapted from the TeXbook, page 416, which is to say,
  57. % the manmac.tex format used to print the TeXbook itself.
  58. catcode`@=11
  59. newboxpartialpage
  60. newdimendoublecolumnhsize
  61. defbegindoublecolumns{begingroup % ended by enddoublecolumns
  62.   % Grab any single-column material above us.
  63.   output = {%
  64.     %
  65.     % Here is a possibility not foreseen in manmac: if we accumulate a
  66.     % whole lot of material, we might end up calling this output
  67.     % routine twice in a row (see the doublecol-lose test, which is
  68.     % essentially a couple of indexes with @setchapternewpage off).  In
  69.     % that case we just ship out what is in partialpage with the normal
  70.     % output routine.  Generally, partialpage will be empty when this
  71.     % runs and this will be a no-op.  See the indexspread.tex test case.
  72.     ifvoidpartialpage else
  73.       onepageout{pagecontentspartialpage}%
  74.     fi
  75.     %
  76.     globalsetboxpartialpage = vbox{%
  77.       % Unvbox the main output page.
  78.       unvboxPAGE
  79.       kern-topskip kernbaselineskip
  80.     }%
  81.   }%
  82.   eject % run that output routine to set partialpage
  83.   %
  84.   % Use the double-column output routine for subsequent pages.
  85.   output = {doublecolumnout}%
  86.   %
  87.   % Change the page size parameters.  We could do this once outside this
  88.   % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
  89.   % format, but then we repeat the same computation.  Repeating a couple
  90.   % of assignments once per index is clearly meaningless for the
  91.   % execution time, so we may as well do it in one place.
  92.   %
  93.   % First we halve the line length, less a little for the gutter between
  94.   % the columns.  We compute the gutter based on the line length, so it
  95.   % changes automatically with the paper format.  The magic constant
  96.   % below is chosen so that the gutter has the same value (well, +-<1pt)
  97.   % as it did when we hard-coded it.
  98.   %
  99.   % We put the result in a separate register, doublecolumhsize, so we
  100.   % can restore it in pagesofar, after hsize itself has (potentially)
  101.   % been clobbered.
  102.   %
  103.   doublecolumnhsize = hsize
  104.     advancedoublecolumnhsize by -.04154hsize
  105.     dividedoublecolumnhsize by 2
  106.   hsize = doublecolumnhsize
  107.   %
  108.   % Double the vsize as well.  (We don't need a separate register here,
  109.   % since nobody clobbers vsize.)
  110.   advancevsize by -htpartialpage
  111.   vsize = 2vsize
  112. }
  113. % The double-column output routine for all double-column pages except
  114. % the last.
  115. %
  116. defdoublecolumnout{%
  117.   splittopskip=topskip splitmaxdepth=maxdepth
  118.   % Get the available space for the double columns -- the normal
  119.   % (undoubled) page height minus any material left over from the
  120.   % previous page.
  121.   dimen@ = vsize
  122.   dividedimen@ by 2
  123.   %
  124.   % box0 will be the left-hand column, box2 the right.
  125.   setbox0=vsplit255 todimen@ setbox2=vsplit255 todimen@
  126.   onepageoutpagesofar
  127.   unvbox255
  128.   penaltyoutputpenalty
  129. }
  130. defpagesofar{%
  131.   % Re-output the contents of the output page -- any previous material,
  132.   % followed by the two boxes we just split, in box0 and box2.
  133.   unvboxpartialpage
  134.   %
  135.   hsize = doublecolumnhsize
  136.   wd0=hsize wd2=hsize
  137.   hbox topagewidth{box0hfilbox2}%
  138. }
  139. defenddoublecolumns{%
  140.   output = {%
  141.     % Split the last of the double-column material.  Leave it on the
  142.     % current page, no automatic page break.
  143.     balancecolumns
  144.     %
  145.     % If we end up splitting too much material for the current page,
  146.     % though, there will be another page break right after this output
  147.     % invocation ends.  Having called balancecolumns once, we do not
  148.     % want to call it again.  Therefore, reset output to its normal
  149.     % definition right away.  (We hope balancecolumns will never be
  150.     % called on to balance too much material, but if it is, this makes
  151.     % the output somewhat more palatable.)
  152.     globaloutput = {onepageout{pagecontentsPAGE}}%
  153.   }%
  154.   eject
  155.   endgroup % started in begindoublecolumns
  156.   %
  157.   % pagegoal was set to the doubled vsize above, since we restarted
  158.   % the current page.  We're now back to normal single-column
  159.   % typesetting, so reset pagegoal to the normal vsize (after the
  160.   % endgroup where vsize got restored).
  161.   pagegoal = vsize
  162. }
  163. defbalancecolumns{%
  164.   % Called at the end of the double column material.
  165.   setbox0 = vbox{unvbox255}% like box255 but more efficient, see p.120.
  166.   dimen@ = ht0
  167.   advancedimen@ by topskip
  168.   advancedimen@ by-baselineskip
  169.   dividedimen@ by 2 % target to split to
  170.   %debugmessage{final 2-column material height=theht0, target=thedimen@.}%
  171.   splittopskip = topskip
  172.   % Loop until we get a decent breakpoint.
  173.   {%
  174.     vbadness = 10000
  175.     loop
  176.       globalsetbox3 = copy0
  177.       globalsetbox1 = vsplit3 to dimen@
  178.     ifdimht3>dimen@
  179.       globaladvancedimen@ by 1pt
  180.     repeat
  181.   }%
  182.   %debugmessage{split to thedimen@, column heights: theht1, theht3.}%
  183.   setbox0=vbox todimen@{unvbox1}%
  184.   setbox2=vbox todimen@{unvbox3}%
  185.   %
  186.   pagesofar
  187. }
  188. catcode`@ = other
  189. message{sectioning,}
  190. % Define chapters, sections, etc.
  191. newcountchapno
  192. newcountsecno        secno=0
  193. newcountsubsecno     subsecno=0
  194. newcountsubsubsecno  subsubsecno=0
  195. % This counter is funny since it counts through charcodes of letters A, B, ...
  196. newcountappendixno  appendixno = `@
  197. defappendixletter{chartheappendixno}
  198. % Each @chapter defines this as the name of the chapter.
  199. % page headings and footings can use it.  @section does likewise.
  200. defthischapter{}
  201. defthissection{}
  202. newcountabsseclevel % used to calculate proper heading level
  203. newcountsecbasesecbase=0 % @raise/lowersections modify this count
  204. % @raisesections: treat @section as chapter, @subsection as section, etc.
  205. defraisesections{globaladvancesecbase by -1}
  206. letup=raisesections % original BFox name
  207. % @lowersections: treat @chapter as section, @section as subsection, etc.
  208. deflowersections{globaladvancesecbase by 1}
  209. letdown=lowersections % original BFox name
  210. % Choose a numbered-heading macro
  211. % #1 is heading level if unmodified by @raisesections or @lowersections
  212. % #2 is text for heading
  213. defnumhead#1#2{absseclevel=secbaseadvanceabsseclevel by #1
  214. ifcaseabsseclevel
  215.   chapterzzz{#2}
  216. or
  217.   seczzz{#2}
  218. or
  219.   numberedsubseczzz{#2}
  220. or
  221.   numberedsubsubseczzz{#2}
  222. else
  223.   ifnum absseclevel<0
  224.     chapterzzz{#2}
  225.   else
  226.     numberedsubsubseczzz{#2}
  227.   fi
  228. fi
  229. }
  230. % like numhead, but chooses appendix heading levels
  231. defapphead#1#2{absseclevel=secbaseadvanceabsseclevel by #1
  232. ifcaseabsseclevel
  233.   appendixzzz{#2}
  234. or
  235.   appendixsectionzzz{#2}
  236. or
  237.   appendixsubseczzz{#2}
  238. or
  239.   appendixsubsubseczzz{#2}
  240. else
  241.   ifnum absseclevel<0
  242.     appendixzzz{#2}
  243.   else
  244.     appendixsubsubseczzz{#2}
  245.   fi
  246. fi
  247. }
  248. % like numhead, but chooses numberless heading levels
  249. defunnmhead#1#2{absseclevel=secbaseadvanceabsseclevel by #1
  250. ifcaseabsseclevel
  251.   unnumberedzzz{#2}
  252. or
  253.   unnumberedseczzz{#2}
  254. or
  255.   unnumberedsubseczzz{#2}
  256. or
  257.   unnumberedsubsubseczzz{#2}
  258. else
  259.   ifnum absseclevel<0
  260.     unnumberedzzz{#2}
  261.   else
  262.     unnumberedsubsubseczzz{#2}
  263.   fi
  264. fi
  265. }
  266. % @chapter, @appendix, @unnumbered.
  267. defthischaptername{No Chapter Title}
  268. outerdefchapter{parseargchapteryyy}
  269. defchapteryyy #1{numhead0{#1}} % normally numhead0 calls chapterzzz
  270. defchapterzzz #1{%
  271. secno=0 subsecno=0 subsubsecno=0
  272. globaladvance chapno by 1 message{putwordChapterspace thechapno}%
  273. chapmacro {#1}{thechapno}%
  274. gdefthissection{#1}%
  275. gdefthischaptername{#1}%
  276. % We don't substitute the actual chapter name into thischapter
  277. % because we don't want its macros evaluated now.
  278. xdefthischapter{putwordChapter{} thechapno: noexpandthischaptername}%
  279. toks0 = {#1}%
  280. edeftemp{noexpandwritetocentry{realbackslash chapentry{thetoks0}%
  281.                                   {thechapno}}}%
  282. temp
  283. donoderef
  284. globalletsection = numberedsec
  285. globalletsubsection = numberedsubsec
  286. globalletsubsubsection = numberedsubsubsec
  287. }
  288. outerdefappendix{parseargappendixyyy}
  289. defappendixyyy #1{apphead0{#1}} % normally apphead0 calls appendixzzz
  290. defappendixzzz #1{%
  291. secno=0 subsecno=0 subsubsecno=0
  292. globaladvance appendixno by 1
  293. message{putwordAppendixspace appendixletter}%
  294. chapmacro {#1}{putwordAppendix{} appendixletter}%
  295. gdefthissection{#1}%
  296. gdefthischaptername{#1}%
  297. xdefthischapter{putwordAppendix{} appendixletter: noexpandthischaptername}%
  298. toks0 = {#1}%
  299. edeftemp{noexpandwritetocentry{realbackslash chapentry{thetoks0}%
  300.                        {putwordAppendix{} appendixletter}}}%
  301. temp
  302. appendixnoderef
  303. globalletsection = appendixsec
  304. globalletsubsection = appendixsubsec
  305. globalletsubsubsection = appendixsubsubsec
  306. }
  307. % @centerchap is like @unnumbered, but the heading is centered.
  308. outerdefcenterchap{parseargcenterchapyyy}
  309. defcenterchapyyy #1{{letunnumbchapmacro=centerchapmacro unnumberedyyy{#1}}}
  310. % @top is like @unnumbered.
  311. outerdeftop{parseargunnumberedyyy}
  312. outerdefunnumbered{parseargunnumberedyyy}
  313. defunnumberedyyy #1{unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
  314. defunnumberedzzz #1{%
  315. secno=0 subsecno=0 subsubsecno=0
  316. %
  317. % This used to be simply message{#1}, but TeX fully expands the
  318. % argument to message.  Therefore, if #1 contained @-commands, TeX
  319. % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
  320. % expanded @cite (which turns out to cause errors because cite is meant
  321. % to be executed, not expanded).
  322. %
  323. % Anyway, we don't want the fully-expanded definition of @cite to appear
  324. % as a result of the message, we just want `@cite' itself.  We use
  325. % the<toks register> to achieve this: TeX expands the<toks> only once,
  326. % simply yielding the contents of <toks register>.  (We also do this for
  327. % the toc entries.)
  328. toks0 = {#1}message{(thetoks0)}%
  329. %
  330. unnumbchapmacro {#1}%
  331. gdefthischapter{#1}gdefthissection{#1}%
  332. toks0 = {#1}%
  333. edeftemp{noexpandwritetocentry{realbackslash unnumbchapentry{thetoks0}}}%
  334. temp
  335. unnumbnoderef
  336. globalletsection = unnumberedsec
  337. globalletsubsection = unnumberedsubsec
  338. globalletsubsubsection = unnumberedsubsubsec
  339. }
  340. % Sections.
  341. outerdefnumberedsec{parseargsecyyy}
  342. defsecyyy #1{numhead1{#1}} % normally calls seczzz
  343. defseczzz #1{%
  344. subsecno=0 subsubsecno=0 globaladvance secno by 1 %
  345. gdefthissection{#1}secheading {#1}{thechapno}{thesecno}%
  346. toks0 = {#1}%
  347. edeftemp{noexpandwritetocentry{realbackslash secentry{thetoks0}%
  348.                                   {thechapno}{thesecno}}}%
  349. temp
  350. donoderef
  351. nobreak
  352. }
  353. outerdefappendixsection{parseargappendixsecyyy}
  354. outerdefappendixsec{parseargappendixsecyyy}
  355. defappendixsecyyy #1{apphead1{#1}} % normally calls appendixsectionzzz
  356. defappendixsectionzzz #1{%
  357. subsecno=0 subsubsecno=0 globaladvance secno by 1 %
  358. gdefthissection{#1}secheading {#1}{appendixletter}{thesecno}%
  359. toks0 = {#1}%
  360. edeftemp{noexpandwritetocentry{realbackslash secentry{thetoks0}%
  361.                                   {appendixletter}{thesecno}}}%
  362. temp
  363. appendixnoderef
  364. nobreak
  365. }
  366. outerdefunnumberedsec{parseargunnumberedsecyyy}
  367. defunnumberedsecyyy #1{unnmhead1{#1}} % normally calls unnumberedseczzz
  368. defunnumberedseczzz #1{%
  369. plainsecheading {#1}gdefthissection{#1}%
  370. toks0 = {#1}%
  371. edeftemp{noexpandwritetocentry{realbackslash unnumbsecentry{thetoks0}}}%
  372. temp
  373. unnumbnoderef
  374. nobreak
  375. }
  376. % Subsections.
  377. outerdefnumberedsubsec{parseargnumberedsubsecyyy}
  378. defnumberedsubsecyyy #1{numhead2{#1}} % normally calls numberedsubseczzz
  379. defnumberedsubseczzz #1{%
  380. gdefthissection{#1}subsubsecno=0 globaladvance subsecno by 1 %
  381. subsecheading {#1}{thechapno}{thesecno}{thesubsecno}%
  382. toks0 = {#1}%
  383. edeftemp{noexpandwritetocentry{realbackslash subsecentry{thetoks0}%
  384.                                     {thechapno}{thesecno}{thesubsecno}}}%
  385. temp
  386. donoderef
  387. nobreak
  388. }
  389. outerdefappendixsubsec{parseargappendixsubsecyyy}
  390. defappendixsubsecyyy #1{apphead2{#1}} % normally calls appendixsubseczzz
  391. defappendixsubseczzz #1{%
  392. gdefthissection{#1}subsubsecno=0 globaladvance subsecno by 1 %
  393. subsecheading {#1}{appendixletter}{thesecno}{thesubsecno}%
  394. toks0 = {#1}%
  395. edeftemp{noexpandwritetocentry{realbackslash subsecentry{thetoks0}%
  396.                                 {appendixletter}{thesecno}{thesubsecno}}}%
  397. temp
  398. appendixnoderef
  399. nobreak
  400. }
  401. outerdefunnumberedsubsec{parseargunnumberedsubsecyyy}
  402. defunnumberedsubsecyyy #1{unnmhead2{#1}} %normally calls unnumberedsubseczzz
  403. defunnumberedsubseczzz #1{%
  404. plainsubsecheading {#1}gdefthissection{#1}%
  405. toks0 = {#1}%
  406. edeftemp{noexpandwritetocentry{realbackslash unnumbsubsecentry%
  407.                                     {thetoks0}}}%
  408. temp
  409. unnumbnoderef
  410. nobreak
  411. }
  412. % Subsubsections.
  413. outerdefnumberedsubsubsec{parseargnumberedsubsubsecyyy}
  414. defnumberedsubsubsecyyy #1{numhead3{#1}} % normally numberedsubsubseczzz
  415. defnumberedsubsubseczzz #1{%
  416. gdefthissection{#1}globaladvance subsubsecno by 1 %
  417. subsubsecheading {#1}
  418.   {thechapno}{thesecno}{thesubsecno}{thesubsubsecno}%
  419. toks0 = {#1}%
  420. edeftemp{noexpandwritetocentry{realbackslash subsubsecentry{thetoks0}%
  421.   {thechapno}{thesecno}{thesubsecno}{thesubsubsecno}}}%
  422. temp
  423. donoderef
  424. nobreak
  425. }
  426. outerdefappendixsubsubsec{parseargappendixsubsubsecyyy}
  427. defappendixsubsubsecyyy #1{apphead3{#1}} % normally appendixsubsubseczzz
  428. defappendixsubsubseczzz #1{%
  429. gdefthissection{#1}globaladvance subsubsecno by 1 %
  430. subsubsecheading {#1}
  431.   {appendixletter}{thesecno}{thesubsecno}{thesubsubsecno}%
  432. toks0 = {#1}%
  433. edeftemp{noexpandwritetocentry{realbackslash subsubsecentry{thetoks0}%
  434.   {appendixletter}{thesecno}{thesubsecno}{thesubsubsecno}}}%
  435. temp
  436. appendixnoderef
  437. nobreak
  438. }
  439. outerdefunnumberedsubsubsec{parseargunnumberedsubsubsecyyy}
  440. defunnumberedsubsubsecyyy #1{unnmhead3{#1}} %normally unnumberedsubsubseczzz
  441. defunnumberedsubsubseczzz #1{%
  442. plainsubsubsecheading {#1}gdefthissection{#1}%
  443. toks0 = {#1}%
  444. edeftemp{noexpandwritetocentry{realbackslash unnumbsubsubsecentry%
  445.                                     {thetoks0}}}%
  446. temp
  447. unnumbnoderef
  448. nobreak
  449. }
  450. % These are variants which are not "outer", so they can appear in @ifinfo.
  451. % Actually, they should now be obsolete; ordinary section commands should work.
  452. definfotop{parseargunnumberedzzz}
  453. definfounnumbered{parseargunnumberedzzz}
  454. definfounnumberedsec{parseargunnumberedseczzz}
  455. definfounnumberedsubsec{parseargunnumberedsubseczzz}
  456. definfounnumberedsubsubsec{parseargunnumberedsubsubseczzz}
  457. definfoappendix{parseargappendixzzz}
  458. definfoappendixsec{parseargappendixseczzz}
  459. definfoappendixsubsec{parseargappendixsubseczzz}
  460. definfoappendixsubsubsec{parseargappendixsubsubseczzz}
  461. definfochapter{parseargchapterzzz}
  462. definfosection{parseargsectionzzz}
  463. definfosubsection{parseargsubsectionzzz}
  464. definfosubsubsection{parseargsubsubsectionzzz}
  465. % These macros control what the section commands do, according
  466. % to what kind of chapter we are in (ordinary, appendix, or unnumbered).
  467. % Define them by default for a numbered chapter.
  468. globalletsection = numberedsec
  469. globalletsubsection = numberedsubsec
  470. globalletsubsubsection = numberedsubsubsec
  471. % Define @majorheading, @heading and @subheading
  472. % NOTE on use of vbox for chapter headings, section headings, and such:
  473. %       1) We use vbox rather than the earlier line to permit
  474. %          overlong headings to fold.
  475. %       2) hyphenpenalty is set to 10000 because hyphenation in a
  476. %          heading is obnoxious; this forbids it.
  477. %       3) Likewise, headings look best if no parindent is used, and
  478. %          if justification is not attempted.  Hence raggedright.
  479. defmajorheading{parseargmajorheadingzzz}
  480. defmajorheadingzzz #1{%
  481. {advancechapheadingskip by 10pt chapbreak }%
  482. {chapfonts vbox{hyphenpenalty=10000tolerance=5000
  483.                   parindent=0ptraggedright
  484.                   rm #1hfill}}bigskip parpenalty 200}
  485. defchapheading{parseargchapheadingzzz}
  486. defchapheadingzzz #1{chapbreak %
  487. {chapfonts vbox{hyphenpenalty=10000tolerance=5000
  488.                   parindent=0ptraggedright
  489.                   rm #1hfill}}bigskip parpenalty 200}
  490. % @heading, @subheading, @subsubheading.
  491. defheading{parseargplainsecheading}
  492. defsubheading{parseargplainsubsecheading}
  493. defsubsubheading{parseargplainsubsubsecheading}
  494. % These macros generate a chapter, section, etc. heading only
  495. % (including whitespace, linebreaking, etc. around it),
  496. % given all the information in convenient, parsed form.
  497. %%% Args are the skip and penalty (usually negative)
  498. defdobreak#1#2{parifdimlastskip<#1removelastskippenalty#2vskip#1fi}
  499. defsetchapterstyle #1 {csname CHAPF#1endcsname}
  500. %%% Define plain chapter starts, and page on/off switching for it
  501. % Parameter controlling skip before chapter headings (if needed)
  502. newskipchapheadingskip
  503. defchapbreak{dobreak chapheadingskip {-4000}}
  504. defchappager{parvfillsupereject}
  505. defchapoddpage{chappager ifoddpageno else hbox to 0pt{} chappagerfi}
  506. defsetchapternewpage #1 {csname CHAPPAG#1endcsname}
  507. defCHAPPAGoff{%
  508. globalletcontentsalignmacro = chappager
  509. globalletpchapsepmacro=chapbreak
  510. globalletpagealignmacro=chappager}
  511. defCHAPPAGon{%
  512. globalletcontentsalignmacro = chappager
  513. globalletpchapsepmacro=chappager
  514. globalletpagealignmacro=chappager
  515. globaldefHEADINGSon{HEADINGSsingle}}
  516. defCHAPPAGodd{
  517. globalletcontentsalignmacro = chapoddpage
  518. globalletpchapsepmacro=chapoddpage
  519. globalletpagealignmacro=chapoddpage
  520. globaldefHEADINGSon{HEADINGSdouble}}
  521. CHAPPAGon
  522. defCHAPFplain{
  523. globalletchapmacro=chfplain
  524. globalletunnumbchapmacro=unnchfplain
  525. globalletcenterchapmacro=centerchfplain}
  526. % Plain chapter opening.
  527. % #1 is the text, #2 the chapter number or empty if unnumbered.
  528. defchfplain#1#2{%
  529.   pchapsepmacro
  530.   {%
  531.     chapfonts rm
  532.     defchapnum{#2}%
  533.     setbox0 = hbox{#2ifxchapnumemptyelseenspacefi}%
  534.     vbox{hyphenpenalty=10000 tolerance=5000 parindent=0pt raggedright
  535.           hangindent = wd0 centerparametersmaybe
  536.           unhbox0 #1par}%
  537.   }%
  538.   nobreakbigskip % no page break after a chapter title
  539.   nobreak
  540. }
  541. % Plain opening for unnumbered.
  542. defunnchfplain#1{chfplain{#1}{}}
  543. % @centerchap -- centered and unnumbered.
  544. letcenterparametersmaybe = relax
  545. defcenterchfplain#1{{%
  546.   defcenterparametersmaybe{%
  547.     advancerightskip by 3rightskip
  548.     leftskip = rightskip
  549.     parfillskip = 0pt
  550.   }%
  551.   chfplain{#1}{}%
  552. }}
  553. CHAPFplain % The default
  554. defunnchfopen #1{%
  555. chapoddpage {chapfonts vbox{hyphenpenalty=10000tolerance=5000
  556.                        parindent=0ptraggedright
  557.                        rm #1hfill}}bigskip parnobreak
  558. }
  559. defchfopen #1#2{chapoddpage {chapfonts
  560. vbox to 3in{vfil hbox tohsize{hfil #2} hbox tohsize{hfil #1} vfil}}%
  561. parpenalty 5000 %
  562. }
  563. defcenterchfopen #1{%
  564. chapoddpage {chapfonts vbox{hyphenpenalty=10000tolerance=5000
  565.                        parindent=0pt
  566.                        hfill {rm #1}hfill}}bigskip parnobreak
  567. }
  568. defCHAPFopen{
  569. globalletchapmacro=chfopen
  570. globalletunnumbchapmacro=unnchfopen
  571. globalletcenterchapmacro=centerchfopen}
  572. % Section titles.
  573. newskipsecheadingskip
  574. defsecheadingbreak{dobreak secheadingskip {-1000}}
  575. defsecheading#1#2#3{sectionheading{sec}{#2.#3}{#1}}
  576. defplainsecheading#1{sectionheading{sec}{}{#1}}
  577. % Subsection titles.
  578. newskip subsecheadingskip
  579. defsubsecheadingbreak{dobreak subsecheadingskip {-500}}
  580. defsubsecheading#1#2#3#4{sectionheading{subsec}{#2.#3.#4}{#1}}
  581. defplainsubsecheading#1{sectionheading{subsec}{}{#1}}
  582. % Subsubsection titles.
  583. letsubsubsecheadingskip = subsecheadingskip
  584. letsubsubsecheadingbreak = subsecheadingbreak
  585. defsubsubsecheading#1#2#3#4#5{sectionheading{subsubsec}{#2.#3.#4.#5}{#1}}
  586. defplainsubsubsecheading#1{sectionheading{subsubsec}{}{#1}}
  587. % Print any size section title.
  588. %
  589. % #1 is the section type (sec/subsec/subsubsec), #2 is the section
  590. % number (maybe empty), #3 the text.
  591. defsectionheading#1#2#3{%
  592.   {%
  593.     expandafteradvancecsname #1headingskipendcsname by parskip
  594.     csname #1headingbreakendcsname
  595.   }%
  596.   {%
  597.     % Switch to the right set of fonts.
  598.     csname #1fontsendcsname rm
  599.     %
  600.     % Only insert the separating space if we have a section number.
  601.     defsecnum{#2}%
  602.     setbox0 = hbox{#2ifxsecnumemptyelseenspacefi}%
  603.     %
  604.     vbox{hyphenpenalty=10000 tolerance=5000 parindent=0pt raggedright
  605.           hangindent = wd0 % zero if no section number
  606.           unhbox0 #3}%
  607.   }%
  608.   ifdimparskip<10pt nobreakkern10ptnobreakkern-parskipfi nobreak
  609. }
  610. message{toc,}
  611. newwritetocfile
  612. % Write an entry to the toc file, opening it if necessary.
  613. % Called from @chapter, etc.  We supply {folio} at the end of the
  614. % argument, which will end up as the last argument to the ...entry macro.
  615. %
  616. % We open the .toc file here instead of at @setfilename or any other
  617. % given time so that @contents can be put in the document anywhere.
  618. %
  619. newififtocfileopened
  620. defwritetocentry#1{%
  621.   iftocfileopenedelse
  622.     immediateopenouttocfile = jobname.toc
  623.     globaltocfileopenedtrue
  624.   fi
  625.   iflinks writetocfile{#1{folio}}fi
  626. }
  627. newskipcontentsrightmargin contentsrightmargin=1in
  628. newcountsavepageno
  629. newcountlastnegativepageno lastnegativepageno = -1
  630. % Finish up the main text and prepare to read what we've written
  631. % to tocfile.
  632. %
  633. defstartcontents#1{%
  634.    % If @setchapternewpage on, and @headings double, the contents should
  635.    % start on an odd page, unlike chapters.  Thus, we maintain
  636.    % contentsalignmacro in parallel with pagealignmacro.
  637.    % From: Torbjorn Granlund <tege@matematik.su.se>
  638.    contentsalignmacro
  639.    immediatecloseouttocfile
  640.    %
  641.    % Don't need to put `Contents' or `Short Contents' in the headline.
  642.    % It is abundantly clear what they are.
  643.    unnumbchapmacro{#1}defthischapter{}%
  644.    savepageno = pageno
  645.    begingroup                  % Set up to handle contents files properly.
  646.       catcode`\=0  catcode`{=1  catcode`}=2  catcode`@=11
  647.       % We can't do this, because then an actual ^ in a section
  648.       % title fails, e.g., @chapter ^ -- exponentiation.  --karl, 9jul97.
  649.       %catcode`^=7 % to see ^^e4 as "a etc. juha@piuha.ydi.vtt.fi
  650.       raggedbottom             % Worry more about breakpoints than the bottom.
  651.       advancehsize by -contentsrightmargin % Don't use the full line length.
  652.       %
  653.       % Roman numerals for page numbers.
  654.       ifnum pageno>0 pageno = lastnegativepageno fi
  655. }
  656. % Normal (long) toc.
  657. defcontents{%
  658.    startcontents{putwordTOC}%
  659.      openin 1 jobname.toc
  660.      ifeof 1 else
  661.        closein 1
  662.        input jobname.toc
  663.      fi
  664.      vfill eject
  665.      contentsalignmacro % in case @setchapternewpage odd is in effect
  666.    endgroup
  667.    lastnegativepageno = pageno
  668.    pageno = savepageno
  669. }
  670. % And just the chapters.
  671. defsummarycontents{%
  672.    startcontents{putwordShortTOC}%
  673.       %
  674.       letchapentry = shortchapentry
  675.       letunnumbchapentry = shortunnumberedentry
  676.       % We want a true roman here for the page numbers.
  677.       secfonts
  678.       letrm=shortcontrm letbf=shortcontbf letsl=shortcontsl
  679.       rm
  680.       hyphenpenalty = 10000
  681.       advancebaselineskip by 1pt % Open it up a little.
  682.       defsecentry ##1##2##3##4{}
  683.       defunnumbsecentry ##1##2{}
  684.       defsubsecentry ##1##2##3##4##5{}
  685.       defunnumbsubsecentry ##1##2{}
  686.       defsubsubsecentry ##1##2##3##4##5##6{}
  687.       defunnumbsubsubsecentry ##1##2{}
  688.       openin 1 jobname.toc
  689.       ifeof 1 else
  690.         closein 1
  691.         input jobname.toc
  692.       fi
  693.      vfill eject
  694.      contentsalignmacro % in case @setchapternewpage odd is in effect
  695.    endgroup
  696.    lastnegativepageno = pageno
  697.    pageno = savepageno
  698. }
  699. letshortcontents = summarycontents
  700. % These macros generate individual entries in the table of contents.
  701. % The first argument is the chapter or section name.
  702. % The last argument is the page number.
  703. % The arguments in between are the chapter number, section number, ...
  704. % Chapter-level things, for both the long and short contents.
  705. defchapentry#1#2#3{dochapentry{#2labelspace#1}{#3}}
  706. % See comments in dochapentry re vbox and related settings
  707. defshortchapentry#1#2#3{%
  708.   tocentry{shortchaplabel{#2}labelspace #1}{doshortpageno{#3}}%
  709. }
  710. % Typeset the label for a chapter or appendix for the short contents.
  711. % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter.
  712. % We could simplify the code here by writing out an appendixentry
  713. % command in the toc file for appendices, instead of using chapentry
  714. % for both, but it doesn't seem worth it.
  715. setbox0 = hbox{shortcontrm putwordAppendix }
  716. newdimenshortappendixwidth shortappendixwidth = wd0
  717. defshortchaplabel#1{%
  718.   % We typeset #1 in a box of constant width, regardless of the text of
  719.   % #1, so the chapter titles will come out aligned.
  720.   setbox0 = hbox{#1}%
  721.   dimen0 = ifdimwd0 > shortappendixwidth shortappendixwidth else 0pt fi
  722.   %
  723.   % This space should be plenty, since a single number is .5em, and the
  724.   % widest letter (M) is 1em, at least in the Computer Modern fonts.
  725.   % (This space doesn't include the extra space that gets added after
  726.   % the label; that gets put in by shortchapentry above.)
  727.   advancedimen0 by 1.1em
  728.   hbox to dimen0{#1hfil}%
  729. }
  730. defunnumbchapentry#1#2{dochapentry{#1}{#2}}
  731. defshortunnumberedentry#1#2{tocentry{#1}{doshortpageno{#2}}}
  732. % Sections.
  733. defsecentry#1#2#3#4{dosecentry{#2.#3labelspace#1}{#4}}
  734. defunnumbsecentry#1#2{dosecentry{#1}{#2}}
  735. % Subsections.
  736. defsubsecentry#1#2#3#4#5{dosubsecentry{#2.#3.#4labelspace#1}{#5}}
  737. defunnumbsubsecentry#1#2{dosubsecentry{#1}{#2}}
  738. % And subsubsections.
  739. defsubsubsecentry#1#2#3#4#5#6{%
  740.   dosubsubsecentry{#2.#3.#4.#5labelspace#1}{#6}}
  741. defunnumbsubsubsecentry#1#2{dosubsubsecentry{#1}{#2}}
  742. % This parameter controls the indentation of the various levels.
  743. newdimentocindent tocindent = 3pc
  744. % Now for the actual typesetting. In all these, #1 is the text and #2 is the
  745. % page number.
  746. %
  747. % If the toc has to be broken over pages, we want it to be at chapters
  748. % if at all possible; hence the penalty.
  749. defdochapentry#1#2{%
  750.    penalty-300 vskip1baselineskip plus.33baselineskip minus.25baselineskip
  751.    begingroup
  752.      chapentryfonts
  753.      tocentry{#1}{dopageno{#2}}%
  754.    endgroup
  755.    nobreakvskip .25baselineskip plus.1baselineskip
  756. }
  757. defdosecentry#1#2{begingroup
  758.   secentryfonts leftskip=tocindent
  759.   tocentry{#1}{dopageno{#2}}%
  760. endgroup}
  761. defdosubsecentry#1#2{begingroup
  762.   subsecentryfonts leftskip=2tocindent
  763.   tocentry{#1}{dopageno{#2}}%
  764. endgroup}
  765. defdosubsubsecentry#1#2{begingroup
  766.   subsubsecentryfonts leftskip=3tocindent
  767.   tocentry{#1}{dopageno{#2}}%
  768. endgroup}
  769. % Final typesetting of a toc entry; we use the same entry macro as for
  770. % the index entries, but we want to suppress hyphenation here.  (We
  771. % can't do that in the entry macro, since index entries might consist
  772. % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
  773. deftocentry#1#2{begingroup
  774.   vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks
  775.   % Do not use turnoffactive in these arguments.  Since the toc is
  776.   % typeset in cmr, so characters such as _ would come out wrong; we
  777.   % have to do the usual translation tricks.
  778.   entry{#1}{#2}%
  779. endgroup}
  780. % Space between chapter (or whatever) number and the title.
  781. deflabelspace{hskip1em relax}
  782. defdopageno#1{{rm #1}}
  783. defdoshortpageno#1{{rm #1}}
  784. defchapentryfonts{secfonts rm}
  785. defsecentryfonts{textfonts}
  786. letsubsecentryfonts = textfonts
  787. letsubsubsecentryfonts = textfonts
  788. message{environments,}
  789. % Since these characters are used in examples, it should be an even number of
  790. % tt widths. Each tt character is 1en, so two makes it 1em.
  791. % Furthermore, these definitions must come after we define our fonts.
  792. newboxdblarrowbox    newboxlongdblarrowbox
  793. newboxpushcharbox    newboxbullbox
  794. newboxequivbox       newboxerrorbox
  795. %{tentt
  796. %globalsetboxdblarrowbox = hbox to 1em{hfil$Rightarrow$hfil}
  797. %globalsetboxlongdblarrowbox = hbox to 1em{hfil$mapsto$hfil}
  798. %globalsetboxpushcharbox = hbox to 1em{hfil$dashv$hfil}
  799. %globalsetboxequivbox = hbox to 1em{hfil$ptexequiv$hfil}
  800. % Adapted from the manmac format (p.420 of TeXbook)
  801. %globalsetboxbullbox = hbox to 1em{kern.15emvrule height .75ex width .85ex
  802. %                                      depth .1exhfil}
  803. %}
  804. % @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
  805. defpoint{$star$}
  806. defresult{leavevmoderaise.15exhbox to 1em{hfil$Rightarrow$hfil}}
  807. defexpansion{leavevmoderaise.1exhbox to 1em{hfil$mapsto$hfil}}
  808. defprint{leavevmodelower.1exhbox to 1em{hfil$dashv$hfil}}
  809. defequiv{leavevmodelower.1exhbox to 1em{hfil$ptexequiv$hfil}}
  810. % Adapted from the TeXbook's boxit.
  811. {tentt globaldimen0 = 3em}% Width of the box.
  812. dimen2 = .55pt % Thickness of rules
  813. % The text. (`r' is open on the right, `e' somewhat less so on the left.)
  814. setbox0 = hbox{kern-.75pt tensf errorkern-1.5pt}
  815. globalsetboxerrorbox=hbox to dimen0{hfil
  816.    hsize = dimen0 advancehsize by -5.8pt % Space to left+right.
  817.    advancehsize by -2dimen2 % Rules.
  818.    vbox{
  819.       hrule heightdimen2
  820.       hbox{vrule widthdimen2 kern3pt          % Space to left of text.
  821.          vtop{kern2.4pt box0 kern2.4pt}% Space above/below.
  822.          kern3ptvrule widthdimen2}% Space to right.
  823.       hrule heightdimen2}
  824.     hfil}
  825. % The @error{} command.
  826. deferror{leavevmodelower.7excopyerrorbox}
  827. % @tex ... @end tex    escapes into raw Tex temporarily.
  828. % One exception: @ is still an escape character, so that @end tex works.
  829. % But @ or @@ will get a plain tex @ character.
  830. deftex{begingroup
  831.   catcode `\=0 catcode `{=1 catcode `}=2
  832.   catcode `$=3 catcode `&=4 catcode `#=6
  833.   catcode `^=7 catcode `_=8 catcode `~=13 let~=tie
  834.   catcode `%=14
  835.   catcode 43=12 % plus
  836.   catcode`"=12
  837.   catcode`==12
  838.   catcode`|=12
  839.   catcode`<=12
  840.   catcode`>=12
  841.   escapechar=`\
  842.   %
  843.   letb=ptexb
  844.   letbullet=ptexbullet
  845.   letc=ptexc
  846.   let,=ptexcomma
  847.   let.=ptexdot
  848.   letdots=ptexdots
  849.   letequiv=ptexequiv
  850.   let!=ptexexclam
  851.   leti=ptexi
  852.   let{=ptexlbrace
  853.   let+=tabalign
  854.   let}=ptexrbrace
  855.   let*=ptexstar
  856.   lett=ptext
  857.   %
  858.   defendldots{mathinner{ldotsldotsldotsldots}}%
  859.   defenddots{relaxifmmodeendldotselse$mathsurround=0pt endldots,$fi}%
  860.   def@{@}%
  861. letEtex=endgroup}
  862. % Define @lisp ... @endlisp.
  863. % @lisp does a begingroup so it can rebind things,
  864. % including the definition of @endlisp (which normally is erroneous).
  865. % Amount to narrow the margins by for @lisp.
  866. newskiplispnarrowing lispnarrowing=0.4in
  867. % This is the definition that ^^M gets inside @lisp, @example, and other
  868. % such environments.  null is better than a space, since it doesn't
  869. % have any width.
  870. deflisppar{nullendgraf}
  871. % Make each space character in the input produce a normal interword
  872. % space in the output.  Don't allow a line break at this space, as this
  873. % is used only in environments like @example, where each line of input
  874. % should produce a line of output anyway.
  875. %
  876. {obeyspaces %
  877. gdefsepspaces{obeyspaceslet =tie}}
  878. % Define obeyedspace to be our active space, whatever it is.  This is
  879. % for use in parsearg.
  880. {sepspaces%
  881. globalletobeyedspace= }
  882. % This space is always present above and below environments.
  883. newskipenvskipamount envskipamount = 0pt
  884. % Make spacing and below environment symmetrical.  We use parskip here
  885. % to help in doing that, since in @example-like environments parskip
  886. % is reset to zero; thus the afterenvbreak inserts no space -- but the
  887. % start of the next paragraph will insert parskip
  888. %
  889. defaboveenvbreak{{advanceenvskipamount by parskip
  890. endgraf ifdimlastskip<envskipamount
  891. removelastskip penalty-50 vskipenvskipamount fi}}
  892. letafterenvbreak = aboveenvbreak
  893. % nonarrowing is a flag.  If "set", @lisp etc don't narrow margins.
  894. letnonarrowing=relax
  895. % @cartouche ... @end cartouche: draw rectangle w/rounded corners around
  896. % environment contents.
  897. fontcircle=lcircle10
  898. newdimencircthick
  899. newdimencartouternewdimencartinner
  900. newskipnormbskipnewskipnormpskipnewskipnormlskip
  901. circthick=fontdimen8circle
  902. %
  903. defctl{{circlechar'013hskip -6pt}}% 6pt from pl file: 1/2charwidth
  904. defctr{{hskip 6ptcirclechar'010}}
  905. defcbl{{circlechar'012hskip -6pt}}
  906. defcbr{{hskip 6ptcirclechar'011}}
  907. defcarttop{hbox to cartouter{hskiplskip
  908.         ctlleadershrule heightcircthickhfilctr
  909.         hskiprskip}}
  910. defcartbot{hbox to cartouter{hskiplskip
  911.         cblleadershrule heightcircthickhfilcbr
  912.         hskiprskip}}
  913. %
  914. newskiplskipnewskiprskip
  915. longdefcartouche{%
  916. begingroup
  917.         lskip=leftskip rskip=rightskip
  918.         leftskip=0ptrightskip=0pt %we want these *outside*.
  919.         cartinner=hsize advancecartinner by-lskip
  920.                           advancecartinner by-rskip
  921.         cartouter=hsize
  922.         advancecartouter by 18.4pt % allow for 3pt kerns on either
  923. %                                    side, and for 6pt waste from
  924. %                                    each corner char, and rule thickness
  925.         normbskip=baselineskip normpskip=parskip normlskip=lineskip
  926.         % Flag to tell @lisp, etc., not to narrow margin.
  927.         letnonarrowing=comment
  928.         vboxbgroup
  929.                 baselineskip=0ptparskip=0ptlineskip=0pt
  930.                 carttop
  931.                 hboxbgroup
  932.                         hskiplskip
  933.                         vrulekern3pt
  934.                         vboxbgroup
  935.                                 hsize=cartinner
  936.                                 kern3pt
  937.                                 begingroup
  938.                                         baselineskip=normbskip
  939.                                         lineskip=normlskip
  940.                                         parskip=normpskip
  941.                                         vskip -parskip
  942. defEcartouche{%
  943.                                 endgroup
  944.                                 kern3pt
  945.                         egroup
  946.                         kern3ptvrule
  947.                         hskiprskip
  948.                 egroup
  949.                 cartbot
  950.         egroup
  951. endgroup
  952. }}
  953. % This macro is called at the beginning of all the @example variants,
  954. % inside a group.
  955. defnonfillstart{%
  956.   aboveenvbreak
  957.   inENV % This group ends at the end of the body
  958.   hfuzz = 12pt % Don't be fussy
  959.   sepspaces % Make spaces be word-separators rather than space tokens.
  960.   singlespace
  961.   letpar = lisppar % don't ignore blank lines
  962.   obeylines % each line of input is a line of output
  963.   parskip = 0pt
  964.   parindent = 0pt
  965.   emergencystretch = 0pt % don't try to avoid overfull boxes
  966.   % @cartouche defines nonarrowing to inhibit narrowing
  967.   % at next level down.
  968.   ifxnonarrowingrelax
  969.     advance leftskip by lispnarrowing
  970.     exdentamount=lispnarrowing
  971.     letexdent=nofillexdent
  972.     letnonarrowing=relax
  973.   fi
  974. }
  975. % Define the E... control sequence only if we are inside the particular
  976. % environment, so the error checking in end will work.
  977. %
  978. % To end an @example-like environment, we first end the paragraph (via
  979. % afterenvbreak's vertical glue), and then the group.  That way we keep
  980. % the zero parskip that the environments set -- parskip glue will be
  981. % inserted at the beginning of the next paragraph in the document, after
  982. % the environment.
  983. %
  984. defnonfillfinish{afterenvbreakendgroup}
  985. % @lisp: indented, narrowed, typewriter font.
  986. deflisp{begingroup
  987.   nonfillstart
  988.   letElisp = nonfillfinish
  989.   tt
  990.   letkbdfont = kbdexamplefont % Allow @kbd to do something special.
  991.   gobble       % eat return
  992. }
  993. % @example: Same as @lisp.
  994. defexample{begingroup defEexample{nonfillfinishendgroup}lisp}
  995. % @small... is usually equivalent to the non-small (@smallbook
  996. % redefines).  We must call example (or whatever) last in the
  997. % definition, since it reads the return following the @example (or
  998. % whatever) command.
  999. %
  1000. % This actually allows (for example) @end display inside an
  1001. % @smalldisplay.  Too bad, but makeinfo will catch the error anyway.
  1002. %
  1003. defsmalldisplay{begingroupdefEsmalldisplay{nonfillfinishendgroup}display}
  1004. defsmallexample{begingroupdefEsmallexample{nonfillfinishendgroup}lisp}
  1005. defsmallformat{begingroupdefEsmallformat{nonfillfinishendgroup}format}
  1006. defsmalllisp{begingroupdefEsmalllisp{nonfillfinishendgroup}lisp}
  1007. % Real @smallexample and @smalllisp (when @smallbook): use smaller fonts.
  1008. % Originally contributed by Pavel@xerox.
  1009. defsmalllispx{begingroup
  1010.   defEsmalllisp{nonfillfinishendgroup}%
  1011.   defEsmallexample{nonfillfinishendgroup}%
  1012.   indexfonts
  1013.   lisp
  1014. }
  1015. % @display: same as @lisp except keep current font.
  1016. %
  1017. defdisplay{begingroup
  1018.   nonfillstart
  1019.   letEdisplay = nonfillfinish
  1020.   gobble
  1021. }
  1022. % @smalldisplay (when @smallbook): @display plus smaller fonts.
  1023. %
  1024. defsmalldisplayx{begingroup
  1025.   defEsmalldisplay{nonfillfinishendgroup}%
  1026.   indexfonts rm
  1027.   display
  1028. }
  1029. % @format: same as @display except don't narrow margins.
  1030. %
  1031. defformat{begingroup
  1032.   letnonarrowing = t
  1033.   nonfillstart
  1034.   letEformat = nonfillfinish
  1035.   gobble
  1036. }
  1037. % @smallformat (when @smallbook): @format plus smaller fonts.
  1038. %
  1039. defsmallformatx{begingroup
  1040.   defEsmallformat{nonfillfinishendgroup}%
  1041.   indexfonts rm
  1042.   format
  1043. }
  1044. % @flushleft (same as @format).
  1045. %
  1046. defflushleft{begingroup defEflushleft{nonfillfinishendgroup}format}
  1047. % @flushright.
  1048. %
  1049. defflushright{begingroup
  1050.   letnonarrowing = t
  1051.   nonfillstart
  1052.   letEflushright = nonfillfinish
  1053.   advanceleftskip by 0pt plus 1fill
  1054.   gobble
  1055. }
  1056. % @quotation does normal linebreaking (hence we can't use nonfillstart)
  1057. % and narrows the margins.
  1058. %
  1059. defquotation{%
  1060.   begingroupinENV %This group ends at the end of the @quotation body
  1061.   {parskip=0pt aboveenvbreak}% because aboveenvbreak inserts parskip
  1062.   singlespace
  1063.   parindent=0pt
  1064.   % We have retained a nonzero parskip for the environment, since we're
  1065.   % doing normal filling. So to avoid extra space below the environment...
  1066.   defEquotation{parskip = 0pt nonfillfinish}%
  1067.   %
  1068.   % @cartouche defines nonarrowing to inhibit narrowing at next level down.
  1069.   ifxnonarrowingrelax
  1070.     advanceleftskip by lispnarrowing
  1071.     advancerightskip by lispnarrowing
  1072.     exdentamount = lispnarrowing
  1073.     letnonarrowing = relax
  1074.   fi
  1075. }
  1076. message{defuns,}
  1077. % Define formatter for defuns
  1078. % First, allow user to change definition object font (df) internally
  1079. defsetdeffont #1 {csname DEF#1endcsname}
  1080. newskipdefbodyindent defbodyindent=.4in
  1081. newskipdefargsindent defargsindent=50pt
  1082. newskipdeftypemargin deftypemargin=12pt
  1083. newskipdeflastargmargin deflastargmargin=18pt
  1084. newcountparencount
  1085. % define functionparens, which makes ( and ) and & do special things.
  1086. % functionparens affects the group it is contained in.
  1087. defactiveparens{%
  1088. catcode`(=active catcode`)=active catcode`&=active
  1089. catcode`[=active catcode`]=active}
  1090. % Make control sequences which act like normal parenthesis chars.
  1091. letlparen = ( letrparen = )
  1092. {activeparens % Now, smart parens don't turn on until &foo (see amprm)
  1093. % Be sure that we always have a definition for `(', etc.  For example,
  1094. % if the fn name has parens in it, boldbrax will not be in effect yet,
  1095. % so TeX would otherwise complain about undefined control sequence.
  1096. globallet(=lparen globallet)=rparen
  1097. globallet[=lbrack globallet]=rbrack
  1098. gdeffunctionparens{boldbraxlet&=amprmparencount=0 }
  1099. gdefboldbrax{let(=opnrlet)=clnrlet[=lbrblet]=rbrb}
  1100. % This is used to turn on special parens
  1101. % but make & act ordinary (given that it's active).
  1102. gdefboldbraxnoamp{let(=opnrlet)=clnrlet[=lbrblet]=rbrblet&=ampnr}
  1103. % Definitions of (, ) and & used in args for functions.
  1104. % This is the definition of ( outside of all parentheses.
  1105. gdefoprm#1 {{rmchar`(}#1 bf let(=opnested
  1106.   globaladvanceparencount by 1
  1107. }
  1108. %
  1109. % This is the definition of ( when already inside a level of parens.
  1110. gdefopnested{char`(globaladvanceparencount by 1 }
  1111. %
  1112. gdefclrm{% Print a paren in roman if it is taking us back to depth of 0.
  1113.   % also in that case restore the outer-level definition of (.
  1114.   ifnum parencount=1 {rm char `)}sl let(=oprm else char `) fi
  1115.   globaladvance parencount by -1 }
  1116. % If we encounter &foo, then turn on ()-hacking afterwards
  1117. gdefamprm#1 {{rm&#1}let(=oprm let)=clrm }
  1118. %
  1119. gdefnormalparens{boldbraxlet&=ampnr}
  1120. } % End of definition inside activeparens
  1121. %% These parens (in boldbrax) actually are a little bolder than the
  1122. %% contained text.  This is especially needed for [ and ]
  1123. defopnr{{sfchar`(}globaladvanceparencount by 1 }
  1124. defclnr{{sfchar`)}globaladvanceparencount by -1 }
  1125. defampnr{&}
  1126. deflbrb{{bfchar`[}}
  1127. defrbrb{{bfchar`]}}
  1128. % First, defname, which formats the header line itself.
  1129. % #1 should be the function name.
  1130. % #2 should be the type of definition, such as "Function".
  1131. defdefname #1#2{%
  1132. % Get the values of leftskip and rightskip as they were
  1133. % outside the @def...
  1134. dimen2=leftskip
  1135. advancedimen2 by -defbodyindent
  1136. noindent
  1137. setbox0=hbox{hskip deflastargmargin{rm #2}hskip deftypemargin}%
  1138. dimen0=hsize advance dimen0 by -wd0 % compute size for first line
  1139. dimen1=hsize advance dimen1 by -defargsindent %size for continuations
  1140. parshape 2 0in dimen0 defargsindent dimen1
  1141. % Now output arg 2 ("Function" or some such)
  1142. % ending at deftypemargin from the right margin,
  1143. % but stuck inside a box of width 0 so it does not interfere with linebreaking
  1144. {% Adjust hsize to exclude the ambient margins,
  1145. % so that rightline will obey them.
  1146. advance hsize by -dimen2
  1147. rlap{rightline{{rm #2}hskip -1.25pc }}}%
  1148. % Make all lines underfull and no complaints:
  1149. tolerance=10000 hbadness=10000
  1150. advanceleftskip by -defbodyindent
  1151. exdentamount=defbodyindent
  1152. {df #1}enskip        % Generate function name
  1153. }
  1154. % Actually process the body of a definition
  1155. % #1 should be the terminating control sequence, such as Edefun.
  1156. % #2 should be the "another name" control sequence, such as defunx.
  1157. % #3 should be the control sequence that actually processes the header,
  1158. %    such as defunheader.
  1159. defdefparsebody #1#2#3{begingroupinENV% Environment for definitionbody
  1160. medbreak %
  1161. % Define the end token that this defining construct specifies
  1162. % so that it will exit this group.
  1163. def#1{endgrafendgroupmedbreak}%
  1164. def#2{begingroupobeylinesactiveparensspacesplit#3}%
  1165. parindent=0in
  1166. advanceleftskip by defbodyindent
  1167. exdentamount=defbodyindent
  1168. begingroup %
  1169. catcode 61=active % 61 is `='
  1170. obeylinesactiveparensspacesplit#3}
  1171. % #1 is the E... control sequence to end the definition (which we define).
  1172. % #2 is the ...x control sequence for consecutive fns (which we define).
  1173. % #3 is the control sequence to call to resume processing.
  1174. % #4, delimited by the space, is the class name.
  1175. %
  1176. defdefmethparsebody#1#2#3#4 {begingroupinENV %
  1177. medbreak %
  1178. % Define the end token that this defining construct specifies
  1179. % so that it will exit this group.
  1180. def#1{endgrafendgroupmedbreak}%
  1181. def#2##1 {begingroupobeylinesactiveparensspacesplit{#3{##1}}}%
  1182. parindent=0in
  1183. advanceleftskip by defbodyindent
  1184. exdentamount=defbodyindent
  1185. begingroupobeylinesactiveparensspacesplit{#3{#4}}}
  1186. % @deftypemethod has an extra argument that nothing else does.  Sigh.
  1187. % #1 is the E... control sequence to end the definition (which we define).
  1188. % #2 is the ...x control sequence for consecutive fns (which we define).
  1189. % #3 is the control sequence to call to resume processing.
  1190. % #4, delimited by the space, is the class name.
  1191. % #5 is the method's return type.
  1192. %
  1193. defdeftypemethparsebody#1#2#3#4 #5 {begingroupinENV %
  1194. medbreak %
  1195. % Define the end token that this defining construct specifies
  1196. % so that it will exit this group.
  1197. def#1{endgrafendgroupmedbreak}%
  1198. def#2##1 ##2 {begingroupobeylinesactiveparensspacesplit{#3{##1}{##2}}}%
  1199. parindent=0in
  1200. advanceleftskip by defbodyindent
  1201. exdentamount=defbodyindent
  1202. begingroupobeylinesactiveparensspacesplit{#3{#4}{#5}}}
  1203. defdefopparsebody #1#2#3#4#5 {begingroupinENV %
  1204. medbreak %
  1205. % Define the end token that this defining construct specifies
  1206. % so that it will exit this group.
  1207. def#1{endgrafendgroupmedbreak}%
  1208. def#2##1 ##2 {def#4{##1}%
  1209. begingroupobeylinesactiveparensspacesplit{#3{##2}}}%
  1210. parindent=0in
  1211. advanceleftskip by defbodyindent
  1212. exdentamount=defbodyindent
  1213. begingroupobeylinesactiveparensspacesplit{#3{#5}}}
  1214. % These parsing functions are similar to the preceding ones
  1215. % except that they do not make parens into active characters.
  1216. % These are used for "variables" since they have no arguments.
  1217. defdefvarparsebody #1#2#3{begingroupinENV% Environment for definitionbody
  1218. medbreak %
  1219. % Define the end token that this defining construct specifies
  1220. % so that it will exit this group.
  1221. def#1{endgrafendgroupmedbreak}%
  1222. def#2{begingroupobeylinesspacesplit#3}%
  1223. parindent=0in
  1224. advanceleftskip by defbodyindent
  1225. exdentamount=defbodyindent
  1226. begingroup %
  1227. catcode 61=active %
  1228. obeylinesspacesplit#3}
  1229. % This is used for def{tp,vr}parsebody.  It could probably be used for
  1230. % some of the others, too, with some judicious conditionals.
  1231. %
  1232. defparsebodycommon#1#2#3{%
  1233.   begingroupinENV %
  1234.   medbreak %
  1235.   % Define the end token that this defining construct specifies
  1236.   % so that it will exit this group.
  1237.   def#1{endgrafendgroupmedbreak}%
  1238.   def#2##1 {begingroupobeylinesspacesplit{#3{##1}}}%
  1239.   parindent=0in
  1240.   advanceleftskip by defbodyindent
  1241.   exdentamount=defbodyindent
  1242.   begingroupobeylines
  1243. }
  1244. defdefvrparsebody#1#2#3#4 {%
  1245.   parsebodycommon{#1}{#2}{#3}%
  1246.   spacesplit{#3{#4}}%
  1247. }
  1248. % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
  1249. % type is just `struct', because we lose the braces in `{struct
  1250. % termios}' when spacesplit reads its undelimited argument.  Sigh.
  1251. % letdeftpparsebody=defvrparsebody
  1252. %
  1253. % So, to get around this, we put empty in with the type name.  That
  1254. % way, TeX won't find exactly `{...}' as an undelimited argument, and
  1255. % won't strip off the braces.
  1256. %
  1257. defdeftpparsebody #1#2#3#4 {%
  1258.   parsebodycommon{#1}{#2}{#3}%
  1259.   spacesplit{parsetpheaderline{#3{#4}}}empty
  1260. }
  1261. % Fine, but then we have to eventually remove the empty *and* the
  1262. % braces (if any).  That's what this does.
  1263. %
  1264. defremoveemptybracesempty#1relax{#1}
  1265. % After spacesplit has done its work, this is called -- #1 is the final
  1266. % thing to call, #2 the type name (which starts with empty), and #3
  1267. % (which might be empty) the arguments.
  1268. %
  1269. defparsetpheaderline#1#2#3{%
  1270.   #1{removeemptybraces#2relax}{#3}%
  1271. }%
  1272. defdefopvarparsebody #1#2#3#4#5 {begingroupinENV %
  1273. medbreak %
  1274. % Define the end token that this defining construct specifies
  1275. % so that it will exit this group.
  1276. def#1{endgrafendgroupmedbreak}%
  1277. def#2##1 ##2 {def#4{##1}%
  1278. begingroupobeylinesspacesplit{#3{##2}}}%
  1279. parindent=0in
  1280. advanceleftskip by defbodyindent
  1281. exdentamount=defbodyindent
  1282. begingroupobeylinesspacesplit{#3{#5}}}
  1283. % Split up #2 at the first space token.
  1284. % call #1 with two arguments:
  1285. %  the first is all of #2 before the space token,
  1286. %  the second is all of #2 after that space token.
  1287. % If #2 contains no space token, all of it is passed as the first arg
  1288. % and the second is passed as empty.
  1289. {obeylines
  1290. gdefspacesplit#1#2^^M{endgroupspacesplitfoo{#1}#2 relaxspacesplitfoo}%
  1291. longgdefspacesplitfoo#1#2 #3#4spacesplitfoo{%
  1292. ifxrelax #3%
  1293. #1{#2}{}else #1{#2}{#3#4}fi}}
  1294. % So much for the things common to all kinds of definitions.
  1295. % Define @defun.
  1296. % First, define the processing that is wanted for arguments of defun
  1297. % Use this to expand the args and terminate the paragraph they make up
  1298. defdefunargs #1{functionparens sl
  1299. % Expand, preventing hyphenation at `-' chars.
  1300. % Note that groups don't affect changes in hyphenchar.
  1301. hyphenchartensl=0
  1302. #1%
  1303. hyphenchartensl=45
  1304. ifnumparencount=0 else errmessage{Unbalanced parentheses in @def}fi%
  1305. interlinepenalty=10000
  1306. advancerightskip by 0pt plus 1fil
  1307. endgrafnobreakvskip -parskipnobreak
  1308. }
  1309. defdeftypefunargs #1{%
  1310. % Expand, preventing hyphenation at `-' chars.
  1311. % Note that groups don't affect changes in hyphenchar.
  1312. % Use boldbraxnoamp, not functionparens, so that & is not special.
  1313. boldbraxnoamp
  1314. tclose{#1}% avoid code because of side effects on active chars
  1315. interlinepenalty=10000
  1316. advancerightskip by 0pt plus 1fil
  1317. endgrafnobreakvskip -parskipnobreak
  1318. }
  1319. % Do complete processing of one @defun or @defunx line already parsed.
  1320. % @deffn Command forward-char nchars
  1321. defdeffn{defmethparsebodyEdeffndeffnxdeffnheader}
  1322. defdeffnheader #1#2#3{doind {fn}{code{#2}}%
  1323. begingroupdefname {#2}{#1}defunargs{#3}endgroup %
  1324. catcode 61=other % Turn off change made in defparsebody
  1325. }
  1326. % @defun == @deffn Function
  1327. defdefun{defparsebodyEdefundefunxdefunheader}
  1328. defdefunheader #1#2{doind {fn}{code{#1}}% Make entry in function index
  1329. begingroupdefname {#1}{putwordDeffunc}%
  1330. defunargs {#2}endgroup %
  1331. catcode 61=other % Turn off change made in defparsebody
  1332. }
  1333. % @deftypefun int foobar (int @var{foo}, float @var{bar})
  1334. defdeftypefun{defparsebodyEdeftypefundeftypefunxdeftypefunheader}
  1335. % #1 is the data type.  #2 is the name and args.
  1336. defdeftypefunheader #1#2{deftypefunheaderx{#1}#2 relax}
  1337. % #1 is the data type, #2 the name, #3 the args.
  1338. defdeftypefunheaderx #1#2 #3relax{%
  1339. doind {fn}{code{#2}}% Make entry in function index
  1340. begingroupdefname {defheaderxcond#1relax$$$#2}{putwordDeftypefun}%
  1341. deftypefunargs {#3}endgroup %
  1342. catcode 61=other % Turn off change made in defparsebody
  1343. }
  1344. % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
  1345. defdeftypefn{defmethparsebodyEdeftypefndeftypefnxdeftypefnheader}
  1346. % defheaderxcond#1relax$$$
  1347. % puts #1 in @code, followed by a space, but does nothing if #1 is null.
  1348. defdefheaderxcond#1#2$$${ifx#1relaxelsecode{#1#2} fi}
  1349. % #1 is the classification.  #2 is the data type.  #3 is the name and args.
  1350. defdeftypefnheader #1#2#3{deftypefnheaderx{#1}{#2}#3 relax}
  1351. % #1 is the classification, #2 the data type, #3 the name, #4 the args.
  1352. defdeftypefnheaderx #1#2#3 #4relax{%
  1353. doind {fn}{code{#3}}% Make entry in function index
  1354. begingroup
  1355. normalparens % notably, turn off `&' magic, which prevents
  1356. %               at least some C++ text from working
  1357. defname {defheaderxcond#2relax$$$#3}{#1}%
  1358. deftypefunargs {#4}endgroup %
  1359. catcode 61=other % Turn off change made in defparsebody
  1360. }
  1361. % @defmac == @deffn Macro
  1362. defdefmac{defparsebodyEdefmacdefmacxdefmacheader}
  1363. defdefmacheader #1#2{doind {fn}{code{#1}}% Make entry in function index
  1364. begingroupdefname {#1}{putwordDefmac}%
  1365. defunargs {#2}endgroup %
  1366. catcode 61=other % Turn off change made in defparsebody
  1367. }
  1368. % @defspec == @deffn Special Form
  1369. defdefspec{defparsebodyEdefspecdefspecxdefspecheader}
  1370. defdefspecheader #1#2{doind {fn}{code{#1}}% Make entry in function index
  1371. begingroupdefname {#1}{putwordDefspec}%
  1372. defunargs {#2}endgroup %
  1373. catcode 61=other % Turn off change made in defparsebody
  1374. }
  1375. % This definition is run if you use @defunx
  1376. % anywhere other than immediately after a @defun or @defunx.
  1377. defdeffnx #1 {errmessage{@deffnx in invalid context}}
  1378. defdefunx #1 {errmessage{@defunx in invalid context}}
  1379. defdefmacx #1 {errmessage{@defmacx in invalid context}}
  1380. defdefspecx #1 {errmessage{@defspecx in invalid context}}
  1381. defdeftypefnx #1 {errmessage{@deftypefnx in invalid context}}
  1382. defdeftypemethodx #1 {errmessage{@deftypemethodx in invalid context}}
  1383. defdeftypefunx #1 {errmessage{@deftypefunx in invalid context}}
  1384. % @defmethod, and so on
  1385. % @defop CATEGORY CLASS OPERATION ARG...
  1386. defdefop #1 {defdefoptype{#1}%
  1387. defopparsebodyEdefopdefopxdefopheaderdefoptype}
  1388. defdefopheader #1#2#3{%
  1389. dosubind {fn}{code{#2}}{putwordon #1}% Make entry in function index
  1390. begingroupdefname {#2}{defoptype{}putwordon #1}%
  1391. defunargs {#3}endgroup %
  1392. }
  1393. % @deftypemethod CLASS RETURN-TYPE METHOD ARG...
  1394. %
  1395. defdeftypemethod{%
  1396.   deftypemethparsebodyEdeftypemethoddeftypemethodxdeftypemethodheader}
  1397. %
  1398. % #1 is the class name, #2 the data type, #3 the method name, #4 the args.
  1399. defdeftypemethodheader#1#2#3#4{%
  1400.   dosubind{fn}{code{#3}}{putwordon code{#1}}% entry in function index
  1401.   begingroup
  1402.     defname{defheaderxcond#2relax$$$#3}{putwordMethodon code{#1}}%
  1403.     deftypefunargs{#4}%
  1404.   endgroup
  1405. }
  1406. % @defmethod == @defop Method
  1407. %
  1408. defdefmethod{defmethparsebodyEdefmethoddefmethodxdefmethodheader}
  1409. %
  1410. % #1 is the class name, #2 the method name, #3 the args.
  1411. defdefmethodheader#1#2#3{%
  1412.   dosubind{fn}{code{#2}}{putwordon code{#1}}% entry in function index
  1413.   begingroup
  1414.     defname{#2}{putwordMethodon code{#1}}%
  1415.     defunargs{#3}%
  1416.   endgroup
  1417. }
  1418. % @defcv {Class Option} foo-class foo-flag
  1419. defdefcv #1 {defdefcvtype{#1}%
  1420. defopvarparsebodyEdefcvdefcvxdefcvarheaderdefcvtype}
  1421. defdefcvarheader #1#2#3{%
  1422. dosubind {vr}{code{#2}}{putwordof #1}% Make entry in var index
  1423. begingroupdefname {#2}{defcvtype putwordof #1}%
  1424. defvarargs {#3}endgroup %
  1425. }
  1426. % @defivar == @defcv {Instance Variable}
  1427. defdefivar{defvrparsebodyEdefivardefivarxdefivarheader}
  1428. defdefivarheader #1#2#3{%
  1429. dosubind {vr}{code{#2}}{putwordof #1}% Make entry in var index
  1430. begingroupdefname {#2}{putwordDefivar putwordof #1}%
  1431. defvarargs {#3}endgroup %
  1432. }
  1433. % These definitions are run if you use @defmethodx, etc.,
  1434. % anywhere other than immediately after a @defmethod, etc.
  1435. defdefopx #1 {errmessage{@defopx in invalid context}}
  1436. defdefmethodx #1 {errmessage{@defmethodx in invalid context}}
  1437. defdefcvx #1 {errmessage{@defcvx in invalid context}}
  1438. defdefivarx #1 {errmessage{@defivarx in invalid context}}
  1439. % Now @defvar
  1440. % First, define the processing that is wanted for arguments of @defvar.
  1441. % This is actually simple: just print them in roman.
  1442. % This must expand the args and terminate the paragraph they make up
  1443. defdefvarargs #1{normalparens #1%
  1444. interlinepenalty=10000
  1445. endgrafnobreakvskip -parskipnobreak}
  1446. % @defvr Counter foo-count
  1447. defdefvr{defvrparsebodyEdefvrdefvrxdefvrheader}
  1448. defdefvrheader #1#2#3{doind {vr}{code{#2}}%
  1449. begingroupdefname {#2}{#1}defvarargs{#3}endgroup}
  1450. % @defvar == @defvr Variable
  1451. defdefvar{defvarparsebodyEdefvardefvarxdefvarheader}
  1452. defdefvarheader #1#2{doind {vr}{code{#1}}% Make entry in var index
  1453. begingroupdefname {#1}{putwordDefvar}%
  1454. defvarargs {#2}endgroup %
  1455. }
  1456. % @defopt == @defvr {User Option}
  1457. defdefopt{defvarparsebodyEdefoptdefoptxdefoptheader}
  1458. defdefoptheader #1#2{doind {vr}{code{#1}}% Make entry in var index
  1459. begingroupdefname {#1}{putwordDefopt}%
  1460. defvarargs {#2}endgroup %
  1461. }
  1462. % @deftypevar int foobar
  1463. defdeftypevar{defvarparsebodyEdeftypevardeftypevarxdeftypevarheader}
  1464. % #1 is the data type.  #2 is the name, perhaps followed by text that
  1465. % is actually part of the data type, which should not be put into the index.
  1466. defdeftypevarheader #1#2{%
  1467. dovarind#2 relax% Make entry in variables index
  1468. begingroupdefname {defheaderxcond#1relax$$$#2}{putwordDeftypevar}%
  1469. interlinepenalty=10000
  1470. endgrafnobreakvskip -parskipnobreak
  1471. endgroup}
  1472. defdovarind#1 #2relax{doind{vr}{code{#1}}}
  1473. % @deftypevr {Global Flag} int enable
  1474. defdeftypevr{defvrparsebodyEdeftypevrdeftypevrxdeftypevrheader}
  1475. defdeftypevrheader #1#2#3{dovarind#3 relax%
  1476. begingroupdefname {defheaderxcond#2relax$$$#3}{#1}
  1477. interlinepenalty=10000
  1478. endgrafnobreakvskip -parskipnobreak
  1479. endgroup}
  1480. % This definition is run if you use @defvarx
  1481. % anywhere other than immediately after a @defvar or @defvarx.
  1482. defdefvrx #1 {errmessage{@defvrx in invalid context}}
  1483. defdefvarx #1 {errmessage{@defvarx in invalid context}}
  1484. defdefoptx #1 {errmessage{@defoptx in invalid context}}
  1485. defdeftypevarx #1 {errmessage{@deftypevarx in invalid context}}
  1486. defdeftypevrx #1 {errmessage{@deftypevrx in invalid context}}
  1487. % Now define @deftp
  1488. % Args are printed in bold, a slight difference from @defvar.
  1489. defdeftpargs #1{bf defvarargs{#1}}
  1490. % @deftp Class window height width ...
  1491. defdeftp{deftpparsebodyEdeftpdeftpxdeftpheader}
  1492. defdeftpheader #1#2#3{doind {tp}{code{#2}}%
  1493. begingroupdefname {#2}{#1}deftpargs{#3}endgroup}
  1494. % This definition is run if you use @deftpx, etc
  1495. % anywhere other than immediately after a @deftp, etc.
  1496. defdeftpx #1 {errmessage{@deftpx in invalid context}}
  1497. message{macros,}
  1498. % @macro.
  1499. % To do this right we need a feature of e-TeX, scantokens,
  1500. % which we arrange to emulate with a temporary file in ordinary TeX.
  1501. ifxeTeXversionundefined
  1502.  newwritemacscribble
  1503.  defscanmacro#1{%
  1504.    begingroup newlinechar`^^M
  1505.    % Undo catcode changes of startcontents and doprintindex
  1506.    catcode`@=0 catcode`\=12 escapechar=`@
  1507.    % Append endinput to make sure that TeX does not see the ending newline.
  1508.    toks0={#1endinput}%
  1509.    immediateopenoutmacscribble=jobname.tmp
  1510.    immediatewritemacscribble{thetoks0}%
  1511.    immediatecloseoutmacscribble
  1512.    letxeatspaceseatspaces
  1513.    input jobname.tmp
  1514.    endgroup
  1515. }
  1516. else
  1517. defscanmacro#1{%
  1518. begingroup newlinechar`^^M
  1519. % Undo catcode changes of startcontents and doprintindex
  1520. catcode`@=0 catcode`\=12 escapechar=`@
  1521. letxeatspaceseatspacesscantokens{#1endinput}endgroup}
  1522. fi
  1523. newcountparamno   % Count of parameters
  1524. newtoksmacname    % Macro name
  1525. newififrecursive  % Is it recursive?
  1526. defmacrolist{}    % List of all defined macros in the form
  1527.                     % domacro1domacro2...
  1528. % Utility routines.
  1529. % Thisdoes let #1 = #2, except with csnames.
  1530. defcslet#1#2{%
  1531. expandafterexpandafter
  1532. expandafterlet
  1533. expandafterexpandafter
  1534. csname#1endcsname
  1535. csname#2endcsname}
  1536. % Trim leading and trailing spaces off a string.
  1537. % Concepts from aro-bend problem 15 (see CTAN).
  1538. {catcode`@=11
  1539. gdefeatspaces #1{expandaftertrim@expandafter{#1 }}
  1540. gdeftrim@ #1{trim@@ @#1 @ #1 @ @@}
  1541. gdeftrim@@ #1@ #2@ #3@@{trim@@@empty #2 @}
  1542. defunbrace#1{#1}
  1543. unbrace{gdeftrim@@@ #1 } #2@{#1}
  1544. }
  1545. % Trim a single trailing ^^M off a string.
  1546. {catcode`^^M=12catcode`Q=3%
  1547. gdefeatcr #1{eatcra #1Q^^MQ}%
  1548. gdefeatcra#1^^MQ{eatcrb#1Q}%
  1549. gdefeatcrb#1Q#2Q{#1}%
  1550. }
  1551. % Macro bodies are absorbed as an argument in a context where
  1552. % all characters are catcode 10, 11 or 12, except  which is active
  1553. % (as in normal texinfo). It is necessary to change the definition of .
  1554. % It's necessary to have hard CRs when the macro is executed. This is
  1555. % done by  making ^^M (endlinechar) catcode 12 when reading the macro
  1556. % body, and then making it the newlinechar in scanmacro.
  1557. defmacrobodyctxt{%
  1558.   catcode`~=12
  1559.   catcode`^=12
  1560.   catcode`_=12
  1561.   catcode`|=12
  1562.   catcode`<=12
  1563.   catcode`>=12
  1564.   catcode`+=12
  1565.   catcode`{=12
  1566.   catcode`}=12
  1567.   catcode`@=12
  1568.   catcode`^^M=12
  1569.   usembodybackslash}
  1570. defmacroargctxt{%
  1571.   catcode`~=12
  1572.   catcode`^=12
  1573.   catcode`_=12
  1574.   catcode`|=12
  1575.   catcode`<=12
  1576.   catcode`>=12
  1577.   catcode`+=12
  1578.   catcode`@=12
  1579.   catcode`\=12}
  1580. % mbodybackslash is the definition of  in @macro bodies.
  1581. % It maps foo => csname macarg.fooendcsname => #N
  1582. % where N is the macro parameter number.
  1583. % We define csname macarg.endcsname to be realbackslash, so
  1584. % \ in macro replacement text gets you a backslash.
  1585. {catcode`@=0 @catcode`@=@active
  1586.  @gdef@usembodybackslash{@let=@mbodybackslash}
  1587.  @gdef@mbodybackslash#1{@csname macarg.#1@endcsname}
  1588. }
  1589. expandafterdefcsname macarg.endcsname{realbackslash}
  1590. defmacro{recursivefalseparseargmacroxxx}
  1591. defrmacro{recursivetrueparseargmacroxxx}
  1592. defmacroxxx#1{%
  1593.   getargs{#1}%           now macname is the macname and argl the arglist
  1594.   ifxarglempty       % no arguments
  1595.      paramno=0%
  1596.   else
  1597.      expandafterparsemargdef argl;%
  1598.   fi
  1599.   if1csname ismacro.themacnameendcsname
  1600.      message{Warning: redefining themacname}%
  1601.   else
  1602.      expandafterifxcsname themacnameendcsname relax
  1603.      else errmessage{The name themacnamespace is reserved}fi
  1604.      globalcslet{macsave.themacname}{themacname}%
  1605.      globalexpandafterletcsname ismacro.themacnameendcsname=1%
  1606.      % Add the macroname to macrolist
  1607.      toks0 = expandafter{macrolistdo}%
  1608.      xdefmacrolist{thetoks0
  1609.        expandafternoexpandcsnamethemacnameendcsname}%
  1610.   fi
  1611.   begingroup macrobodyctxt
  1612.   ifrecursive expandafterparsermacbody
  1613.   else expandafterparsemacbody
  1614.   fi}
  1615. defunmacro{parseargunmacroxxx}
  1616. defunmacroxxx#1{%
  1617.   if1csname ismacro.#1endcsname
  1618.     globalcslet{#1}{macsave.#1}%
  1619.     globalexpandafterlet csname ismacro.#1endcsname=0%
  1620.     % Remove the macro name from macrolist
  1621.     begingroup
  1622.       edeftempa{expandafternoexpandcsname#1endcsname}%
  1623.       defdo##1{%
  1624.         deftempb{##1}%
  1625.         ifxtempatempb
  1626.           % remove this
  1627.         else
  1628.           toks0 = expandafter{newmacrolistdo}%
  1629.           edefnewmacrolist{thetoks0expandafternoexpandtempa}%
  1630.         fi}%
  1631.       defnewmacrolist{}%
  1632.       % Execute macro list to define newmacrolist
  1633.       macrolist
  1634.       globalletmacrolistnewmacrolist
  1635.     endgroup
  1636.   else
  1637.     errmessage{Macro #1 not defined}%
  1638.   fi
  1639. }
  1640. % This makes use of the obscure feature that if the last token of a
  1641. % <parameter list> is #, then the preceding argument is delimited by
  1642. % an opening brace, and that opening brace is not consumed.
  1643. defgetargs#1{getargsxxx#1{}}
  1644. defgetargsxxx#1#{getmacname #1 relaxgetmacargs}
  1645. defgetmacname #1 #2relax{macname={#1}}
  1646. defgetmacargs#1{defargl{#1}}
  1647. % Parse the optional {params} list.  Set up paramno and paramlist
  1648. % so defmacro knows what to do.  Define macarg.blah for each blah
  1649. % in the params list, to be ##N where N is the position in that list.
  1650. % That gets used by mbodybackslash (above).
  1651. % We need to get `macro parameter char #' into several definitions.
  1652. % The technique used is stolen from LaTeX:  let hash be something
  1653. % unexpandable, insert that wherever you need a #, and then redefine
  1654. % it to # just before using the token list produced.
  1655. %
  1656. % The same technique is used to protect eatspaces till just before
  1657. % the macro is used.
  1658. defparsemargdef#1;{paramno=0defparamlist{}%
  1659.         lethashrelaxletxeatspacesrelaxparsemargdefxxx#1,;,}
  1660. defparsemargdefxxx#1,{%
  1661.   if#1;letnext=relax
  1662.   else letnext=parsemargdefxxx
  1663.     advanceparamno by 1%
  1664.     expandafteredefcsname macarg.eatspaces{#1}endcsname
  1665.         {xeatspaces{hashtheparamno}}%
  1666.     edefparamlist{paramlisthashtheparamno,}%
  1667.   finext}
  1668. % These two commands read recursive and nonrecursive macro bodies.
  1669. % (They're different since rec and nonrec macros end differently.)
  1670. longdefparsemacbody#1@end macro%
  1671. {xdeftemp{eatcr{#1}}endgroupdefmacro}%
  1672. longdefparsermacbody#1@end rmacro%
  1673. {xdeftemp{eatcr{#1}}endgroupdefmacro}%
  1674. % This defines the macro itself. There are six cases: recursive and
  1675. % nonrecursive macros of zero, one, and many arguments.
  1676. % Much magic with expandafter here.
  1677. % xdef is used so that macro definitions will survive the file
  1678. % they're defined in; @include reads the file inside a group.
  1679. defdefmacro{%
  1680.   lethash=##% convert placeholders to macro parameter chars
  1681.   ifrecursive
  1682.     ifcaseparamno
  1683.     % 0
  1684.       expandafterxdefcsnamethemacnameendcsname{%
  1685.         noexpandscanmacro{temp}}%
  1686.     or % 1
  1687.       expandafterxdefcsnamethemacnameendcsname{%
  1688.          bgroupnoexpandmacroargctxt
  1689.          noexpandbraceorline
  1690.          expandafternoexpandcsnamethemacname xxxendcsname}%
  1691.       expandafterxdefcsnamethemacname xxxendcsname##1{%
  1692.          egroupnoexpandscanmacro{temp}}%
  1693.     else % many
  1694.       expandafterxdefcsnamethemacnameendcsname{%
  1695.          bgroupnoexpandmacroargctxt
  1696.          noexpandcsnamethemacname xxendcsname}%
  1697.       expandafterxdefcsnamethemacname xxendcsname##1{%
  1698.           expandafternoexpandcsnamethemacname xxxendcsname ##1,}%
  1699.       expandafterexpandafter
  1700.       expandafterxdef
  1701.       expandafterexpandafter
  1702.         csnamethemacname xxxendcsname
  1703.           paramlist{egroupnoexpandscanmacro{temp}}%
  1704.     fi
  1705.   else
  1706.     ifcaseparamno
  1707.     % 0
  1708.       expandafterxdefcsnamethemacnameendcsname{%
  1709.         noexpandnorecurse{themacname}%
  1710.         noexpandscanmacro{temp}egroup}%
  1711.     or % 1
  1712.       expandafterxdefcsnamethemacnameendcsname{%
  1713.          bgroupnoexpandmacroargctxt
  1714.          noexpandbraceorline
  1715.          expandafternoexpandcsnamethemacname xxxendcsname}%
  1716.       expandafterxdefcsnamethemacname xxxendcsname##1{%
  1717.         egroup
  1718.         noexpandnorecurse{themacname}%
  1719.         noexpandscanmacro{temp}egroup}%
  1720.     else % many
  1721.       expandafterxdefcsnamethemacnameendcsname{%
  1722.          bgroupnoexpandmacroargctxt
  1723.          expandafternoexpandcsnamethemacname xxendcsname}%
  1724.       expandafterxdefcsnamethemacname xxendcsname##1{%
  1725.           expandafternoexpandcsnamethemacname xxxendcsname ##1,}%
  1726.       expandafterexpandafter
  1727.       expandafterxdef
  1728.       expandafterexpandafter
  1729.       csnamethemacname xxxendcsname
  1730.       paramlist{%
  1731.           egroup
  1732.           noexpandnorecurse{themacname}%
  1733.           noexpandscanmacro{temp}egroup}%
  1734.     fi
  1735.   fi}
  1736. defnorecurse#1{bgroupcslet{#1}{macsave.#1}}
  1737. % braceorline decides whether the next nonwhitespace character is a
  1738. % {.  If so it reads up to the closing }, if not, it reads the whole
  1739. % line.  Whatever was read is then fed to the next control sequence
  1740. % as an argument (by parsebrace or parsearg)
  1741. defbraceorline#1{letnext=#1futureletncharbraceorlinexxx}
  1742. defbraceorlinexxx{%
  1743.   ifxncharbgroupelse
  1744.     expandafterparsearg
  1745.   fi next}
  1746. % We mant to disable all macros during shipout so that they are not
  1747. % expanded by write.
  1748. defturnoffmacros{begingroup defdo##1{letnoexpand##1=relax}%
  1749.   edefnext{macrolist}expandafterendgroupnext}
  1750. % @alias.
  1751. defalias#1=#2{gdef#1{#2}}
  1752. message{cross references,}
  1753. newwriteauxfile
  1754. newififhavexrefs    % True if xref values are known.
  1755. newififwarnedxrefs  % True if we warned once that they aren't known.
  1756. % @inforef is relatively simple.
  1757. definforef #1{inforefzzz #1,,,,**}
  1758. definforefzzz #1,#2,#3,#4**{putwordSee{} putwordInfo{} putwordfile{} file{ignorespaces #3{}},
  1759.   node samp{ignorespaces#1{}}}
  1760. % @node's job is to define lastnode.
  1761. defnode{ENVcheckparseargnodezzz}
  1762. defnodezzz#1{nodexxx [#1,]}
  1763. defnodexxx[#1,#2]{gdeflastnode{#1}}
  1764. letnwnode=node
  1765. letlastnode=relax
  1766. % The sectioning commands (@chapter, etc.) call these.
  1767. defdonoderef{%
  1768.   ifxlastnoderelaxelse
  1769.     expandafterexpandafterexpandaftersetref{lastnode}%
  1770.       {Ysectionnumberandtype}%
  1771.     globalletlastnode=relax
  1772.   fi
  1773. }
  1774. defunnumbnoderef{%
  1775.   ifxlastnoderelaxelse
  1776.     expandafterexpandafterexpandaftersetref{lastnode}{Ynothing}%
  1777.     globalletlastnode=relax
  1778.   fi
  1779. }
  1780. defappendixnoderef{%
  1781.   ifxlastnoderelaxelse
  1782.     expandafterexpandafterexpandaftersetref{lastnode}%
  1783.       {Yappendixletterandtype}%
  1784.     globalletlastnode=relax
  1785.   fi
  1786. }
  1787. % @anchor{NAME} -- define xref target at arbitrary point.
  1788. %
  1789. defanchor#1{setref{#1}{Ynothing}}
  1790. % setref{NAME}{SNT} defines a cross-reference point NAME, namely
  1791. % NAME-title, NAME-pg, and NAME-SNT.  Called from foonoderef.  We have
  1792. % to set indexdummies so commands such as @code in a section title
  1793. % aren't expanded.  It would be nicer not to expand the titles in the
  1794. % first place, but there's so many layers that that is hard to do.
  1795. %
  1796. defsetref#1#2{{%
  1797.   indexdummies
  1798.   dosetq{#1-title}{Ytitle}%
  1799.   dosetq{#1-pg}{Ypagenumber}%
  1800.   dosetq{#1-snt}{#2}%
  1801. }}
  1802. % @xref, @pxref, and @ref generate cross-references.  For xrefX, #1 is
  1803. % the node name, #2 the name of the Info cross-reference, #3 the printed
  1804. % node name, #4 the name of the Info file, #5 the name of the printed
  1805. % manual.  All but the node name can be omitted.
  1806. %
  1807. defpxref#1{putwordsee{} xrefX[#1,,,,,,,]}
  1808. defxref#1{putwordSee{} xrefX[#1,,,,,,,]}
  1809. defref#1{xrefX[#1,,,,,,,]}
  1810. defxrefX[#1,#2,#3,#4,#5,#6]{begingroup
  1811.   defprintedmanual{ignorespaces #5}%
  1812.   defprintednodename{ignorespaces #3}%
  1813.   setbox1=hbox{printedmanual}%
  1814.   setbox0=hbox{printednodename}%
  1815.   ifdim wd0 = 0pt
  1816.     % No printed node name was explicitly given.
  1817.     expandafterifxcsname SETxref-automatic-section-titleendcsnamerelax
  1818.       % Use the node name inside the square brackets.
  1819.       defprintednodename{ignorespaces #1}%
  1820.     else
  1821.       % Use the actual chapter/section title appear inside
  1822.       % the square brackets.  Use the real section title if we have it.
  1823.       ifdim wd1 > 0pt
  1824.         % It is in another manual, so we don't have it.
  1825.         defprintednodename{ignorespaces #1}%
  1826.       else
  1827.         ifhavexrefs
  1828.           % We know the real title if we have the xref values.
  1829.           defprintednodename{refx{#1-title}{}}%
  1830.         else
  1831.           % Otherwise just copy the Info node name.
  1832.           defprintednodename{ignorespaces #1}%
  1833.         fi%
  1834.       fi
  1835.     fi
  1836.   fi
  1837.   %
  1838.   % If we use unhbox0 and unhbox1 to print the node names, TeX does not
  1839.   % insert empty discretionaries after hyphens, which means that it will
  1840.   % not find a line break at a hyphen in a node names.  Since some manuals
  1841.   % are best written with fairly long node names, containing hyphens, this
  1842.   % is a loss.  Therefore, we give the text of the node name again, so it
  1843.   % is as if TeX is seeing it for the first time.
  1844.   ifdim wd1 > 0pt
  1845.     putwordsection{} ``printednodename'' in cite{printedmanual}%
  1846.   else
  1847.     % _ (for example) has to be the character _ for the purposes of the
  1848.     % control sequence corresponding to the node, but it has to expand
  1849.     % into the usual leavevmode...vrule stuff for purposes of
  1850.     % printing. So we turnoffactive for the refx-snt, back on for the
  1851.     % printing, back off for the refx-pg.
  1852.     {normalturnoffactive
  1853.      % Only output a following space if the -snt ref is nonempty; for
  1854.      % @unnumbered and @anchor, it won't be.
  1855.      setbox2 = hbox{ignorespaces refx{#1-snt}{}}%
  1856.      ifdim wd2 > 0pt refx{#1-snt}spacefi
  1857.     }%
  1858.     % [mynode],
  1859.     [printednodename],space
  1860.     % page 3
  1861.     turnoffactive putwordpagetierefx{#1-pg}{}%
  1862.   fi
  1863. endgroup}
  1864. % dosetq is the interface for calls from other macros
  1865. % Use normalturnoffactive so that punctuation chars such as underscore
  1866. % and backslash work in node names.  (turnoffactive doesn't do .)
  1867. defdosetq#1#2{%
  1868.   {letfolio=0
  1869.    normalturnoffactive
  1870.    edefnext{writeauxfile{internalsetq{#1}{#2}}}%
  1871.    iflinks
  1872.      next
  1873.    fi
  1874.   }%
  1875. }
  1876. % internalsetq {foo}{page} expands into
  1877. % CHARACTERS 'xrdef {foo}{...expansion of Ypage...}
  1878. % When the aux file is read, ' is the escape character
  1879. definternalsetq #1#2{'xrdef {#1}{csname #2endcsname}}
  1880. % Things to be expanded by internalsetq
  1881. defYpagenumber{folio}
  1882. defYtitle{thissection}
  1883. defYnothing{}
  1884. defYsectionnumberandtype{%
  1885. ifnumsecno=0 putwordChapterxreftiethechapno %
  1886. else ifnum subsecno=0 putwordSectionxreftiethechapno.thesecno %
  1887. else ifnum subsubsecno=0 %
  1888. putwordSectionxreftiethechapno.thesecno.thesubsecno %
  1889. else %
  1890. putwordSectionxreftiethechapno.thesecno.thesubsecno.thesubsubsecno %
  1891. fi fi fi }
  1892. defYappendixletterandtype{%
  1893. ifnumsecno=0 putwordAppendixxreftie'chartheappendixno{}%
  1894. else ifnum subsecno=0 putwordSectionxreftie'chartheappendixno.thesecno %
  1895. else ifnum subsubsecno=0 %
  1896. putwordSectionxreftie'chartheappendixno.thesecno.thesubsecno %
  1897. else %
  1898. putwordSectionxreftie'chartheappendixno.thesecno.thesubsecno.thesubsubsecno %
  1899. fi fi fi }
  1900. gdefxreftie{'tie}
  1901. % Use TeX 3.0's inputlineno to get the line number, for better error
  1902. % messages, but if we're using an old version of TeX, don't do anything.
  1903. %
  1904. ifxinputlinenothisisundefined
  1905.   letlinenumber = empty % Non-3.0.
  1906. else
  1907.   deflinenumber{theinputlineno:space}
  1908. fi
  1909. % Define refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
  1910. % If its value is nonempty, SUFFIX is output afterward.
  1911. defrefx#1#2{%
  1912.   expandafterifxcsname X#1endcsnamerelax
  1913.     % If not defined, say something at least.
  1914.     angleleft un-de-finedangleright
  1915.     iflinks
  1916.       ifhavexrefs
  1917.         message{linenumber Undefined cross reference `#1'.}%
  1918.       else
  1919.         ifwarnedxrefselse
  1920.           globalwarnedxrefstrue
  1921.           message{Cross reference values unknown; you must run TeX again.}%
  1922.         fi
  1923.       fi
  1924.     fi
  1925.   else
  1926.     % It's defined, so just use it.
  1927.     csname X#1endcsname
  1928.   fi
  1929.   #2% Output the suffix in any case.
  1930. }
  1931. % This is the macro invoked by entries in the aux file.
  1932. %
  1933. defxrdef#1{begingroup
  1934.   % Reenable  as an escape while reading the second argument.
  1935.   catcode`\ = 0
  1936.   afterassignmentendgroup
  1937.   expandaftergdefcsname X#1endcsname
  1938. }
  1939. % Read the last existing aux file, if any.  No error if none exists.
  1940. defreadauxfile{begingroup
  1941.   catcode`^^@=other
  1942.   catcode`^^A=other
  1943.   catcode`^^B=other
  1944.   catcode`^^C=other
  1945.   catcode`^^D=other
  1946.   catcode`^^E=other
  1947.   catcode`^^F=other
  1948.   catcode`^^G=other
  1949.   catcode`^^H=other
  1950.   catcode`^^K=other
  1951.   catcode`^^L=other
  1952.   catcode`^^N=other
  1953.   catcode`^^P=other
  1954.   catcode`^^Q=other
  1955.   catcode`^^R=other
  1956.   catcode`^^S=other
  1957.   catcode`^^T=other
  1958.   catcode`^^U=other
  1959.   catcode`^^V=other
  1960.   catcode`^^W=other
  1961.   catcode`^^X=other
  1962.   catcode`^^Z=other
  1963.   catcode`^^[=other
  1964.   catcode`^^=other
  1965.   catcode`^^]=other
  1966.   catcode`^^^=other
  1967.   catcode`^^_=other
  1968.   catcode`@=other
  1969.   catcode`^=other
  1970.   % It was suggested to define this as 7, which would allow ^^e4 etc.
  1971.   % in xref tags, i.e., node names.  But since ^^e4 notation isn't
  1972.   % supported in the main text, it doesn't seem desirable.  Furthermore,
  1973.   % that is not enough: for node names that actually contain a ^
  1974.   % character, we would end up writing a line like this: 'xrdef {'hat
  1975.   % b-title}{'hat b} and xrdef does a csname...endcsname on the first
  1976.   % argument, and hat is not an expandable control sequence.  It could
  1977.   % all be worked out, but why?  Either we support ^^ or we don't.
  1978.   %
  1979.   % The other change necessary for this was to define auxhat:
  1980.   % defauxhat{def^{'hat }}% extra space so ok if followed by letter
  1981.   % and then to call auxhat in setq.
  1982.   %
  1983.   catcode`~=other
  1984.   catcode`[=other
  1985.   catcode`]=other
  1986.   catcode`"=other
  1987.   catcode`_=other
  1988.   catcode`|=other
  1989.   catcode`<=other
  1990.   catcode`>=other
  1991.   catcode`$=other
  1992.   catcode`#=other
  1993.   catcode`&=other
  1994.   catcode`+=other % avoid + for paranoia even though we've turned it off
  1995.   % Make the characters 128-255 be printing characters
  1996.   {%
  1997.     count 1=128
  1998.     defloop{%
  1999.       catcodecount 1=other
  2000.       advancecount 1 by 1
  2001.       ifnum count 1<256 loop fi
  2002.     }%
  2003.   }%
  2004.   % The aux file uses ' as the escape (for now).
  2005.   % Turn off  as an escape so we do not lose on
  2006.   % entries which were dumped with control sequences in their names.
  2007.   % For example, 'xrdef {$leq $-fun}{page ...} made by @defun ^^
  2008.   % Reference to such entries still does not work the way one would wish,
  2009.   % but at least they do not bomb out when the aux file is read in.
  2010.   catcode`{=1
  2011.   catcode`}=2
  2012.   catcode`%=other
  2013.   catcode`'=0
  2014.   catcode`\=other
  2015.   %
  2016.   openin 1 jobname.aux
  2017.   ifeof 1 else
  2018.     closein 1
  2019.     input jobname.aux
  2020.     globalhavexrefstrue
  2021.     globalwarnedobstrue
  2022.   fi
  2023.   % Open the new aux file.  TeX will close it automatically at exit.
  2024.   openoutauxfile=jobname.aux
  2025. endgroup}
  2026. % Footnotes.
  2027. newcount footnoteno
  2028. % The trailing space in the following definition for supereject is
  2029. % vital for proper filling; pages come out unaligned when you do a
  2030. % pagealignmacro call if that space before the closing brace is
  2031. % removed. (Generally, numeric constants should always be followed by a
  2032. % space to prevent strange expansion errors.)
  2033. defsupereject{parpenalty -20000footnoteno =0 }
  2034. % @footnotestyle is meaningful for info output only.
  2035. letfootnotestyle=comment
  2036. letptexfootnote=footnote
  2037. {catcode `@=11
  2038. %
  2039. % Auto-number footnotes.  Otherwise like plain.
  2040. gdeffootnote{%
  2041.   globaladvancefootnoteno by @ne
  2042.   edefthisfootno{$^{thefootnoteno}$}%
  2043.   %
  2044.   % In case the footnote comes at the end of a sentence, preserve the
  2045.   % extra spacing after we do the footnote number.
  2046.   let@sfempty
  2047.   ifhmodeedef@sf{spacefactorthespacefactor}/fi
  2048.   %
  2049.   % Remove inadvertent blank space before typesetting the footnote number.
  2050.   unskip
  2051.   thisfootno@sf
  2052.   footnotezzz
  2053. }%
  2054. % Don't bother with the trickery in plain.tex to not require the
  2055. % footnote text as a parameter.  Our footnotes don't need to be so general.
  2056. %
  2057. % Oh yes, they do; otherwise, @ifset and anything else that uses
  2058. % parseargline fail inside footnotes because the tokens are fixed when
  2059. % the footnote is read.  --karl, 16nov96.
  2060. %
  2061. longgdeffootnotezzz{insertfootinsbgroup
  2062.   % We want to typeset this text as a normal paragraph, even if the
  2063.   % footnote reference occurs in (for example) a display environment.
  2064.   % So reset some parameters.
  2065.   interlinepenaltyinterfootnotelinepenalty
  2066.   splittopskiphtstrutbox % top baseline for broken footnotes
  2067.   splitmaxdepthdpstrutbox
  2068.   floatingpenalty@MM
  2069.   leftskipz@skip
  2070.   rightskipz@skip
  2071.   spaceskipz@skip
  2072.   xspaceskipz@skip
  2073.   parindentdefaultparindent
  2074.   %
  2075.   % Hang the footnote text off the number.
  2076.   hang
  2077.   textindent{thisfootno}%
  2078.   %
  2079.   % Don't crash into the line above the footnote text.  Since this
  2080.   % expands into a box, it must come within the paragraph, lest it
  2081.   % provide a place where TeX can split the footnote.
  2082.   footstrut
  2083.   futureletnextfo@t
  2084. }
  2085. deffo@t{ifcatbgroupnoexpandnext letnextf@@t
  2086.   elseletnextf@tfi next}
  2087. deff@@t{bgroupaftergroup@footletnext}
  2088. deff@t#1{#1@foot}
  2089. def@foot{strutegroup}
  2090. }%end catcode `@=11
  2091. % Set the baselineskip to #1, and the lineskip and strut size
  2092. % correspondingly.  There is no deep meaning behind these magic numbers
  2093. % used as factors; they just match (closely enough) what Knuth defined.
  2094. %
  2095. deflineskipfactor{.08333}
  2096. defstrutheightpercent{.70833}
  2097. defstrutdepthpercent {.29167}
  2098. %
  2099. defsetleading#1{%
  2100.   normalbaselineskip = #1relax
  2101.   normallineskip = lineskipfactornormalbaselineskip
  2102.   normalbaselines
  2103.   setboxstrutbox =hbox{%
  2104.     vrule width0pt heightstrutheightpercentbaselineskip
  2105.                     depth strutdepthpercent baselineskip
  2106.   }%
  2107. }
  2108. % @| inserts a changebar to the left of the current line.  It should
  2109. % surround any changed text.  This approach does *not* work if the
  2110. % change spans more than two lines of output.  To handle that, we would
  2111. % have adopt a much more difficult approach (putting marks into the main
  2112. % vertical list for the beginning and end of each change).
  2113. %
  2114. def|{%
  2115.   % vadjust can only be used in horizontal mode.
  2116.   leavevmode
  2117.   %
  2118.   % Append this vertical mode material after the current line in the output.
  2119.   vadjust{%
  2120.     % We want to insert a rule with the height and depth of the current
  2121.     % leading; that is exactly what strutbox is supposed to record.
  2122.     vskip-baselineskip
  2123.     %
  2124.     % vadjust-items are inserted at the left edge of the type.  So
  2125.     % the llap here moves out into the left-hand margin.
  2126.     llap{%
  2127.       %
  2128.       % For a thicker or thinner bar, change the `1pt'.
  2129.       vrule heightbaselineskip width1pt
  2130.       %
  2131.       % This is the space between the bar and the text.
  2132.       hskip 12pt
  2133.     }%
  2134.   }%
  2135. }
  2136. % For a final copy, take out the rectangles
  2137. % that mark overfull boxes (in case you have decided
  2138. % that the text looks ok even though it passes the margin).
  2139. %
  2140. deffinalout{overfullrule=0pt}
  2141. % @image.  We use the macros from epsf.tex to support this.
  2142. % If epsf.tex is not installed and @image is used, we complain.
  2143. %
  2144. % Check for and read epsf.tex up front.  If we read it only at @image
  2145. % time, we might be inside a group, and then its definitions would get
  2146. % undone and the next image would fail.
  2147. openin 1 = epsf.tex
  2148. ifeof 1 else
  2149.   closein 1
  2150.   % Do not bother showing banner with post-v2.7 epsf.tex (available in
  2151.   % doc/epsf.tex until it shows up on ctan).
  2152.   defepsfannounce{toks0 = }%
  2153.   input epsf.tex
  2154. fi
  2155. %
  2156. newififwarnednoepsf
  2157. newhelpnoepsfhelp{epsf.tex must be installed for images to
  2158.   work.  It is also included in the Texinfo distribution, or you can get
  2159.   it from ftp://tug.org/tex/epsf.tex.}
  2160. %
  2161. % Only complain once about lack of epsf.tex.
  2162. defimage#1{%
  2163.   ifxpdfoutputundefined
  2164.     ifxepsfboxundefined
  2165.       ifwarnednoepsf else
  2166.         errhelp = noepsfhelp
  2167.         errmessage{epsf.tex not found, images will be ignored}%
  2168.         globalwarnednoepsftrue
  2169.       fi
  2170.     else
  2171.       imagexxx #1,,,finish
  2172.     fi
  2173.   else
  2174.     centerline{pdfimage #1.pdf}%
  2175.   fi
  2176. }
  2177. %
  2178. % Arguments to @image:
  2179. % #1 is (mandatory) image filename; we tack on .eps extension.
  2180. % #2 is (optional) width, #3 is (optional) height.
  2181. % #4 is just the usual extra ignored arg for parsing this stuff.
  2182. defimagexxx#1,#2,#3,#4finish{%
  2183.   % epsfbox itself resets epsf?size at each figure.
  2184.   setbox0 = hbox{ignorespaces #2}ifdimwd0 > 0pt epsfxsize=#2relax fi
  2185.   setbox0 = hbox{ignorespaces #3}ifdimwd0 > 0pt epsfysize=#3relax fi
  2186.   % If the image is by itself, center it.
  2187.   ifvmode
  2188.     nobreakmedskip
  2189.     nobreak
  2190.     centerline{epsfbox{#1.eps}}%
  2191.     bigbreak
  2192.   else
  2193.     % In the middle of a paragraph, no extra space.
  2194.     epsfbox{#1.eps}%
  2195.   fi
  2196. }
  2197. message{localization,}
  2198. % @documentlanguage is usually given very early, just after
  2199. % @setfilename.  If done too late, it may not override everything
  2200. % properly.  Single argument is the language abbreviation.
  2201. % It would be nice if we could set up a hyphenation file here.
  2202. %
  2203. defdocumentlanguage{parseargdodocumentlanguage}
  2204. defdodocumentlanguage#1{%
  2205.   tex % read txi-??.tex file in plain TeX.
  2206.   % Read the file if it exists.
  2207.   openin 1 txi-#1.tex
  2208.   ifeof1
  2209.     errhelp = nolanghelp
  2210.     errmessage{Cannot read language file txi-#1.tex}%
  2211.     lettemp = relax
  2212.   else
  2213.     deftemp{input txi-#1.tex }%
  2214.   fi
  2215.   temp
  2216.   endgroup
  2217. }
  2218. newhelpnolanghelp{The given language definition file cannot be found or
  2219. is empty.  Maybe you need to install it?  In the current directory
  2220. should work if nowhere else does.}
  2221. % @documentencoding should change something in TeX eventually, most
  2222. % likely, but for now just recognize it.
  2223. letdocumentencoding = comment
  2224. % Page size parameters.
  2225. %
  2226. newdimendefaultparindent defaultparindent = 15pt
  2227. chapheadingskip = 15pt plus 4pt minus 2pt
  2228. secheadingskip = 12pt plus 3pt minus 2pt
  2229. subsecheadingskip = 9pt plus 2pt minus 2pt
  2230. % Prevent underfull vbox error messages.
  2231. vbadness = 10000
  2232. % Don't be so finicky about underfull hboxes, either.
  2233. hbadness = 2000
  2234. % Following George Bush, just get rid of widows and orphans.
  2235. widowpenalty=10000
  2236. clubpenalty=10000
  2237. % Use TeX 3.0's emergencystretch to help line breaking, but if we're
  2238. % using an old version of TeX, don't do anything.  We want the amount of
  2239. % stretch added to depend on the line length, hence the dependence on
  2240. % hsize.  We call this whenever the paper size is set.
  2241. %
  2242. defsetemergencystretch{%
  2243.   ifxemergencystretchthisisundefined
  2244.     % Allow us to assign to emergencystretch anyway.
  2245.     defemergencystretch{dimen0}%
  2246.   else
  2247.     emergencystretch = hsize
  2248.     divideemergencystretch by 40
  2249.   fi
  2250. }
  2251. % Parameters in order: 1) textheight; 2) textwidth; 3) voffset;
  2252. % 4) hoffset; 5) binding offset; 6) topskip.  Then whoever calls us can
  2253. % set parskip and call setleading for baselineskip.
  2254. %
  2255. definternalpagesizes#1#2#3#4#5#6{%
  2256.   voffset = #3relax
  2257.   topskip = #6relax
  2258.   splittopskip = topskip
  2259.   %
  2260.   vsize = #1relax
  2261.   advancevsize by topskip
  2262.   outervsize = vsize
  2263.   advanceoutervsize by 2topandbottommargin
  2264.   pageheight = vsize
  2265.   %
  2266.   hsize = #2relax
  2267.   outerhsize = hsize
  2268.   advanceouterhsize by 0.5in
  2269.   pagewidth = hsize
  2270.   %
  2271.   normaloffset = #4relax
  2272.   bindingoffset = #5relax
  2273.   %
  2274.   parindent = defaultparindent
  2275.   setemergencystretch
  2276. }
  2277. % @letterpaper (the default).
  2278. defletterpaper{{globaldefs = 1
  2279.   parskip = 3pt plus 2pt minus 1pt
  2280.   setleading{13.2pt}%
  2281.   %
  2282.   % If page is nothing but text, make it come out even.
  2283.   internalpagesizes{46baselineskip}{6in}{voffset}{.25in}{bindingoffset}{36pt}%
  2284. }}
  2285. % Use @smallbook to reset parameters for 7x9.5 (or so) format.
  2286. defsmallbook{{globaldefs = 1
  2287.   parskip = 2pt plus 1pt
  2288.   setleading{12pt}%
  2289.   %
  2290.   internalpagesizes{7.5in}{5.in}{voffset}{.25in}{bindingoffset}{16pt}%
  2291.   %
  2292.   lispnarrowing = 0.3in
  2293.   tolerance = 700
  2294.   hfuzz = 1pt
  2295.   contentsrightmargin = 0pt
  2296.   deftypemargin = 0pt
  2297.   defbodyindent = .5cm
  2298.   %
  2299.   letsmalldisplay = smalldisplayx
  2300.   letsmallexample = smalllispx
  2301.   letsmallformat = smallformatx
  2302.   letsmalllisp = smalllispx
  2303. }}
  2304. % Use @afourpaper to print on European A4 paper.
  2305. defafourpaper{{globaldefs = 1
  2306.   setleading{12pt}%
  2307.   parskip = 3pt plus 2pt minus 1pt
  2308.   %
  2309.   internalpagesizes{53baselineskip}{160mm}{voffset}{4mm}{bindingoffset}{44pt}%
  2310.   %
  2311.   tolerance = 700
  2312.   hfuzz = 1pt
  2313. }}
  2314. % A specific text layout, 24x15cm overall, intended for A4 paper.  Top margin
  2315. % 29mm, hence bottom margin 28mm, nominal side margin 3cm.
  2316. defafourlatex{{globaldefs = 1
  2317.   setleading{13.6pt}%
  2318.   %
  2319.   afourpaper
  2320.   internalpagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}%
  2321.   %
  2322.   globaldefs = 0
  2323. }}
  2324. % Use @afourwide to print on European A4 paper in wide format.
  2325. defafourwide{%
  2326.   afourpaper
  2327.   internalpagesizes{9.5in}{6.5in}{hoffset}{normaloffset}{bindingoffset}{7mm}%
  2328.   %
  2329.   globaldefs = 0
  2330. }
  2331. % @pagesizes TEXTHEIGHT[,TEXTWIDTH]
  2332. % Perhaps we should allow setting the margins, topskip, parskip,
  2333. % and/or leading, also. Or perhaps we should compute them somehow.
  2334. %
  2335. defpagesizes{parseargpagesizesxxx}
  2336. defpagesizesxxx#1{pagesizesyyy #1,,finish}
  2337. defpagesizesyyy#1,#2,#3finish{{%
  2338.   setbox0 = hbox{ignorespaces #2}ifdimwd0 > 0pt hsize=#2relax fi
  2339.   globaldefs = 1
  2340.   %
  2341.   parskip = 3pt plus 2pt minus 1pt
  2342.   setleading{13.2pt}%
  2343.   %
  2344.   internalpagesizes{#1}{hsize}{voffset}{normaloffset}{bindingoffset}{44pt}%
  2345. }}
  2346. % Set default to letter.
  2347. %
  2348. letterpaper
  2349. message{and turning on texinfo input format.}
  2350. % Define macros to output various characters with catcode for normal text.
  2351. catcode`"=other
  2352. catcode`~=other
  2353. catcode`^=other
  2354. catcode`_=other
  2355. catcode`|=other
  2356. catcode`<=other
  2357. catcode`>=other
  2358. catcode`+=other
  2359. defnormaldoublequote{"}
  2360. defnormaltilde{~}
  2361. defnormalcaret{^}
  2362. defnormalunderscore{_}
  2363. defnormalverticalbar{|}
  2364. defnormalless{<}
  2365. defnormalgreater{>}
  2366. defnormalplus{+}
  2367. % This macro is used to make a character print one way in ttfont
  2368. % where it can probably just be output, and another way in other fonts,
  2369. % where something hairier probably needs to be done.
  2370. %
  2371. % #1 is what to print if we are indeed using tt; #2 is what to print
  2372. % otherwise.  Since all the Computer Modern typewriter fonts have zero
  2373. % interword stretch (and shrink), and it is reasonable to expect all
  2374. % typewriter fonts to have this, we can check that font parameter.
  2375. %
  2376. defifusingtt#1#2{ifdim fontdimen3thefont=0pt #1else #2fi}
  2377. % Turn off all special characters except @
  2378. % (and those which the user can use as if they were ordinary).
  2379. % Most of these we simply print from the tt font, but for some, we can
  2380. % use math or other variants that look better in normal text.
  2381. catcode`"=active
  2382. defactivedoublequote{{ttchar34}}
  2383. let"=activedoublequote
  2384. catcode`~=active
  2385. def~{{ttchar126}}
  2386. chardefhat=`^
  2387. catcode`^=active
  2388. def^{{tt hat}}
  2389. catcode`_=active
  2390. def_{ifusingttnormalunderscore_}
  2391. % Subroutine for the previous macro.
  2392. def_{leavevmode kern.06em vbox{hrule width.3em height.1ex}}
  2393. catcode`|=active
  2394. def|{{ttchar124}}
  2395. chardef less=`<
  2396. catcode`<=active
  2397. def<{{tt less}}
  2398. chardef gtr=`>
  2399. catcode`>=active
  2400. def>{{tt gtr}}
  2401. catcode`+=active
  2402. def+{{tt char 43}}
  2403. %catcode 27=active
  2404. %def^^[{$diamondsuit$}
  2405. % Set up an active definition for =, but don't enable it most of the time.
  2406. {catcode`==active
  2407. globaldef={{tt char 61}}}
  2408. catcode`+=active
  2409. catcode`_=active
  2410. % If a .fmt file is being used, characters that might appear in a file
  2411. % name cannot be active until we have parsed the command line.
  2412. % So turn them off again, and have everyjob (or @setfilename) turn them on.
  2413. % otherifyactive is called near the end of this file.
  2414. defotherifyactive{catcode`+=other catcode`_=other}
  2415. catcode`@=0
  2416. % rawbackslashxx output one backslash character in current font
  2417. globalchardefrawbackslashxx=`\
  2418. %{catcode`\=other
  2419. %@gdef@rawbackslashxx{}}
  2420. % rawbackslash redefines  as input to do rawbackslashxx.
  2421. {catcode`\=active
  2422. @gdef@rawbackslash{@let=@rawbackslashxx }}
  2423. % normalbackslash outputs one backslash in fixed width font.
  2424. defnormalbackslash{{ttrawbackslashxx}}
  2425. % Say @foo, not foo, in error messages.
  2426. escapechar=`@
  2427. % catcode 17=0   % Define control-q
  2428. catcode`\=active
  2429. % Used sometimes to turn off (effectively) the active characters
  2430. % even after parsing them.
  2431. @def@turnoffactive{@let"=@normaldoublequote
  2432. @let=@realbackslash
  2433. @let~=@normaltilde
  2434. @let^=@normalcaret
  2435. @let_=@normalunderscore
  2436. @let|=@normalverticalbar
  2437. @let<=@normalless
  2438. @let>=@normalgreater
  2439. @let+=@normalplus}
  2440. @def@normalturnoffactive{@let"=@normaldoublequote
  2441. @let=@normalbackslash
  2442. @let~=@normaltilde
  2443. @let^=@normalcaret
  2444. @let_=@normalunderscore
  2445. @let|=@normalverticalbar
  2446. @let<=@normalless
  2447. @let>=@normalgreater
  2448. @let+=@normalplus}
  2449. % Make _ and + other characters, temporarily.
  2450. % This is canceled by @fixbackslash.
  2451. @otherifyactive
  2452. % If a .fmt file is being used, we don't want the `input texinfo' to show up.
  2453. % That is what eatinput is for; after that, the `' should revert to printing
  2454. % a backslash.
  2455. %
  2456. @gdef@eatinput input texinfo{@fixbackslash}
  2457. @global@let = @eatinput
  2458. % On the other hand, perhaps the file did not have a `input texinfo'. Then
  2459. % the first `{ in the file would cause an error. This macro tries to fix
  2460. % that, assuming it is called before the first `' could plausibly occur.
  2461. % Also back turn on active characters that might appear in the input
  2462. % file name, in case not using a pre-dumped format.
  2463. %
  2464. @gdef@fixbackslash{@ifx@eatinput @let = @normalbackslash @fi
  2465.   @catcode`+=@active @catcode`@_=@active}
  2466. % These look ok in all fonts, so just make them not special.  The @rm below
  2467. % makes sure that the current font starts out as the newly loaded cmr10
  2468. @catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
  2469. @textfonts
  2470. @rm
  2471. @c Local variables:
  2472. @c eval: (add-hook 'write-file-hooks 'time-stamp)
  2473. @c page-delimiter: "^\\message"
  2474. @c time-stamp-start: "def\\texinfoversion{"
  2475. @c time-stamp-format: "%:y-%02m-%02d.%H"
  2476. @c time-stamp-end: "}"
  2477. @c End: