home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume38 / lout / part27 < prev    next >
Encoding:
Text File  |  1993-08-11  |  72.9 KB  |  1,890 lines

  1. Newsgroups: comp.sources.misc
  2. From: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  3. Subject: v38i095:  lout - Lout document formatting system, v2.05, Part27/35
  4. Message-ID: <1993Aug10.132146.18703@sparky.sterling.com>
  5. X-Md4-Signature: d6c4242f990370d84e4ff65bf0d9e7ea
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Tue, 10 Aug 1993 13:21:46 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  12. Posting-number: Volume 38, Issue 95
  13. Archive-name: lout/part27
  14. Environment: UNIX
  15. Supersedes: lout: Volume 37, Issue 99-128
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  doc/tr.fig/s8 doc/tr.impl/s2.4 doc/tr.lout/ch1.00 z09.c
  22. #   z21.c z26.c z39.c
  23. # Wrapped by kent@sparky on Sun Aug  8 12:29:31 1993
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 27 (of 35)."'
  27. if test -f 'doc/tr.fig/s8' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'doc/tr.fig/s8'\"
  29. else
  30.   echo shar: Extracting \"'doc/tr.fig/s8'\" \(12131 characters\)
  31.   sed "s/^X//" >'doc/tr.fig/s8' <<'END_OF_FILE'
  32. X@Section
  33. X   @Title { A Concise Reference for Fig }
  34. X@Begin
  35. X@PP
  36. XThe options to the @Code "@Fig" symbol, and their
  37. Xdefault values, are as follows.  The complete range of options is shown
  38. Xat right:
  39. X@ID @Tab
  40. X  hmargin { 1s }
  41. X  vmargin { 0.5vx }
  42. X  @Fmth { @Col @Code A ! @Col @Code " " ! @Col @Code B ! @Col @Code " " !
  43. X      @Col 1.0c @Wide ! @Col C }
  44. X  @Fmta { @Col @Code A ! @Col @Code "{" ! @Col @Code B ! @Col @Code "}" !
  45. X      @Col 1.0c @Wide ! @Col C }
  46. X{
  47. X@Rowh
  48. X  A { "@Fig" }
  49. X@Rowa
  50. X  A { "   maxlabels" }
  51. X  B { 200 }
  52. X  C { any whole number }
  53. X@Rowa
  54. X  A { "   linestyle" }
  55. X  B { solid }
  56. X  C { @Code "solid dashed cdashed dotted noline" }
  57. X@Rowa
  58. X  A { "   linewidth" }
  59. X  B { 0.5 pt }
  60. X  C { any Fig length (see below) }
  61. X@Rowa
  62. X  A { "   linecap"   }
  63. X  B { round  }
  64. X  C { @Code "butt round project" }
  65. X@Rowa
  66. X  A { "   dashlength"}
  67. X  B { 0.15 cm }
  68. X  C { any Fig length }
  69. X@Rowa
  70. X  A { "   paint"     }
  71. X  B { nopaint }
  72. X  C { @Code "nopaint white light grey gray dark black" }
  73. X@Rowa
  74. X  A { "   margin"    }
  75. X  B { 0.4c }
  76. X  C { any Lout length }
  77. X@Rowa
  78. X  A { "   arrow"     }
  79. X  B { noarrow }
  80. X  C { @Code "noarrow forward back both" }
  81. X@Rowa
  82. X  A { "   headstyle" }
  83. X  B { open }
  84. X  C { @Code "open halfopen closed" }
  85. X@Rowa
  86. X  A { "   headwidth" }
  87. X  B { 0.05 cm }
  88. X  C { any Fig length }
  89. X@Rowa
  90. X  A { "   headlength"}
  91. X  B { 0.15 cm }
  92. X  C { any Fig length }
  93. X}
  94. XThe @Code "linecap" option determines the shape of the ends of lines:
  95. X@Code "round" puts a round cap on them, which is the most useful in
  96. XFig;  @Code "butt" is a square end; and @Code "project" is a square end
  97. Xprojecting half a line width past the end of the line; it is useful for
  98. Xgetting sharp corners on rectangles and square dots in dotted lines.
  99. X@FootNote {
  100. XThe line joining options of PostScript are not reflected in Fig options
  101. Xbecause Fig strokes paths segment by segment, not all at once, and so
  102. Xthere are no line joins in the PostScript sense.  This was done to
  103. Ximprove the appearance of dashed and dotted lines.
  104. X}
  105. X@PP
  106. XThe following standard shapes take the same options as {@Code "@Fig"},
  107. Xexcept that they do not have @Code "maxlabels" or the last four
  108. X(arrow-drawing) options,
  109. Xand occasionally they have other options.  In most cases the default
  110. Xvalues of these options are taken from the enclosing {@Code "@Fig"}.
  111. XWhere there are extra options, or where a different default value is
  112. Xused, the option and its default value are shown.  The list also shows
  113. Xthe shape's labels, and how it is superimposed on its right parameter
  114. X(shown as a grey rectangle).  A larger margin will enlarge the right
  115. Xparameter and hence the shape as well.  Squares, polygons and circles
  116. Xhave a diameter equal to the larger of @Code xsize and {@Code ysize}.
  117. X@LP
  118. X@ID {
  119. X5c @Wide @Code "@Box"
  120. X||7ct
  121. X@Fig {
  122. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  123. Xlinestyle { noline }  margin { 0c }
  124. X@Box margin { 0c }
  125. X{ 2c @Wide 1c @High }
  126. X// @ShowLabels
  127. X}
  128. X}
  129. X
  130. X@LP
  131. X@ID {
  132. X5c @Wide @Code "@Square"
  133. X||7ct
  134. X@Fig {
  135. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  136. Xlinestyle { noline }  margin { 0c }
  137. X@Square margin { 0c }
  138. X{ 2c @Wide 1c @High }
  139. X// @ShowLabels
  140. X}
  141. X}
  142. X@LP
  143. X
  144. X@ID {
  145. X5c @Wide @Code "@Diamond"
  146. X||7ct
  147. X@Fig {
  148. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  149. Xlinestyle { noline }  margin { 0c }
  150. X@Diamond margin { 0c }
  151. X{ 2c @Wide 1c @High }
  152. X// @ShowLabels
  153. X}
  154. X}
  155. X
  156. X@LP
  157. X@ID {
  158. X5c @Wide @Code {
  159. X"@Polygon"
  160. X"   sides { 3 }"
  161. X"   angle { 180/sides }"
  162. X}
  163. X||7ct
  164. X@Fig {
  165. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  166. Xlinestyle { noline }  margin { 0c }
  167. X@Polygon margin { 0c }
  168. X{ 2c @Wide 1c @High }
  169. X|| @ShowLabels ||0.5c ... ||0.5c
  170. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  171. Xlinestyle { noline }  margin { 0c }
  172. X@Polygon sides { 12 } margin { 0c }
  173. X{ 2c @Wide 1c @High }
  174. X||1c ...
  175. X// @ShowLabels
  176. X}
  177. X}
  178. X
  179. X@ID {
  180. X5c @Wide @Code "@Ellipse"
  181. X||7ct
  182. X@Fig {
  183. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  184. Xlinestyle { noline }  margin { 0c }
  185. X@Ellipse margin { 0c }
  186. X{ 2c @Wide 1c @High }
  187. X// @ShowLabels
  188. X}
  189. X}
  190. X
  191. X@LP
  192. X@ID {
  193. X5c @Wide @Code "@Circle"
  194. X||7ct
  195. X@Fig {
  196. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  197. Xlinestyle { noline }  margin { 0c }
  198. X@Circle margin { 0c }
  199. X{ 2c @Wide 1c @High }
  200. X// @ShowLabels
  201. X}
  202. X}
  203. X@LP
  204. X
  205. XThe following standard shapes have the same options as
  206. X{@Code "@Fig"}, including the four arrow-drawing options,
  207. Xand occasionally they have others.  In each case the only difference
  208. Xbetween the line and arrow symbols is the default value of
  209. X{@Code "arrow"}, which lines take from {@Code "@Fig"} and arrows set
  210. Xto {@Code "forward"}.  The first four draw a line along the mark of the
  211. Xright parameter, which is not necessarily the same as its left or top
  212. Xedge.
  213. X@LP
  214. X@ID {
  215. X5c @Wide @Code {
  216. X"@HLine"
  217. X"   margin { 0c }"
  218. X}
  219. X||7ct
  220. X@Fig {
  221. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  222. Xlinestyle { noline }  margin { 0c }
  223. X@HLine
  224. X{ 2c @Wide 1c @High }
  225. X// @ShowLabels
  226. X}
  227. X}
  228. X
  229. X@ID {
  230. X5c @Wide @Code {
  231. X"@HArrow"
  232. X"   margin { 0c }"
  233. X"   arrow { forward }"
  234. X}
  235. X||7ct
  236. X@Fig {
  237. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  238. Xlinestyle { noline }  margin { 0c }
  239. X@HArrow
  240. X{ 2c @Wide 1c @High }
  241. X// @ShowLabels
  242. X}
  243. X}
  244. X
  245. X@ID {
  246. X5c @Wide @Code {
  247. X"@VLine"
  248. X"   margin { 0c }"
  249. X}
  250. X||7ct
  251. X@Fig {
  252. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  253. Xlinestyle { noline }  margin { 0c }
  254. X@VLine
  255. X{ 2c @Wide 1c @High }
  256. X// @ShowLabels
  257. X}
  258. X}
  259. X
  260. X@ID {
  261. X5c @Wide @Code {
  262. X"@VArrow"
  263. X"   margin { 0c }"
  264. X"   arrow { forward }"
  265. X}
  266. X||7ct
  267. X@Fig {
  268. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  269. Xlinestyle { noline }  margin { 0c }
  270. X@VArrow
  271. X{ 2c @Wide 1c @High }
  272. X// @ShowLabels
  273. X}
  274. X}
  275. X
  276. X@ID {
  277. X5c @Wide @Code {
  278. X"@Line"
  279. X"   from { 0 ysize }"
  280. X"   to { xsize 0 }"
  281. X"   margin { 0c }"
  282. X}
  283. X||7ct
  284. X@Fig {
  285. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  286. Xlinestyle { noline }  margin { 0c }
  287. X@Line
  288. X{ 2c @Wide 1c @High }
  289. X// @ShowLabels
  290. X}
  291. X}
  292. X
  293. X@ID {
  294. X5c @Wide @Code {
  295. X"@Arrow"
  296. X"   from { 0 ysize }"
  297. X"   to { xsize 0 }"
  298. X"   margin { 0c }"
  299. X"   arrow { forward }"
  300. X}
  301. X||7ct
  302. X@Fig {
  303. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  304. Xlinestyle { noline }  margin { 0c }
  305. X@Arrow
  306. X{ 2c @Wide 1c @High }
  307. X// @ShowLabels
  308. X}
  309. X}
  310. X
  311. X@ID {
  312. X5c @Wide @Code {
  313. X"@Arc"
  314. X"   from { 0 ysize }"
  315. X"   to { xsize 0 }"
  316. X"   ctr { 0 0 }"
  317. X"   direction { clockwise }"
  318. X"   margin { 0c }"
  319. X}
  320. X||7ct
  321. X@Fig {
  322. X@Figure shape { 0 0 xsize 0 xsize ysize 0 ysize 0 0 } paint { grey }
  323. Xlinestyle { noline }  margin { 0c }
  324. X@Arc
  325. X{ 2c @Wide 1c @High }
  326. X// @ShowLabels
  327. X}
  328. X}
  329. X
  330. XMore generally, the @Code "@Figure" symbol takes all the options of
  331. X@Code "@Fig" except {@Code "maxlabels"}, together with a @Code shape
  332. Xoption containing a sequence of points, and it connects each pair of
  333. Xpoints by a line or curve as specified by the following:
  334. X@ID @Tab
  335. X   vmargin { 0.5vx }
  336. X   @Fmta { @Col A ! @Col B }
  337. X{
  338. X@Rowa
  339. X  A { @I { point  point } }
  340. X  B { Straight line }
  341. X@Rowa
  342. X  A { @I { point } @Code "[" &0.5s @Code "]" @I { point } }
  343. X  B { Draw nothing }
  344. X@Rowa
  345. X  A { @I { point } @Code "[" @I point @Code "]" @I { point } }
  346. X  B { Anticlockwise circular or elliptical arc }
  347. X@Rowa
  348. X  A { @I { point } @Code "[" @I point @Code "clockwise ]" @I { point } }
  349. X  B { Clockwise circular or elliptical arc }
  350. X@Rowa
  351. X  A { @I { point } @Code "[" @I {point point} @Code "]" @I { point } }
  352. X  B { Bezier curve with two control points }
  353. X}
  354. X@LP
  355. XThe remaining symbols do not draw shapes.  They are
  356. X@ID lines @Break {
  357. X@I colour  @Code "@Colour"  @I object
  358. X@I colour  @Code "@Color"  @I object
  359. X}
  360. XPrint @I object in {@I colour}, which may be {@Code "white"},
  361. X{@Code "grey"}, {@Code "gray"}, {@Code "black"}, {@Code "red"},
  362. X{@Code "green"}, or {@Code "blue"} at least.
  363. X@ID lines @Break {
  364. X@Code "{" @I {number number number} @Code "} @RGBColour"  @I object
  365. X@Code "{" @I {number number number} @Code "} @RGBColor"  @I object
  366. X@Code "{" @I {number number number} @Code "} @HSBColour"  @I object
  367. X@Code "{" @I {number number number} @Code "} @HSBColor"  @I object
  368. X}
  369. XPrint @I object in the colour defined by the three numbers, using the
  370. Xred-green-blue or hue-saturation-brightness colour models.
  371. X@ID {
  372. X@I point  @Code "@Label"  @I label
  373. X}
  374. XWithin a shape, makes @I label stand for the point on the page denoted
  375. Xby {@I point}, which is not made part of the shape.  The label applies
  376. Xfrom here onwards until some other point is given this label, a
  377. Xrelabelling occurs, or the figure ends.
  378. X@ID {
  379. X@I label  @Code "::"  @I object
  380. X}
  381. XRelabel every labelled point in the right parameter (which may be an
  382. Xarbitrary Lout object), by adding {@I label}{@Code "@"} to the front of
  383. Xeach label.
  384. X@ID {
  385. X@Code "@Frame"  @I object
  386. X}
  387. XEquivalent to @Code "@Figure shape {xsize 0 @Label X 0 ysize @Label Y}"
  388. X@I object & .
  389. X@ID {
  390. X@I point  @Code "@BaseOf"  @I object
  391. X}
  392. XTranslate @I object so that its bottom left-hand corner appears at
  393. X{@I point}.  Lout thinks that the result is an empty object.
  394. X@ID {
  395. X@I point  @Code "@MarkOf"  @I object
  396. X}
  397. XTranslate @I object so that the point where its marks cross appears at
  398. X{@I point}.  Lout thinks that the result is an empty object.
  399. X@ID {
  400. X@Code "@ShowLabels"
  401. X}
  402. XDisplay all the labels of the figure created up to this point.
  403. X@PP
  404. XThe following lists define all the ways to specify lengths, angles and
  405. Xpoints.
  406. X@FootNote {
  407. XA length is represented in PostScript by a single number on the operand
  408. Xstack; so is an angle.  A point is represented by two numbers on the
  409. Xstack.  Those familiar with PostScript and willing to sacrifice portability
  410. Xand increase their risk of error can therefore write, for example,
  411. X@OneCol {@I length @Code "sqrt"} within a shape, to obtain a length which
  412. Xis the square root of another length, or @OneCol { @I point @Code "exch" }
  413. Xto obtain the reflection of a point about the main diagonal, and so on.
  414. X}
  415. XBrief explanations appear to the right, with the symbols' precedences in
  416. Xparentheses where appropriate.
  417. X@DP
  418. X@Tab
  419. X  vmargin { 0.5vx }
  420. X  @Fmth { @Col { &@DispIndent     A } ! @Col   }
  421. X  @Fmta { @Col { &@DispIndent &2s A } ! @Col B }
  422. X{
  423. X@Rowh A { @I length } vmargin { 0.2vx }
  424. X@Rowh
  425. X@Rowa
  426. X  A { 0 }
  427. X  B { zero }
  428. X@Rowa
  429. X  A { @Code xmark }
  430. X  B { distance to column mark }
  431. X@Rowa
  432. X  A { @Code ymark }
  433. X  B { distance to row mark }
  434. X@Rowa
  435. X  A { @Code xsize }
  436. X  B { distance to right boundary }
  437. X@Rowa
  438. X  A { @Code ysize }
  439. X  B { distance to top boundary }
  440. X@Rowa
  441. X  A { @I number @Code in }
  442. X  B { @I number inches (39) }
  443. X@Rowa
  444. X  A { @I number @Code cm }
  445. X  B { @I number centimetres (39) }
  446. X@Rowa
  447. X  A { @I number @Code pt }
  448. X  B { @I number points (39) }
  449. X@Rowa
  450. X  A { @I number @Code em }
  451. X  B { @I number ems (39) }
  452. X@Rowa
  453. X  A { @I number @Code sp }
  454. X  B { 1 sp is the current width of a space (39) }
  455. X@Rowa
  456. X  A { @I number @Code vs }
  457. X  B { 1 vs is the current inter-line space (39) }
  458. X@Rowa
  459. X  A { @I number @Code ft }
  460. X  B { 1 ft is the size of the current font (39) }
  461. X@Rowa
  462. X  A { @I point @Code "@Distance" @I point }
  463. X  B { distance between two points (35) }
  464. X@Rowa
  465. X  A { @I point @Code "@XDistance" @I point }
  466. X  B { horizontal distance between two points (35) }
  467. X@Rowa
  468. X  A { @I point @Code "@YDistance" @I point }
  469. X  B { vertical distance between two points (35) }
  470. X@Rowh
  471. X@Rowh
  472. X@Rowh A { @I angle } vmargin { 0.2vx }
  473. X@Rowh
  474. X@Rowa
  475. X  A { @I number @Code dg }
  476. X  B { @I number degrees (39) }
  477. X@Rowa
  478. X  A { @I number }
  479. X  B { @I number degrees (@Code dg is optional) }
  480. X@Rowa
  481. X  A { @I point @Code "@Angle" @I point }
  482. X  B { angle from first point to second (35) }
  483. X@Rowh
  484. X@Rowh
  485. X@Rowh A { @I point } vmargin { 0.2vx }
  486. X@Rowh
  487. X@Rowa
  488. X  A { @I {length  length} }
  489. X  B { @I x and @I y distance from origin (5) }
  490. X@Rowa
  491. X  A { @I length  @Code "<<"  @I angle }
  492. X  B { distance and angle from origin (38) }
  493. X@Rowa
  494. X  A { @I point  @Code "++"  @I point }
  495. X  B { vector sum of two points (36) }
  496. X@Rowa
  497. X  A { @I point  @Code "--"  @I point }
  498. X  B { vector difference of two points (36) }
  499. X@Rowa
  500. X  A { @I point  @Code "@Max"  @I point }
  501. X  B { vector maximum of two points (36) }
  502. X@Rowa
  503. X  A { @I point  @Code "@Min"  @I point }
  504. X  B { vector minimum of two points (36) }
  505. X@Rowa
  506. X  A { @I point  @Code "**"  @I number }
  507. X  B { multiplication of point by number (37) }
  508. X@Rowa
  509. X  A { @I label }
  510. X  B {  a previously defined label }
  511. X@Rowa
  512. X  A { @Code "@Prev"     }
  513. X  B {  the previous point in a shape }
  514. X}
  515. X@End @Section
  516. END_OF_FILE
  517.   if test 12131 -ne `wc -c <'doc/tr.fig/s8'`; then
  518.     echo shar: \"'doc/tr.fig/s8'\" unpacked with wrong size!
  519.   fi
  520.   # end of 'doc/tr.fig/s8'
  521. fi
  522. if test -f 'doc/tr.impl/s2.4' -a "${1}" != "-c" ; then 
  523.   echo shar: Will not clobber existing file \"'doc/tr.impl/s2.4'\"
  524. else
  525.   echo shar: Extracting \"'doc/tr.impl/s2.4'\" \(12152 characters\)
  526.   sed "s/^X//" >'doc/tr.impl/s2.4' <<'END_OF_FILE'
  527. X@SubSection
  528. X    @Tag { objects.impl }
  529. X    @Title { Implementation of objects and concatenation }
  530. X@Begin
  531. X@PP
  532. XIn this section we discuss the implementation of objects and concatenation,
  533. Xand especially mark alignment.  The first step is to use an operator
  534. Xprecedence parser to convert input such as
  535. X@ID @Code "a  |0.5i  b  /0.2i  c  |  d"
  536. Xinto parse trees such as
  537. X@ID @Eq {
  538. X@Fig {
  539. X@Tree {
  540. X@Node @FCircle fraction
  541. X@FirstSub {
  542. X   @Node @FCircle bar
  543. X   @FirstSub { @Node @FCircle a }
  544. X   @NextSub  { @Node @FEllipse 0.5i }
  545. X   @NextSub  { @Node @FCircle b }
  546. X}
  547. X@NextSub { @Node @FEllipse 0.2i }
  548. X@NextSub {
  549. X   @Node @FCircle bar
  550. X   @FirstSub { @Node @FCircle c }
  551. X   @NextSub  { @Node @FCircle   }
  552. X   @NextSub  { @Node @FCircle d }
  553. X}
  554. X}
  555. X}
  556. X}
  557. XMissing objects are replaced by empty objects, and sequences of
  558. Xconcatenation operators are consolidated:
  559. X@ID @Eq {
  560. X@Fig {
  561. X@Tree {
  562. X@Node @FCircle bar
  563. X@FirstSub { @Node @FCircle a }
  564. X@NextSub { @Node @FEllipse 0.2i }
  565. X@NextSub {
  566. X   @Node @FCircle bar
  567. X   @FirstSub { @Node @FCircle c     }
  568. X   @NextSub  { @Node @FEllipse 0.3i }
  569. X   @NextSub  { @Node @FCircle d     }
  570. X}
  571. X}
  572. X}
  573. X&2m ==> &2m
  574. X@Fig {
  575. X@Tree {
  576. X@Node @FCircle bar
  577. X@FirstSub { @Node @FCircle a     }
  578. X@NextSub  { @Node @FEllipse 0.2i }
  579. X@NextSub  { @Node @FCircle c     }
  580. X@NextSub  { @Node @FEllipse 0.3i }
  581. X@NextSub  { @Node @FCircle d     }
  582. X}
  583. X}
  584. X}
  585. Xto make manifest their associativity and reduce the depth of the tree
  586. Xfor efficiency later.
  587. X@PP
  588. XThe required semantic information is the size of each subobject,
  589. Xconsisting of four integers:  width to left and right of the
  590. Xdistinguished column mark, and height above and below the distinguished
  591. Xrow mark.  These numbers are always non-negative in Basser Lout, but
  592. Xthis restriction is unnecessary and should be dropped.
  593. X@PP
  594. XFor the leaves, which are simple words, the numbers are obtained from
  595. Xfont tables.  For the higher levels we apply recursive rules.  Suppose
  596. Xthat @Eq { hgap(x, g, y) } returns the desired distance between the
  597. Xcolumn marks of objects @Eq { x } and @Eq { y } when they are separated by
  598. Xgap @Eq { g }:  @Eq { right(x) + length(g) + left(y) } when the gap mode is
  599. Xedge-to-edge, the larger of @Eq { length(g) } and
  600. X@Eq { right(x) + left(y) } when the mode is mark-to-mark, and so on.  Given
  601. Xan object
  602. X@ID @Eq {
  603. XX = x sub 1 ````` bar g sub 1 ````` ... ````` { "-2p" @Font "^"}bar g sub i-1
  604. X````` x sub i ````` ... ````` bar g sub n-1 ````` x sub n
  605. X}
  606. Xwe may calculate its size as follows:
  607. X@ID @Eq {
  608. Xleft(X) ^= left( x sub 1 ) + hgap( x sub 1 , g sub 1 , x sub 2 )
  609. X+ ... + hgap( x sub i-1 , g sub i-1 , x sub i )
  610. X/1.4vx
  611. Xright(X) ^= hgap( x sub i , g sub i , x sub i+1 )
  612. X+ ... + hgap( x sub n-1 , g sub n-1 , x sub n ) + right( x sub n )
  613. X/1.4vx
  614. X"above"(X) ^= "above"(x sub 1 ) up ... up "above"(x sub n )
  615. X/1.4vx
  616. X"below"(X) ^= "below"(x sub 1 ) up ... up "below"(x sub n )
  617. X}
  618. Xwhere @Eq { non up } returns the larger of its two parameters.  Similar
  619. Xformulas are easily derived for the other operators.
  620. X@PP
  621. XFor purposes of exposition we will now make the simplifying
  622. Xassumptions that all gaps are {@Code "0i"}, all column marks lie at
  623. Xthe left edge, and all row marks lie at the top edge.  Then the size
  624. Xof each object can be expressed by just two numbers, width and
  625. Xheight, and the four formulas reduce to
  626. X@ID @Eq {
  627. Xwidth( x sub 1 rel bar ... rel bar x sub n ) ^=
  628. Xwidth( x sub 1 ) + ... + width( x sub n )
  629. X/1.4vx
  630. Xheight( x sub 1 rel bar ... rel bar x sub n ) ^=
  631. Xheight( x sub 1 ) up ... up height( x sub n )
  632. X}
  633. XThe corresponding formulas for vertical concatenation are
  634. X@ID @Eq {
  635. Xwidth( x sub 1 rel "/" ... rel "/" x sub n ) ^=
  636. Xwidth( x sub 1 ) up ... up width( x sub n )
  637. X/1.4vx
  638. Xheight( x sub 1 rel "/" ... rel "/" x sub n ) ^=
  639. Xheight( x sub 1 ) + ... + height( x sub n )
  640. X}
  641. XAccording to these formulas, the height of
  642. X@ID @Eq { @Fig { @Tree {
  643. X@Node @FCircle fraction
  644. X@LeftSub {
  645. X   @Node @FCircle bar
  646. X   @LeftSub  { @Node @FCircle a }
  647. X   @RightSub { @Node @FCircle b }
  648. X}
  649. X@RightSub {
  650. X   @Node @FCircle bar
  651. X   @LeftSub  { @Node @FCircle c }
  652. X   @RightSub { @Node @FCircle d }
  653. X}
  654. X}}}
  655. Xis
  656. X@ID @Eq {
  657. X[ height(a) up height(b)] + [ height(c) up height(d)]
  658. X}
  659. Xwhich is correct, but for width they yield
  660. X@ID @Eq {
  661. X[ width(a) + width(b)] up [ width(c) + width(d)]
  662. X}
  663. Xwhich is not, since it does not take the merging of column marks into
  664. Xaccount.  The asymmetry between horizontal and vertical has come
  665. Xabout because the row entries, such as @Eq {a} and {@Eq {b}}, are
  666. Xadjacent in the tree, but the column entries, such as @Eq {a} and
  667. X{@Eq {c}}, are not.  It would be possible to solve this cross-linking
  668. Xproblem by augmenting the size information stored in each node to
  669. Xrecord the number of marks and the size of each, but the author has
  670. Xpreferred the following method which makes structural changes to the
  671. Xtree instead.
  672. X@PP
  673. XIf @Eq { a } and @Eq { c } share a column mark, they each might as well
  674. Xhave width { @Eq {width(a) up width(c) }}, since all width calculations
  675. Xapply to entire columns.  Accordingly, we introduce a new operator,
  676. X@Eq {COL}, defined by
  677. X@ID @Eq { width( x sub 1 bin COL ... bin COL x sub n ) =
  678. Xwidth( x sub 1 ) up ... up width( x sub n )
  679. X}
  680. Xand replace both @Eq { a } and @Eq { c } by {@Eq { a bin COL c }}.  To
  681. Xprevent @Eq { COL } operators from disturbing height calculations, we
  682. Xdefine a binary operator called @Eq { SPLIT } by
  683. X@ID @Eq { width( x bin SPLIT y) ^= width(x)
  684. X/1.4vx
  685. Xheight( x bin SPLIT y) ^= height(y) }
  686. Xwhich switches height and width calculations onto different
  687. Xsubtrees.  Then the transformation
  688. X@ID @Eq {
  689. X@Fig { @Tree {
  690. X   @Node @FCircle a
  691. X}}
  692. X&2m ==> &2m
  693. X@Fig { @Tree {
  694. X   @Node @FEllipse SPLIT
  695. X   @LeftSub {
  696. X      @Node @FEllipse COL
  697. X      @LeftSub  { @Node @FCircle a }
  698. X      @RightSub { @Node @FCircle c }
  699. X   }
  700. X   @RightSub { @Node @FCircle a }
  701. X}}
  702. X}
  703. X# where @Eq { S } denotes a @Eq { SPLIT } node and @Eq { C } denotes a
  704. X# @Eq { COL } node,
  705. Xwidens @Eq { a } to @Eq {width(a) up width(c) } without affecting its height;
  706. Xit is applied to every object that shares its column mark with at least
  707. Xone other object.  A similar transformation involving a @Eq { ROW } operator
  708. Xdeals with shared row marks.  The effect on our little table is to replace
  709. X@ID @Eq { @Fig { @Tree {
  710. X@Node @FCircle fraction
  711. X@LeftSub {
  712. X   @Node @FCircle bar
  713. X   @LeftSub  { @Node @FCircle a }
  714. X   @RightSub { @Node @FCircle b }
  715. X}
  716. X@RightSub {
  717. X   @Node @FCircle bar
  718. X   @LeftSub  { @Node @FCircle c }
  719. X   @RightSub { @Node @FCircle d }
  720. X}
  721. X}}}
  722. Xby
  723. X@ID @Eq { @Fig maxlabels { "70" } { @Tree hmargin { "0.1c" } {
  724. X@Node @FCircle fraction
  725. X@FirstSub {
  726. X   @Node @FCircle bar
  727. X   @FirstSub  {
  728. X      @Node @FEllipse SPLIT
  729. X      @FirstSub {
  730. X         @Node @FEllipse COL
  731. X         @FirstSub  { @Node @FCircle a }
  732. X         @NextSub { @Node @FCircle c }
  733. X      }
  734. X      @NextSub {
  735. X         @Node @FEllipse ROW
  736. X         @FirstSub  { @Node @FCircle a }
  737. X         @NextSub { @Node @FCircle b }
  738. X      }
  739. X   }
  740. X   @NextSub {
  741. X      @Node @FEllipse SPLIT
  742. X      @FirstSub {
  743. X         @Node @FEllipse COL
  744. X         @FirstSub  { @Node @FCircle b }
  745. X         @NextSub { @Node @FCircle d }
  746. X      }
  747. X      @NextSub {
  748. X         @Node @FEllipse ROW
  749. X         @FirstSub  { @Node @FCircle a }
  750. X         @NextSub { @Node @FCircle b }
  751. X      }
  752. X   }
  753. X}
  754. X@NextSub {
  755. X   @Node @FCircle bar
  756. X   @FirstSub  {
  757. X      @Node @FEllipse SPLIT
  758. X      @FirstSub {
  759. X         @Node @FEllipse COL
  760. X         @FirstSub  { @Node @FCircle a }
  761. X         @NextSub { @Node @FCircle c }
  762. X      }
  763. X      @NextSub {
  764. X         @Node @FEllipse ROW
  765. X         @FirstSub  { @Node @FCircle c }
  766. X         @NextSub { @Node @FCircle d }
  767. X      }
  768. X   }
  769. X   @NextSub {
  770. X      @Node @FEllipse SPLIT
  771. X      @FirstSub {
  772. X         @Node @FEllipse COL
  773. X         @FirstSub  { @Node @FCircle b }
  774. X         @NextSub { @Node @FCircle d }
  775. X      }
  776. X      @NextSub {
  777. X         @Node @FEllipse ROW
  778. X         @FirstSub  { @Node @FCircle c }
  779. X         @NextSub { @Node @FCircle d }
  780. X      }
  781. X   }
  782. X}
  783. X}}}
  784. XIn fact, common subexpressions are identified (trivially) and the result
  785. Xis a directed acyclic graph; each affected leaf has two parents, one for
  786. Xwidth and one for height; and each @Eq { COL } or @Eq { ROW } node has
  787. Xone parent and one child for each object lying on the corresponding
  788. Xmark.  The data structure roughly doubles in size, and this occurs only
  789. Xrarely in practice.
  790. X@PP
  791. XThis method can cope with any legal input, including
  792. X@ID @Code {
  793. X"{  a  //  c  |  d  }  |  {  b  /  e  }"
  794. X"/  {  f  /  i  }  |  {  g  |  h  //  j  }"
  795. X}
  796. Xwhich produces overlapping spanning columns:
  797. X@ID @I @Fig {
  798. X    @FBox margin { 0.2c } width { 1.6c } 1.2f @Font a |
  799. X    @FBox margin { 0.2c } width { 0.6c } 1.2f @Font b |
  800. X//  @FBox margin { 0.2c } width { 0.6c } 1.2f @Font c |
  801. X    @FBox margin { 0.2c } width { 0.6c } 1.2f @Font d |
  802. X    @FBox margin { 0.2c } width { 0.6c } 1.2f @Font e |
  803. X//  @FBox margin { 0.2c } width { 0.6c } 1.2f @Font f |
  804. X    @FBox margin { 0.2c } width { 0.6c } 1.2f @Font g |
  805. X    @FBox margin { 0.2c } width { 0.6c } 1.2f @Font h |
  806. X//  @FBox margin { 0.2c } width { 0.6c } 1.2f @Font i |
  807. X    @FBox margin { 0.2c } width { 1.6c } 1.2f @Font j |
  808. X}
  809. XThe boxes have been added to clarify the structure.  The width of this
  810. Xobject is formally
  811. X@ID @Eq { ((width(a) up (x + y)) + z) up (x + ((y + z) up width(j))) }
  812. Xwhere
  813. X@IL
  814. X@ListItem @Eq { x = width(c) up width(`f`) up width(i) }
  815. X@ListItem @Eq { y = width(d`) up width(g) }
  816. X@ListItem @Eq { z = width(b) up width(e) up width(h) }
  817. X@EL
  818. XIt seems clear that @Eq { y } at least must appear twice in any
  819. Xexpression for the width of this object made out of simple addition
  820. Xand maxing operations, showing that an ordinary tree
  821. Xstructure is insufficient for overlapping spanning columns.  The Basser
  822. XLout interpreter actually rejects such structures, owing to the author's
  823. Xdoubts about the implementability of @I Constrained and @I AdjustSize
  824. X(Section {@NumberOf constraints}) on them; but with hindsight this caution
  825. Xwas unnecessary.
  826. X@PP
  827. XThe directed acyclic graph is ordered in the sense that the order of
  828. Xthe edges entering and leaving each node matters.  The structure is
  829. Xhighly dynamic, and traversals both with and against the arrows are
  830. Xrequired.  After a few ad-hoc attempts to extend the usual tree
  831. Xrepresentation had failed, the author developed a representation based
  832. Xon doubly linked lists of records denoting links, whose flexibility more
  833. Xthan compensated for the somewhat excessive memory consumption.  For example,
  834. X@ID @Eq { @Fig {
  835. X       A:: @FCircle a   |2c                  |2c  B:: @FCircle b
  836. X/1.5c  C:: @FCircle c   |    D:: @FCircle d
  837. X// A @JoinFigures arrow { forward } C
  838. X// A @JoinFigures arrow { forward } D
  839. X// B @JoinFigures arrow { forward } D
  840. X}}
  841. Xis represented by
  842. X@CD @Eq { @Fig maxlabels { "300" } {
  843. XA:: @DagBox mid { @BlackDot } base { a } |2c |2c |2c |2c
  844. XB:: @DagBox mid { @BlackDot } base { b }
  845. X/1c L:: @DagBox top { @BlackDot } mid { @BlackDot } base { LK }
  846. X|   M:: @DagBox top { @BlackDot } mid { @BlackDot } base { LK }
  847. X| | N:: @DagBox top { @BlackDot } mid { @BlackDot } base { LK }
  848. X/1c
  849. XC:: @DagBox top { @BlackDot } base { c } | |
  850. XD:: @DagBox top { @BlackDot } base { d }
  851. X// @TVShape nw { A@MID@CTR } ne { A@MID@CTR } sw {L@MID@CTR } se { M@MID@CTR }
  852. X// @TVShape nw { L@TOP@CTR } ne { L@TOP@CTR } sw {C@TOP@CTR } se { C@TOP@CTR }
  853. X// @TVShape nw { M@TOP@CTR } ne { N@TOP@CTR } sw {D@TOP@CTR } se { D@TOP@CTR }
  854. X// @TVShape nw { B@MID@CTR } ne { B@MID@CTR } sw {N@MID@CTR } se { N@MID@CTR }
  855. X}}
  856. Xwhere @Eq { LK } tags a record representing a link.  The first list
  857. Xin any node contains all the incoming links, the second contains the
  858. Xoutgoing ones.  The node serves as the header for both lists.  The
  859. Xrequired operations reduce to simple appends, deletes, and traversals
  860. Xof doubly linked lists, all having small constant cost.  There is a
  861. Xhighly tuned memory allocator, and care is taken to dispose of each node
  862. Xwhen the last incoming link is deleted, so that there is no need for
  863. Xgarbage collection.
  864. X@PP
  865. XIn normal use the number of nodes at higher levels of the dag is small
  866. Xin comparison with the leaves and their incoming links, so we may
  867. Xestimate the space complexity at about 60 bytes per input word (20 bytes
  868. Xper link, 40 per leaf node).  Careful optimization could easily halve
  869. Xthis, but since memory is reclaimed after printing each page there is
  870. Xlittle need.
  871. X@End @SubSection
  872. END_OF_FILE
  873.   if test 12152 -ne `wc -c <'doc/tr.impl/s2.4'`; then
  874.     echo shar: \"'doc/tr.impl/s2.4'\" unpacked with wrong size!
  875.   fi
  876.   # end of 'doc/tr.impl/s2.4'
  877. fi
  878. if test -f 'doc/tr.lout/ch1.00' -a "${1}" != "-c" ; then 
  879.   echo shar: Will not clobber existing file \"'doc/tr.lout/ch1.00'\"
  880. else
  881.   echo shar: Extracting \"'doc/tr.lout/ch1.00'\" \(301 characters\)
  882.   sed "s/^X//" >'doc/tr.lout/ch1.00' <<'END_OF_FILE'
  883. X@Chapter
  884. X   @Title { Principles }
  885. X   @Tag { principles }
  886. X@Begin
  887. X@LP
  888. XThe document formatting language Lout is based on just four key ideas:
  889. Xobjects, definitions, cross references, and galleys.  In this chapter we
  890. Xconcentrate on them, postponing the inevitable details to later chapters.
  891. X@BeginSections
  892. END_OF_FILE
  893.   if test 301 -ne `wc -c <'doc/tr.lout/ch1.00'`; then
  894.     echo shar: \"'doc/tr.lout/ch1.00'\" unpacked with wrong size!
  895.   fi
  896.   # end of 'doc/tr.lout/ch1.00'
  897. fi
  898. if test -f 'z09.c' -a "${1}" != "-c" ; then 
  899.   echo shar: Will not clobber existing file \"'z09.c'\"
  900. else
  901.   echo shar: Extracting \"'z09.c'\" \(11009 characters\)
  902.   sed "s/^X//" >'z09.c' <<'END_OF_FILE'
  903. X/*@z09.c:Closure Expansion:SearchEnv()@***************************************/
  904. X/*                                                                           */
  905. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  906. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  907. X/*                                                                           */
  908. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  909. X/*  Basser Department of Computer Science                                    */
  910. X/*  The University of Sydney 2006                                            */
  911. X/*  AUSTRALIA                                                                */
  912. X/*                                                                           */
  913. X/*  This program is free software; you can redistribute it and/or modify     */
  914. X/*  it under the terms of the GNU General Public License as published by     */
  915. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  916. X/*  any later version.                                                       */
  917. X/*                                                                           */
  918. X/*  This program is distributed in the hope that it will be useful,          */
  919. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  920. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  921. X/*  GNU General Public License for more details.                             */
  922. X/*                                                                           */
  923. X/*  You should have received a copy of the GNU General Public License        */
  924. X/*  along with this program; if not, write to the Free Software              */
  925. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  926. X/*                                                                           */
  927. X/*  FILE:         z09.c                                                      */
  928. X/*  MODULE:       Closure Expansion                                          */
  929. X/*  EXTERNS:      SearchEnv(), SetEnv(), AttachEnv(), GetEnv(),              */
  930. X/*                DetachEnv(), ClosureExpand()                               */
  931. X/*                                                                           */
  932. X/*****************************************************************************/
  933. X#include "externs"
  934. X
  935. X
  936. X/*****************************************************************************/
  937. X/*                                                                           */
  938. X/*  OBJECT SearchEnv(env, sym)                                               */
  939. X/*                                                                           */
  940. X/*  Search environment env for a symbol such that actual() == sym.           */
  941. X/*                                                                           */
  942. X/*****************************************************************************/
  943. X
  944. XOBJECT SearchEnv(env, sym)
  945. XOBJECT env, sym;
  946. X{ OBJECT link, y;
  947. X  debug2(DCE, DD, "SearchEnv(%s, %s)", EchoObject(env), SymName(sym));
  948. X  for(;;)
  949. X  {
  950. X    debug1(DCE, DDD, "  searching env %s", EchoObject(env));
  951. X    assert( env != nil && type(env) == ENV, "SearchEnv: env!" );
  952. X    if( Down(env) == env )
  953. X    { debug0(DCE, DD, "SearchEnv returning <nil>");
  954. X      return nil;
  955. X    }
  956. X    Child(y, Down(env));
  957. X    assert( type(y) == CLOSURE, "SearchEnv: type(y) != CLOSURE!" );
  958. X    if( actual(y) == sym )
  959. X    { debug1(DCE, DD, "SearchEnv returning %s", EchoObject(y));
  960. X      return y;
  961. X    }
  962. X    assert( LastDown(y) != y, "SearchEnv: LastDown(y) == y!" );
  963. X    link = LastDown(env) != Down(env) ? LastDown(env) : LastDown(y);
  964. X    Child(env, link);
  965. X  }
  966. X} /* end SearchEnv */
  967. X
  968. X
  969. X/*@::SetEnv(), AttachEnv(), GetEnv(), DetachEnv()@****************************/
  970. X/*                                                                           */
  971. X/*  OBJECT SetEnv(x, y)                                                      */
  972. X/*                                                                           */
  973. X/*  Create a new environment containing x and possibly y.                    */
  974. X/*                                                                           */
  975. X/*****************************************************************************/
  976. X
  977. XOBJECT SetEnv(x, y)
  978. XOBJECT x, y;
  979. X{ OBJECT res;
  980. X  debug2(DCR, DD, "SetEnv( %s, %s )", EchoObject(x), EchoObject(y));
  981. X  debug2(DCE, D, "SetEnv( %s, %s )", EchoObject(x), EchoObject(y));
  982. X  assert( x != nil && type(x) == CLOSURE, "SetEnv: x == nil or not CLOSURE!" );
  983. X  assert( y == nil || type(y) == ENV, "SetEnv: y != nil && type(y) != ENV!" );
  984. X  res = New(ENV);  Link(res, x);
  985. X  if( y != nil )  Link(res, y);
  986. X  debug1(DCE, D, "SetEnv returning %s", EchoObject(res));
  987. X  return res;
  988. X} /* end SetEnv */
  989. X
  990. X
  991. X/*****************************************************************************/
  992. X/*                                                                           */
  993. X/*  AttachEnv(env, x)                                                        */
  994. X/*                                                                           */
  995. X/*  Attach environment env to CLOSURE x.                                     */
  996. X/*                                                                           */
  997. X/*****************************************************************************/
  998. X
  999. XAttachEnv(env, x)
  1000. XOBJECT env, x;
  1001. X{ debug2(DCE, D, "AttachEnv( %s, %s )", EchoObject(env), EchoObject(x));
  1002. X  assert( env != nil && type(env) == ENV, "AttachEnv: type(env) != ENV!" );
  1003. X  assert( type(x) == CLOSURE, "AttachEnv: type(x) != CLOSURE!" );
  1004. X  Link(x, env);
  1005. X  debug0(DCE, D, "AttachEnv returning.");
  1006. X} /* end AttachEnv */
  1007. X
  1008. X
  1009. X/*****************************************************************************/
  1010. X/*                                                                           */
  1011. X/*  OBJECT GetEnv(x)                                                         */
  1012. X/*                                                                           */
  1013. X/*  Get from CLOSURE x the environment previously attached.                  */
  1014. X/*                                                                           */
  1015. X/*****************************************************************************/
  1016. X
  1017. XOBJECT GetEnv(x)
  1018. XOBJECT x;
  1019. X{ OBJECT env;
  1020. X  assert( type(x) == CLOSURE, "GetEnv: type(x) != CLOSURE!" );
  1021. X  assert( LastDown(x) != x, "GetEnv: LastDown(x) == x!" );
  1022. X  Child(env, LastDown(x));
  1023. X  assert( type(env) == ENV, "GetEnv: type(env) != ENV!" );
  1024. X  return env;
  1025. X} /* end GetEnv */
  1026. X
  1027. X
  1028. X/*****************************************************************************/
  1029. X/*                                                                           */
  1030. X/*  OBJECT DetachEnv(x)                                                      */
  1031. X/*                                                                           */
  1032. X/*  Detach from CLOSURE x the environment previously attached.               */
  1033. X/*                                                                           */
  1034. X/*****************************************************************************/
  1035. X
  1036. XOBJECT DetachEnv(x)
  1037. XOBJECT x;
  1038. X{ OBJECT env;
  1039. X  debug1(DCE, DD, "DetachEnv( %s )", EchoObject(x));
  1040. X  assert( type(x) == CLOSURE, "DetachEnv: type(x) != CLOSURE!" );
  1041. X  assert( LastDown(x) != x, "DetachEnv: LastDown(x) == x!" );
  1042. X  Child(env, LastDown(x));
  1043. X  DeleteLink(LastDown(x));
  1044. X  assert( type(env) == ENV, "DetachEnv: type(env) != ENV!" );
  1045. X  debug1(DCE, DD, "DetachEnv resturning %s", EchoObject(env));
  1046. X  return env;
  1047. X} /* end DetachEnv */
  1048. X
  1049. X
  1050. X/*@::ClosureExpand()@*********************************************************/
  1051. X/*                                                                           */
  1052. X/*  OBJECT ClosureExpand(x, env, crs_wanted, crs, res_env)                   */
  1053. X/*                                                                           */
  1054. X/*  Return expansion of closure x in environment env.                        */
  1055. X/*  The body comes from the environment of x if x is a parameter, else from  */
  1056. X/*  the symbol table.  The original x is pushed into the environments.       */
  1057. X/*  If crs_wanted and x has a tag, a cross-reference is added to crs.        */
  1058. X/*                                                                           */
  1059. X/*****************************************************************************/
  1060. X
  1061. XOBJECT ClosureExpand(x, env, crs_wanted, crs, res_env)
  1062. XOBJECT x, env;  BOOLEAN crs_wanted;  OBJECT *crs, *res_env;
  1063. X{ OBJECT link, y, res, prnt_env, par, prnt;
  1064. X  debug3(DCE, D, "ClosureExpand( %s, crs, %s, %s, res_env )",
  1065. X    EchoObject(x), bool(crs_wanted), EchoObject(env));
  1066. X  assert( type(x) == CLOSURE, "ClosureExpand given non-CLOSURE!");
  1067. X  assert( predefined(actual(x)) == FALSE, "ClosureExpand given predefined!" );
  1068. X
  1069. X  /* add tag to x if needed but not provided;  add cross-reference to crs  */
  1070. X  CrossAddTag(x);
  1071. X  if( crs_wanted && has_tag(actual(x)) )
  1072. X  { OBJECT tmp = CopyObject(x, no_fpos);  AttachEnv(env, tmp);
  1073. X    y = CrossMake(actual(x), tmp, CROSS_TARG);
  1074. X    tmp = New(CROSS_TARG);  actual(tmp) = y;  Link(tmp, y);
  1075. X    if( *crs == nil )  *crs = New(CR_LIST);   Link(*crs, tmp);
  1076. X  }
  1077. X
  1078. X  /* case x is a parameter */
  1079. X  res = *res_env = nil;
  1080. X  if( is_par(type(actual(x))) )
  1081. X  { prnt = SearchEnv(env, enclosing(actual(x)));
  1082. X    if( prnt==nil ) Error(FATAL, &fpos(x), "symbol with import list misused");
  1083. X    assert( prnt != nil, "ClosureExpand: is_par but prnt == nil!" );
  1084. X    prnt_env = GetEnv(prnt);
  1085. X    for( link = Down(prnt);  link != prnt;  link = NextDown(link) )
  1086. X    { Child(par, link);
  1087. X      if( type(par) == PAR && actual(par) == actual(x) )
  1088. X      {    assert( Down(par) != par, "ExpandCLosure: Down(par)!");
  1089. X    Child(res, Down(par));
  1090. X    if( dirty(enclosing(actual(par))) )
  1091. X    { debug2(DSU, DD, "c %s %s", SymName(actual(par)), EchoObject(res));
  1092. X      res = CopyObject(res, no_fpos);
  1093. X    }
  1094. X    else
  1095. X    { debug2(DSU, DD, "l %s %s", SymName(actual(par)), EchoObject(res));
  1096. X      DeleteLink(Down(par));
  1097. X      y = MakeWord(WORD, STR_NOCROSS, &fpos(res));
  1098. X      Link(par, y);
  1099. X    }
  1100. X    ReplaceNode(res, x);
  1101. X    if( type(actual(x)) == RPAR && has_body(enclosing(actual(x))) )
  1102. X    { debug0(DCR, DD, "  calling SetEnv from ClosureExpand (a)");
  1103. X      *res_env = SetEnv(prnt, nil);  DisposeObject(x);
  1104. X    }
  1105. X    else
  1106. X    { AttachEnv(env, x);
  1107. X      debug0(DCR, DD, "  calling SetEnv from ClosureExpand (b)");
  1108. X      *res_env = SetEnv(x, prnt_env);
  1109. X    }
  1110. X    break;
  1111. X      }
  1112. X    }
  1113. X  }
  1114. X
  1115. X  /* case x is a user-defined symbol or default parameter */
  1116. X  if( res == nil )
  1117. X  { if( sym_body(actual(x)) == nil )  res = MakeWord(WORD,STR_NOCROSS,&fpos(x));
  1118. X    else res = CopyObject(sym_body(actual(x)), &fpos(x));
  1119. X    ReplaceNode(res, x);  AttachEnv(env, x);
  1120. X    debug0(DCR, DD, "  calling SetEnv from ClosureExpand (c)");
  1121. X    *res_env = SetEnv(x, nil);
  1122. X  }
  1123. X
  1124. X  assert( *res_env != nil && type(*res_env) == ENV, "ClosureExpand: *res_env!");
  1125. X  debug0(DCE, D, "ClosureExpand returning, res =");
  1126. X  ifdebug(DCE, D, DebugObject(res));
  1127. X  debug1(DCE, DD, "  environment = %s", EchoObject(*res_env));
  1128. X  return res;
  1129. X} /* end ClosureExpand */
  1130. END_OF_FILE
  1131.   if test 11009 -ne `wc -c <'z09.c'`; then
  1132.     echo shar: \"'z09.c'\" unpacked with wrong size!
  1133.   fi
  1134.   # end of 'z09.c'
  1135. fi
  1136. if test -f 'z21.c' -a "${1}" != "-c" ; then 
  1137.   echo shar: Will not clobber existing file \"'z21.c'\"
  1138. else
  1139.   echo shar: Extracting \"'z21.c'\" \(10803 characters\)
  1140.   sed "s/^X//" >'z21.c' <<'END_OF_FILE'
  1141. X/*@z21.c:Galley Maker:SizeGalley()@*******************************************/
  1142. X/*                                                                           */
  1143. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  1144. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1145. X/*                                                                           */
  1146. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1147. X/*  Basser Department of Computer Science                                    */
  1148. X/*  The University of Sydney 2006                                            */
  1149. X/*  AUSTRALIA                                                                */
  1150. X/*                                                                           */
  1151. X/*  This program is free software; you can redistribute it and/or modify     */
  1152. X/*  it under the terms of the GNU General Public License as published by     */
  1153. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1154. X/*  any later version.                                                       */
  1155. X/*                                                                           */
  1156. X/*  This program is distributed in the hope that it will be useful,          */
  1157. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1158. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1159. X/*  GNU General Public License for more details.                             */
  1160. X/*                                                                           */
  1161. X/*  You should have received a copy of the GNU General Public License        */
  1162. X/*  along with this program; if not, write to the Free Software              */
  1163. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1164. X/*                                                                           */
  1165. X/*  FILE:         z21.c                                                      */
  1166. X/*  MODULE:       Galley Maker                                               */
  1167. X/*  EXTERNS:      SizeGalley()                                               */
  1168. X/*                                                                           */
  1169. X/*****************************************************************************/
  1170. X#include "externs"
  1171. X
  1172. X
  1173. X/*****************************************************************************/
  1174. X/*                                                                           */
  1175. X/*  SizeGalley(hd, env, rows, joined, nonblock, trig, style, c, target,      */
  1176. X/*                                                dest_index, recs, inners)  */
  1177. X/*                                                                           */
  1178. X/*  Convert unsized galley hd into sized format.  The input parameters are:  */
  1179. X/*                                                                           */
  1180. X/*    hd          the galley to be converted                                 */
  1181. X/*    env         its environment                                            */
  1182. X/*    rows        TRUE if the resulting galley may have more than one row    */
  1183. X/*    joined      TRUE if the resulting galley must be simply joined         */
  1184. X/*    nonblock    Set the non_blocking() field of RECEPTIVEs to this value   */
  1185. X/*    trig        TRUE if indefinites of hd may trigger external galleys     */
  1186. X/*    *style      The initial style                                          */
  1187. X/*    *c          the width constraint hd should conform to                  */
  1188. X/*    target      if non-nil, expand indefinite objects to reveal a          */
  1189. X/*                @Galley within this symbol                                 */
  1190. X/*                                                                           */
  1191. X/*  The output parameters, in addition to the converted hd, are:             */
  1192. X/*                                                                           */
  1193. X/*    dest_index  the index of the @Galley found within target, if any       */
  1194. X/*    recs        list of all RECURSIVE indexes found (or nil if none)       */
  1195. X/*    inners      list of all UNATTACHED indexes found (or nil if none)      */
  1196. X/*                                                                           */
  1197. X/*****************************************************************************/
  1198. X
  1199. XSizeGalley(hd, env, rows, joined, nonblock, trig, style, c, target,
  1200. X                        dest_index, recs, inners)
  1201. XOBJECT hd, env;  BOOLEAN rows, joined, nonblock, trig;  STYLE *style;
  1202. XCONSTRAINT *c;  OBJECT target, *dest_index, *recs, *inners;
  1203. X{ OBJECT y, link, z, crs, t, tlink, zlink, tmp;
  1204. X  OBJECT extras, tmp1, tmp2, bt[2], ft[2];
  1205. X  
  1206. X  assert( type(hd) == HEAD && Down(hd) != hd, "SizeGalley: precondition!" );
  1207. X  assert( !sized(hd), "SizeGalley: already sized!" );
  1208. X  debug6(DGM, D, "SizeGalley(hd, -, %s, %s, %s, %s, %s, %s, -, -, -), hd =",
  1209. X    bool(joined), bool(nonblock), bool(trig), EchoStyle(style),
  1210. X    EchoConstraint(c), SymName(target));
  1211. X  ifdebug(DGM, DD, DebugObject(hd));
  1212. X
  1213. X  /* manifest the child of hd, making sure it is simply joined if required */
  1214. X  tmp1 = target;
  1215. X  Child(y, Down(hd));
  1216. X  crs = nil;
  1217. X  bt[COL] = ft[COL] = bt[ROW] = ft[ROW] = nil;
  1218. X  if( joined )
  1219. X  { bt[COL] = New(THREAD);  ft[COL] = New(THREAD);
  1220. X    y = Manifest(y, env, style, bt, ft, &tmp1, &crs, TRUE, must_expand(hd));
  1221. X    assert( Down(bt[COL]) != bt[COL] && Down(ft[COL]) != ft[COL],
  1222. X    "SizeGalley: threads!" );
  1223. X    Child(tmp1, Down(bt[COL]));  Child(tmp2, Down(ft[COL]));
  1224. X    if( Down(bt[COL]) != LastDown(bt[COL]) ||
  1225. X      Down(ft[COL]) != LastDown(ft[COL]) || tmp1 != tmp2 )
  1226. X      Error(FATAL, &fpos(y), "galley %s must have just one column mark",
  1227. X                        SymName(actual(hd)) );
  1228. X    DisposeObject(bt[COL]);  DisposeObject(ft[COL]);
  1229. X  }
  1230. X  else y = Manifest(y, env, style, bt, ft, &tmp1, &crs, TRUE, must_expand(hd));
  1231. X
  1232. X  /* horizontally size and break hd */
  1233. X  debug0(DGM, DD, "SizeGalley: after manifesting, hd =");
  1234. X  ifdebug(DGM, DD, DebugObject(hd));
  1235. X  debug0(DGM, DD, "SizeGalley horizontally sizing and breaking hd:");
  1236. X  CopyConstraint(constraint(hd), *c);
  1237. X  y = MinSize(y, COL, &extras);
  1238. X  debug0(DOB, DD, "  calling BreakObject from SizeGalley");
  1239. X  y = BreakObject(y, c);
  1240. X  back(hd, COL) = back(y, COL);
  1241. X  fwd(hd, COL)  = fwd(y, COL);
  1242. X  assert( FitsConstraint(back(hd, COL), fwd(hd, COL), *c),
  1243. X    "SizeGalley: BreakObject failed to fit!" );
  1244. X  debug2(DSF, D, "MinSize(hd, COL) = %s,%s",
  1245. X      EchoLength(back(hd, COL)), EchoLength(fwd(hd, COL)) );
  1246. X
  1247. X  /* get the rows of hd to the top level, if required */
  1248. X  seen_nojoin(hd) = FALSE;
  1249. X  if( rows )
  1250. X  { /* OBJECT prev_gap = nil; */
  1251. X    debug0(DGM, DD, "SizeGalley cleaning up rows of hd:");
  1252. X    for( link = hd;  NextDown(link) != hd;  link = NextDown(link) )
  1253. X    { Child(y, NextDown(link));
  1254. X      debug2(DGM, DD, "  cleaning %s: %s", Image(type(y)), EchoObject(y));
  1255. X      switch( type(y) )
  1256. X      {
  1257. X    case GAP_OBJ:
  1258. X
  1259. X      /* prev_gap = y; */
  1260. X      if( !join(gap(y)) )  seen_nojoin(hd) = TRUE;
  1261. X      break;
  1262. X
  1263. X
  1264. X    case VCAT:
  1265. X      
  1266. X      TransferLinks(Down(y), y, Up(y));
  1267. X      DisposeChild(Up(y));
  1268. X      link = PrevDown(link);
  1269. X      break;
  1270. X
  1271. X
  1272. X    case SPLIT:
  1273. X      
  1274. X      assert(Up(y)==LastUp(y), "SizeGalley COL_THR: Up(y)!=LastUp(y)!");
  1275. X      Child(z, DownDim(y, ROW));
  1276. X      if( is_indefinite(type(z)) )  external(z) = TRUE;
  1277. X      else if( type(z) == VCAT )
  1278. X      { OBJECT hor, thor, clink, dlink;
  1279. X        Child(hor, DownDim(y, COL));
  1280. X        assert( type(hor) == COL_THR, "SizeGalley: missing COL_THR!" );
  1281. X        Parent(thor, UpDim(z, COL));
  1282. X        assert( hor == thor, "SizeGalley/SPLIT: hor != thor!" );
  1283. X        clink = DownDim(y, COL);
  1284. X        dlink = UpDim(z, COL);
  1285. X        for( tlink = LastDown(z);  tlink != z;  tlink = PrevDown(tlink) )
  1286. X        { Child(t, tlink);
  1287. X          if( type(t) == GAP_OBJ )  Link(NextDown(link), t);
  1288. X          else
  1289. X          {    tmp = New(SPLIT);
  1290. X        back(tmp, COL) = back(hor, COL);
  1291. X        fwd(tmp, COL) = fwd(hor, COL);
  1292. X        Link(NextDown(link), tmp);
  1293. X        Link(tmp, NextUp(clink));
  1294. X        Link(NextDown(dlink), t);
  1295. X        Link(tmp, t);
  1296. X          }
  1297. X        }
  1298. X        DeleteLink(dlink);
  1299. X        assert(Up(y)==LastUp(y), "SizeGalley COL_THR: Up(y) != LastUp(y)!");
  1300. X        DisposeChild(Up(y));
  1301. X        link = PrevDown(link);
  1302. X      }
  1303. X      break;
  1304. X
  1305. X
  1306. X    case CLOSURE:
  1307. X    case HEAD:
  1308. X      
  1309. X      external(y) = TRUE;
  1310. X      break;
  1311. X
  1312. X
  1313. X    default:
  1314. X      
  1315. X      break;
  1316. X      }
  1317. X    }
  1318. X  }
  1319. X
  1320. X  /* size the rows of hd and attach indices where needed */
  1321. X  debug0(DGM, DD, "SizeGalley sizing rows of hd =");
  1322. X  ifdebug(DGM, DD, DebugObject(hd));
  1323. X  *recs = *inners = *dest_index = nil;
  1324. X  for( link = Down(hd);  link != hd;  link = NextDown(link) )
  1325. X  { Child(y, link);
  1326. X    if( type(y) == GAP_OBJ || is_index(type(y)) )  continue;
  1327. X    debug0(DGM, DDD, "  ROW sizing:");
  1328. X    ifdebug(DGM, DDD, DebugObject(y));
  1329. X    extras = New(ACAT);
  1330. X    y = MinSize(y, ROW, &extras);
  1331. X    debug3(DSF, D, "MinSize( %s , ROW ) = %s,%s", EchoObject(y),
  1332. X      EchoLength(back(y, ROW)), EchoLength(fwd(y, ROW)) );
  1333. X    debug0(DGM, DDD, "  ROW result:");
  1334. X    ifdebug(DGM, DDD, DebugObject(y));
  1335. X
  1336. X    /* now attach indexes in front of y */
  1337. X    for( zlink = Down(extras);  zlink != extras;  zlink = NextDown(zlink) )
  1338. X    { Child(z, zlink);
  1339. X      blocked(z) = FALSE;
  1340. X      /* debug1(DCR, D, "  extra: %s", EchoObject(z)); */
  1341. X      debug1(DGM, DD, "  extra: %s", EchoObject(z));
  1342. X      switch( type(z) )
  1343. X      {
  1344. X    case RECEPTIVE:
  1345. X
  1346. X      /* debug2(DCR, D, "  ... uses_ext  = %s, trig = %s",
  1347. X        bool(uses_extern_target(actual(actual(z)))), bool(trig)); */
  1348. X      trigger_externs(z) = uses_extern_target(actual(actual(z))) && trig;
  1349. X      non_blocking(z)    = nonblock;
  1350. X      if( actual(actual(z)) == GalleySym )  *dest_index = z;
  1351. X      break;
  1352. X
  1353. X
  1354. X    case RECURSIVE:
  1355. X
  1356. X      if( *recs == nil )  *recs = New(ACAT);
  1357. X      Link(*recs, z);
  1358. X      break;
  1359. X
  1360. X
  1361. X    case UNATTACHED:
  1362. X
  1363. X      if( *inners == nil )  *inners = New(ACAT);
  1364. X      Link(*inners, z);
  1365. X      break;
  1366. X
  1367. X        
  1368. X    case EXPAND_IND:
  1369. X    case GALL_PREC:
  1370. X    case GALL_FOLL:
  1371. X    case GALL_TARG:
  1372. X    case CROSS_PREC:
  1373. X    case CROSS_FOLL:
  1374. X    case CROSS_TARG:
  1375. X
  1376. X      debug1(DCR, DD, "  SizeGalley: %s", EchoObject(z));
  1377. X      break;
  1378. X
  1379. X
  1380. X    default:
  1381. X      
  1382. X      Error(INTERN, no_fpos, "SizeGalley: %s", Image(type(z)) );
  1383. X      break;
  1384. X
  1385. X      }
  1386. X    }
  1387. X    TransferLinks(Down(extras), extras, link);
  1388. X    assert( Down(extras) == extras && Up(extras) == extras, "SizeG: extras!");
  1389. X    Dispose(extras);
  1390. X  }
  1391. X  
  1392. X  /* insinuate cross references */
  1393. X  if( crs != nil )
  1394. X  { 
  1395. X    debug1(DCR, D, "SizeGalley insinuating %s", crs);
  1396. X    TransferLinks(Down(crs), crs, Down(hd));
  1397. X    DisposeObject(crs);
  1398. X  }
  1399. X
  1400. X  /* check that *dest_index was found if it was required, and exit */
  1401. X  if( target != nil && *dest_index == nil )
  1402. X    Error(FATAL, &fpos(hd), "Unexpected absence of %s from the body of %s",
  1403. X      SymName(target), SymName(actual(hd)));
  1404. X  debug3(DGM, D, "SizeGalley returning %s,%s  %s;  hd =",
  1405. X    EchoLength(back(hd, COL)), EchoLength(fwd(hd, COL)),
  1406. X    EchoConstraint(&constraint(hd)));
  1407. X  ifdebug(DGM, DD, DebugObject(hd));
  1408. X  sized(hd) = TRUE;
  1409. X
  1410. X} /* end SizeGalley */
  1411. END_OF_FILE
  1412.   if test 10803 -ne `wc -c <'z21.c'`; then
  1413.     echo shar: \"'z21.c'\" unpacked with wrong size!
  1414.   fi
  1415.   # end of 'z21.c'
  1416. fi
  1417. if test -f 'z26.c' -a "${1}" != "-c" ; then 
  1418.   echo shar: Will not clobber existing file \"'z26.c'\"
  1419. else
  1420.   echo shar: Extracting \"'z26.c'\" \(11364 characters\)
  1421.   sed "s/^X//" >'z26.c' <<'END_OF_FILE'
  1422. X/*@z26.c:Echo Service:BeginString()@******************************************/
  1423. X/*                                                                           */
  1424. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  1425. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1426. X/*                                                                           */
  1427. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1428. X/*  Basser Department of Computer Science                                    */
  1429. X/*  The University of Sydney 2006                                            */
  1430. X/*  AUSTRALIA                                                                */
  1431. X/*                                                                           */
  1432. X/*  This program is free software; you can redistribute it and/or modify     */
  1433. X/*  it under the terms of the GNU General Public License as published by     */
  1434. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1435. X/*  any later version.                                                       */
  1436. X/*                                                                           */
  1437. X/*  This program is distributed in the hope that it will be useful,          */
  1438. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1439. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1440. X/*  GNU General Public License for more details.                             */
  1441. X/*                                                                           */
  1442. X/*  You should have received a copy of the GNU General Public License        */
  1443. X/*  along with this program; if not, write to the Free Software              */
  1444. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1445. X/*                                                                           */
  1446. X/*  FILE:         z26.c                                                      */
  1447. X/*  MODULE:       Echo Service                                               */
  1448. X/*  EXTERNS:      BeginString(), AppendString(), EndString(),                */
  1449. X/*                EchoLength(), Image()                                      */
  1450. X/*                                                                           */
  1451. X/*****************************************************************************/
  1452. X#include "externs"
  1453. X
  1454. X#if DEBUG_ON
  1455. X#define    MULTI      7            /* max no of simultaneous calls      */
  1456. X
  1457. Xstatic    FULL_CHAR buff[MULTI][MAX_LINE];/* buffers for strings       */
  1458. Xstatic    int    curr = 1;        /* current buffer in use             */
  1459. Xstatic    int    bp;            /* next free space in buff[curr]     */
  1460. Xstatic    BOOLEAN    instring = FALSE;    /* TRUE while making a string        */
  1461. X
  1462. X
  1463. X/*****************************************************************************/
  1464. X/*                                                                           */
  1465. X/*  BeginString()                                                            */
  1466. X/*                                                                           */
  1467. X/*  Locate a clear buffer into which debug output may be accumulated.        */
  1468. X/*                                                                           */
  1469. X/*****************************************************************************/
  1470. X
  1471. XBeginString()
  1472. X{ if( instring ) Error(INTERN, no_fpos, "BeginString: currently in string!");
  1473. X  instring = TRUE;  curr = (curr + 1) % MULTI;
  1474. X  assert( 0 <= curr && curr < MULTI, "BeginString: curr!" );
  1475. X  StringCopy(buff[curr], "");  bp = 0;
  1476. X}
  1477. X
  1478. X
  1479. X/*@::AppendString(), EndString(), EchoLength()@*******************************/
  1480. X/*                                                                           */
  1481. X/*  AppendString(str, p1, p2, p3, p4, p5, p6)                                */
  1482. X/*                                                                           */
  1483. X/*  Sprintf str to the current buffer, if space is available there.          */
  1484. X/*                                                                           */
  1485. X/*****************************************************************************/
  1486. X
  1487. X/*VARARGS1*/
  1488. XAppendString(str, p1, p2, p3, p4, p5, p6)
  1489. XFULL_CHAR *str;  int p1, p2, p3, p4, p5, p6;
  1490. X{ int len;
  1491. X  if( !instring ) Error(INTERN, no_fpos, "AppendString: no current string!");
  1492. X  assert( 0 <= curr && curr < MULTI, "BeginString: curr!" );
  1493. X  if( bp == MAX_LINE ) return;        /* no space, do nothing */
  1494. X
  1495. X  len = StringLength(str);
  1496. X  if( len + bp >= MAX_LINE )
  1497. X  { StringCopy( &buff[curr][MAX_LINE/2], AsciiToFull(" ... <too long>") );
  1498. X    bp = MAX_LINE;
  1499. X  }
  1500. X  else
  1501. X  { sprintf( (char *) &buff[curr][bp], str, p1, p2, p3, p4, p5, p6 );
  1502. X    while( buff[curr][bp] != '\0' )  bp++;
  1503. X    if( bp >= MAX_LINE )  Error(INTERN, no_fpos, "AppendString abort");
  1504. X  }
  1505. X} /* end AppendString */
  1506. X
  1507. X
  1508. X/*****************************************************************************/
  1509. X/*                                                                           */
  1510. X/*  FULL_CHAR *EndString()                                                   */
  1511. X/*                                                                           */
  1512. X/*  Return the string constructed by previous AppendString operations.       */
  1513. X/*                                                                           */
  1514. X/*****************************************************************************/
  1515. X
  1516. XFULL_CHAR *EndString()
  1517. X{ if( !instring ) Error(INTERN, no_fpos, "EndString: no current string!");
  1518. X  assert( 0 <= curr && curr < MULTI, "BeginString: curr!" );
  1519. X  instring = FALSE;
  1520. X  return buff[curr];
  1521. X} /* end Endstring */
  1522. X#endif
  1523. X
  1524. X
  1525. X/*****************************************************************************/
  1526. X/*                                                                           */
  1527. X/*  FULL_CHAR *EchoLength(len)                                               */
  1528. X/*                                                                           */
  1529. X/*  Echo a length.                                                           */
  1530. X/*                                                                           */
  1531. X/*****************************************************************************/
  1532. X
  1533. XFULL_CHAR *EchoLength(len)
  1534. Xint len;
  1535. X{ static FULL_CHAR buff[6][20];
  1536. X  static int i = 0;
  1537. X  i = (i + 1) % 6;
  1538. X  sprintf( (char *) buff[i], "%.3fc", (float) len/CM);
  1539. X  return buff[i];
  1540. X} /* end EchoLength */
  1541. X
  1542. X
  1543. X/*@::Image()@*****************************************************************/
  1544. X/*                                                                           */
  1545. X/*  FULL_CHAR *Image(c)                                                      */
  1546. X/*                                                                           */
  1547. X/*  Returns the string value of type c.                                      */
  1548. X/*                                                                           */
  1549. X/*****************************************************************************/
  1550. X
  1551. XFULL_CHAR *Image(c)
  1552. Xunsigned int c;
  1553. X{ static FULL_CHAR b[20];
  1554. X  switch(c)
  1555. X  {
  1556. X
  1557. X    case LINK:        return  AsciiToFull("link");
  1558. X
  1559. X    case SPLIT:        return  AsciiToFull("split");
  1560. X    case HEAD:        return  AsciiToFull("head");
  1561. X    case PAR:        return  AsciiToFull("par");
  1562. X    case WORD:        return  AsciiToFull("word");
  1563. X    case QWORD:        return  AsciiToFull("qword");
  1564. X    case GAP_OBJ:    return  AsciiToFull("gap_obj");
  1565. X    case ROW_THR:    return  AsciiToFull("row_thr");
  1566. X    case COL_THR:    return  AsciiToFull("col_thr");
  1567. X    case CLOSURE:    return  AsciiToFull("closure");
  1568. X    case NULL_CLOS:    return  KW_NULL;
  1569. X    case CROSS:        return  KW_CROSS;
  1570. X    case ONE_COL:    return  KW_ONE_COL;
  1571. X    case ONE_ROW:    return  KW_ONE_ROW;
  1572. X    case WIDE:        return  KW_WIDE;
  1573. X    case HIGH:        return  KW_HIGH;
  1574. X    case HSCALE:    return  KW_HSCALE;
  1575. X    case VSCALE:    return  KW_VSCALE;
  1576. X    case HCONTRACT:    return  KW_HCONTRACT;
  1577. X    case VCONTRACT:    return  KW_VCONTRACT;
  1578. X    case HEXPAND:    return  KW_HEXPAND;
  1579. X    case VEXPAND:    return  KW_VEXPAND;
  1580. X    case PADJUST:    return  KW_PADJUST;
  1581. X    case HADJUST:    return  KW_HADJUST;
  1582. X    case VADJUST:    return  KW_VADJUST;
  1583. X    case ROTATE:    return  KW_ROTATE;
  1584. X    case SCALE:        return  KW_SCALE;
  1585. X    case CASE:        return  KW_CASE;
  1586. X    case YIELD:        return  KW_YIELD;
  1587. X    case XCHAR:        return  KW_XCHAR;
  1588. X    case FONT:        return  KW_FONT;
  1589. X    case SPACE:        return  KW_SPACE;
  1590. X    case BREAK:        return  KW_BREAK;
  1591. X    case NEXT:        return  KW_NEXT;
  1592. X    case ENV:        return  KW_ENV;
  1593. X    case CLOS:        return  KW_CLOS;
  1594. X    case LVIS:        return  KW_LVIS;
  1595. X    case OPEN:        return  KW_OPEN;
  1596. X    case TAGGED:    return  KW_TAGGED;
  1597. X    case INCGRAPHIC:    return  KW_INCGRAPHIC;
  1598. X    case SINCGRAPHIC:    return  KW_SINCGRAPHIC;
  1599. X    case GRAPHIC:    return  KW_GRAPHIC;
  1600. X    case ACAT:        return  AsciiToFull("acat");
  1601. X    case HCAT:        return  AsciiToFull("hcat");
  1602. X    case VCAT:        return  AsciiToFull("vcat");
  1603. X
  1604. X    case TSPACE:    return  AsciiToFull("tspace");
  1605. X    case TJUXTA:    return  AsciiToFull("tjuxta");
  1606. X    case LBR:        return  AsciiToFull("lbr");
  1607. X    case RBR:        return  AsciiToFull("rbr");
  1608. X    case BEGIN:        return  KW_BEGIN;
  1609. X    case END:        return  KW_END;
  1610. X    case USE:        return  KW_USE;
  1611. X    case GSTUB_NONE:    return  AsciiToFull("gstub_none");
  1612. X    case GSTUB_INT:    return  AsciiToFull("gstub_int");
  1613. X    case GSTUB_EXT:    return  AsciiToFull("gstub_ext");
  1614. X    case INCLUDE:    return  KW_INCLUDE;
  1615. X    case SYS_INCLUDE:    return  KW_SYSINCLUDE;
  1616. X    case PREPEND:    return  KW_PREPEND;
  1617. X    case SYS_PREPEND:    return  KW_SYSPREPEND;
  1618. X    case DATABASE:    return  KW_DATABASE;
  1619. X    case SYS_DATABASE:    return  KW_SYSDATABASE;
  1620. X    case START:         return  AsciiToFull("start");
  1621. X
  1622. X    case DEAD:        return  AsciiToFull("dead");
  1623. X    case UNATTACHED:    return  AsciiToFull("unattached");
  1624. X    case RECEPTIVE:    return  AsciiToFull("receptive");
  1625. X    case RECEIVING:    return  AsciiToFull("receiving");
  1626. X    case RECURSIVE:    return  AsciiToFull("recursive");
  1627. X    case PRECEDES:    return  AsciiToFull("precedes");
  1628. X    case FOLLOWS:    return  AsciiToFull("follows");
  1629. X    case CROSS_FOLL:    return  AsciiToFull("cross_foll");
  1630. X    case GALL_FOLL:    return  AsciiToFull("gall_foll");
  1631. X    case CROSS_TARG:    return  AsciiToFull("cross_targ");
  1632. X    case GALL_TARG:    return  AsciiToFull("gall_targ");
  1633. X    case GALL_PREC:    return  AsciiToFull("gall_prec");
  1634. X    case CROSS_PREC:    return  AsciiToFull("cross_prec");
  1635. X    case EXPAND_IND:    return  AsciiToFull("expand_ind");
  1636. X    case THREAD:    return  AsciiToFull("thread");
  1637. X    case CROSS_SYM:    return  AsciiToFull("cross_sym");
  1638. X    case CR_ROOT:    return  AsciiToFull("cr_root");
  1639. X    case MACRO:        return  KW_MACRO;
  1640. X    case LOCAL:        return  AsciiToFull("local");
  1641. X    case LPAR:        return  AsciiToFull("lpar");
  1642. X    case NPAR:        return  AsciiToFull("npar");
  1643. X    case RPAR:        return  AsciiToFull("rpar");
  1644. X    case CR_LIST:    return  AsciiToFull("cr_list");
  1645. X    case EXT_GALL:    return  AsciiToFull("ext_gall");
  1646. X    case DISPOSED:    return  AsciiToFull("disposed");
  1647. X
  1648. X    case BACK:        return  AsciiToFull("back");
  1649. X    case ON:        return  AsciiToFull("on");
  1650. X    case FWD:        return  AsciiToFull("fwd");
  1651. X
  1652. X    case PROMOTE:    return  AsciiToFull("promote");
  1653. X    case CLOSE:        return  AsciiToFull("close");
  1654. X    case BLOCK:        return  AsciiToFull("block");
  1655. X    case CLEAR:        return  AsciiToFull("clear");
  1656. X
  1657. X    case GAP_ABS:    return  AsciiToFull("abs");
  1658. X    case GAP_INC:    return  AsciiToFull("inc");
  1659. X    case GAP_DEC:    return  AsciiToFull("dec");
  1660. X
  1661. X    default:        sprintf( (char *) b, "??(%d)", c);
  1662. X            return b;
  1663. X  } /* end switch */
  1664. X} /* end Image */
  1665. END_OF_FILE
  1666.   if test 11364 -ne `wc -c <'z26.c'`; then
  1667.     echo shar: \"'z26.c'\" unpacked with wrong size!
  1668.   fi
  1669.   # end of 'z26.c'
  1670. fi
  1671. if test -f 'z39.c' -a "${1}" != "-c" ; then 
  1672.   echo shar: Will not clobber existing file \"'z39.c'\"
  1673. else
  1674.   echo shar: Extracting \"'z39.c'\" \(10885 characters\)
  1675.   sed "s/^X//" >'z39.c' <<'END_OF_FILE'
  1676. X/*@z39.c:String Handler:AsciiToFull(), StringEqual(), etc.@*******************/
  1677. X/*                                                                           */
  1678. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  1679. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1680. X/*                                                                           */
  1681. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1682. X/*  Basser Department of Computer Science                                    */
  1683. X/*  The University of Sydney 2006                                            */
  1684. X/*  AUSTRALIA                                                                */
  1685. X/*                                                                           */
  1686. X/*  This program is free software; you can redistribute it and/or modify     */
  1687. X/*  it under the terms of the GNU General Public License as published by     */
  1688. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1689. X/*  any later version.                                                       */
  1690. X/*                                                                           */
  1691. X/*  This program is distributed in the hope that it will be useful,          */
  1692. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1693. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1694. X/*  GNU General Public License for more details.                             */
  1695. X/*                                                                           */
  1696. X/*  You should have received a copy of the GNU General Public License        */
  1697. X/*  along with this program; if not, write to the Free Software              */
  1698. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1699. X/*                                                                           */
  1700. X/*  FILE:         z39.c                                                      */
  1701. X/*  MODULE:       String Handler                                             */
  1702. X/*  EXTERNS:      AsciiToFull(), StringEqual(), StringLessEqual(),           */
  1703. X/*                StringCat(), StringCopy(), StringLength(),                 */
  1704. X/*                StringFOpen(), StringFPuts(), StringFGets(),               */
  1705. X/*                StringUnlink(), StringLink(), StringBeginsWith(),          */
  1706. X/*                StringContains(), StringInt(), StringFiveInt(),            */
  1707. X/*                StringQuotedWord()                                         */
  1708. X/*                                                                           */
  1709. X/*****************************************************************************/
  1710. X#include "externs"
  1711. X
  1712. X
  1713. X/*****************************************************************************/
  1714. X/*                                                                           */
  1715. X/*          AsciiToFull(str)          Returns ASCII string as FULL_CHARs.    */
  1716. X/*  BOOLEAN StringEqual(a, b)         TRUE if strings a and b are equal      */
  1717. X/*  BOOLEAN StringLessEqual(a, b)     TRUE if string a <= string b           */
  1718. X/*          StringCat(a, b)           Catenate string b onto end of a        */
  1719. X/*          StringCopy(a, b)          Overwrite string a with string b       */
  1720. X/*          StringLength(a)           Length of string a                     */
  1721. X/*          StringFOpen(str, mode)    Equivalent to fopen(str, mode)         */
  1722. X/*          StringFPuts(str, fp)      Equivalent to fputs(str, fp)           */
  1723. X/*          StringFGets(str, n, fp)   Equivalent to fgets(str, n, fp)        */
  1724. X/*          StringUnlink(a)           Equivalent to unlink(a)                */
  1725. X/*          StringLink(a, b)          Equivalent to link(a, b)               */
  1726. X/*                                                                           */
  1727. X/*  These procedures are defined as macros in file externs.                  */
  1728. X/*                                                                           */
  1729. X/*****************************************************************************/
  1730. X
  1731. X
  1732. X/*@::StringBeginsWith(), StringContains(), StringInt(), StringFiveInt()@******/
  1733. X/*                                                                           */
  1734. X/*  BOOLEAN StringBeginsWith(str, pattern)                                   */
  1735. X/*                                                                           */
  1736. X/*  Check whether str begins with pattern.                                   */
  1737. X/*                                                                           */
  1738. X/*****************************************************************************/
  1739. X
  1740. XBOOLEAN StringBeginsWith(str, pattern)
  1741. XFULL_CHAR *str, *pattern;
  1742. X{ FULL_CHAR *sp, *pp;
  1743. X  sp = str;  pp = pattern;
  1744. X  while( *sp != '\0' && *pp != '\0' )
  1745. X  { if( *sp++ != *pp++ )  return FALSE;
  1746. X  }
  1747. X  return (*pp == '\0');
  1748. X} /* end StringBeginsWith */
  1749. X
  1750. X
  1751. X/*****************************************************************************/
  1752. X/*                                                                           */
  1753. X/*  BOOLEAN StringContains(str, pattern)                                     */
  1754. X/*                                                                           */
  1755. X/*  Check whether str contains pattern.                                      */
  1756. X/*                                                                           */
  1757. X/*****************************************************************************/
  1758. X
  1759. XBOOLEAN StringContains(str, pattern)
  1760. XFULL_CHAR *str, *pattern;
  1761. X{ FULL_CHAR *sp;
  1762. X  for( sp = str;  *sp != '\0';  sp++ )
  1763. X  { if( StringBeginsWith(sp, pattern) )  return TRUE;
  1764. X  }
  1765. X  return FALSE;
  1766. X} /* end StringContains */
  1767. X
  1768. X
  1769. X/*****************************************************************************/
  1770. X/*                                                                           */
  1771. X/*  FULL_CHAR *StringInt(i)                                                  */
  1772. X/*  FULL_CHAR *StringFiveInt(i)                                              */
  1773. X/*                                                                           */
  1774. X/*  Returns a string version of integer i.                                   */
  1775. X/*                                                                           */
  1776. X/*****************************************************************************/
  1777. X
  1778. XFULL_CHAR *StringInt(i)
  1779. Xint i;
  1780. X{ static FULL_CHAR buff[20];
  1781. X  sprintf( (char *) buff, "%d", i);
  1782. X  return buff;
  1783. X} /* end StringInt */
  1784. X
  1785. XFULL_CHAR *StringFiveInt(i)
  1786. Xint i;
  1787. X{ static FULL_CHAR buff[20];
  1788. X  sprintf( (char *) buff, "%.5d", i);
  1789. X  return buff;
  1790. X} /* end StringInt */
  1791. X
  1792. X
  1793. X/*@::StringQuotedWord()@******************************************************/
  1794. X/*                                                                           */
  1795. X/*  static char *quoted_string[]                                             */
  1796. X/*                                                                           */
  1797. X/*  quoted_string[ch] is a string containing the representation of the       */
  1798. X/*  8-bit character ch within a quoted string in a Lout source file.         */
  1799. X/*                                                                           */
  1800. X/*****************************************************************************/
  1801. X
  1802. Xstatic char *quoted_string[] = {
  1803. X    "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
  1804. X    "\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017",
  1805. X    "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027",
  1806. X    "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037",
  1807. X    " ",     "!",     "\\\"",  "#",     "$",     "%",     "&",     "'",
  1808. X    "(",     ")",     "*",     "+",     ",",     "-",     ".",     "/",
  1809. X    "0",     "1",     "2",     "3",     "4",     "5",     "6",     "7",
  1810. X    "8",     "9",     ":",     ";",     "<",     "=",     ">",     "?",
  1811. X
  1812. X    "@",     "A",     "B",     "C",     "D",     "E",     "F",     "G",
  1813. X    "H",     "I",     "J",     "K",     "L",     "M",     "N",     "O",
  1814. X    "P",     "Q",     "R",     "S",     "T",     "U",     "V",     "W",
  1815. X    "X",     "Y",     "Z",     "[",     "\\\\",  "]",     "^",     "_",
  1816. X    "`",     "a",     "b",     "c",     "d",     "e",     "f",     "g",
  1817. X    "h",     "i",     "j",     "k",     "l",     "m",     "n",     "o",
  1818. X    "p",     "q",     "r",     "s",     "t",     "u",     "v",     "w",
  1819. X    "x",     "y",     "z",     "{",     "|",     "}",     "~",     "\\177",
  1820. X
  1821. X    "\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
  1822. X    "\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
  1823. X    "\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\226", "\\227",
  1824. X    "\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237",
  1825. X    "\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247",
  1826. X    "\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257",
  1827. X    "\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267",
  1828. X    "\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277",
  1829. X
  1830. X    "\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307",
  1831. X    "\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317",
  1832. X    "\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327",
  1833. X    "\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337",
  1834. X    "\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347",
  1835. X    "\\350", "\\351", "\\352", "\\353", "\\354", "\\355", "\\356", "\\357",
  1836. X    "\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367",
  1837. X    "\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377",
  1838. X};
  1839. X
  1840. X
  1841. X/*****************************************************************************/
  1842. X/*                                                                           */
  1843. X/*  FULL_CHAR *StringQuotedWord(x)                                           */
  1844. X/*                                                                           */
  1845. X/*  Returns the string in QWORD x in the form it would need to take if it    */
  1846. X/*  was a quoted word in a Lout source file.  Note that the result is        */
  1847. X/*  returned in a static variable so it needs to be copied before a          */
  1848. X/*  subsequent call to StringQuotedWord is made.                             */
  1849. X/*                                                                           */
  1850. X/*****************************************************************************/
  1851. X
  1852. XFULL_CHAR *StringQuotedWord(x)
  1853. XOBJECT x;
  1854. X{ FULL_CHAR *p, *q, *r;
  1855. X  static FULL_CHAR buff[MAX_LINE];
  1856. X  assert( type(x) == QWORD, "StringQuotedWord: type(x) != QWORD!" );
  1857. X  q = buff;
  1858. X  *q++ = CH_QUOTE;
  1859. X  for( p = string(x);  *p != '\0';  p++ )
  1860. X  { 
  1861. X    for( r = (FULL_CHAR *) quoted_string[*p];  *r != '\0';  *q++ = *r++ );
  1862. X  }
  1863. X  *q++ = CH_QUOTE;
  1864. X  *q++ = '\0';
  1865. X  return buff;
  1866. X} /* StringQuotedWord */
  1867. END_OF_FILE
  1868.   if test 10885 -ne `wc -c <'z39.c'`; then
  1869.     echo shar: \"'z39.c'\" unpacked with wrong size!
  1870.   fi
  1871.   # end of 'z39.c'
  1872. fi
  1873. echo shar: End of archive 27 \(of 35\).
  1874. cp /dev/null ark27isdone
  1875. MISSING=""
  1876. 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 31 32 33 34 35 ; do
  1877.     if test ! -f ark${I}isdone ; then
  1878.     MISSING="${MISSING} ${I}"
  1879.     fi
  1880. done
  1881. if test "${MISSING}" = "" ; then
  1882.     echo You have unpacked all 35 archives.
  1883.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1884. else
  1885.     echo You still must unpack the following archives:
  1886.     echo "        " ${MISSING}
  1887. fi
  1888. exit 0
  1889. exit 0 # Just in case...
  1890.