home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / lout / part24 < prev    next >
Encoding:
Text File  |  1993-06-19  |  82.5 KB  |  2,166 lines

  1. Newsgroups: comp.sources.misc
  2. From: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  3. Subject: v37i122:  lout - Lout document formatting system, v2, Part24/30
  4. Message-ID: <1993Jun2.030501.28853@sparky.imd.sterling.com>
  5. X-Md4-Signature: 135715d89c295cb429cebe77ed816289
  6. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Wed, 2 Jun 1993 03:05:01 GMT
  9. Approved: kent@sparky.imd.sterling.com
  10.  
  11. Submitted-by: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  12. Posting-number: Volume 37, Issue 122
  13. Archive-name: lout/part24
  14. Environment: UNIX
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  lout/doc/tr.begin/s14 lout/doc/tr.fig/s5
  21. #   lout/doc/tr.impl/s3.2 lout/doc/tr.lout/ch1.02
  22. #   lout/doc/tr.lout/ch2.06 lout/doc/tr.lout/ch4.03 lout/makefile
  23. #   lout/z30.c lout/z31.c
  24. # Wrapped by kent@sparky on Sun May 30 19:44:01 1993
  25. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  26. echo If this archive is complete, you will see the following message:
  27. echo '          "shar: End of archive 24 (of 30)."'
  28. if test -f 'lout/doc/tr.begin/s14' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'lout/doc/tr.begin/s14'\"
  30. else
  31.   echo shar: Extracting \"'lout/doc/tr.begin/s14'\" \(9025 characters\)
  32.   sed "s/^X//" >'lout/doc/tr.begin/s14' <<'END_OF_FILE'
  33. X@Section
  34. X   @Tag { booklayout }
  35. X   @Title { Books }
  36. X@Begin
  37. X@PP
  38. XThe DocumentLayout package may also be used to produce books.  Type
  39. X@Code "-ibook" in the Unix command instead of {@Code "-idoc"} to use the
  40. Xpackage in this way.
  41. X@PP
  42. XA book begins with a @Code "@Book" symbol:
  43. X@ID @Code {
  44. X"@Book"
  45. X"    @Title {}"
  46. X"    @Author {}"
  47. X"    @Edition {}"
  48. X"    @Publisher {}"
  49. X"    @InitialFont { Times Roman 12p }"
  50. X"    @InitialBreak { adjust 1.2fx }"
  51. X"    @Hyphenate { Yes }"
  52. X"//"
  53. X}
  54. XThe first four options are printed on the title page, the first three
  55. Xusing {@Code "clines @Break"} (see page {@PageOf clines}).  There are no
  56. X{@Code "@Columns"}, {@Code "@PageNumbers"}, or {@Code "@FirstPageNumber"}
  57. Xoptions.  The last three options are as for @Code "@Document" and
  58. X{@Code "@Report"}.  Disaster will ensue if the @Code "//" is omitted.
  59. X@PP
  60. XNext comes an optional preface:
  61. X@ID @Code {
  62. X"@Preface"
  63. X"    @Tag { preface }"
  64. X"    @Title { About this book }"
  65. X"@Begin"
  66. X"@PP"
  67. X"..."
  68. X"@End @Preface"
  69. X}
  70. XSince the title of most prefaces is simply Preface, this is the default
  71. Xvalue of the @Code "@Title" option.  After the preface, BookLayout will
  72. Xproduce a table of contents listing the introduction, chapters,
  73. Xsections, subsections, appendices, biblio&-graphy, and index as
  74. Xappropriate.
  75. X@PP
  76. XThe pages up to this point will be numbered in lower case Roman
  77. Xnumerals; subsequent pages will be numbered in Arabic starting from 1.
  78. X@PP
  79. XNext comes an optional introduction, in exactly the same style as the
  80. Xpreface except that @Code "@Introduction" replaces @Code "@Preface" and
  81. Xthe default title is Introduction.  After that comes a sequence of chapters
  82. Xin the usual style:
  83. X@ID @Code {
  84. X"@Chapter"
  85. X"    @Title { Principles }"
  86. X"    @Tag { principles }"
  87. X"@Begin"
  88. X"@PP"
  89. X"..."
  90. X"@End @Chapter"
  91. X}
  92. XNo @Code "@BeginChapters" or @Code "@EndChapters" symbols are
  93. Xneeded.  Within a chapter, there may be a sequence of sections,
  94. Xeach introduced by @Code "@Section" in the usual way, all bracketed
  95. Xby @Code "@BeginSections" and {@Code "@EndSections"}.  Within each
  96. Xsection there may be subsections, each introduced by {@Code "@SubSection"},
  97. Xand the sequence as a whole bracketed by @Code "@BeginSubSections" and
  98. X{@Code "@EndSubSections"}.  The first subsection of the first section of the
  99. Xfirst chapter will be numbered 1.1.1, and so on.  There are no sub-subsections.
  100. X@PP
  101. XFinally there is opportunity for a sequence of appendices, each
  102. Xintroduced by @Code "@Appendix" in the usual way.  No
  103. X@Code "@BeginAppendices" or @Code "@EndAppendices" symbols are
  104. Xneeded.  The appendices are numbered A, B, C, etc., and there
  105. Xare sub-appendices, obtained in the usual way.
  106. X@PP
  107. XEach symbol with a @Code "@Title" option also has a @Code "@RunningTitle"
  108. Xoption.  The more important parts of the book (preface, introduction,
  109. Xchapters, and appendices) have their @Code "@RunningTitle" printed at
  110. Xthe top of each even-numbered page; if omitted, the @Code "@Title" option
  111. Xis used instead.
  112. X@PP
  113. XWith Basser Lout, a long document is best broken into a sequence of files,
  114. Xeach containing one section, from @Code "@Section" to @Code "@End @Section"
  115. Xinclusive.  Other files are needed for the beginning of each chapter,
  116. Xfrom @Code "@Chapter" to {@Code "@BeginSections"}, and for the end of
  117. Xeach chapter, that is the final @Code "@EndSections" and
  118. X{@Code "@End @Chapter"}.  On the Unix operating system a good scheme for
  119. Xnaming these files is
  120. X@ID lines @Break {
  121. X@Code ch0.00     @Code "@Book" ... @Code "//"
  122. X@Code ch0.01     Preface
  123. X@Code ch0.02     Introduction
  124. X@Code ch1.00     Beginning of Chapter 1
  125. X@Code ch1.01     Section 1.1
  126. X@Code ch1.02     Section 1.2
  127. X. . .
  128. X@Code ch1.99     End of Chapter 1
  129. X@Code ch2.00     Beginning of Chapter 2
  130. X@Code ch2.01     Section 2.1
  131. X@Code ch2.02     Section 2.2
  132. X. . .
  133. X@Code ch2.99     End of Chapter 2
  134. X}
  135. Xand so on.  Then the Unix command
  136. X@ID @Code "lout -ibook ch0.00 ch3.??"
  137. Xwill format Chapter 3 only; and
  138. X@ID @Code "lout -ibook ch?.??"
  139. Xwill format the entire book.  The whole book must be formatted by one
  140. Xcommand to get the page numbers right, but there is no need to do
  141. Xthis until everything is perfect.
  142. X@PP
  143. XThe symbols described in Sections 1--7 above are all available as
  144. Xusual.  The numbering of figures and tables includes a chapter or
  145. Xappendix number:  the first figure of Appendix A will be numbered A.1,
  146. Xand so on.  Figures and tables within the preface and introduction are
  147. Xnumbered 1, 2, 3, etc.  When figures and tables appear near the end of
  148. Xa chapter, the following page on which they appear may also be the first
  149. Xpage of the next chapter, which looks very poor.  The solution is to move
  150. Xthe figure or table to an earlier point in the chapter.
  151. X@PP
  152. XFigures and tables work in a slightly different way to previously, owing
  153. Xto the need to attach a chapter or appendix number to each one.  The
  154. Xfirst figure of each chapter or appendix must be preceded by
  155. X{@Code "@BeginFigures"}, and the last figure of each chapter or appendix
  156. Xmust be followed by {@Code "@EndFigures"}.  These symbols must also bracket
  157. Xfigures in the preface and introduction.  The symbols are not required
  158. Xwhen there are no figures.  Similarly, {@Code "@BeginTables"} and
  159. X{@Code "@EndTables"} must bracket tables.
  160. X@PP
  161. XCross referencing works as described in Section {@NumberOf cross};
  162. X@Code "@Tag" options may be given to the preface, introduction,
  163. Xchapters, sections, subsections, appendices, and sub-appendices.
  164. X@PP
  165. XReferences work as described in Section {@NumberOf refs}, except
  166. Xthat @Code "@ReferenceSection" is added automatically as needed.  A variant of
  167. Xthe @Code "@Ref" symbol called @Code "@ChapRef" is provided, which
  168. Xcauses the reference to appear at the end of the current preface,
  169. Xintroduction, chapter, or appendix, rather than at the end of the book.
  170. X@PP
  171. XAlso available are symbols for making an index.  To
  172. Xadd an entry to the index, place
  173. X@ID @Code "packages @Index { Packages }"
  174. Xfor example at the relevant point.  The result will be something like
  175. X@ID { Packages, 27 }
  176. Xappearing in the index in the alphabetical position determined by the
  177. Xleft parameter, which should be a juxtaposition of simple words composed,
  178. Xby convention, of lower-case letters and periods only.
  179. X@PP
  180. XA variant called @Code "@SubIndex" provides a small indent, as is
  181. Xconventional for sub-entries in indexes.  For example,
  182. X@ID @Code {
  183. X"package  @Index  { Packages }"
  184. X"package.r @SubIndex {ReportLayout}"
  185. X"package.b @SubIndex {BookLayout}"
  186. X}
  187. Xscattered through a document will produce something like
  188. X@ID lines @Break {
  189. XPackages, 27
  190. X   BookLayout, 45
  191. X   ReportLayout, 40
  192. X}
  193. XNote how the left parameters have been carefully chosen to produce the
  194. Xcorrect ordering.  There is also a @Code "@SubSubIndex" symbol with a
  195. Xdouble indent.
  196. X@PP
  197. XThese symbols attach one page number to each entry.  Although the best
  198. Xauthorities recommend exactly this, many authors choose to have entries
  199. Xlike
  200. X@ID { Fourier Transform, 576, 583--593 }
  201. Xdespite the inconvenience to their readers.  {@Code "@RawIndex"},
  202. X{@Code "@RawSubIndex"}, and {@Code "@RawSubSubIndex"}
  203. Xsymbols are provided which do not add page numbers to the entry, leaving
  204. Xthis to the user.  For example, one systematic way to get page number
  205. Xranges is to place
  206. X@ID @Code {
  207. X"packages @RawIndex {"
  208. X"    Packages, {@PageOf packages}"
  209. X"    -- {@PageOf packages.end}"
  210. X"}"
  211. X}
  212. Xat the start of the range, and
  213. X@ID @Code {
  214. X"{@PageMark packages.end}"
  215. X}
  216. Xat the end of the range.  This works because all six index symbols
  217. Xinclude a @Code "@PageMark" operation.  Incidentally, this means that
  218. Xindex tags should be different from chapter and other tags.
  219. X@PP
  220. XAnother use for @Code "@RawIndex" is to get blank lines into the index
  221. Xbetween the letters of the alphabet, by inserting phantom entries:
  222. X@ID @Code {
  223. X"b @RawIndex {}"
  224. X"c @RawIndex {}"
  225. X"..."
  226. X"z @RawIndex {}"
  227. X}
  228. XIn fact there is a symbol called @Code "@IndexBlanks" which creates
  229. Xexactly these 25 entries.  Unfortunately, these blanks will occasionally
  230. Xappear at the top of a column, and if there are no entries beginning with
  231. Xx, for example, there will be two blank lines between the w and y
  232. Xentries.  The careful user can start off with @Code "@IndexBlanks" and
  233. Xreplace it later by the appropriate subset.
  234. X@FootNote {
  235. XFor Lout to solve this problem automatically, it would need to be told
  236. Xwhich letter each index entry belongs under, perhaps by symbols
  237. X{@Code "@AIndex"}, {@Code "@BIndex"}, etc.  The author
  238. Xfelt that this would have been too tedious.
  239. X}
  240. X@PP
  241. XOwing to problems behind the scenes, the Index heading will be printed,
  242. Xand an entry will be made in the table of contents, even if there are no
  243. Xentries in the index.  To prevent this, you will need to change the
  244. X@Code "@MakeIndex" option in the @Code book setup file to {@Code "No"},
  245. Xusing the method described in the following section.
  246. X@PP
  247. XAlthough the page numbers in index entries will be kept up to date
  248. Xautomatically as the document changes, as all cross references are, 
  249. Xthe user is recommended to refrain from inserting index entries until
  250. Xthe book is complete and an overall plan of the structure of the index
  251. Xcan be made.
  252. X@End @Section
  253. END_OF_FILE
  254.   if test 9025 -ne `wc -c <'lout/doc/tr.begin/s14'`; then
  255.     echo shar: \"'lout/doc/tr.begin/s14'\" unpacked with wrong size!
  256.   fi
  257.   # end of 'lout/doc/tr.begin/s14'
  258. fi
  259. if test -f 'lout/doc/tr.fig/s5' -a "${1}" != "-c" ; then 
  260.   echo shar: Will not clobber existing file \"'lout/doc/tr.fig/s5'\"
  261. else
  262.   echo shar: Extracting \"'lout/doc/tr.fig/s5'\" \(9154 characters\)
  263.   sed "s/^X//" >'lout/doc/tr.fig/s5' <<'END_OF_FILE'
  264. X@Section
  265. X   @Title { Lengths, angles, and points }
  266. X@Begin
  267. X@PP
  268. XWe already know that two lengths placed side by side define a point.  This is 
  269. Xonly the simplest of a number of such geometrical combinations.
  270. X@PP
  271. XThe symbol @Code "@Distance" returns the length of the line joining two
  272. Xpoints:
  273. X@ID @Code "{0 0} @Distance {3 cm  4 cm}"
  274. Xis equivalent to the length {@Code "5 cm"}.  The result of @Code "@Distance"
  275. Xis never negative.  Notice that braces must enclose the two points.  The
  276. Xsymbol @Code "@XDistance" returns the distance in the @Eq { x } direction
  277. Xfrom one point to another:
  278. X@ID {
  279. X@Code "{" & @Eq { x sub 1 ``` y sub 1 } & @Code "}  @XDistance  {"
  280. X& @Eq { x sub 2 ``` y sub 2 } & @Code "}"
  281. X}
  282. Xhas for its result the length @Eq { x sub 2 - x sub 1 }, and so may be
  283. Xnegative.  There is an analogous @Code "@YDistance" symbol.
  284. X@PP
  285. XThe symbol @Code "@Angle" returns the angle @Eq {theta} from one point to
  286. Xanother:
  287. X@ID {
  288. X@Code "{" & @Eq { x sub 1 ``` y sub 1 } & @Code "}  @Angle  {"
  289. X& @Eq { x sub 2 ``` y sub 2 } & @Code "}"
  290. X||7ct
  291. X@Fig {
  292. X@Figure
  293. X   arrow { forward }
  294. X   shape { 4 cm 0 0 0 4 cm 3 cm }
  295. X{ 4c @Wide 3c @High }
  296. X// {4 cm 3 cm} ** 0.4 ++ { 0.5 cm 0 } @MarkOf @Eq { (x sub 1 & , y sub 1 & ) }
  297. X// {4 cm 3 cm} ** 0.4 @BaseOf @Circle margin { 0.05c } paint { black } {}
  298. X// {4 cm 3 cm} ** 0.8 ++ { 0.5 cm 0 } @MarkOf @Eq { (x sub 2 & , y sub 2 & ) }
  299. X// {4 cm 3 cm} ** 0.8 @BaseOf @Circle margin { 0.05c } paint { black } {}
  300. X// { 1 cm 0.2 cm } ** 0.7 @BaseOf @Eq { theta }
  301. X}
  302. X}
  303. XThe result will be 0 if the two points are equal.  The symbol @Code "<<"
  304. Xreturns the point at a given distance and angle from @Eq { (0, 0) }:
  305. X@ID {
  306. X@Code "{" & @Eq { length }  @Code "<<"  @Eq { theta } & @Code "}"
  307. X||7ct
  308. X@Fig {
  309. X@Figure
  310. X   arrow { forward }
  311. X   shape { 4 cm 0 0 0 4 cm 3 cm }
  312. X{ 4c @Wide 3c @High }
  313. X// {4 cm 3 cm} ** 0.5 -- {1.5 cm 0} @BaseOf @I length
  314. X// {4 cm 3 cm} ** 0.8 @BaseOf @Circle margin { 0.05c } paint { black } {}
  315. X// { 1 cm 0.2 cm } ** 0.7 @BaseOf @Eq { theta }
  316. X}
  317. X}
  318. XFor example, @Code "{ 5 cm << 45 dg }" is the point 5 cm
  319. Xfrom @Eq { (0, 0) } at 45 degrees.
  320. X@PP
  321. XPoints may be added, subtracted, and multiplied by a number:
  322. X@ID @Tab
  323. X     vmargin { 0.5vx }
  324. X     @Fmta { @Col A ! @Col is ! @Col B }
  325. X{
  326. X@Rowa
  327. X   A { @Code "{" & @Eq {x sub 1 ``` y sub 1} & @Code "}  ++  {" &
  328. X@Eq {x sub 2 ``` y sub 2} & @Code "}" }
  329. X   B { @Eq { (x sub 1 + x sub 2 & , y sub 1 + y sub 2 & ) } }
  330. X@Rowa
  331. X   A { @Code "{" & @Eq {x sub 1 ``` y sub 1} & @Code "}  --  {" &
  332. X@Eq {x sub 2 ``` y sub 2} & @Code "}" }
  333. X   B { @Eq { (x sub 1 - x sub 2 & , y sub 1 - y sub 2 & ) } }
  334. X@Rowa
  335. X   A { @Code "{" & @Eq {x sub 1 ``` y sub 1} & @Code "}  **  " & @Eq {k} }
  336. X   B { @Eq { (x sub 1 & k, y sub 1 & k) } }
  337. X}
  338. XFor example,
  339. X@ID {
  340. X@Code "{" & @Eq {x sub 1 ``` y sub 1} & @Code "} ** 0.2  ++  " &
  341. X@Code "{" & @Eq {x sub 2 ``` y sub 2} & @Code "} ** 0.8"
  342. X}
  343. Xis the point eight tenths of the way from 
  344. X@Eq { (x sub 1 & , y sub 1 & ) } to
  345. X@Eq { (x sub 2 & , y sub 2 & ) } on the line joining them:
  346. X@LP
  347. X@ID @Fig {
  348. X@Figure
  349. X   shape {
  350. X      {xsize 0} ** 0.3 ++ {0 ysize} @Label P1
  351. X      {xsize 0} ++ {0 ysize} ** 0.4 @Label P2
  352. X      P1 ** 0.2 @Label FP1
  353. X      P2 ** 0.8 @Label FP2
  354. X      0 0 P1 P2 0 0 [] FP1 FP1 ++ FP2 FP2
  355. X   }
  356. X{ 6c @High 9c @Wide }
  357. X// P1 ++ {0.3 cm 0} @BaseOf @Eq { (x sub 1 & , y sub 1 & ) }
  358. X// P2 ++ {0.3 cm 0} @BaseOf @Eq { (x sub 2 & , y sub 2 & ) }
  359. X// FP1 ++ FP2 ++ {0.3 cm 0} @BaseOf
  360. X@Eq { (0.2x sub 1 & + 0.8x sub 2 & , 0.2y sub 1 & + 0.8y sub 2 & ) }
  361. X}
  362. XWhen using {@Code "**"}, the point must be on the left and the number on
  363. Xthe right.  It would be more convenient to name these symbols
  364. X{@Code "+"}, {@Code "-"}, and {@Code "*"}, but these names
  365. Xare often taken by equation formatters, and @Code "-" appears in
  366. Xlengths, so we don't.  There are @Code "@Max" and @Code "@Min" symbols:
  367. X@ID @Tab
  368. X     vmargin { 0.5vx }
  369. X     @Fmta { @Col A ! @Col is ! @Col B }
  370. X{
  371. X@Rowa
  372. X  A { @Code "{" & @Eq {x sub 1 ``` y sub 1} & @Code "}  @Max  {" &
  373. X@Eq {x sub 2 ``` y sub 2} & @Code "}" }
  374. X  B { @Eq { (max(x sub 1 & , x sub 2 & ), max(y sub 1 & , y sub 2 & )) } }
  375. X@Rowa
  376. X  A { @Code "{" & @Eq {x sub 1 ``` y sub 1} & @Code "}  @Min  {" &
  377. X@Eq {x sub 2 ``` y sub 2} & @Code "}" }
  378. X  B { @Eq { (min(x sub 1 & , x sub 2 & ), min(y sub 1 & , y sub 2 & )) } }
  379. X}
  380. XNote carefully that these apply to points, not to numbers.
  381. X@PP
  382. XThe result of adding two points together depends on where the origin is
  383. Xat the time, as well as on the points themselves.  This can lead to
  384. Xunexpected results, as the author has found to his cost more than
  385. Xonce.  Within the @Code shape option of {@Code "@Figure"}, the origin is
  386. Xthe lower left corner of the result of the {@Code "@Figure"}.  In cases
  387. Xlike the example on page {@PageOf sumpoints}, where points are added
  388. Xoutside of any {@Code "@Figure"} symbol, the origin is usually at the
  389. Xbottom left corner of the figure as a whole.  A label always denotes a
  390. Xparticular point on the printed page, regardless of where the origin
  391. Xhappens to be.
  392. X@PP
  393. XThe symbol @Code "@Prev" within the @Code "shape" option of @Code
  394. X"@Figure" denotes the previous point of the shape, ignoring points within
  395. X{@Code {"[" &0.5s "]"}}.  This makes it easy to specify each point
  396. Xrelative to the previous one:
  397. X@ID {
  398. X@Code {
  399. X"   shape {"
  400. X"      0 0"
  401. X"      { 2 cm << 30 }"
  402. X"      @Prev ++ { 2 cm << 90 }"
  403. X"      @Prev ++ { 2 cm << 150 }"
  404. X"      @Prev ++ { 2 cm << 210 }"
  405. X"      @Prev ++ { 2 cm << 270 }"
  406. X"      0 0"
  407. X"   }"
  408. X}
  409. X||7ct
  410. X@Fig { ||2.5c
  411. X@Figure
  412. X   shape {
  413. X      0 0
  414. X      { 2 cm << 30 }
  415. X      @Prev ++ { 2 cm << 90 }
  416. X      @Prev ++ { 2 cm << 150 }
  417. X      @Prev ++ { 2 cm << 210 }
  418. X      @Prev ++ { 2 cm << 270 }
  419. X      0 0
  420. X   }
  421. X{ 4c @Wide 4c @High }
  422. X}
  423. X}
  424. X@PP
  425. XFig provides a @Code "@Label" symbol for attaching a label to a point in
  426. Xa shape, like this:
  427. X@ID @Code "{xsize ysize} ** 0.5 @Label CTR"
  428. XThe point may then be referred to more concisely by its label,
  429. X{@Code CTR}.  For example, the large arrow appearing in Section 2 was
  430. Xbuilt like this:
  431. X@ID {
  432. X@Code {
  433. X"@Figure"
  434. X"   shape {"
  435. X"      {0 ysize} ** 0.4 @Label SB"
  436. X"      {0 ysize} ** 0.6 @Label ST"
  437. X"      {xsize 0} ** 0.7 @Label HB"
  438. X"      SB"
  439. X"      SB ++ HB"
  440. X"      HB"
  441. X"      {xsize 0} ++ {0 ysize} ** 0.5"
  442. X"      HB ++ {0 ysize}"
  443. X"      HB ++ ST"
  444. X"      ST"
  445. X"      SB"
  446. X"   }"
  447. X"   paint { grey }"
  448. X"{ 6c @Wide 2c @High }"
  449. X}
  450. X||7ct
  451. X@Fig {
  452. X@Figure
  453. X   shape {
  454. X      {0 ysize} ** 0.4 @Label SB
  455. X      {0 ysize} ** 0.6 @Label ST
  456. X      {xsize 0} ** 0.7 @Label HB
  457. X      SB
  458. X      SB ++ HB
  459. X      HB
  460. X      {xsize 0} ++ {0 ysize} ** 0.5
  461. X      HB ++ {0 ysize}
  462. X      HB ++ ST
  463. X      ST
  464. X      SB
  465. X   }
  466. X   paint { grey }
  467. X{ 6c @Wide 2c @High }
  468. X// @ShowLabels
  469. X}
  470. X}
  471. XIncidentally, the labels of a figure can be displayed as above by putting
  472. Xthe symbol @Code "@ShowLabels" at the end of the figure.  Labels can
  473. Xsave a lot of effort.  They should contain only digits, upper-case
  474. Xletters and {@Code "@"}, because Fig and Lout use labels of their own
  475. Xmade from lower-case letters.
  476. X@PP
  477. XThe standard shapes have standard labels; for example, the labels
  478. Xof @Code "@Ellipse" are
  479. X@LP
  480. X@ID {
  481. X@Code {
  482. X"@Ellipse"
  483. X"{ 3c @Wide 2c @High }"
  484. X}
  485. X||7ct
  486. X@Fig {
  487. X@Ellipse { 3c @Wide 2c @High }
  488. X// @ShowLabels
  489. X}
  490. X}
  491. XThere is a symbol, {@Code "::"}, for @I relabelling an object.
  492. XEach label in the right parameter is relabelled in the following way:
  493. X@LP
  494. X@ID {
  495. X@Code {
  496. X"E1:: @Ellipse"
  497. X"{ 3c @Wide 2c @High }"
  498. X}
  499. X||7ct
  500. X@Fig {
  501. XE1:: @Ellipse { 3c @Wide 2c @High }
  502. X// @ShowLabels
  503. X}
  504. X}
  505. XWithin the right parameter of @Code "::" the original names hold sway;
  506. Xbut afterwards the names are changed by prefixing the label
  507. Xand @Code "@" to them.  These composite labels may be used exactly like
  508. Xother labels.  Relabelling can be nested to arbitrary depth:
  509. X@LP
  510. X@ID {
  511. X5c @Wide @Code {
  512. X"A::"
  513. X"{   1:: @Ellipse"
  514. X"    { 3c @Wide 2c @High }"
  515. X"    //1c"
  516. X"    2:: @Box"
  517. X"    { 3c @Wide 2c @High }"
  518. X"}"
  519. X}
  520. X||7ct
  521. X@Fig {
  522. XA::
  523. X{   1:: @Ellipse { 3c @Wide 2c @High }
  524. X    //1c
  525. X    2:: @Box { 3c @Wide 2c @High }
  526. X}
  527. X// @ShowLabels
  528. X}
  529. X}
  530. XThe right parameter of @Code "::" may be any object.
  531. X@PP
  532. XThe six standard shapes ({@Code "@Box"}, {@Code "@Square"},
  533. X{@Code "@Diamond"}, {@Code "@Polygon"}, {@Code "@Ellipse"}, and
  534. X{@Code "@Circle"}) have a special @Code CIRCUM label, not displayed by
  535. X{@Code "@ShowLabels"}.  The expression
  536. X@ID {
  537. X@Eq { "angle" } @Code CIRCUM
  538. X}
  539. Xyields the point on the boundary of the shape at the given angle from
  540. Xthe centre, in a coord&-inate system with the centre for origin.  Thus,
  541. Xgiven a labelled standard shape such as
  542. X@ID @Code "A :: @Ellipse ..."
  543. Xthe point on its boundary at an angle of 45 degrees from the centre is
  544. X@ID @Code "A@CTR ++ {45 A@CIRCUM}"
  545. XThe braces must be present.  Regrettably, there is no way to produce a
  546. X@Code CIRCUM label for shapes defined by the user in any reasonable time.
  547. X@PP
  548. XIf the same label is used twice, as is inevitable with unlabelled standard
  549. Xshapes, only the most recent value is remembered.  There is a limit on the
  550. Xmaximum number of distinct labels in any one figure, which
  551. Xcan be changed by means of an option to the @Code "@Fig" symbol:
  552. X@ID @Code {
  553. X"@Fig"
  554. X"   maxlabels { 500 }"
  555. X"{ ... }"
  556. X}
  557. XThe default value is 200.  Large values could cause the printing device
  558. Xto run out of memory.  Memory is reclaimed at the end of each figure.
  559. X@End @Section
  560. END_OF_FILE
  561.   if test 9154 -ne `wc -c <'lout/doc/tr.fig/s5'`; then
  562.     echo shar: \"'lout/doc/tr.fig/s5'\" unpacked with wrong size!
  563.   fi
  564.   # end of 'lout/doc/tr.fig/s5'
  565. fi
  566. if test -f 'lout/doc/tr.impl/s3.2' -a "${1}" != "-c" ; then 
  567.   echo shar: Will not clobber existing file \"'lout/doc/tr.impl/s3.2'\"
  568. else
  569.   echo shar: Extracting \"'lout/doc/tr.impl/s3.2'\" \(3408 characters\)
  570.   sed "s/^X//" >'lout/doc/tr.impl/s3.2' <<'END_OF_FILE'
  571. X@SubSection
  572. X    @Tag { recursion }
  573. X    @Title { Recursion and page layout }
  574. X@Begin
  575. X@PP
  576. XDesign and implementation should proceed together in exploratory projects,
  577. Xsince otherwise the design too easily becomes unrealistic.  Sometimes the
  578. Ximplementation does more than its designer intended.  The author wrote the
  579. Xfollowing purely as a testing scaffold:
  580. X@ID @Code {
  581. X"def @Page right x"
  582. X"{"
  583. X"    8i @Wide 11i @High"
  584. X"    {"
  585. X"        //1i  ||1i  x  ||1i"
  586. X"        //1i"
  587. X"    }"
  588. X"}"
  589. X}
  590. XOnly afterwards did he realize its significance:  the concept of a page
  591. Xhad been defined outside the implementation, removing the need for
  592. Xcommands for setting page width and height, margins, and so on.
  593. X@PP
  594. XDefining a sequence of pages is harder, since their number is not known
  595. Xin advance.  A simple version of this same problem is afforded by the
  596. Xleaders found in tables of contents:
  597. X@ID {
  598. X4i @Wide { Chapter 7  @Leaders  53 }
  599. X}
  600. XThis seemed to require recursion, specifically the definition
  601. X@ID @Code {
  602. X"def @Leaders { ..   @Leaders }"
  603. X}
  604. XNote that both @Code ".." and @Code "@Leaders" are objects, so the two
  605. Xspaces separating them are significant.  No base case is given, and indeed
  606. Xwe have no boolean or conditional operators with which to express it;
  607. Xbut we can adopt the implicit base `if space is not sufficient, delete
  608. X{@Code "@Leaders"} and any preceding space'.  Then the expression
  609. X@ID @Code "4i @Wide { Chapter 7  @Leaders  53 }"
  610. Xwill produce the object shown above.  It is hard to see how this base
  611. Xcould be made explicit, without violating the general principle of
  612. Xkeeping all size information internal.  In the implementation,
  613. X@Code "@Leaders" remains unexpanded while sizes are being
  614. Xcalculated; then it is treated similarly to a receptive symbol, with
  615. Xits body as an incoming galley (Section {@NumberOf flushing}).
  616. X@PP
  617. XWith this settled, it is now clear how to define a document which is a
  618. Xnumbered sequence of pages.  Let @Code "@Next" be a prefix operator
  619. Xwhich returns its parameter plus one.  Then
  620. X@ID @Code {
  621. X"def @PageList"
  622. X"    right @PageNum"
  623. X"{"
  624. X"    @Page {"
  625. X"          |0.5rt - @PageNum -"
  626. X"          //1v   @TextPlace"
  627. X"          //1rt  @FootSect"
  628. X"    }"
  629. X"    //"
  630. X"    @PageList @Next @PageNum"
  631. X"}"
  632. X}
  633. Xwhen invoked in the expression {@Code "@PageList 1"}, has for its result
  634. Xthe potentially infinite object
  635. X@ID {
  636. X@LittlePage {
  637. X|0.5rt - 1 -
  638. X//1.2vx @Code "@TextPlace"
  639. X//1rt @Code "@FootSect"
  640. X}
  641. X//
  642. X@LittlePage {
  643. X|0.5rt - 2 -
  644. X//1.2vx @Code "@TextPlace"
  645. X//1rt @Code "@FootSect"
  646. X}
  647. X//0.2c
  648. X8p @Font @Code "@PageList 3"
  649. X}
  650. XSimilarly, we may define @Code "@FootSect" like this:
  651. X@ID @Code {
  652. X"def @FootSect"
  653. X"{"
  654. X"    def @FootList"
  655. X"        right @Num"
  656. X"    {"
  657. X"        @FootPlace"
  658. X"        //1v"
  659. X"        @FootList @Next @Num"
  660. X"    }"
  661. X""
  662. X"    1i @Wide @HLine"
  663. X"    //1v"
  664. X"    @FootList 1"
  665. X"}"
  666. X}
  667. Xso that an invocation of @Code "@FootSect" produces
  668. X@ID @Code {
  669. X1i @Wide @HLine
  670. X"@FootPlace"
  671. X"@FootPlace"
  672. X"@FootPlace"
  673. X"..."
  674. X}
  675. XThe expansion process is very similar to a BNF derivation, and would be
  676. Xattempted only on demand.
  677. X@PP
  678. XClearly, deciding which expansions to take and replacing @Code "@TextPlace"
  679. Xand {@Code "@FootPlace"} by the appropriate actual text will not be easy;
  680. Xthis is the subject of Section {@NumberOf galleys}.  The important point
  681. Xfor now is that we have here a very simple and flexible method of specifying
  682. Xthe layout of pages, which requires no specialized language features.
  683. X@End @SubSection
  684. END_OF_FILE
  685.   if test 3408 -ne `wc -c <'lout/doc/tr.impl/s3.2'`; then
  686.     echo shar: \"'lout/doc/tr.impl/s3.2'\" unpacked with wrong size!
  687.   fi
  688.   # end of 'lout/doc/tr.impl/s3.2'
  689. fi
  690. if test -f 'lout/doc/tr.lout/ch1.02' -a "${1}" != "-c" ; then 
  691.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch1.02'\"
  692. else
  693.   echo shar: Extracting \"'lout/doc/tr.lout/ch1.02'\" \(8755 characters\)
  694.   sed "s/^X//" >'lout/doc/tr.lout/ch1.02' <<'END_OF_FILE'
  695. X@Section
  696. X   @Title { Definitions }
  697. X   @Tag { definitions }
  698. X@Begin
  699. X@PP
  700. XThe features of Lout are very general.  They do not assume that documents
  701. Xare composed of pages, nor that there are such things as margins and
  702. Xfootnotes, for example.  @I Definitions
  703. Xdefinitions. @Index { Definitions }
  704. Xbridge the gap between Lout's general features and the
  705. Xspecial features -- footnotes, equations, pages -- that particular
  706. Xdocuments require.  They hold the instr&-uct&-ions for producing these
  707. Xspecial features, conveniently packaged ready for use.
  708. X@PP
  709. XFor example, consider the challenge posed by `@TeX', which is the name of
  710. Xone of Lout's most illustrious rivals [{@Ref knuth84}].  Lout solves it
  711. Xeasily enough, like this:
  712. X@ID @Code {
  713. X"T{ /0.2fo E }X"
  714. X}
  715. Xbut to type this every time @TeX is mentioned would be tedious and
  716. Xerror-prone.  So we place a definition at the beginning of the document:
  717. X@ID @Code {
  718. X"def  @TeX  {  T{ /0.2fo E }X  }"
  719. X}
  720. XNow @Code "@TeX" stands for the object following it between
  721. Xbraces, and we may write
  722. X@ID @Code {
  723. Xconsider the challenge posed by "`@TeX'", ...
  724. X}
  725. Xas the author did earlier in this paragraph.
  726. X@PP
  727. XA @I symbol
  728. Xsymbol. @Index Symbol
  729. Xis a name, like {@Code "@TeX"}, which stands for
  730. Xsomething other than itself.  The initial @Code "@" is not compulsory,
  731. Xbut it does make the name stand out clearly.  A @I definition of a symbol
  732. Xdeclares a name to be a symbol, and says what the symbol stands for.  The
  733. X@I body of a definition
  734. Xbody.of @Index { Body of a definition }
  735. Xis the part following the name, between the braces.  To @I invoke
  736. Xinvocation @Index { Invocation of a symbol }
  737. Xa symbol is to make use of it.
  738. X@PP
  739. XAnother expression ripe for packaging in a definition is
  740. X@ID @Code {
  741. X"@OneRow {  |  -2p @Font n  ^/0.5fk  2  }"
  742. X}
  743. Xwhich produces @OneRow { | -2p @Font n ^/0.5sk 2 } as the reader
  744. Xfamiliar with Chapter {@NumberOf details}
  745. Xcan verify.  But this time we would like to be able to write
  746. X@ID {
  747. X@I object  @Code "@Super"  @I object
  748. X}
  749. Xso that @Code { a "@Super" 2 } would come out as {a @Super 2}, and so
  750. Xon, for in this way the usefulness of the definition is greatly
  751. Xincreased.  Here is how it is done:
  752. X@ID @Code {
  753. X"def @Super"
  754. X"   left x"
  755. X"   right y"
  756. X"{ @OneRow {  |  -2p @Font y  ^/0.5fk  x  }"
  757. X"}"
  758. X}
  759. XThis definition says that @Code "@Super" has two {@I parameters},
  760. Xparameter @Index Parameter
  761. X@Code x and {@Code y}.  When @Code "@Super" is invoked, all occurrences
  762. Xof @Code x in the body will be replaced by the object just to the left
  763. Xof {@Code "@Super"}, and all occurrences of @Code y will be replaced by
  764. Xthe object just to the right.  So, for example, the expression
  765. X@ID @Code {
  766. X"2  @Super  { Slope @Font n }"
  767. X}
  768. Xis equal to
  769. X@ID @Code {
  770. X"@OneRow {  |  -2p @Font { Slope @Font n }  ^/0.5fk  2  }"
  771. X}
  772. Xand so comes out as {2 @Super {Slope @Font n}}.
  773. X@PP
  774. XLout permits definitions to invoke themselves, a peculiarly circular
  775. Xthing to do which goes by the name of
  776. Xrecursion @Index Recursion
  777. X@I recursion.  Here is an example
  778. Xof a recursive definition:
  779. X@ID @Code {
  780. X"def  @Leaders  {  ..   @Leaders  }"
  781. X}
  782. XThe usual rule is that the value of an invocation of a symbol is a copy of
  783. Xthe body of the symbol's definition, so the value of @Code "@Leaders" must be
  784. X@ID @Code {
  785. X"..   @Leaders"
  786. X}
  787. XBut now this rule applies to this new invocation of {@Code "@Leaders"};
  788. Xsubstituting its body gives
  789. X@ID @Code {
  790. X"..   ..   @Leaders"
  791. X}
  792. Xand so on forever.  In order to make this useful,
  793. Xan invocation of a recursive symbol is replaced by its body only if
  794. Xsufficient space is available.  So, for example,
  795. X@ID @Code {
  796. X"4i @Wide { Chapter 7  @Leaders   62 }"
  797. X}
  798. Xhas for its result the object
  799. X@ID {
  800. X4i @Wide { Chapter 7  @Leaders   62 }
  801. X}
  802. Xwith Lout checking before each replacement of @Code "@Leaders" by
  803. X@OneCol @Code { ".."   "@Leaders" } that the total length afterwards,
  804. Xincluding the other words, would not exceed four inches.
  805. X@PP
  806. XThe remaining issue is what happens when Lout decides that it is time to
  807. Xstop.  The obvious thing to do is to replace the last invocation by an
  808. Xempty object:
  809. X@ID @Code {
  810. X"..    ..    ..    ..    ..    ..    ..    ..    {}"
  811. X}
  812. XAs the example shows, this would leave a small trailing space, which in
  813. Xpractice turns out to be a major headache.  Lout solves this problem
  814. Xby replacing the last invocation with a different kind of empty object,
  815. Xcalled @@Null, whose effect is to make an adjacent concatenation symbol
  816. Xdisappear, preferably one preceding the @@Null.  Thus, when Lout
  817. Xreplaces @Code "@Leaders" by @@Null in the expression
  818. X@ID @Code {
  819. X"..    ..    ..    ..    ..    ..    ..    ..    @Leaders"
  820. X}
  821. Xthe trailing space, which is really a horizontal concatenation symbol,
  822. Xdisappears as well.  This is carefully taken into account when deciding
  823. Xwhether there is room to replace @Code "@Leaders" by its body at each
  824. Xstage.
  825. X@PP
  826. XThe remainder of this section is devoted to showing how definitions may
  827. Xbe used to specify the @I {page layout}
  828. Xpage.layout @RawIndex { Page layout }
  829. Xpage.layout.basic @SubIndex { principles of }
  830. Xof a document.  To begin with,
  831. Xwe can define a page like this:
  832. X@ID @Code {
  833. X"def @Page"
  834. X"{"
  835. X"    //1i  ||1i"
  836. X"    6i @Wide 9.5i @High"
  837. X"    { @TextPlace  //1rt  @FootSect }"
  838. X"    ||1i  //1i"
  839. X"}"
  840. X}
  841. XNow @Code "@Page" is an eight by
  842. Xeleven and a half inch object, with one inch margins, a place at the top for
  843. Xtext, and a section at the bottom for footnotes (since @Code "//1rt" leaves
  844. Xsufficient space to bottom-justify the following object).  It will be
  845. Xconvenient for us to show the effect of invoking @Code "@Page" like this:
  846. X@ID @Code
  847. X{ { //0.5ix 8p @Font "@Page" &2m => } &2m
  848. X@LittlePage { "@TextPlace" //1rt "@FootSect" }
  849. X}
  850. Xwith the invoked symbol appearing to the left of the arrow, and its body to
  851. Xthe right.
  852. X@PP
  853. XThe definition of a vertical list of pages should come as no surprise:
  854. X@ID @Code {
  855. X"def @PageList"
  856. X"{"
  857. X"    @Page"
  858. X"    //"
  859. X"    @PageList"
  860. X"}"
  861. X}
  862. XThis allows invocations like the following:
  863. X@ID @Code @HExpand @HScale {
  864. X{ //0.5ix 8p @Font "@PageList" }
  865. X||1m { //0.5ix => } ||1m
  866. X{        @LittlePage { "@TextPlace" //1rt "@FootSect" }
  867. X  //0.2c 8p @Font "@PageList"
  868. X}
  869. X||1m { //0.5ix => } ||1m
  870. X{        @LittlePage { "@TextPlace" //1rt "@FootSect" }
  871. X  //     @LittlePage { "@TextPlace" //1rt "@FootSect" }
  872. X  //0.2c 8p @Font "@PageList"
  873. X}
  874. X||1m { //0.5ix => } ||1m
  875. X{        @LittlePage { "@TextPlace" //1rt "@FootSect" }
  876. X  //     @LittlePage { "@TextPlace" //1rt "@FootSect" }
  877. X}
  878. X}
  879. Xsetting  @Code "@PageList" to @Code @@Null on the last step.  An
  880. Xarbitrary number of pages can be generated in this way.
  881. X@PP
  882. XA definition for @Code "@TextPlace" is beyond us at present, since
  883. X@Code "@TextPlace" must be replaced by different parts of the text
  884. Xof the document on different pages.  We can,
  885. Xhowever, define @Code "@FootSect" to be a small space followed by a
  886. Xhorizontal line followed by a list of places where footnotes are to go:
  887. X@ID @Code {
  888. X"def @FootList         "
  889. X"{                     "
  890. X"   @FootPlace         "
  891. X"   //0.3v             "
  892. X"   @FootList          "
  893. X"}                     "
  894. X"                      "
  895. X"def @FootSect"
  896. X"{                        "
  897. X"   //0.3v 1i @Wide @HLine"
  898. X"   //0.3v @FootList      "
  899. X"}                        "
  900. X}
  901. Xassuming that @Code "@HLine" will produce a horizontal line of the
  902. Xindicated width.  With this definition we can generate pages like this:
  903. X@ID @Code {
  904. X@LittlePage { "@TextPlace"
  905. X               //1rt
  906. X               "@FootSect"
  907. X             }
  908. X||2m { //0.5ix => } ||2m
  909. X@LittlePage { "@TextPlace"
  910. X               //1rt
  911. X               @OneRow { 1c @Wide @HLine
  912. X                         //0.1c
  913. X                         "@FootList"
  914. X                       }
  915. X             }
  916. X||2m { //0.5ix => } ||2m
  917. X@LittlePage { "@TextPlace"
  918. X               //1rt
  919. X               @OneRow { 1c @Wide @HLine
  920. X                         //0.1c
  921. X                         "@FootPlace"
  922. X                         //0.1c
  923. X                         "@FootList"
  924. X                       }
  925. X             }
  926. X}
  927. Xand so on for arbitrarily many footnotes.
  928. X@PP
  929. XWe will see in the next section how invocations of @Code "@PageList",
  930. X@Code "@FootSect" and @Code "@FootList" are replaced by their bodies only
  931. Xwhen the need to insert text and footnotes obliges Lout to do so;
  932. Xotherwise the invocations are replaced by @@Null.  In this way, the
  933. Xright number of pages is made, the small line appears only on pages that
  934. Xhave at least one footnote, and unnecessary concatenation symbols
  935. Xdisappear.
  936. X@PP
  937. XThis approach to page layout is the most original contribution Lout has
  938. Xmade to document formatting.  It is extraordinarily flexible.  Two-column
  939. Xpages?  Use
  940. X@ID @Code {
  941. X"{2.8i @Wide @TextPlace}  ||0.4i  {2.8i @Wide @TextPlace}"
  942. X}
  943. Xinstead of {@Code "@TextPlace"}.  Footnotes in smaller type?  Use
  944. X@Code { -2p "@Font" "@FootPlace" } instead of {@Code "@FootPlace"}.  And
  945. Xon and on.
  946. X@End @Section
  947. END_OF_FILE
  948.   if test 8755 -ne `wc -c <'lout/doc/tr.lout/ch1.02'`; then
  949.     echo shar: \"'lout/doc/tr.lout/ch1.02'\" unpacked with wrong size!
  950.   fi
  951.   # end of 'lout/doc/tr.lout/ch1.02'
  952. fi
  953. if test -f 'lout/doc/tr.lout/ch2.06' -a "${1}" != "-c" ; then 
  954.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch2.06'\"
  955. else
  956.   echo shar: Extracting \"'lout/doc/tr.lout/ch2.06'\" \(9965 characters\)
  957.   sed "s/^X//" >'lout/doc/tr.lout/ch2.06' <<'END_OF_FILE'
  958. X@Section
  959. X   @Title { Galleys and targets }
  960. X   @Tag { targets }
  961. X@Begin
  962. X@PP
  963. XThe behaviour of galleys and their targets, as described in Section
  964. Xgalley.feature.in.detail @SubIndex { in detail }
  965. Xtargets.in.detail @SubIndex { in detail }
  966. X{@NumberOf galleys}, can be summarized in three laws:
  967. X@DP
  968. X{@I {First Law}}:  The first target is the closest invocation of the
  969. Xtarget symbol, either preceding or following the invocation point of the
  970. Xgalley as required, which has sufficient space to receive the first
  971. Xcomponent;
  972. X@DP
  973. X{@I {Second Law}}:  Each subsequent target is the closest invocation of
  974. Xthe target symbol, following the previous target and lying within the same
  975. Xgalley, which has sufficient space to receive the first remaining component;
  976. X@DP
  977. X{@I {Third Law}}:  A receptive symbol that does not receive at least one
  978. Xcomponent of any galley is replaced by @@Null.
  979. X@DP
  980. XThe terms `closest,' `preceding,' and `following' refer to position in
  981. Xthe final printed document.  This section explains the operation of
  982. Xthese laws in Basser Lout.
  983. X@PP
  984. XWhen a galley cannot be fitted into just one target, Lout must find
  985. Xpoints in the galley where it can be split in two.  The object lying
  986. Xbetween two neighbouring potential split points is called a @I component
  987. Xcomponent @Index { Components of a galley }
  988. Xof the galley.  By definition, a component cannot be split.
  989. X@PP
  990. XTo determine the components of a galley, expand all symbols other than
  991. Xrecursive and receptive ones, discard all @@Font, @@Break, and @@Space
  992. Xsymbols, perform paragraph breaking as required, and discard all
  993. Xredundant braces.  Then view the galley as a sequence of one or more
  994. Xobjects separated by vertical concatenation symbols; these are the
  995. Xcomponents and split points.  For example, given the definition
  996. X@ID @Code {
  997. X"def @Section into { @SectionPlace&&preceding }"
  998. X"    named @Title {}"
  999. X"    right @Body"
  1000. X"{"
  1001. X"    15p @Font { @Title //0.7f }"
  1002. X"    //"
  1003. X"    @Body"
  1004. X"}"
  1005. X}
  1006. Xthe galley
  1007. X@ID @Code {
  1008. X"@Section"
  1009. X"    @Title { Introduction }"
  1010. X"{ This is a subject that really"
  1011. X"needs no introduction. }"
  1012. X}
  1013. Xbecomes
  1014. X@ID @Code {
  1015. X"Introduction"
  1016. X"//0.7f"
  1017. X"{}"
  1018. X"//"
  1019. X"This is a subject that really needs"
  1020. X"//1vx"
  1021. X"no introduction."
  1022. X}
  1023. Xwith four components.  If @Code "@Body" was preceded by @Code "|1.0c" in
  1024. Xthe definition, the result would be
  1025. X@ID @Code {
  1026. X"Introduction"
  1027. X"//0.7f"
  1028. X"{}"
  1029. X"//"
  1030. X"|1.0c { This is a subject that really needs //1vx no introduction. }"
  1031. X}
  1032. Xand now @Code "//1vx" is buried within one component and is not a
  1033. Xpotential split point.  In fact, in this case the broken paragraph as
  1034. Xa whole is enclosed in @@OneRow.  This highlights a deficiency of
  1035. XBasser Lout:  an indented paragraph cannot be split.
  1036. X@PP
  1037. XThe lines of a paragraph become separate components if the paragraph
  1038. Xoccupies an entire component before breaking; otherwise they are
  1039. Xenclosed in a @@OneRow symbol within one component.  The same is true of
  1040. Xincoming components of other galleys.  If a @@Galley symbol occupies an
  1041. Xentire component by the rules above, then the incoming components that
  1042. Xreplace it become components of their new home:
  1043. X@ID @Tab
  1044. X  @Fmta { @Col @Code A ! @Col lines @Break B ! @Col @Code C }
  1045. X{
  1046. X@Rowa
  1047. X   A {
  1048. X"An example"
  1049. X"//0.5c"
  1050. X"@Galley"
  1051. X"//0.5c"
  1052. X"@SomethingList"
  1053. X}
  1054. X  B {
  1055. X""
  1056. X@Eq { ==> }
  1057. X}
  1058. X   C {
  1059. X"An example"
  1060. X"//0.5c"
  1061. X"Incoming components"
  1062. X"//0.2c"
  1063. X"from some other galley"
  1064. X"//0.5c"
  1065. X"@SomethingList"
  1066. X}
  1067. X}
  1068. XOtherwise the incoming components are grouped within a @@OneRow symbol
  1069. Xand lie within one component.
  1070. X@PP
  1071. XThis distinction has a marked effect on the vertical concatenation
  1072. Xb.unit.use @SubIndex { use in @Code "//1.1b" }
  1073. Xsymbol {@Code "//1.1b"}, which calls for more space than is available
  1074. X(Section {@NumberOf concatenation}).  There is no room for this symbol
  1075. Xwithin any component, so it will force a split and be discarded in that
  1076. Xcase.  But it can be promoted to between two components.
  1077. X@PP
  1078. XComponents may be separated by @Code "/" as well as by {@Code "//"},
  1079. Xgiving rise to column mark alignment between adjacent components:
  1080. X@ID @ShowVMark {
  1081. X@HContract @GreyBox { 1c @Wide ^| 1c @Wide 0.6c @High }
  1082. X/0.3c
  1083. X@HContract @GreyBox { 2c @Wide 0.6c @High }
  1084. X/0.3c
  1085. X@HContract @GreyBox { 0.5c @Wide ^| 0.8c @Wide 0.6c @High }
  1086. X}
  1087. XWhen aligned components are promoted into different targets, the meaning
  1088. Xof alignment becomes very doubtful.  For example, what if the targets
  1089. Xmark.alignment.in.detail @SubIndex { in detail }
  1090. Xare in different columns of one page, or what if one lies within
  1091. X{@Code "90d @Rotate"}?
  1092. X@PP
  1093. XThe truth is that @Code "/" causes all the objects that share a mark to
  1094. Xhave equal width:
  1095. X@ID @ShowVMark {
  1096. X@Box @HContract @GreyBox { 1c @Wide ^| 1c @Wide 0.6c @High }
  1097. X/0.3c
  1098. X@Box @HContract @GreyBox { 2c @Wide 0.6c @High }
  1099. X/0.3c
  1100. X@Box @HContract @GreyBox { 0.5c @Wide ^| 0.8c @Wide 0.6c @High }
  1101. X}
  1102. XThis is a consequence of the `as wide as possible' rule (Section
  1103. X{@NumberOf size}).  Mark alignment occurs {@I incidentally}, whenever
  1104. Xthe fragments are placed into similar contexts.
  1105. X@PP
  1106. XIn this connection we must also consider the special case of a @@Galley
  1107. Xsymbol which shares its column mark with some other object:
  1108. X@ID @Code {
  1109. X"@Galley"
  1110. X"/0.2c"
  1111. X"@SomethingList"
  1112. X}
  1113. X(The @@Galley may or may not occupy an entire component; that doesn't
  1114. Xmatter here.)  If incoming components are separated by @Code "//" rather
  1115. Xthan by {@Code "/"}, the meaning is so doubtful that this is forbidden.  In
  1116. Xfact, a galley whose components replace such a @@Galley must have a
  1117. Xsingle column mark running its full length; that is, its components must
  1118. Xall share a single column mark.  This mark will be merged with the
  1119. Xcolumn mark passing through each @@Galley that these components replace;
  1120. Xall the objects on the resulting merged mark will have equal width.
  1121. X@PP
  1122. XThe root galley, where everything collects immediately prior to output,
  1123. Xroot.galley.in.detail @SubIndex { in detail }
  1124. Xis created automatically, not by a definition.  Its target is the output
  1125. Xfile, and its object is the entire input, which typically looks like this:
  1126. X@ID @Code {
  1127. X"@PageList"
  1128. X"//"
  1129. X"@Text {"
  1130. X"  Body text of the document ..."
  1131. X"}"
  1132. X}
  1133. Xwhere @Code "@PageList" expands to a sequence of pages containing
  1134. X@Code "@TextPlace" symbols (see Section {@NumberOf definitions}), and
  1135. X@Code "@Text" is a galley:
  1136. X@ID @Code {
  1137. X"def @TextPlace { @Galley }"
  1138. X""
  1139. X"def @Text into { @TextPlace&&preceding }"
  1140. X"    right x"
  1141. X"{"
  1142. X"    x"
  1143. X"}"
  1144. X}
  1145. XThe spot vacated by a galley -- its invocation point -- becomes a @@Null
  1146. Xobject, so this root galley is effectively @Code "@PageList" alone, as
  1147. Xrequired.  The @Code "@Text" galley will find its first target preceding
  1148. Xits invocation point, within {@Code "@PageList"}.
  1149. X@PP
  1150. XPrinting {@PageMark rootg} the root galley on the output file is somewhat problematical,
  1151. Xroot.galley.printing @SubIndex { printing of }
  1152. Xbecause Lout has no way of knowing how large the paper is.  Basser Lout
  1153. Xsimply prints one root galley component per page (except it skips
  1154. Xcomponents of height zero), and the user is responsible for ensuring
  1155. Xthat each component is page-sized.
  1156. X@PP
  1157. XBasser Lout will promote a component only after any receptive symbols
  1158. Xcomponents.promotion @SubIndex { promotion of }
  1159. Xpromotion @Index { Promotion of components }
  1160. Xwithin it have been replaced, either by galleys or by @@Null, since
  1161. Xuntil then the component is not complete.  A component which shares a
  1162. Xmark with following components is held up until they are all complete,
  1163. Xsince until then their width is uncertain.
  1164. X@PP
  1165. XConsider a page with @Code "@TextPlace" and @Code "@FootSect" receptive
  1166. Xsymbols.  The rule just given will prevent the page from being printed
  1167. Xuntil @Code "@TextPlace" is replaced by body text, quite rightly; but
  1168. X@Code "@FootSect" will also prevent its printing, even when there are no
  1169. Xfootnotes.
  1170. X@PP
  1171. XBasser Lout is keen to write out pages as soon as possible, to save memory,
  1172. Xand it cannot afford to wait forever for non-existent footnotes.  A variant
  1173. Xof the galley concept, called a {@I {forcing galley}},
  1174. Xforcing.galley @Index { Forcing galley } {@PageMark forcing}
  1175. Xis introduced to solve this problem.  A forcing galley is defined like this:
  1176. X@ID @Code {
  1177. X"def @Text force into { @TextPlace&&preceding }"
  1178. X"   ..."
  1179. X}
  1180. Xand so on.  When such a galley replaces a @@Galley symbol, Lout replaces
  1181. Xevery receptive symbol preceding the @@Galley by @@Null, thus ensuring that
  1182. Xas soon as text enters a page, for example, everything up to and including
  1183. Xthe preceding page can be printed.  This does not take care of the very last
  1184. Xpage, but Basser Lout replaces all receptive symbols by @@Null when it realizes
  1185. Xthat its input has all been read, thus allowing the last page to print.
  1186. X@PP
  1187. XA forcing galley causes the Third Law to be applied earlier than
  1188. Xexpected, and this creates two problems.  First, the replacement by
  1189. X@@Null may be premature:  a galley may turn up later wanting one of the
  1190. Xdefunct targets.  Such galleys (entries in tables of contents are
  1191. Xtypical examples) are copied into the cross reference database and read
  1192. Xin during the next run just before their targets are closed, and so they
  1193. Xfind their targets in the end.  Care must be taken to ensure that
  1194. Xlarge galleys such as chapters and sections do not have defunct targets,
  1195. Xsince the cost of copying them to and from the database is unacceptably high.
  1196. X@PP
  1197. XA @Code "following" galley may fail to find a first target lying in a
  1198. Xfollowing component of the same galley as its invocation point.  This is
  1199. Xa deficiency of Basser Lout, which occurs if the target has not been
  1200. Xread from input at the time the galley tries to find it.  A workaround
  1201. Xis to use a @Code "preceding" galley instead, defined like this:
  1202. X@ID @Code {
  1203. X"def @AGalley into { @AGalleyPlace&&preceding }"
  1204. X"    right @Body"
  1205. X"{"
  1206. X"    //1.1b"
  1207. X"    @Body"
  1208. X"}"
  1209. X}
  1210. Xand invoked like this:
  1211. X@ID @Code {
  1212. X"@AGalleyPlace | @AGalley { content of galley }"
  1213. X"//"
  1214. X"..."
  1215. X"@AGalleyPlace"
  1216. X}
  1217. XThe first @Code "@AGalleyPlace" receives only the initial empty object,
  1218. Xsince the @Code "//1.1b" forces a split; and the Second Law puts Basser
  1219. XLout on the right track thereafter.
  1220. X@End @Section
  1221. END_OF_FILE
  1222.   if test 9965 -ne `wc -c <'lout/doc/tr.lout/ch2.06'`; then
  1223.     echo shar: \"'lout/doc/tr.lout/ch2.06'\" unpacked with wrong size!
  1224.   fi
  1225.   # end of 'lout/doc/tr.lout/ch2.06'
  1226. fi
  1227. if test -f 'lout/doc/tr.lout/ch4.03' -a "${1}" != "-c" ; then 
  1228.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch4.03'\"
  1229. else
  1230.   echo shar: Extracting \"'lout/doc/tr.lout/ch4.03'\" \(9416 characters\)
  1231.   sed "s/^X//" >'lout/doc/tr.lout/ch4.03' <<'END_OF_FILE'
  1232. X@Section
  1233. X   @Title { Page layout }
  1234. X   @Tag { pagelayout }
  1235. X@Begin
  1236. X@PP
  1237. XThe page layout
  1238. Xpage.layout.inpractice @SubIndex { in practice }
  1239. Xdocument.layout.page.layout. @SubIndex { page layout }
  1240. Xdefinitions given in Section {@NumberOf definitions},
  1241. Xalthough correct, are very basic.  In this section we present the
  1242. Xdefinitions used by the DocumentLayout package for laying out the pages
  1243. Xof books, including running page headers and footers, different formats
  1244. Xfor odd and even pages, and so on.  The present document is produced with
  1245. Xthese definitions.
  1246. X@PP
  1247. XWe begin with a few definitions which permit the user to create cross
  1248. Xreferences of the `see page 27' variety which will be kept up to date
  1249. Xautomatically.  The user marks the target page by placing
  1250. X@Code {"@PageMark intro"}, for example, at the point of interest, and
  1251. Xrefers to the marked page as @Code "@PageOf intro" elsewhere:
  1252. Xpageof.example @Index { @Code "@PageOf" example }
  1253. X@IndentedList
  1254. X@LI @Code {
  1255. X"export @Tag"
  1256. X"def @PageMarker right @Tag { @Null }"
  1257. X}
  1258. X@LI @Code {
  1259. X"def @PageMark right x"
  1260. X"{"
  1261. X"    @PageMarker&&preceding @Tagged x"
  1262. X"}"
  1263. X}
  1264. X@LI @Code {
  1265. X"def @PageOf right x"
  1266. X"{"
  1267. X"    @PageMarker&&x @Open { @Tag }"
  1268. X"}"
  1269. X}
  1270. X@EndList
  1271. XWe will see below that an invocation of @Code "@PageMarker" appears before
  1272. Xeach page, with @Code "@Tag" parameter equal to the
  1273. Xpage number.  Suppose that {@Code "@PageMark intro"}, which expands to
  1274. X@ID @Code "@PageMarker&&preceding @Tagged intro"
  1275. Xhappens to fall on page 27 of the final printed document (of course, its
  1276. Xvalue is @@Null which makes it invisible).  Then the effect of @@Tagged
  1277. Xis to attach @Code "intro" as an extra tag to the first invocation of
  1278. X{@Code "@PageMarker"} preceding that final point, and this must be
  1279. X{@Code "@PageMarker 27"}.  Therefore the expression
  1280. X@ID @Code "@PageMarker&&intro @Open { @Tag }"
  1281. Xwill open the invocation {@Code "@PageMarker 27"} and yield the value of
  1282. Xits @Code "@Tag" parameter, 27.  Thus, {@Code "@PageOf intro"} appearing
  1283. Xanywhere in the document yields 27.
  1284. X@PP
  1285. XNext we have some little definitions for various parts of the
  1286. Xpage.  {@Code "@FullPlace"} will be the target of full-width body text:
  1287. X@ID @Code {
  1288. X"def @FullPlace { @Galley }"
  1289. X}
  1290. X{@Code "@ColPlace"} will be the target of body text within one column:
  1291. X@ID @Code {
  1292. X"def @ColPlace { @Galley }"
  1293. X}
  1294. X{@Code "@TopList"} will be the target of figures and tables:
  1295. X@ID @Code {
  1296. X"export @Tag"
  1297. X"def @TopList right @Tag"
  1298. X"{"
  1299. X"    @Galley"
  1300. X"    //@TopGap @TopList @Next @Tag"
  1301. X"}"
  1302. X}
  1303. XWe have taken a shortcut here, avoiding an unnecessary @Code "@TopPlace"
  1304. Xsymbol.  @Code "@FootList" and {@Code "@FootSect"} define a sequence of
  1305. Xfull-width targets at the foot of the page for footnotes,
  1306. Xpreceded by a short horizontal line:
  1307. Xfootsect.example @Index { @Code "@FootSect" example }
  1308. X@IndentedList
  1309. X@LI @Code {
  1310. X"export @Tag"
  1311. X"def @FootList right @Tag"
  1312. X"{"
  1313. X"    @Galley"
  1314. X"    //@FootGap  @FootList @Next @Tag"
  1315. X"}"
  1316. X}
  1317. X@LI @Code {
  1318. X"def @FootSect"
  1319. X"{"
  1320. X"    @FootLen @Wide @HLine"
  1321. X"    //@FootGap  @FootList 1  ||@FootLen"
  1322. X"}"
  1323. X}
  1324. X@EndList
  1325. XSimilarly, @Code "@ColFootList" and @Code "@ColFootSect" provide a
  1326. Xsequence of targets for footnotes within one column:
  1327. X@ID @Code {
  1328. X"export @Tag"
  1329. X"def @ColFootList right @Tag"
  1330. X"{"
  1331. X"    @Galley"
  1332. X"    //@FootGap  @ColFootList @Next @Tag"
  1333. X"}"
  1334. X""
  1335. X"def @ColFootSect"
  1336. X"{"
  1337. X"    @ColFootLen @Wide @HLine"
  1338. X"    //@FootGap  @ColFootList 1  ||@ColFootLen"
  1339. X"}"
  1340. X}
  1341. XThe next definition provides a horizontal sequence of one or more columns:
  1342. Xcollist.example @Index { @Code "@ColList" example }
  1343. X@ID @Code {
  1344. X"def @ColList right col"
  1345. X"{"
  1346. X"    def @Column"
  1347. X"    {  @VExpand { @ColPlace //1rt @OneRow { //@MidGap @ColFootSect } }  }"
  1348. X""
  1349. X"    col @Case {"
  1350. X"        Single @Yield @Column"
  1351. X"        Double @Yield { @DoubleColWidth @Wide @Column  ||@ColGap  @ColList col }"
  1352. X"        Multi  @Yield { @MultiColWidth @Wide @Column  ||@ColGap  @ColList col }"
  1353. X"    }"
  1354. X"}"
  1355. X}
  1356. XEach column consists of a @Code "@ColPlace" at the top and a
  1357. X@Code "@FootSect" at the foot.  The @@VExpand symbol ensures that
  1358. Xwhenever a column comes into existence, it will expand vertically so
  1359. Xthat the bottom-justification @Code "//1rt" has as much space as
  1360. Xpossible to work within.  The @Code "col" parameter determines whether
  1361. Xthe result has a single column, double columns, or multiple columns.
  1362. X@PP
  1363. XThe {@Code "@Page"} symbol places its parameter in a page of fixed width,
  1364. Xheight, and margins:
  1365. Xpage.example @Index { @Code "@Page" example }
  1366. X@ID @Code {
  1367. X"def @Page right x"
  1368. X"{"
  1369. X"    @PageWidth @Wide @PageHeight @High {"
  1370. X"        //@PageMargin  ||@PageMargin"
  1371. X"        @HExpand @VExpand x"
  1372. X"        ||@PageMargin  //@PageMargin"
  1373. X"    }"
  1374. X"}"
  1375. X}
  1376. X@@HExpand and @@VExpand ensure that the right parameter occupies all the
  1377. Xavailable space; this is important when the right parameter is unusually
  1378. Xsmall.  The @@High symbol gives the page a single row mark, ensuring that
  1379. Xit will be printed on a single sheet of paper (page {@PageOf rootg}).
  1380. X@PP
  1381. XNext we have {@Code "@OnePage"}, defining a typical page of a book or
  1382. Xother document:
  1383. Xonepage.example @Index { @Code "@OnePage" example }
  1384. X@ID @Code {
  1385. X"def @OnePage"
  1386. X"    named @Columns {}"
  1387. X"    named @PageTop {}"
  1388. X"    named @PageFoot {}"
  1389. X"{"
  1390. X"    @Page {"
  1391. X"        @PageTop"
  1392. X"        //@MidGap  @TopList"
  1393. X"        //@MidGap  @FullPlace"
  1394. X"        //@MidGap  @ColList @Columns"
  1395. X"        // //1rt   @OneRow { //@MidGap @FootSect //@MidGap @PageFoot }"
  1396. X"    }"
  1397. X"}"
  1398. X}
  1399. XThe page top and page foot, and the number of columns, are parameters
  1400. Xthat will be given later when @Code "@OnePage" is invoked.  The body of
  1401. Xthe page is a straightforward combination of previous definitions.  The
  1402. X@Code "//" symbol protects the following @Code "//1rt" from deletion in
  1403. Xthe unlikely event that all the preceding symbols are replaced by
  1404. X@@Null.  The following object is enclosed in @@OneRow to ensure that
  1405. Xall of it is bottom-justified, not just its first component.
  1406. X@PP
  1407. XBefore presenting the definition of a sequence of pages, we must detour
  1408. Xto describe how running page headers and footers (like those in the
  1409. Xpresent document) are produced.  These are based on the
  1410. X@Code "@Runner" symbol:
  1411. Xrunner.example @Index { @Code "@Runner" example }
  1412. X@ID @Code {
  1413. X"export @TopOdd @TopEven @FootOdd @FootEven"
  1414. X"def @Runner"
  1415. X"    named @TopOdd right @PageNum { @Null }"
  1416. X"    named @TopEven right @PageNum { @Null }"
  1417. X"    named @FootOdd right @PageNum { @Null }"
  1418. X"    named @FootEven right @PageNum { @Null }"
  1419. X"    named @Tag {}"
  1420. X"{ @Null }"
  1421. X}
  1422. XThe four parameters control the format of running headers and footers on
  1423. Xodd and even pages respectively.  Invocations of {@Code "@Runner"}, for
  1424. Xexample
  1425. X@ID @Code {
  1426. X"@Runner"
  1427. X"    @TopEven { @B @PageNum |1rt @I { Chapter 4 } }"
  1428. X"    @TopOdd  { @I { Examples }   |1rt @B @PageNum }"
  1429. X}
  1430. Xwill be embedded in the body text of the document, and, as we will see
  1431. Xin a moment, are accessed by @Code "@Runner&&following" cross references
  1432. Xon the pages.  Notice how the @Code "@PageNum" parameter of each
  1433. Xparameter allows the format of the running header to be specified while
  1434. Xleaving the page number to be substituted later.
  1435. X@PP
  1436. XWe may now define {@Code "@OddPageList"}, whose result is a sequence of
  1437. Xpages beginning with an odd-numbered page:
  1438. Xoddpagelist.example @Index { @Code "@OddPageList" example }
  1439. X@ID @Code {
  1440. X"def @OddPageList"
  1441. X"    named @Columns {}"
  1442. X"    right @PageNum"
  1443. X"{"
  1444. X"    def @EvenPageList ..."
  1445. X""
  1446. X"        @PageMarker @PageNum"
  1447. X"    //  @Runner&&following @Open {"
  1448. X"            @OnePage"
  1449. X"                @Columns { @Columns }"
  1450. X"                @PageTop { @TopOdd @PageNum }"
  1451. X"                @PageFoot { @FootOdd @PageNum }"
  1452. X"        }"
  1453. X"    //  @EvenPageList"
  1454. X"            @Columns { @Columns }"
  1455. X"            @Next @PageNum"
  1456. X"}"
  1457. X}
  1458. XIgnoring @Code "@EvenPageList" for the moment, notice first that the
  1459. Xinvocation of @Code "@OnePage" is enclosed in
  1460. X{@Code "@Runner&&following @Open"}.  Since {@Code "@Runner&&following"}
  1461. Xrefers to the first invocation of @Code "@Runner" appearing after itself
  1462. Xin the final printed document, the symbols @Code "@TopOdd" and
  1463. X@Code "@FootOdd" will take their value from the first invocation of
  1464. X@Code "@Runner" following the top of the page, even though @Code "@FootOdd"
  1465. Xappears at the foot of the page.  Their @Code "@PageNum" parameters are
  1466. Xreplaced by {@Code "@PageNum"}, the actual page number parameter of
  1467. X{@Code "@OddPageList"}.
  1468. X@PP
  1469. XAfter producing the odd-numbered page, @Code "@OddPageList" invokes
  1470. X{@Code "@EvenPageList"}:
  1471. Xevenpagelist.example @Index { @Code "@EvenPageList" example }
  1472. X@ID @Code {
  1473. X"def @EvenPageList"
  1474. X"    named @Columns {}"
  1475. X"    right @PageNum"
  1476. X"{"
  1477. X"        @PageMarker @PageNum"
  1478. X"    //  @Runner&&following @Open {"
  1479. X"            @OnePage"
  1480. X"                @Columns { @Columns }"
  1481. X"                @PageTop { @TopEven @PageNum }"
  1482. X"                @PageFoot { @FootEven @PageNum }"
  1483. X"        }"
  1484. X"    //  @OddPageList"
  1485. X"            @Columns { @Columns }"
  1486. X"            @Next @PageNum"
  1487. X"}"
  1488. X}
  1489. XThis produces an even-numbered page, then passes the ball back to
  1490. X@Code "@OddPageList" -- a delightful example of what computer
  1491. Xscientists call mutual recursion.  The two page types differ only in
  1492. Xtheir running headers and footers, but other changes could easily be made.
  1493. X@PP
  1494. XIt was foreshadowed earlier that an invocation of @Code "@PageMarker"
  1495. Xwould precede each page, and this has been done.  Although this @Code
  1496. X"@PageMarker" is a component of the root galley, it will not cause a
  1497. Xpage to be printed, because Basser Lout skips components of height zero.
  1498. X@End @Section
  1499. END_OF_FILE
  1500.   if test 9416 -ne `wc -c <'lout/doc/tr.lout/ch4.03'`; then
  1501.     echo shar: \"'lout/doc/tr.lout/ch4.03'\" unpacked with wrong size!
  1502.   fi
  1503.   # end of 'lout/doc/tr.lout/ch4.03'
  1504. fi
  1505. if test -f 'lout/makefile' -a "${1}" != "-c" ; then 
  1506.   echo shar: Will not clobber existing file \"'lout/makefile'\"
  1507. else
  1508.   echo shar: Extracting \"'lout/makefile'\" \(8738 characters\)
  1509.   sed "s/^X//" >'lout/makefile' <<'END_OF_FILE'
  1510. X
  1511. X###################################################################
  1512. X#                                                                 #
  1513. X#  Make file for installing Lout Version 2.03                     #
  1514. X#                                                                 #
  1515. X#  Jeffrey H. Kingston                                            #
  1516. X#  23 April 1993                                                  #
  1517. X#                                                                 #
  1518. X#     make lout        Compile the Lout source                    #
  1519. X#     make install     Install the Lout binary and libraries and  #
  1520. X#                      perform a compulsory initial run           #
  1521. X#     make installman  Install the Lout manual entry              #
  1522. X#     make installdoc  Install the Lout documentation             #
  1523. X#     make clean       Remove compilation temporaries             #
  1524. X#     make clobber     Undo the effect of `make lout'             #
  1525. X#     make uninstall   Undo the effect of `make install',         #
  1526. X#                      `make installman', and `make installdoc'   #
  1527. X#                                                                 #
  1528. X#  Most installations of Lout should require no more than the     #
  1529. X#  following steps.                                               #
  1530. X#                                                                 #
  1531. X#  (1) Set the following five macros defined below to appropriate #
  1532. X#      values.  The macros are                                    #
  1533. X#                                                                 #
  1534. X#         LATIN        Set this to 1 if the ISO-LATIN-1 character #
  1535. X#                      set is to be used (i.e. for non-English    #
  1536. X#                      languages), or 0 for ASCII (i.e. English). #
  1537. X#                      This has two effects: it changes the       #
  1538. X#                      lexical analyser in the lout binary so     #
  1539. X#                      as to recognize ISO-LATIN-1 characters,    #
  1540. X#                      and it changes the directory that the Lout #
  1541. X#                      font files are copied from during install  #
  1542. X#                      so that Latin .AFM files are used.  It     #
  1543. X#                      has no effect on hyphenation.              #
  1544. X#                                                                 #
  1545. X#                      At the time of writing the Latin font      #
  1546. X#                      directory is empty and the changes to the  #
  1547. X#                      lexical analyser are not implemented; but  #
  1548. X#                      someday someone will fill in these gaps.   #
  1549. X#                                                                 #
  1550. X#         BINDIR       The directory where the Lout binary goes   #
  1551. X#                      (this directory is assumed to exist)       #
  1552. X#                                                                 #
  1553. X#         LIBDIR       Directory where the Lout libraries go      #
  1554. X#                      (this directory will be created)           #
  1555. X#                                                                 #
  1556. X#         DOCDIR       Directory where the Lout documents go;     #
  1557. X#                      they are tech. reports written in Lout     #
  1558. X#                      describing various parts of the system     #
  1559. X#                      (this directory will be created)           #
  1560. X#                                                                 #
  1561. X#         MANDIR       Directory where Lout manual entry goes;    #
  1562. X#                      it has the form of input to nroff -man     #
  1563. X#                      (this directory is assumed to exist)       #
  1564. X#                                                                 #
  1565. X#  (2) Execute "make lout".  This will compile the Lout source    #
  1566. X#      code and leave the binary in this directory.  No changes   #
  1567. X#      will be made in any other directories.                     #
  1568. X#                                                                 #
  1569. X#  (3) Execute "make install".  This will (a) copy the Lout       #
  1570. X#      binary into directory BINDIR; (b) create LIBDIR and copy   #
  1571. X#      all the library files into it; and finally (c) perform a   #
  1572. X#      test run on the document stored in ./doc/tr.eq.  This test #
  1573. X#      is compulsory because it has side effects: the database    #
  1574. X#      index files loutrefs.li, refstyles.li, and standard.li     #
  1575. X#      are created in directory $(LIBDIR)/data, and the packed    #
  1576. X#      hyphenation pattern file lout.hyph.packed is created in    #
  1577. X#      directory $(LIBDIR)/include.  The test run will produce    #
  1578. X#      quite a few warning messages about unresolved cross        #
  1579. X#      references, but there should be no fatal errors.  (These   #
  1580. X#      warning messages gradually go away on subsequent runs.)    #
  1581. X#                                                                 #
  1582. X#  (4) Execute "make installman".  This installs the manual       #
  1583. X#      entry in directory $(MANDIR).                              #
  1584. X#                                                                 #
  1585. X#  (5) Execute "make installdoc".  This creates $(DOCDIR) and     #
  1586. X#      copies the tech. reports into it.                          #
  1587. X#                                                                 #
  1588. X#  (6) Execute "make clobber".  This undoes "make lout".          #
  1589. X#                                                                 #
  1590. X#  You probably also want to change the default values of the     #
  1591. X#  @PageWidth and @PageHeight parameters of the DocumentLayout    #
  1592. X#  package, if you are using something other than A4 paper.       #
  1593. X#  These are found on lines 154-5 of file $(LIBDIR)/include/dl.   #
  1594. X#  Set them to the physical width and height of your paper; for   #
  1595. X#  example, 29.70c is 29.7 centimetres, the A4 height.            #
  1596. X#                                                                 #
  1597. X#  Mail jeff@cs.su.oz.au if you have any problems.                #
  1598. X#                                                                 #
  1599. X###################################################################
  1600. X
  1601. XLATIN    = 0
  1602. XBINDIR    = /usr/local/bin
  1603. XLIBDIR    = /usr/local/lib/lout
  1604. XDOCDIR    = /usr/local/lib/lout.doc
  1605. XMANDIR    = /usr/local/man/man1
  1606. X
  1607. XCFLAGS    = -DFONT_DIR=\"$(LIBDIR)/font$(LATIN)\"            \
  1608. X      -DINCL_DIR=\"$(LIBDIR)/include\"            \
  1609. X      -DDATA_DIR=\"$(LIBDIR)/data\"                \
  1610. X      -DLATIN=$(LATIN)                    \
  1611. X      -DDEBUG_ON=0                        \
  1612. X      -DASSERT_ON=1
  1613. X
  1614. XOBJS    = z01.o z02.o z03.o z04.o z05.o z06.o z07.o        \
  1615. X      z08.o z09.o z10.o z11.o z12.o z13.o z14.o        \
  1616. X      z15.o z16.o z17.o z18.o z19.o z20.o z21.o        \
  1617. X      z22.o z23.o z24.o z25.o z26.o z27.o z28.o        \
  1618. X      z29.o z30.o z31.o z32.o z33.o z34.o z35.o z36.o
  1619. X
  1620. Xlout:    $(OBJS)
  1621. X    $(CC) -o lout $(OBJS) -lm
  1622. X    chmod a+x lout
  1623. X
  1624. X$(OBJS): externs
  1625. X
  1626. Xexterns:
  1627. X
  1628. Xinstall: lout
  1629. X    @echo ""
  1630. X    @echo "Copying Lout binary to BINDIR"
  1631. X    cp lout $(BINDIR)/lout
  1632. X    chmod a+x-w $(BINDIR)/lout
  1633. X    @echo ""
  1634. X    @echo "Creating LIBDIR and copying library files"
  1635. X    mkdir $(LIBDIR)
  1636. X    chmod 775 $(LIBDIR)
  1637. X    mkdir $(LIBDIR)/include
  1638. X    chmod 775 $(LIBDIR)/include
  1639. X    mkdir $(LIBDIR)/data
  1640. X    chmod 775 $(LIBDIR)/data
  1641. X    mkdir $(LIBDIR)/font$(LATIN)
  1642. X    chmod 775 $(LIBDIR)/font$(LATIN)
  1643. X    cp include/* $(LIBDIR)/include
  1644. X    chmod a+r-wx $(LIBDIR)/include/*
  1645. X    cp data/* $(LIBDIR)/data
  1646. X    chmod a+r-wx $(LIBDIR)/data/*
  1647. X    cp font$(LATIN)/* $(LIBDIR)/font$(LATIN)
  1648. X    chmod a+r-wx $(LIBDIR)/font$(LATIN)/*
  1649. X    @echo ""
  1650. X    @echo "Compulsory test run on doc/tr.eq (expect many non-fatal error messages)"
  1651. X    ./lout ./doc/tr.eq/setup ./doc/tr.eq/s? > ./doc/tr.eq/op
  1652. X    rm ./doc/tr.eq/op ./doc/tr.eq/s?.ld lout.li
  1653. X
  1654. Xinstallman:
  1655. X    sed -e "s@<BINDIR>@$(BINDIR)@" -e "s@<LIBDIR>@$(LIBDIR)@"    \
  1656. X        -e "s@<DOCDIR>@$(DOCDIR)@" -e "s@<MANDIR>@$(MANDIR)@"    \
  1657. X    man/lout.1 > $(MANDIR)/lout.1
  1658. X    chmod a+r $(MANDIR)/lout.1
  1659. X
  1660. Xinstalldoc:
  1661. X    mkdir $(DOCDIR)
  1662. X    chmod 775 $(DOCDIR)
  1663. X    mkdir $(DOCDIR)/tr.lout
  1664. X    chmod 775 $(DOCDIR)/tr.lout
  1665. X    cp doc/tr.lout/* $(DOCDIR)/tr.lout
  1666. X    chmod a+r-wx $(DOCDIR)/tr.lout/*
  1667. X    mkdir $(DOCDIR)/tr.impl
  1668. X    chmod 775 $(DOCDIR)/tr.impl
  1669. X    cp doc/tr.impl/* $(DOCDIR)/tr.impl
  1670. X    chmod a+r-wx $(DOCDIR)/tr.impl/*
  1671. X    mkdir $(DOCDIR)/tr.over
  1672. X    chmod 775 $(DOCDIR)/tr.over
  1673. X    cp doc/tr.over/* $(DOCDIR)/tr.over
  1674. X    chmod a+r-wx $(DOCDIR)/tr.over/*
  1675. X    mkdir $(DOCDIR)/tr.begin
  1676. X    chmod 775 $(DOCDIR)/tr.begin
  1677. X    cp doc/tr.begin/* $(DOCDIR)/tr.begin
  1678. X    chmod a+r-wx $(DOCDIR)/tr.begin/*
  1679. X    mkdir $(DOCDIR)/tr.eq
  1680. X    chmod 775 $(DOCDIR)/tr.eq
  1681. X    cp doc/tr.eq/*   $(DOCDIR)/tr.eq
  1682. X    chmod a+r-wx $(DOCDIR)/tr.eq/*
  1683. X    mkdir $(DOCDIR)/tr.fig
  1684. X    chmod 775 $(DOCDIR)/tr.fig
  1685. X    cp doc/tr.fig/*  $(DOCDIR)/tr.fig
  1686. X    chmod a+r-wx $(DOCDIR)/tr.fig/*
  1687. X    mkdir $(DOCDIR)/tr.tab
  1688. X    chmod 775 $(DOCDIR)/tr.tab
  1689. X    cp doc/tr.tab/*  $(DOCDIR)/tr.tab
  1690. X    chmod a+r-wx $(DOCDIR)/tr.tab/*
  1691. X
  1692. Xuninstall:
  1693. X    -rm -f  $(BINDIR)/lout
  1694. X    -rm -fr $(LIBDIR)
  1695. X    -rm -fr $(DOCDIR)
  1696. X    -rm -f  $(MANDIR)/lout.1
  1697. X
  1698. Xclean:    
  1699. X    rm -f *.o
  1700. X
  1701. Xclobber: clean
  1702. X    rm -f lout
  1703. END_OF_FILE
  1704.   if test 8738 -ne `wc -c <'lout/makefile'`; then
  1705.     echo shar: \"'lout/makefile'\" unpacked with wrong size!
  1706.   fi
  1707.   # end of 'lout/makefile'
  1708. fi
  1709. if test -f 'lout/z30.c' -a "${1}" != "-c" ; then 
  1710.   echo shar: Will not clobber existing file \"'lout/z30.c'\"
  1711. else
  1712.   echo shar: Extracting \"'lout/z30.c'\" \(8790 characters\)
  1713.   sed "s/^X//" >'lout/z30.c' <<'END_OF_FILE'
  1714. X/*@z30.c:Symbol uses:InsertUses(), FlattenUses(), SearchUses()@***************/
  1715. X/*                                                                           */
  1716. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.03)       */
  1717. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1718. X/*                                                                           */
  1719. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1720. X/*  Basser Department of Computer Science                                    */
  1721. X/*  The University of Sydney 2006                                            */
  1722. X/*  AUSTRALIA                                                                */
  1723. X/*                                                                           */
  1724. X/*  This program is free software; you can redistribute it and/or modify     */
  1725. X/*  it under the terms of the GNU General Public License as published by     */
  1726. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1727. X/*  any later version.                                                       */
  1728. X/*                                                                           */
  1729. X/*  This program is distributed in the hope that it will be useful,          */
  1730. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1731. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1732. X/*  GNU General Public License for more details.                             */
  1733. X/*                                                                           */
  1734. X/*  You should have received a copy of the GNU General Public License        */
  1735. X/*  along with this program; if not, write to the Free Software              */
  1736. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1737. X/*                                                                           */
  1738. X/*  FILE:         z30.c                                                      */
  1739. X/*  MODULE:       Symbol Uses                                                */
  1740. X/*  EXTERNS:      InsertUses(), FlattenUses(), SearchUses(), TargetUsedBy()  */
  1741. X/*                                                                           */
  1742. X/*****************************************************************************/
  1743. X#include "externs"
  1744. X
  1745. X
  1746. X/*****************************************************************************/
  1747. X/*                                                                           */
  1748. X/*  InsertUses(x, y)                                                         */
  1749. X/*                                                                           */
  1750. X/*  Record the fact that symbol x uses symbol y, by linking them.            */
  1751. X/*  Increment count of the number of times y is used, if y is a parameter.   */
  1752. X/*                                                                           */
  1753. X/*****************************************************************************/
  1754. X
  1755. XInsertUses(x, y)
  1756. XOBJECT x, y;
  1757. X{ OBJECT tmp;
  1758. X  debug2(DSU, D, "InsertUses( %s, %s )", SymName(x), SymName(y));
  1759. X  if( type(x) == LOCAL && type(y) == LOCAL && !predefined(y) )
  1760. X  { tmp = GetMem(USES_SIZE, no_fpos);  item(tmp) = y;
  1761. X    if( base_uses(x) == nil )  next(tmp) = tmp;
  1762. X    else next(tmp) = next(base_uses(x)), next(base_uses(x)) = tmp;
  1763. X    base_uses(x) = tmp;
  1764. X  }
  1765. X  if( is_par(type(y)) )
  1766. X  { uses_count(y) += (enclosing(y) == x ? 1 : 2);
  1767. X    if( dirty(y) || uses_count(y) > 1 )  dirty(enclosing(y)) = TRUE;
  1768. X  }
  1769. X  else if( sym_body(y) == nil || dirty(y) )  dirty(x) = TRUE;
  1770. X  debug5(DSU, D, "InsertUses returning ( %s %s; %s %s, count = %d )",
  1771. X    SymName(x), (dirty(x) ? "dirty" : "clean"),
  1772. X    SymName(y), (dirty(y) ? "dirty" : "clean"), uses_count(y));
  1773. X} /* end InsertUses */
  1774. X
  1775. X
  1776. X/*****************************************************************************/
  1777. X/*                                                                           */
  1778. X/*  static gather_uses(x, sym)                                               */
  1779. X/*  static gather_all_uses(x)                                                */
  1780. X/*                                                                           */
  1781. X/*  gather_uses adds all the unmarked descendants of x to the uses relation  */
  1782. X/*  of sym;  gather_all_uses applies gather_uses to all descendants of x.    */
  1783. X/*                                                                           */
  1784. X/*****************************************************************************/
  1785. X
  1786. Xstatic gather_uses(x, sym)
  1787. XOBJECT x, sym;
  1788. X{ OBJECT link, y, tmp;
  1789. X  if( base_uses(x) != nil )
  1790. X  { link = next(base_uses(x));
  1791. X    do
  1792. X    { y = item(link);
  1793. X      if( marker(y) != sym )
  1794. X      {    if( y != sym )
  1795. X    { marker(y) = sym;
  1796. X      tmp = GetMem(USES_SIZE, no_fpos);  item(tmp) = y;
  1797. X      if( uses(sym) == nil )  next(tmp) = tmp;
  1798. X      else next(tmp) = next(uses(sym)), next(uses(sym)) = tmp;
  1799. X      uses(sym) = tmp;
  1800. X      if( indefinite(y) )  indefinite(sym) = TRUE;
  1801. X      if( uses_extern_target(y) )  uses_extern_target(sym) = TRUE;
  1802. X      gather_uses(y, sym);
  1803. X    }
  1804. X    else recursive(sym) = TRUE;
  1805. X      }
  1806. X      link = next(link);
  1807. X    } while( link != next(base_uses(x)) );
  1808. X  }
  1809. X} /* end gather_uses */
  1810. X
  1811. X
  1812. Xstatic gather_all_uses(x)
  1813. XOBJECT x;
  1814. X{ OBJECT link, y;
  1815. X  for( link = Down(x);  link != x;  link = NextDown(link) )
  1816. X  { Child(y, link);
  1817. X    if( type(y) == LOCAL )  gather_uses(y, y);
  1818. X    gather_all_uses(y);
  1819. X  }
  1820. X} /* end gather_all_uses */
  1821. X
  1822. X
  1823. X/*@@**************************************************************************/
  1824. X/*                                                                           */
  1825. X/*  FlattenUses()                                                            */
  1826. X/*                                                                           */
  1827. X/*  Traverse the directed graph assembled by InsertUses, finding its         */
  1828. X/*  transitive closure and storing this explicitly in uses(x) for all x.     */
  1829. X/*                                                                           */
  1830. X/*****************************************************************************/
  1831. X
  1832. XFlattenUses()
  1833. X{ gather_all_uses(StartSym);
  1834. X} /* end FlattenUses */
  1835. X
  1836. X
  1837. X/*****************************************************************************/
  1838. X/*                                                                           */
  1839. X/*  BOOLEAN SearchUses(x, y)                                                 */
  1840. X/*                                                                           */
  1841. X/*  Determine whether symbol x uses symbol y by searching x's uses list.     */
  1842. X/*                                                                           */
  1843. X/*****************************************************************************/
  1844. X
  1845. XBOOLEAN SearchUses(x, y)
  1846. XOBJECT x, y;
  1847. X{ OBJECT p;
  1848. X  debug3(DSU, DD, "SearchUses(%s, %s) uses: %d", SymName(x),SymName(y),uses(x));
  1849. X  if( x == y )  return TRUE;
  1850. X  if( uses(x) != nil )
  1851. X  { p = next(uses(x));
  1852. X    do
  1853. X    { debug1(DSU, DDD, "  checking %s", SymName(item(p)));
  1854. X      if( item(p) == y )  return TRUE;
  1855. X      p = next(p);
  1856. X    } while( p != next(uses(x)) );
  1857. X  }
  1858. X  return FALSE;
  1859. X} /* end SearchUses */
  1860. X
  1861. X
  1862. X/*****************************************************************************/
  1863. X/*                                                                           */
  1864. X/*  OBJECT FirstExternTarget(sym, cont)                                      */
  1865. X/*  OBJECT NextExternTarget(sym, cont)                                       */
  1866. X/*                                                                           */
  1867. X/*  Together these two procedures return all symbols which are both used by  */
  1868. X/*  sym and a target for at least one external galley.  Return nil at end.   */
  1869. X/*                                                                           */
  1870. X/*****************************************************************************/
  1871. X
  1872. XOBJECT FirstExternTarget(sym, cont)
  1873. XOBJECT sym, *cont;
  1874. X{ OBJECT res;
  1875. X  debug1(DSU, D, "FirstExternTarget( %s )", SymName(sym));
  1876. X  res = nil;  *cont = nil;
  1877. X  if( is_extern_target(sym) )  res = sym;
  1878. X  else if( uses(sym) != nil )
  1879. X  { *cont = next(uses(sym));
  1880. X    do
  1881. X    { if( is_extern_target(item(*cont)) )
  1882. X      {    res = item(*cont);
  1883. X    break;
  1884. X      }
  1885. X      *cont = next(*cont);
  1886. X    } while( *cont != next(uses(sym)) );
  1887. X  }
  1888. X  debug1(DSU, D, "FirstExternTarget returning %s", SymName(res));
  1889. X  return res;
  1890. X} /* end FirstExternTarget */
  1891. X
  1892. XOBJECT NextExternTarget(sym, cont)
  1893. XOBJECT sym, *cont;
  1894. X{ OBJECT res;
  1895. X  debug1(DSU, D, "NextExternTarget( %s )", SymName(sym));
  1896. X  res = nil;
  1897. X  if( *cont != nil )
  1898. X  { *cont = next(*cont);
  1899. X    while( *cont != next(uses(sym)) )
  1900. X    { if( is_extern_target(item(*cont)) )
  1901. X      {    res = item(*cont);
  1902. X    break;
  1903. X      }
  1904. X      *cont = next(*cont);
  1905. X    }
  1906. X  }
  1907. X  debug1(DSU, D, "NextExternTarget returning %s", SymName(res));
  1908. X  return res;
  1909. X} /* end NextExternTarget */
  1910. END_OF_FILE
  1911.   if test 8790 -ne `wc -c <'lout/z30.c'`; then
  1912.     echo shar: \"'lout/z30.c'\" unpacked with wrong size!
  1913.   fi
  1914.   # end of 'lout/z30.c'
  1915. fi
  1916. if test -f 'lout/z31.c' -a "${1}" != "-c" ; then 
  1917.   echo shar: Will not clobber existing file \"'lout/z31.c'\"
  1918. else
  1919.   echo shar: Extracting \"'lout/z31.c'\" \(9723 characters\)
  1920.   sed "s/^X//" >'lout/z31.c' <<'END_OF_FILE'
  1921. X/*@z31.c:Memory Allocator:zz_free[], GetMemory() etc.@************************/
  1922. X/*                                                                           */
  1923. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.03)       */
  1924. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1925. X/*                                                                           */
  1926. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1927. X/*  Basser Department of Computer Science                                    */
  1928. X/*  The University of Sydney 2006                                            */
  1929. X/*  AUSTRALIA                                                                */
  1930. X/*                                                                           */
  1931. X/*  This program is free software; you can redistribute it and/or modify     */
  1932. X/*  it under the terms of the GNU General Public License as published by     */
  1933. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1934. X/*  any later version.                                                       */
  1935. X/*                                                                           */
  1936. X/*  This program is distributed in the hope that it will be useful,          */
  1937. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1938. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1939. X/*  GNU General Public License for more details.                             */
  1940. X/*                                                                           */
  1941. X/*  You should have received a copy of the GNU General Public License        */
  1942. X/*  along with this program; if not, write to the Free Software              */
  1943. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1944. X/*                                                                           */
  1945. X/*  FILE:         z31.c                                                      */
  1946. X/*  MODULE:       Memory Allocator                                           */
  1947. X/*  EXTERNS:      zz_free[], GetMemory(), DebugMemory()                      */
  1948. X/*                                                                           */
  1949. X/*****************************************************************************/
  1950. X#include "externs"
  1951. X
  1952. X#define    MEM_CHUNK    1020        /* how many ALIGNs to get from sys   */
  1953. X
  1954. X
  1955. X#if DEBUG_ON
  1956. Xstatic    int    no_of_calls    = 0;    /* number of calls to calloc()       */
  1957. X    int    zz_newcount    = 0;    /* number of calls to New()          */
  1958. X    int    zz_disposecount    = 0;    /* number of calls to Dispose()      */
  1959. X
  1960. X/*****************************************************************************/
  1961. X/*                                                                           */
  1962. X/*  DebugMemory()                                                            */
  1963. X/*                                                                           */
  1964. X/*  Print memory usage.                                                      */
  1965. X/*                                                                           */
  1966. X/*****************************************************************************/
  1967. X
  1968. XDebugMemory()
  1969. X{ int i, j;  OBJECT p;
  1970. X  debug2(DMA, D, "calloc called %d times (%d bytes total)",
  1971. X    no_of_calls, no_of_calls * MEM_CHUNK * sizeof(ALIGN));
  1972. X  debug2(DMA, D, "New() called %d times;  Dispose() called %d times",
  1973. X    zz_newcount, zz_disposecount);
  1974. X  for( i = 0;  i < MAX_OBJECT_REC;  i++ )
  1975. X  { if( zz_free[i] != nil )
  1976. X    { j = 0;
  1977. X      for( p = zz_free[i];  p != nil;  p = pred(p, CHILD) )  j++;
  1978. X      debug2(DMA, DD, "zz_free[%2d]: %3d", i, j);
  1979. X    }
  1980. X  }
  1981. X} /* end DebugMemory */
  1982. X#endif
  1983. X
  1984. X
  1985. X/*****************************************************************************/
  1986. X/*                                                                           */
  1987. X/*  OBJECT         zz_free[], zz_hold, zz_tmp, zz_res                        */
  1988. X/*  int            zz_size                                                   */
  1989. X/*  unsigned char  zz_lengths[]                                              */
  1990. X/*                                                                           */
  1991. X/*  zz_free[i]:    free records of size i*sizeof(ALIGN).                     */
  1992. X/*  zz_lengths[i]: the number of ALIGNs in a record of type i.               */
  1993. X/*  These variables are used only within the New() and Dispose() macros,     */
  1994. X/*  and the list handling macros.                                            */
  1995. X/*                                                                           */
  1996. X/*****************************************************************************/
  1997. X
  1998. XOBJECT        zz_free[MAX_OBJECT_REC], zz_hold, zz_tmp, zz_res;
  1999. Xint        zz_size;
  2000. Xunsigned char    zz_lengths[DISPOSED];        /* DISPOSED is 1 + max type */
  2001. XOBJECT         xx_link, xx_tmp, xx_res, xx_hold;
  2002. X
  2003. X
  2004. X/*@@**************************************************************************/
  2005. X/*                                                                           */
  2006. X/*  MemInit()                                                                */
  2007. X/*                                                                           */
  2008. X/*  Initialise memory allocator.                                             */
  2009. X/*                                                                           */
  2010. X/*****************************************************************************/
  2011. X
  2012. XMemInit()
  2013. X{
  2014. X  zz_lengths[ WORD        ] = 0;
  2015. X  zz_lengths[ LINK        ] = ceiling( sizeof(struct link_type), sizeof(ALIGN));
  2016. X
  2017. X  /* object types, except closure NB have actual() field in token phase! */
  2018. X  zz_lengths[ SPLIT       ] =
  2019. X  zz_lengths[ HEAD        ] =
  2020. X  zz_lengths[ PAR         ] =
  2021. X  zz_lengths[ ROW_THR     ] =
  2022. X  zz_lengths[ COL_THR     ] =
  2023. X  zz_lengths[ CLOSURE     ] =
  2024. X  zz_lengths[ NULL_CLOS   ] =
  2025. X  zz_lengths[ CROSS       ] =
  2026. X  zz_lengths[ ONE_COL     ] =
  2027. X  zz_lengths[ ONE_ROW     ] =
  2028. X  zz_lengths[ WIDE        ] =
  2029. X  zz_lengths[ HIGH        ] =
  2030. X  zz_lengths[ HSCALE      ] =
  2031. X  zz_lengths[ VSCALE      ] =
  2032. X  zz_lengths[ HCONTRACT   ] =
  2033. X  zz_lengths[ VCONTRACT   ] =
  2034. X  zz_lengths[ HEXPAND     ] =
  2035. X  zz_lengths[ VEXPAND     ] =
  2036. X  zz_lengths[ PADJUST     ] =
  2037. X  zz_lengths[ HADJUST     ] =
  2038. X  zz_lengths[ VADJUST     ] =
  2039. X  zz_lengths[ ROTATE      ] =
  2040. X  zz_lengths[ SCALE       ] =
  2041. X  zz_lengths[ CASE        ] =
  2042. X  zz_lengths[ YIELD       ] =
  2043. X  zz_lengths[ FONT        ] =
  2044. X  zz_lengths[ SPACE       ] =
  2045. X  zz_lengths[ BREAK       ] =
  2046. X  zz_lengths[ NEXT        ] =
  2047. X  zz_lengths[ ENV         ] =
  2048. X  zz_lengths[ CLOS        ] =
  2049. X  zz_lengths[ LVIS        ] =
  2050. X  zz_lengths[ OPEN        ] =
  2051. X  zz_lengths[ TAGGED      ] =
  2052. X  zz_lengths[ INCGRAPHIC  ] =
  2053. X  zz_lengths[ SINCGRAPHIC ] =
  2054. X  zz_lengths[ GRAPHIC     ] =
  2055. X  zz_lengths[ ACAT        ] =
  2056. X  zz_lengths[ HCAT        ] =
  2057. X  zz_lengths[ VCAT        ] =
  2058. X  zz_lengths[ LBR         ] =
  2059. X  zz_lengths[ RBR         ] =
  2060. X  zz_lengths[ BEGIN       ] =
  2061. X  zz_lengths[ END         ] =
  2062. X  zz_lengths[ USE         ] =
  2063. X  zz_lengths[ DATABASE    ] =
  2064. X  zz_lengths[ SYS_DATABASE] =
  2065. X  zz_lengths[ GSTUB_NONE  ] =
  2066. X  zz_lengths[ GSTUB_INT   ] =
  2067. X  zz_lengths[ GSTUB_EXT   ] =
  2068. X  zz_lengths[ DEAD        ] =
  2069. X  zz_lengths[ UNATTACHED  ] =
  2070. X  zz_lengths[ RECEPTIVE   ] =
  2071. X  zz_lengths[ RECEIVING   ] =
  2072. X  zz_lengths[ RECURSIVE   ] =
  2073. X  zz_lengths[ PRECEDES    ] =
  2074. X  zz_lengths[ FOLLOWS     ] =
  2075. X  zz_lengths[ CROSS_FOLL  ] =
  2076. X  zz_lengths[ GALL_FOLL   ] =
  2077. X  zz_lengths[ CROSS_TARG  ] =
  2078. X  zz_lengths[ GALL_TARG   ] =
  2079. X  zz_lengths[ GALL_PREC   ] =
  2080. X  zz_lengths[ CROSS_PREC  ] =
  2081. X  zz_lengths[ EXPAND_IND  ] =
  2082. X  zz_lengths[ THREAD      ] =
  2083. X  zz_lengths[ CR_LIST     ] =
  2084. X    ceiling(sizeof(struct closure_type), sizeof(ALIGN));
  2085. X
  2086. X  /* symbol types */
  2087. X  zz_lengths[ MACRO       ] =
  2088. X  zz_lengths[ LOCAL       ] =
  2089. X  zz_lengths[ LPAR        ] =
  2090. X  zz_lengths[ RPAR        ] =
  2091. X  zz_lengths[ NPAR        ] =
  2092. X    ceiling(sizeof(struct symbol_type), sizeof(ALIGN));
  2093. X
  2094. X  /* gap objects */
  2095. X  zz_lengths[ TSPACE      ] =
  2096. X  zz_lengths[ TJUXTA      ] =
  2097. X  zz_lengths[ GAP_OBJ     ] =
  2098. X    ceiling(sizeof(struct gapobj_type), sizeof(ALIGN));
  2099. X
  2100. X  /* cross-reference and data base types */
  2101. X  zz_lengths[ CROSS_SYM   ] =
  2102. X  zz_lengths[ CR_ROOT     ] = ceiling(sizeof(struct cr_type) , sizeof(ALIGN));
  2103. X
  2104. X  /* external galley record */
  2105. X  zz_lengths[ EXT_GALL  ] = ceiling(sizeof(struct ext_gall_type),sizeof(ALIGN));
  2106. X
  2107. X} /* end MemInit() */
  2108. X
  2109. X
  2110. X/*@@**************************************************************************/
  2111. X/*                                                                           */
  2112. X/*  OBJECT GetMemory(siz, pos)                                               */
  2113. X/*                                                                           */
  2114. X/*  Return a pointer to siz ALIGNs of memory (0 < siz < MAX_OBJECT_REC).     */
  2115. X/*                                                                           */
  2116. X/*****************************************************************************/
  2117. X
  2118. XOBJECT GetMemory(siz, pos)
  2119. Xint siz;  FILE_POS *pos;
  2120. X{ static ALIGN *next_free = (ALIGN *) nil;
  2121. X  static ALIGN *top_free  = (ALIGN *) nil;
  2122. X  OBJECT res;
  2123. X  char *calloc();
  2124. X
  2125. X  debug1(DMA, DDD, "GetMemory( %d )", siz);
  2126. X
  2127. X  /* get memory from operating system, if not enough left here */
  2128. X  if( &next_free[siz] > top_free )
  2129. X  { next_free = (ALIGN *) calloc(MEM_CHUNK, sizeof(ALIGN));
  2130. X    ifdebug(DMA, D, no_of_calls++; )
  2131. X    if( next_free == NULL ) Error(FATAL,pos,"run out of memory - exiting now");
  2132. X    top_free = &next_free[MEM_CHUNK];
  2133. X    debug2(DMA, D, "GetMemory: calloc returned %d - %d",
  2134. X      (int) next_free, (int) top_free);
  2135. X  }
  2136. X
  2137. X  res = (OBJECT) next_free;
  2138. X  next_free = &next_free[siz];
  2139. X  debug3(DMA, DDD, "GetMemory returning @%d (next_free = @%d, top_free = @%d",
  2140. X    (int) res, (int) next_free, (int) top_free);
  2141. X  return res;
  2142. X} /* end GetMemory */
  2143. END_OF_FILE
  2144.   if test 9723 -ne `wc -c <'lout/z31.c'`; then
  2145.     echo shar: \"'lout/z31.c'\" unpacked with wrong size!
  2146.   fi
  2147.   # end of 'lout/z31.c'
  2148. fi
  2149. echo shar: End of archive 24 \(of 30\).
  2150. cp /dev/null ark24isdone
  2151. MISSING=""
  2152. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ; do
  2153.     if test ! -f ark${I}isdone ; then
  2154.     MISSING="${MISSING} ${I}"
  2155.     fi
  2156. done
  2157. if test "${MISSING}" = "" ; then
  2158.     echo You have unpacked all 30 archives.
  2159.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2160. else
  2161.     echo You still must unpack the following archives:
  2162.     echo "        " ${MISSING}
  2163. fi
  2164. exit 0
  2165. exit 0 # Just in case...
  2166.