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

  1. Newsgroups: comp.sources.misc
  2. From: jeff@joyce.cs.su.oz.au (Jeff Kingston)
  3. Subject: v37i123:  lout - Lout document formatting system, v2, Part25/30
  4. Message-ID: <1993Jun2.030522.28932@sparky.imd.sterling.com>
  5. X-Md4-Signature: f4435d608aa6a7818f7045c74a8667ed
  6. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Wed, 2 Jun 1993 03:05:22 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 123
  13. Archive-name: lout/part25
  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.eq/s3 lout/doc/tr.lout/ch3.23
  21. #   lout/doc/tr.lout/ch4.01 lout/doc/tr.lout/ch4.02
  22. #   lout/doc/tr.lout/ch4.05 lout/doc/tr.lout/setup lout/z07.c
  23. #   lout/z11.c lout/z28.c lout/z35.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 25 (of 30)."'
  28. if test -f 'lout/doc/tr.eq/s3' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'lout/doc/tr.eq/s3'\"
  30. else
  31.   echo shar: Extracting \"'lout/doc/tr.eq/s3'\" \(3414 characters\)
  32.   sed "s/^X//" >'lout/doc/tr.eq/s3' <<'END_OF_FILE'
  33. X@Section
  34. X   @Title { Spacing }
  35. X@Begin
  36. X@PP
  37. XThere is a basic rule governing the use of white space characters
  38. X(space, tab, and newline) in the input to Lout:  white space between two
  39. Xobjects affects the result; white space between a symbol and its
  40. Xparameter does not.
  41. X@PP
  42. XAlthough this rule is just right most of the time, it is not adequate
  43. Xfor equation formatting.  Getting the horizontal spacing right in
  44. Xequations is a very fiddly business, involving four different sizes of
  45. Xspace (zero, thin, medium, and thick), and different rules for spacing
  46. Xwithin superscripts and subscripts to those applying outside, according
  47. Xto a leading authority [{@Ref knuth84}].  Eq therefore takes the spacing
  48. Xdecisions upon itself, and con&-sequently chooses to ignore all white
  49. Xspace in its input, even between two objects.
  50. X@FootNote {
  51. XThis effect is produced by enclosing the entire equation in
  52. X{@Code "0c @Space"}.  The simplest way to restore the effect of white
  53. Xspace to part of an equation is to enclose that part in a @Code "@Font"
  54. Xsymbol.  Eq also changes the value of the @Code v unit, so if a paragraph
  55. Xof filled text is desired within an equation, it may be necessary to
  56. Xenclose it in a @Code "@Break" symbol. }
  57. X@PP
  58. XEvery symbol provided by Eq has a {@I {full name}}, which denotes the
  59. Xsymbol without any space attached.  Many symbols also
  60. Xhave a {@I {short name}}, which denotes the same symbol with what Eq
  61. Xconsiders to be an appropriate amount of space for that symbol attached
  62. Xto it.  For example, @Eq { lessequal } has full name @Code lessequal
  63. Xand short name {@Code "<="}:
  64. X@IL
  65. X@LI {
  66. X@Code "a lessequal b"
  67. X|7ct
  68. X@Eq { a lessequal b }
  69. X}
  70. X@LI {
  71. X@Code "a <= b"
  72. X|7ct
  73. X@Eq { a <= b }
  74. X}
  75. X@EL
  76. XEq puts a thick space around relation symbols like {@Code "<="}, a
  77. Xmedium space around binary operator symbols like {@Code "+"}, and a thin
  78. Xspace after punctuation symbols (@Code ";" and {@Code ","}); except
  79. Xthat in places where the symbols appear in a smaller size (superscripts,
  80. Xsubscripts, etc.), these spaces are omitted.  No other horizontal space
  81. Xis ever inserted.
  82. X@PP
  83. XThe short names have been carefully designed to produce good-looking
  84. Xmathematics most of the time.  It is best to rely
  85. Xon them in the first instance and only think about spacing when the result
  86. Xis not pleasing.  In that case, Eq's space can be removed by using the
  87. Xfull names, and thin, medium and thick space can be added using the
  88. Xfollowing symbols:
  89. X@ID @Tab
  90. X    vmargin { 0.5vx }
  91. X    @Fmta { @Col A ! @Col B }
  92. X{
  93. X@Rowa
  94. X  A { @Code "`" }
  95. X  B { {@Code "0.18f"}  ({@Code "0.018f"} in subscripts, etc.) }
  96. X@Rowa
  97. X  A { @Code "``" }
  98. X  B { {@Code "0.24f"}  ({@Code "0.024f"} in subscripts, etc.) }
  99. X@Rowa
  100. X  A { @Code "```" }
  101. X  B { {@Code "0.30f"}  ({@Code "0.030f"} in subscripts, etc.) }
  102. X}
  103. Xwhere @Code "1f" is the current font size.  These symbols have low
  104. Xprecedence.  The @Code "&" symbol from standard Lout is also available;
  105. Xthe @Code "s" unit has value 0 and so is not very useful, but one can write
  106. X@Code "&2m" for example for a two em space.  Since the full names are tedious
  107. Xto remember, Eq provides a symbol @Code "non" which removes spaces from
  108. Xits right parameter; thus @Code "non <=" is equivalent to {@Code "lessequal"},
  109. Xfor example.  There are also symbols {@Code "rel"}, {@Code "bin"}, and
  110. X{@Code "punct"} for telling Eq to add space to the following symbol as
  111. Xthough it was a relation symbol, binary operator, or punctuation symbol.
  112. X@End @Section
  113. END_OF_FILE
  114.   if test 3414 -ne `wc -c <'lout/doc/tr.eq/s3'`; then
  115.     echo shar: \"'lout/doc/tr.eq/s3'\" unpacked with wrong size!
  116.   fi
  117.   # end of 'lout/doc/tr.eq/s3'
  118. fi
  119. if test -f 'lout/doc/tr.lout/ch3.23' -a "${1}" != "-c" ; then 
  120.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch3.23'\"
  121. else
  122.   echo shar: Extracting \"'lout/doc/tr.lout/ch3.23'\" \(7416 characters\)
  123.   sed "s/^X//" >'lout/doc/tr.lout/ch3.23' <<'END_OF_FILE'
  124. X@Section
  125. X   @Title { "@Graphic" }
  126. X   @Tag { graphic }
  127. X@Begin
  128. X@PP
  129. Xgraphic.sym @Index { @@Graphic symbol }
  130. Xdiagrams @Index { Diagrams }
  131. XLout does not provide the vast repertoire of graphical objects (lines,
  132. Xcircles, boxes, etc.) required by diagrams.  Instead, it provides an
  133. Xescape route to some other language that does have these features, via
  134. Xits @@Graphic symbol:
  135. Xpostscript.graphic @SubIndex { used by @@Graphic }
  136. X@ID @Code {
  137. X"{ 0 0 moveto"
  138. X"  0 ysize lineto"
  139. X"  xsize ysize lineto"
  140. X"  xsize 0 lineto"
  141. X"  closepath"
  142. X"  stroke"
  143. X"}"
  144. X"@Graphic"
  145. X"{ //0.2c"
  146. X"  ||0.2c hello, world ||0.2c"
  147. X"  //0.2c"
  148. X"}"
  149. X}
  150. XThe result of the above invocation of the symbol @@Graphic is
  151. X@ID {
  152. X{ 0     0     moveto
  153. X  0     ysize lineto
  154. X  xsize ysize lineto
  155. X  xsize 0     lineto
  156. X  closepath
  157. X  stroke
  158. X}
  159. X@Graphic
  160. X{ //0.2c
  161. X  ||0.2c hello, world ||0.2c
  162. X  //0.2c
  163. X}
  164. X}
  165. X@PP
  166. XThe right parameter always appears as part of the result, and indeed the
  167. Xresult is always an object whose size is identical to the size of the
  168. Xright parameter with @@OneCol and @@OneRow applied to
  169. Xit.  From now on we refer to this part of the result as the {@I base}.
  170. X@PP
  171. XThe left parameter is implementation-dependent: that is, its
  172. Xmeaning is not defined by Lout, and different implementations could
  173. Xrequire different values for it.  The following description applies to
  174. XBasser Lout, which uses the PostScript page description language
  175. X[{@Ref adobe90}].
  176. X@PP
  177. XThe left parameter refers to a coordinate system whose origin 
  178. Xis the bottom left-hand corner of the base.  It may use the symbols
  179. X@Code xsize and @Code ysize to denote the horizontal and vertical size
  180. Xof the base; similarly, @Code xmark and @Code ymark denote the positions
  181. Xof the base's column and row marks:
  182. X@ID 9p @Font @Fig {
  183. X   { &1rt @I ysize /0ik &1rt @I ymark /0ik &1rt 0 } |0.4c
  184. X   {  /
  185. X      |0ik @ShowMarks { 1c @High 1.5c @Wide ^| 3c @Wide ^/ 2c @High }
  186. X      |0ik /
  187. X   }
  188. X   /0.2c
  189. X   | 0 | @I xmark | @I xsize
  190. X}
  191. XIn addition to these four symbols and 0, lengths may be denoted in
  192. Xcentimetres, inches, points, ems, f's, v's and s's using the notation
  193. X@ID @Tab
  194. X    vmargin { 0.5vx }
  195. X    hmargin { 1m }
  196. X    @Fmta { @Col {@I l  @Code A} ! @Col {instead of Lout's} ! @Col {{@I l}B} }
  197. X{
  198. X@Rowa A { cm } B { c }
  199. X@Rowa A { in } B { i }
  200. X@Rowa A { pt } B { p }
  201. X@Rowa A { em } B { m }
  202. X@Rowa A { ft } B { f }
  203. X@Rowa A { vs } B { v }
  204. X@Rowa A { sp } B { s }
  205. X}
  206. XNote that there must be a space between the number and its unit,
  207. Xunlike Lout proper.
  208. X@PP
  209. XA point within the base (and, with care, a point outside it) may
  210. Xbe denoted by a pair of lengths.  For example,
  211. X@ID @Code {
  212. X"xmark  ymark"
  213. X}
  214. Xis the point where the marks cross, and
  215. X@ID @Code {
  216. X"0   2 cm"
  217. X}
  218. Xis a point on the left edge, two centimetres above the bottom left-hand
  219. Xcorner.  These two numbers are called the @I {x coordinate} and the
  220. X@I {y coordinate} of the point.
  221. X@PP
  222. XThe first step in specifying a graphic object is to define a
  223. X{@I path}.  A path can be thought of as the track of a pen moving over
  224. Xthe page.  The pen may be up (not drawing) or down (drawing a line or
  225. Xcurve) as it moves.  The entire path is a sequence of the following
  226. Xitems:
  227. X@LP
  228. X2i @Wide { |1rt @I {x y} @Code moveto }
  229. X|2m Lift the pen and move it to the indicated point.
  230. X@JP
  231. X2i @Wide { |1rt @I {x y} @Code lineto }
  232. X|2m Put the pen down and draw a straight line to the indicated point.
  233. X@JP
  234. X2i @Wide { |1rt @I {x y r angle1 angle2} @Code arc }
  235. X|2m Put the pen down and draw a circular arc whose centre has
  236. Xcoordinates @I x and @I y and whose radius is {@I r}.  The arc begins
  237. Xat the angle @I angle1 measuring counterclockwise from the point
  238. Xdirectly to the right of the centre, and proceeds counterclockwise to
  239. X{@I angle2}.  If the arc is not the first thing on the path, a straight
  240. Xline will be drawn connecting the current point to the start of the arc.
  241. X@JP
  242. X2i @Wide { |1rt @I {x y r angle1 angle2} @Code arcn }
  243. X|2m As for arc, but the arc goes clockwise from @I angle1 to
  244. X{@I angle2 }.
  245. X@JP
  246. X2i @Wide @Code { |1rt closepath }
  247. X|2m Draw a straight line back to the point most recently moved to.
  248. X@LP
  249. XThe first item should always be a {@Code moveto}, {@Code arc}, or
  250. X{@Code arcn}.  It should be clear from this that the path given earlier:
  251. X@ID @Code {
  252. X"0 0 moveto"
  253. X"0 ysize lineto"
  254. X"xsize ysize lineto"
  255. X"xsize 0 lineto"
  256. X"closepath"
  257. X}
  258. Xtraces around the boundary of the base with the pen down.
  259. X@PP
  260. XOnce a path is set up, we are ready to @I paint it onto the page.  There 
  261. Xare two choices: we can either @I stroke it, which means to display it
  262. Xas described; or we can @I fill it, which means to paint everything
  263. Xinside it grey or black.  For stroking the two main options are
  264. X@IL
  265. X@LI {
  266. X2i @Wide { |1rt @I length @Code setlinewidth }
  267. X|2m The pen will draw lines of the given width.
  268. X}
  269. X@LI {
  270. X2i @Wide { |1rt @Code "[" @I length @Code {"]" 0 setdash} }
  271. X|2m The pen will draw dashed lines when it is down, with the dashes each
  272. Xof the given length.
  273. X}
  274. X@EL
  275. XThese options are followed by the word {@Code "stroke"}.  So, for example,
  276. X@ID @Code {
  277. X"{ 0 0 moveto xsize 0 lineto"
  278. X"  2 pt setlinewidth [ 5 pt ] 0 setdash stroke"
  279. X"}"
  280. X"@Graphic { 3i @Wide }"
  281. X}
  282. Xhas result
  283. X@ID {
  284. X{ 0 0 moveto xsize 0 lineto
  285. X  2 pt setlinewidth [ 5 pt ] 0 setdash stroke
  286. X}
  287. X@Graphic { 3i @Wide }
  288. X}
  289. X@PP
  290. XWhen filling in the region enclosed by a path, the main option is
  291. X{@Code setgray}, which determines the shade of grey to use, on a scale
  292. Xfrom 0 (black) to 1 (white).  So, for example,
  293. X@ID @Code {
  294. X"{ 0 0 moveto xsize 0 lineto 0 ysize lineto closepath"
  295. X"  0.8 setgray fill"
  296. X"}"
  297. X"@Graphic"
  298. X"{ 2c @Wide  2c @High }"
  299. X}
  300. Xhas result
  301. X@ID {
  302. X{ 0 0 moveto xsize 0 lineto 0 ysize lineto closepath
  303. X  0.8 setgray fill
  304. X}
  305. X@Graphic
  306. X{ 2c @Wide  2c @High }
  307. X}
  308. X@PP
  309. XThere are many other options.  The value of the left parameter of
  310. X@@Graphic may be any fragment of the PostScript page description language
  311. X[{@Ref adobe90}].  Here are two other examples:
  312. X@ID @Code {
  313. Xxsize 2 div
  314. X}
  315. Xdenoting a length equal to half the horizontal size of the base, and
  316. X@ID @Code {
  317. Xgsave fill grestore stroke
  318. X}
  319. Xwhich both fills and strokes the path.  Since Basser Lout does not check
  320. Xthat the left parameter is valid PostScript, it is possible to cause
  321. Xmysterious errors in the printing device, resulting in no output, if an
  322. Xincorrect value is given.  It is a good idea to encapsulate graphics
  323. Xobjects in carefully tested definitions, like those of the Fig figure
  324. Xdrawing package [{@Ref kingston92fig}],
  325. Xfig @Index { Fig figure-drawing package }
  326. Xto be sure of avoiding these errors.
  327. X@PP
  328. XPostScript experts may find the following information helpful when
  329. Xdesigning advanced graphics features.  The left parameter of @@Graphic
  330. Xmay have two parts, separated by {@Code "//"}:
  331. X@ID {
  332. X@Code "{" @I {first part} @Code "//" @I {second part} @Code "} @Graphic"
  333. X@I object
  334. X}
  335. XIf there is no {@Code "//"}, the second part is taken to be empty.  The
  336. XPostScript output has the form
  337. X@ID lines @Break {
  338. X@Code gsave
  339. X@I x @I y @Code translate
  340. X@I {Code which defines {@Code xsize}, {@Code ysize}, {@Code xmark}, {@Code ymark}, {@Code ft}, {@Code vs}, and {@Code sp} }
  341. X@Code gsave
  342. X@I {first part}
  343. X@Code grestore
  344. X@I {Code which renders the right parameter in translated coordinates}
  345. X@I {second part}
  346. X@Code grestore
  347. X}
  348. Xwhere @Eq {x, y} is the position of the lower left corner of the
  349. Xbase.  Having two parts permits bracketing operations, like @Code save
  350. Xand @Code restore or @Code begin and {@Code end}, to enclose an
  351. Xobject.  See the source file of the Fig package for examples.
  352. X@End @Section
  353. END_OF_FILE
  354.   if test 7416 -ne `wc -c <'lout/doc/tr.lout/ch3.23'`; then
  355.     echo shar: \"'lout/doc/tr.lout/ch3.23'\" unpacked with wrong size!
  356.   fi
  357.   # end of 'lout/doc/tr.lout/ch3.23'
  358. fi
  359. if test -f 'lout/doc/tr.lout/ch4.01' -a "${1}" != "-c" ; then 
  360.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch4.01'\"
  361. else
  362.   echo shar: Extracting \"'lout/doc/tr.lout/ch4.01'\" \(7273 characters\)
  363.   sed "s/^X//" >'lout/doc/tr.lout/ch4.01' <<'END_OF_FILE'
  364. X@Section
  365. X   @Title { An equation formatting package }
  366. X   @Tag { eq }
  367. X@Begin
  368. X@PP
  369. XIn this section we describe the design and implementation of the Eq
  370. Xeq @Index { Eq equation formatting package }
  371. Xequation formatting package.  Equation formatting makes a natural first
  372. Xexample, partly because its requirements have strongly influenced the
  373. Xdesign of Lout, and partly because no cross references or galleys are
  374. Xrequired.
  375. X@PP
  376. XTo the author's knowledge, Eq is the first equation formatter to be
  377. Ximplemented as a collection of high-level definitions.  This approach
  378. Xhas significant advantages:  the basics of language and layout are
  379. Xtrivial, so the implementor can concentrate on fine-tuning; and the
  380. Xdefinitions, being readily available, can be improved, extended, or even
  381. Xreplaced.
  382. X@PP
  383. XAs described in the Eq user manual [{@Ref kingston92eq}], an equation is
  384. Xentered in a format based on the one introduced by the eqn language of
  385. XKernighan and Cherry [{@Ref kernighan75}]:
  386. Xkernighan.b @Index { Kernighan, B. }
  387. Xcherry.l @Index { Cherry, L. }
  388. X@ID @Code {
  389. X"@Eq { { x sup 2  +  y sup 2 }  over  2 }"
  390. X}
  391. XThe result is
  392. X@ID @Eq { { x sup 2  +  y sup 2 }  over  2 }
  393. XIn outline, the definition of the @Code "@Eq" symbol is
  394. Xeq.example @Index { @Code "@Eq" example }
  395. X@ID @Code {
  396. X"export  sup  over \"+\"  \"2\"  \"<=\""
  397. X"def @Eq"
  398. X"   body @Body"
  399. X"{"
  400. X"   def sup precedence 60 left x right y { ... }"
  401. X"   def over precedence 54 left x right y { ... }"
  402. X"   def \"2\" { Base @Font \"2\" }"
  403. X"   def \"+\" { {Symbol Base} @Font \"+\" }"
  404. X"   def \"<=\" { {Symbol Base} @Font \"\\243\" }"
  405. X"   ..."
  406. X""
  407. X"   Slope @Font 1.2f @Break 0c @Space @Body"
  408. X"}"
  409. X}
  410. XA body parameter is used to restrict the visibility of the equation
  411. Xformatting symbols (there are hundreds of them).  The equation as a whole
  412. Xis set in Slope (i.e. Italic) font, and symbols such as @Code "\"2\"" and
  413. X@Code "\"+\"" are defined when other fonts are needed.  Precedences are
  414. Xused to resolve ambiguities such as {@Code "a sup b over c"}.  Eq takes
  415. Xall spacing decisions on itself, so to prevent white space
  416. Xtyped by the user from interfering, the equation is enclosed in
  417. X{@Code "0c @Space"}.  We will discuss the {@Code "1.2f @Break"} later.
  418. X@PP
  419. XThus have we disposed of the language design part of the equation
  420. Xformatting problem; it remains now to define the twenty or so symbols
  421. Xwith parameters, and get the layout right.
  422. X@PP
  423. XEvery equation has an {@I axis}:  an imaginary horizontal line through
  424. Xthe centre of variables, through the bar of built-up fractions, and so
  425. Xon.  We can satisfy this requirement by ensuring that the result of each
  426. Xsymbol has a single row mark, on the axis.  For example, the
  427. Xsuperscripting symbol is defined as follows:
  428. Xsup.example @Index { @Code "sup" example }
  429. X@ID @Code {
  430. X"def sup"
  431. X"    precedence 60"
  432. X"    associativity left"
  433. X"    left x"
  434. X"    named gap { @SupGap }"
  435. X"    right y"
  436. X"{"
  437. X"    @HContract @VContract {"
  438. X"        |  @Smaller y"
  439. X"        ^/gap  x"
  440. X"    }"
  441. X"}"
  442. X}
  443. XThe @Code "@VContract" and @Code "^/" symbols together ensure that the axis
  444. Xof the result is the axis of the left parameter.  A @Code "gap"
  445. Xparameter has been provided for varying the height of the superscript,
  446. Xwith default value @Code "@SupGap"  defined elsewhere as
  447. X{@Code "0.40fk"}.  It is important that such gaps be expressed in units
  448. Xthat vary with the font size, so that they remain correct when the size
  449. Xchanges.  Collecting the default values into symbols like @Code
  450. X"@SupGap" ensures consistency and assists when tuning the values.  Here
  451. Xis another characteristic definition:
  452. Xover.example @Index { @Code "over" example }
  453. X@ID @Code {
  454. X"def over"
  455. X"    precedence 54"
  456. X"    associativity left"
  457. X"    left x"
  458. X"    named gap { 0.2f }"
  459. X"    right y"
  460. X"{"
  461. X"    @HContract @VContract {"
  462. X"        |0.5rt  @OneCol x"
  463. X"        ^//gap  @HLine"
  464. X"        //gap  |0.5rt @OneCol y"
  465. X"    }"
  466. X"}"
  467. X}
  468. XBoth parameters are centred, since we do not know which will be the
  469. Xwider; we use @@OneCol to make sure that the entire parameter is
  470. Xcentred, not just its first column, and @@HContract ensures that the
  471. Xfraction will never expand to fill all the available space, as Lout objects
  472. Xhave a natural tendency to do (Section {@NumberOf size}).  @Code "@HLine"
  473. Xis a horizontal line of the width of the column:
  474. Xhline.example @Index { @Code "@Hline" example }
  475. X@ID @Code {
  476. X"def @HLine"
  477. X"    named line { \"0.05 ft setlinewidth\" }"
  478. X"{  "
  479. X"    { \"0 0 moveto xsize 0 lineto\" line \"stroke\" } @Graphic {}"
  480. X"}"
  481. X}
  482. XHere we are relying on the expanding tendency just mentioned.
  483. X@PP
  484. XThe remaining symbols are quite similar to these ones.  We conclude with
  485. Xa few fine points of mathematical typesetting mentioned by a leading
  486. Xauthority, D. E. Knuth [{@Ref knuth84}].
  487. Xknuth.d @Index { Knuth, D. }
  488. X@PP
  489. XSome symbols, such as @Eq {lessequal} and @Eq { notequal }, should have a
  490. Xthick space on each side; others, such as @Eq {plus} and @Eq {minus},
  491. Xhave a medium space; others have a thin space on the right only.  This
  492. Xwould be easy to do except that these spaces are not wanted in
  493. Xsuperscripts and subscripts:
  494. X@ID @Eq { r sup n+1 - 1 }
  495. XIn effect, the definition of such symbols changes depending on the
  496. Xcontext; but Lout does not permit such a change.  Luckily, the so-called
  497. X`style' information set by the @@Font, @@Break, and @@Space symbols can
  498. Xchange in this way.  Accordingly, Eq commandeers the @Code v unit,
  499. Xnormally used for line gaps, and uses it for these spaces instead:
  500. X@ID @Code {
  501. X"def @MedGap { 0.20v }"
  502. X""
  503. X"def \"+\" { &@MedGap plus &@MedGap }"
  504. X""
  505. X"def @Smaller right x { 0.7f @Font 0c @Space 0.2f @Break x }"
  506. X}
  507. XThe @Code "@Smaller" symbol is applied to all superscripts and subscripts,
  508. Xreducing the font size and also reducing the @Code "v" unit,
  509. Xthereby reducing the space around @Code "+" and similar symbols.
  510. X@PP
  511. XSome objects, notably matrices and large summation signs, must be
  512. Xvertically centred in the sense that their axis must be placed halfway
  513. Xdown the object.  This seems quite different to the usual kind of
  514. Xcentring of one object within another handled by the @Code "0.5rt" gap.
  515. X With the aid of the @Code w unit used with concatenation symbols (one
  516. Xw.unit.example @SubIndex { example of use of }
  517. X@Code w is the size of the following object) and some ingenuity we find that
  518. Xvctr.example @Index { @Code vctr example }
  519. X@ID @Code {
  520. X"def vctr right x"
  521. X"{ @OneRow { /0.5wo @OneRow { @OneRow x ^/ } }"
  522. X"}"
  523. X}
  524. Xwill vertically centre its parameter: @Code "@OneRow { @OneRow x ^/ }"
  525. Xreplaces {@Code x}'s mark by one mark along its lower boundary; then
  526. X@Code "/0.5wo" overstrikes the desired mark, and the outer @@OneRow
  527. Xhides the lower mark.  Unfortunately, although the parameter is
  528. Xcorrectly placed and printed, the overstriking hides its top half, and
  529. X@ID @Code {
  530. X"vctr sum from i=0 to n i"
  531. X}
  532. Xappears as
  533. X@ID @Eq { 
  534. X@OneRow { /0.5wo @OneRow { @OneRow sum ^/ } }
  535. Xfrom i=0 to n i
  536. X}
  537. Xusing this definition.  The version of @Code "vctr" in Eq
  538. Xovercomes this problem by overstriking two copies of the parameter, one
  539. Xof which has been rotated twice by 180 degrees:
  540. X@ID @Code {
  541. X"def vctr  right x"
  542. X"{  @OneRow"
  543. X"   {  -180d @Rotate { /0.5wo 180d @Rotate { / @OneRow @OneCol x  } }"
  544. X"      ^/  @OneRow { /0.5wo @OneRow { @OneRow @OneCol x ^/ } }"
  545. X"   }"
  546. X"}"
  547. X}
  548. XThis is very ugly and suggests that something is lacking from Lout's features.
  549. X@End @Section
  550. END_OF_FILE
  551.   if test 7273 -ne `wc -c <'lout/doc/tr.lout/ch4.01'`; then
  552.     echo shar: \"'lout/doc/tr.lout/ch4.01'\" unpacked with wrong size!
  553.   fi
  554.   # end of 'lout/doc/tr.lout/ch4.01'
  555. fi
  556. if test -f 'lout/doc/tr.lout/ch4.02' -a "${1}" != "-c" ; then 
  557.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch4.02'\"
  558. else
  559.   echo shar: Extracting \"'lout/doc/tr.lout/ch4.02'\" \(8479 characters\)
  560.   sed "s/^X//" >'lout/doc/tr.lout/ch4.02' <<'END_OF_FILE'
  561. X@Section
  562. X   @Title { Paragraphs, displays, and lists }
  563. X   @Tag { paras }
  564. X@Begin
  565. X@PP
  566. XThe remaining sections of this chapter are all based on the
  567. XDocumentLayout package, described from the user's perspective in the
  568. Xdocument.layout @Index { DocumentLayout package }
  569. XBeginners' Guide [{@Ref kingston92begin}].  In 26 pages of Lout,
  570. Xthe package defines many features required in the formatting of simple
  571. Xdocuments, technical reports, and books, including displays, lists, page
  572. Xlayout, cross references, tables of contents, footnotes, figures,
  573. Xtables, references, chapters, sections, and sorted indexes.
  574. X@PP
  575. XThe symbols used for separating paragraphs and producing displays and
  576. Xdocument.layout.paras @SubIndex { paragraphs }
  577. Xlists may lack the excitement of more exotic features, but they can
  578. Xteach some important lessons about robust design.  The following macro
  579. Xfor separating paragraphs produces a 0.3 cm vertical space and a 1 cm
  580. Xindent on the following line, and is clearly on the right track:
  581. X@ID @Code "macro  @PP  { //0.3c &1c }"
  582. XNevertheless it has several major problems.
  583. X@PP
  584. XThe @Code "&" symbol is subject to widening during line adjustment, so
  585. Xit should be replaced by {@Code "1c @Wide {}"}.  But then white space
  586. Xfollowing the symbol will affect the result, so an extra @Code "&0i" must
  587. Xbe added.  If the document is printed double spaced, this paragraph gap
  588. Xwill fail to widen:  it should be expressed in terms of the @Code "v" unit,
  589. Xwith mark-to-mark spacing mode.  Similarly, the paragraph indent should
  590. Xprobably be made proportional to the font size.
  591. X@PP
  592. X`Magic numbers' like @Code "0.3c" should not be buried in definitions
  593. Xwhere they cannot be changed easily, or kept consistent with similar
  594. Xdefinitions during tuning.  They are much better placed as symbols,
  595. Xpossibly parameters of the enclosing package:
  596. X@ID @Code {
  597. X"def @DocumentLayout" pp.example @Index { @Code "@PP" example }
  598. X"    named @ParaGap { 1.3vx }"
  599. X"    named @ParaIndent { 2f }"
  600. X"    ..."
  601. X"@Begin"
  602. X""
  603. X"    macro @PP { //@ParaGap @ParaIndent @Wide &0i }"
  604. X"    macro @LP { //@ParaGap }"
  605. X"    ..."
  606. X"@End @DocumentLayout"
  607. X}
  608. Xand we have arrived at the definition of @Code "@PP" as it appears in
  609. Xthe DocumentLayout package.
  610. X@PP
  611. XA display is a table in which the first column is blank:
  612. Xdocument.layout.displays @SubIndex { displays }
  613. X@ID lines @Break {
  614. X@I { preceding text }
  615. X@Code "//@DispGap |@DispIndent"  @I display
  616. X@Code "//@DispGap"
  617. X@I { following text }
  618. X}
  619. XEdge-to-edge is the appropriate spacing mode before and after displays,
  620. Xsince the display could be a table or figure whose mark does not
  621. Xcorrespond to a baseline.  Thus, @Code "1v" is a reasonable value for
  622. X{@Code "@DispGap"}.
  623. X@PP
  624. XThe ordinary user cannot be expected to type the Lout source shown
  625. Xabove; a more appropriate syntax is
  626. Xindented.display.example @Index { @Code "@IndentedDisplay" example }
  627. X@ID lines @Break {
  628. X@I { preceding text }
  629. X@Code "@IndentedDisplay {"  @I display  @Code "}"
  630. X@I { following text }
  631. X}
  632. XThis presents a problem:  if @Code "@IndentedDisplay" is made a definition
  633. Xwith a right parameter, its result will be an object separated from the
  634. Xsurrounding text only by white space, hence part of the paragraph; while
  635. Xif it is a macro, the final @Code "//@DispGap" cannot be included in it.
  636. X The solution adopted in the DocumentLayout package uses a galley and a macro:
  637. X@ID @Code {
  638. X"    def @DispPlace { @Galley }"
  639. X"    def @Disp into { @DispPlace&&preceding }"
  640. X"        right x"
  641. X"    {"
  642. X"        @OneRow x"
  643. X"    }"
  644. X""
  645. X"    macro @IndentedDisplay"
  646. X"    {"
  647. X"        //@DispGap  |@DispIndent  @DispPlace  |"
  648. X"        //@DispGap  //  @Disp"
  649. X"    }"
  650. X}
  651. X@Code "@DispPlace" and @Code "@Disp" are not exported, so there is
  652. Xno danger of a name clash with some other symbol.  The ordinary user's
  653. Xsyntax expands to
  654. X@ID lines @Break {
  655. X@I { preceding text }
  656. X@Code "//@DispGap  |@DispIndent  @DispPlace  |"
  657. X@Code "//@DispGap  //  @Disp {" @I display @Code "}"
  658. X@I { following text }
  659. X}
  660. Xand the @Code "@Disp" galley appears at the preceding
  661. X{@Code "@DispPlace"}, being itself replaced by @@Null.  The @Code "//"
  662. Xsymbol protects the preceding @Code "//@DispGap" from being deleted by
  663. Xthis @@Null when there is no following text.
  664. X@PP
  665. XAn automatically numbered list
  666. Xdocument.layout.lists @SubIndex { lists }
  667. Xnumbered @Index { Numbered list }
  668. Xcould have an arbitrarily large number of
  669. Xitems, so, by analogy with sequences of pages, we see immmediately that
  670. Xrecursion must be involved:
  671. X@ID @Code {
  672. X"def @List right num"
  673. X"{"
  674. X"    @DispIndent @Wide num.  |  @ItemPlace"
  675. X"    //@DispGap @List @Next num"
  676. X"}"
  677. X}
  678. XNotice how the @@Next symbol works in conjunction with the recursion to
  679. Xproduce an ascending sequence of numbers; the result of @Code "@List 1"
  680. Xwill be
  681. X@ID @Code {
  682. X"1.   @ItemPlace"
  683. X"2.   @ItemPlace"
  684. X"3.   @ItemPlace"
  685. X"..."
  686. X}
  687. XWe can follow this with items which are galleys targeted to
  688. X{@Code "@ItemPlace&&preceding"}, and @Code "@List" will expand just
  689. Xenough to accommodate them.
  690. X@PP
  691. XThe usual problem with recursive-receptive symbols now arises:  there is
  692. Xalways one unexpanded {@Code "@List"}, and until it can be removed the
  693. Xgalley containing it will appear to be incomplete and will be prevented at
  694. Xthat point from flushing into its parent (see page {@PageOf forcing}).  We
  695. Xadopt the usual solution:  a forcing galley into a later target will
  696. Xreplace the last @Code "@List" by @@Null.  This brings us to the
  697. Xdefinitions as they appear in DocumentLayout:
  698. Xindented.list.example @Index { @Code "@IndentedList" example }
  699. X@IndentedList
  700. X@LI @Code {
  701. X"def @ItemPlace { @Galley }"
  702. X"def @ListItem into { @ItemPlace&&preceding }"
  703. X"    right x"
  704. X"{ x }"
  705. X}
  706. X@LI @Code {
  707. X"def @EndListPlace { @Galley }"
  708. X"def @EndList force into { @EndListPlace&&preceding }"
  709. X"{}"
  710. X}
  711. X@LI @Code {
  712. X"def @RawIndentedList"
  713. X"   named style right tag {}"
  714. X"   named indent { @DispIndent }"
  715. X"   named gap { @DispGap }"
  716. X"   named start { 1 }"
  717. X"{"
  718. X"    def @IList right num"
  719. X"    {"
  720. X"        indent @Wide {style num} | @ItemPlace"
  721. X"        //gap @IList @Next num"
  722. X"    }"
  723. X""
  724. X"    @IList start  //  @EndListPlace"
  725. X"}"
  726. X}
  727. X@EndList
  728. XNow given the input
  729. X@ID @Code {
  730. X"@RawIndentedList"
  731. X"@ListItem { first item }"
  732. X"@ListItem { second item }"
  733. X"..."
  734. X"@ListItem { last item }"
  735. X"@EndList"
  736. X}
  737. X@Code "@RawIndentedList" will expand to receive the items, and will be
  738. Xclosed off by {@Code "@EndList"}.
  739. X@PP
  740. XThe {@Code indent}, {@Code gap}, and {@Code start} parameters are
  741. Xstraightforward (note that the burden of typing @Code 1 has been lifted
  742. Xfrom the ordinary user), but the @Code style parameter has a parameter
  743. Xof its own (see page {@PageOf strange}).  It is used like this:
  744. X@ID @Code {
  745. X"def @RawNumberedList { @RawIndentedList style { tag. } }"
  746. X"def @RawParenNumberedList { @RawIndentedList style { (tag) } }"
  747. X}
  748. XIn {@Code "@RawNumberedList"}, @Code "style" is given the value
  749. X{@Code "tag."}, where @Code tag is its own right parameter, so the value
  750. Xof @Code "{style num}" within @Code "@IList" is {@Code "num."}; while in
  751. X{@Code "@RawParenNumberedList"}, @Code "{style num}" is {@Code "(num)"}.  In
  752. Xthis way we achieve an unlimited variety of numbering formats without
  753. Xhaving to rewrite @Code "@RawIndentedList" over and over.
  754. X@PP
  755. XThese list symbols are objects without surrounding space, so macros
  756. Xsimilar to those used for displays are needed:
  757. X@ID @Code {
  758. X"macro @NumberedList { //@DispGap @RawNumberedList //@DispGap }"
  759. X"macro @ParenNumberedList { //@DispGap @RawParenNumberedList //@DispGap }"
  760. X}
  761. Xand so on.
  762. X@PP
  763. XLists numbered by Roman numerals
  764. Xroman @Index { Roman numerals }
  765. Xpresent a problem, because @@Next will
  766. Xnot increment Roman numerals.  Instead, they must be stored in a
  767. Xdatabase:
  768. X@ID @Code {
  769. X"def @Roman"
  770. X"    left @Tag"
  771. X"    right @Val"
  772. X"{ @Val }"
  773. X""
  774. X"@SysDatabase @Roman { standard }"
  775. X}
  776. X@Code "@SysDatabase" is preferred over @Code "@Database" here because
  777. Xthis database should be kept in a standard place and shared by
  778. Xeveryone.  The database itself, a file called @Code "standard.ld" in
  779. XBasser Lout, contains invocations of {@Code "@Roman"}, each enclosed in
  780. Xbraces:
  781. X@ID @Code {
  782. X"{ 1 @Roman i }"
  783. X"{ 2 @Roman ii }"
  784. X"..."
  785. X"{ 100 @Roman c }"
  786. X}
  787. XThen @Code "@Roman&&12" for example has value {@Roman&&12}, and
  788. X@ID @Code {
  789. X"def @RawRomanList { @RawIndentedList style { {@Roman&&tag}. } }"
  790. X}
  791. Xproduces a list numbered by Roman numerals.  The counting still
  792. Xproceeds in Arabic, but each Arabic numeral is converted to Roman by the
  793. Xcross reference.  Since arbitrary objects may be stored in databases,
  794. Xarbitrary finite sequences of objects may be `counted' in this way.
  795. X@End @Section
  796. END_OF_FILE
  797.   if test 8479 -ne `wc -c <'lout/doc/tr.lout/ch4.02'`; then
  798.     echo shar: \"'lout/doc/tr.lout/ch4.02'\" unpacked with wrong size!
  799.   fi
  800.   # end of 'lout/doc/tr.lout/ch4.02'
  801. fi
  802. if test -f 'lout/doc/tr.lout/ch4.05' -a "${1}" != "-c" ; then 
  803.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/ch4.05'\"
  804. else
  805.   echo shar: Extracting \"'lout/doc/tr.lout/ch4.05'\" \(8311 characters\)
  806.   sed "s/^X//" >'lout/doc/tr.lout/ch4.05' <<'END_OF_FILE'
  807. X@Section
  808. X   @Title { Bibliographies }
  809. X   @Tag { biblio }
  810. X@Begin
  811. X@PP
  812. Xbibliographies @Index { Bibliographies }
  813. XThe first step in the production of a bibliography is to create a
  814. Xdatabase of references based on the definition
  815. Xreference.example @Index { @Code "@Reference" example }
  816. X@ID @Code {
  817. X      "export @Type @Author @Title @Institution @Number @Publisher"
  818. X//1vx "       @Year @Proceedings @Journal @Volume @Pages @Comment"
  819. X//1vx ""
  820. X//1vx "def @Reference"
  821. X//1vx "   named @Tag"         |2f  "{ TAG? }"
  822. X /1vx "   named @Type"        |    "{ TYPE? }"
  823. X /1vx "   named @Author"      |    "{ AUTHOR? }"
  824. X /1vx "   named @Title"       |    "{ TITLE? }"
  825. X /1vx "   named @Institution" |    "{ INSTITUTION? }"
  826. X /1vx "   named @Number"      |    "{ NUMBER? }"
  827. X /1vx "   named @Publisher"   |    "{ PUBLISHER? }"
  828. X /1vx "   named @Year"        |    "{ YEAR? }"
  829. X /1vx "   named @Proceedings" |    "{ PROCEEDINGS? }"
  830. X /1vx "   named @Journal"     |    "{ JOURNAL? }"
  831. X /1vx "   named @Volume"      |    "{ VOLUME? }"
  832. X /1vx "   named @Pages"       |    "{ PAGES? }"
  833. X /1vx "   named @Comment"     |    "{ @Null }"
  834. X//1vx "{ @Null }"
  835. X}
  836. XFor example, the database might contain
  837. X@IL
  838. X@LI @Code {
  839. X"{ @Reference"
  840. X"     @Tag { strunk79 }"
  841. X"     @Type { Book }"
  842. X"     @Author { Strunk, William and White, E. B. }"
  843. X"     @Title { The Elements of Style }"
  844. X"     @Publisher { MacMillan, third edition }"
  845. X"     @Year { 1979 }"
  846. X"}"
  847. X}
  848. X
  849. X@LI @Code {
  850. X"{ @Reference"
  851. X"     @Tag { kingston92 }"
  852. X"     @Type { TechReport }"
  853. X"     @Author { Kingston, Jeffrey H. }"
  854. X"     @Title { Document Formatting with Lout (Second Edition) }"
  855. X"     @Number { 449 }"
  856. X"     @Institution { Basser Department of Computer"
  857. X"Science F09, University of Sydney 2006, Australia }"
  858. X"     @Year { 1992 }"
  859. X"}"
  860. X}
  861. X@EL
  862. XSince named parameters are optional, we have one for every conceivable
  863. Xtype of attribute, and simply leave out those that do not apply in any
  864. Xparticular reference.  We can print a reference by using the @@Open
  865. Xsymbol to get at its attributes:
  866. X@ID @Code {
  867. X"@Reference&&strunk79 @Open"
  868. X"{  @Author,  {Slope @Font @Title}.  @Publisher, @Year.  }"
  869. X}
  870. XThe right parameter of @@Open may use the exported parameters of the
  871. Xleft, and so the result is
  872. X@ID {
  873. X@Reference&&strunk79 @Open
  874. X{  @Author,  {Slope @Font @Title}.  @Publisher, @Year.  } &0io
  875. X}
  876. XIncidentally, we are not limited to just one database of references;
  877. Xseveral @@Database symbols can nominate the same symbol, and invocations of
  878. Xthat symbol can appear in the document itself as well if we wish.
  879. X@PP
  880. XThe second step is to create a database of print styles for the various
  881. Xtypes of reference (Book, TechReport, etc.), based on the following
  882. Xdefinition:
  883. X@ID @Code {
  884. X"export @Style"
  885. X"def @RefStyle"
  886. X"   left @Tag"
  887. X"   named @Style right reftag {}"
  888. X"{}"
  889. X}
  890. XNotice that the named parameter @Code "@Style" has a right parameter
  891. X{@Code "reftag"}.  The style database has one entry for each type of
  892. Xreference:
  893. X@ID @Code {
  894. X"{ Book @RefStyle @Style"
  895. X"  {  @Reference&&reftag @Open"
  896. X"     { @Author,  {Slope @Font @Title}.  @Publisher, @Year.  @Comment }"
  897. X"  }"
  898. X"}"
  899. X""
  900. X"{ TechReport @RefStyle @Style"
  901. X"  {  @Reference&&reftag @Open"
  902. X"     { @Author,  {Slope @Font @Title}.  Tech. Rep. @Number (@Year),"
  903. X"@Institution.  @Comment }"
  904. X"  }"
  905. X"}"
  906. X}
  907. Xand so on.  The following prints the reference whose tag is
  908. X@Code strunk79 in the Book style:
  909. X@ID @Code {
  910. X"@RefStyle&&Book @Open { @Style strunk79 }"
  911. X}
  912. XIt has result
  913. X@ID {
  914. X@RefStyle&&Book @Open { @Style strunk79 } &0io
  915. X}
  916. XNotice how the @Code "@Style" parameter of @Code "@RefStyle" is given the
  917. Xparameter {@Code strunk79}, which it uses to open the appropriate
  918. Xreference.
  919. X@PP
  920. XWe can consult the @Code "@Type" attribute of a reference to find out
  921. Xits style, which brings us to the following definition for printing out
  922. Xa reference in the style appropriate to it:
  923. X@ID @Code {
  924. X"def @RefPrint"
  925. X"   right reftag"
  926. X"{  @RefStyle&&{ @Reference&&reftag @Open { @Type } }"
  927. X"   @Open { @Style reftag }"
  928. X"}"
  929. X}
  930. XFor example, to evaluate {@Code "@RefPrint strunk79"}, Lout first
  931. Xevaluates
  932. X@ID @Code {
  933. X"@Reference&&strunk79  @Open  { @Type }"
  934. X}
  935. Xwhose result is {@Code { @Reference&&strunk79  @Open  { @Type } }},
  936. Xand then evaluates
  937. X@Code {
  938. X"@RefStyle&&Book @Open { @Style strunk79 }"
  939. X}
  940. Xas before.  Complicated as this is, with its two databases and clever
  941. Xpassing about of tags, the advantages of separating references from
  942. Xprinting styles are considerable:  printing styles may be changed
  943. Xeasily, and non-expert users need never see them.
  944. X@PP
  945. XFinally, we come to the problem of printing out a numbered list of
  946. Xreferences, and referring to them by number in the body of the
  947. Xdocument.  The first step is to create a numbered list of places that
  948. Xgalleys containing references may attach to:
  949. Xreferencesection.example @Index { @Code "@ReferenceSection" example }
  950. X@ID @Code {
  951. X"def @ReferenceSection"
  952. X"    named @Tag {}"
  953. X"    named @Title { References }"
  954. X"    named @RunningTitle { dft }"
  955. X"    named style right tag { tag. }"
  956. X"    named headstyle right @Title { @Heading @Title }"
  957. X"    named indent { @DispIndent }"
  958. X"    named gap { @DispGap }"
  959. X"    named start { 1 }"
  960. X"{"
  961. X"    def @RefList right num"
  962. X"    {"
  963. X"        @NumberMarker num  &  indent @Wide {style num}  |  @RefPlace"
  964. X"        //gap @RefList @Next num"
  965. X"    }"
  966. X""
  967. X"        @Protect headstyle @Title"
  968. X"    //  @PageMarker&&preceding @Tagged @Tag"
  969. X"    //  @Title @MajorContentsEntry {@PageOf @Tag}"
  970. X"    //  @Runner"
  971. X"            @FootEven { |0.5rt 0.8f @Font @B @PageNum }"
  972. X"            @FootOdd  { |0.5rt 0.8f @Font @B @PageNum }"
  973. X"    //@DispGap  @RefList start"
  974. X"    //  @Runner"
  975. X"            @TopEven { @B @PageNum }"
  976. X"            @TopOdd  { @I {@RunningTitle @OrElse @Title} |1rt @B @PageNum }"
  977. X"}"
  978. X}
  979. XWe place the expression @Code "@ReferenceSection" at the point where we
  980. Xwant the list of references to appear; its value is something like
  981. X@ID @Code {
  982. X"1.   @RefPlace"
  983. X"2.   @RefPlace"
  984. X"3.   @RefPlace"
  985. X"..."
  986. X}
  987. Xwhere @Code "@RefPlace" is @Code "@Galley" as usual.  We can scatter
  988. Xmultiple lists of references through the document if we wish (at the end
  989. Xof each chapter, for example), simply by placing @Code "@ReferenceSection"
  990. Xat each point.
  991. X@PP
  992. XOur task is completed by the following definition:
  993. Xref.example @Index { @Code "@Ref" example }
  994. X@ID @Code {
  995. X"def @Ref right x"
  996. X"{"
  997. X"    def sendref into { @RefPlace&&following }"
  998. X"        right @Key"
  999. X"    {"
  1000. X"        @NumberMarker&&preceding @Tagged x  &"
  1001. X"        @PageMarker&&preceding @Tagged x  &"
  1002. X"        @RefPrint x"
  1003. X"    }"
  1004. X""
  1005. X"    @NumberMarker&&x @Open { @Tag } sendref x"
  1006. X"}"
  1007. X}
  1008. XGiven this definition, the invocation {@Code "@Ref strunk79"} has result
  1009. X@ID @Code "@NumberMarker&&strunk79 @Open { @Tag }"
  1010. Xplus the galley {@Code "sendref strunk79"}.  We first
  1011. Xfollow what happens to the galley.
  1012. X@PP
  1013. XAccording to its @Code into clause, the galley will replace a
  1014. X@Code "@RefPlace" in the nearest following {@Code "@ReferenceSection"}.  If
  1015. Xevery such galley is a sorted galley whose key is the reference's tag, as
  1016. Xthis one is, they will appear sorted by tag.  The galley's object is
  1017. X@ID @Code {
  1018. X"@NumberMarker&&preceding @Tagged strunk79  &"
  1019. X"@PageMarker&&preceding @Tagged strunk79  &"
  1020. X"@RefPrint strunk79"
  1021. X}
  1022. XThe result of the @@Tagged symbol is always @@Null, so this prints the
  1023. X@Code strunk79 reference in the appropriate style at the
  1024. X{@Code "@RefPlace"}, as desired.
  1025. X@PP
  1026. XNow @Code "@NumberMarker&&preceding" is the nearest preceding invocation of
  1027. X@Code "@NumberMarker" in the final document.  This must be the invocation of
  1028. X@Code "@NumberMarker" just before the @Code "@RefPlace" that received
  1029. Xthe galley, and so this invocation of @Code "@NumberMarker" is given @Code
  1030. Xstrunk79 as an additional tag by the @@Tagged symbol.  Its original tag
  1031. Xwas the number of the reference place, which means that
  1032. X@ID @Code {
  1033. X"@NumberMarker&&strunk79 @Open { @Tag }"
  1034. X}
  1035. Xhas for its result the number of the reference place that received the
  1036. X@Code strunk79 galley, and this is the desired result of
  1037. X{@Code "@Ref strunk79"}.
  1038. X@PP
  1039. XIt might seem that if we refer to the @Code strunk79 reference twice,
  1040. Xtwo copies will be sent to the reference list and it will appear
  1041. Xtwice.  However, when more than one sorted galley with the same key is sent
  1042. Xto the same place, only one of them is printed (Section {@NumberOf galleys});
  1043. Xso provided that sorted galleys are used there is no problem.
  1044. X@End @Section
  1045. END_OF_FILE
  1046.   if test 8311 -ne `wc -c <'lout/doc/tr.lout/ch4.05'`; then
  1047.     echo shar: \"'lout/doc/tr.lout/ch4.05'\" unpacked with wrong size!
  1048.   fi
  1049.   # end of 'lout/doc/tr.lout/ch4.05'
  1050. fi
  1051. if test -f 'lout/doc/tr.lout/setup' -a "${1}" != "-c" ; then 
  1052.   echo shar: Will not clobber existing file \"'lout/doc/tr.lout/setup'\"
  1053. else
  1054.   echo shar: Extracting \"'lout/doc/tr.lout/setup'\" \(8555 characters\)
  1055.   sed "s/^X//" >'lout/doc/tr.lout/setup' <<'END_OF_FILE'
  1056. X
  1057. X######################################################
  1058. X#                                                    #
  1059. X#  Lout setup file for producing the user manual.    #
  1060. X#                                                    #
  1061. X#  Jeffrey H. Kingston                               #
  1062. X#  20 June 1991                                      #
  1063. X#  22 December 1991                                  #
  1064. X#                                                    #
  1065. X######################################################
  1066. X
  1067. X@SysInclude { ft  }
  1068. X@SysInclude { dl  }
  1069. X@SysInclude { eq  }
  1070. X@SysInclude { fig }
  1071. X@SysInclude { tab }
  1072. X
  1073. X
  1074. X   def "->" { {Symbol Base} @Font "\256" } #174 decimal
  1075. X   def "=>" { {Symbol Base} @Font "\336" } #222 decimal
  1076. X   macro @JP    { /0.5v  }
  1077. X
  1078. X   def @Code right x
  1079. X   { { Helvetica Base -1p } @Font lines @Break x }
  1080. X
  1081. X   macro @JL { //1vx }
  1082. X
  1083. X   ###################################################
  1084. X   #                                                 #
  1085. X   #  Lout keywords.                                 #
  1086. X   #                                                 #
  1087. X   ###################################################
  1088. X
  1089. X   def @@Begin             { @Code "@Begin"             }
  1090. X   def @@Break             { @Code "@Break"             }
  1091. X   def @@Case              { @Code "@Case"              }
  1092. X   def @@Database          { @Code "@Database"          }
  1093. X   def @@End               { @Code "@End"               }
  1094. X   def @@Font              { @Code "@Font"              }
  1095. X   def @@Galley            { @Code "@Galley"            }
  1096. X   def @@Graphic           { @Code "@Graphic"           }
  1097. X   def @@HAdjust           { @Code "@HAdjust"           }
  1098. X   def @@HContract         { @Code "@HContract"         }
  1099. X   def @@HExpand           { @Code "@HExpand"           }
  1100. X   def @@HScale            { @Code "@HScale"            }
  1101. X   def @@High              { @Code "@High"              }
  1102. X   def @@Include           { @Code "@Include"           }
  1103. X   def @@IncludeGraphic    { @Code "@IncludeGraphic"    }
  1104. X   def @@Key               { @Code "@Key"               }
  1105. X   def @@LClos             { @Code "@LClos"             }
  1106. X   def @@LEnv              { @Code "@LEnv"              }
  1107. X   def @@LInput            { @Code "@LInput"            }
  1108. X   def @@LVis              { @Code "@LVis"              }
  1109. X   def @@Moment            { @Code "@Moment"            }
  1110. X   def @@Next              { @Code "@Next"              }
  1111. X   def @@Null              { @Code "@Null"              }
  1112. X   def @@OneCol            { @Code "@OneCol"            }
  1113. X   def @@OneRow            { @Code "@OneRow"            }
  1114. X   def @@Open              { @Code "@Open"              }
  1115. X   def @@PAdjust           { @Code "@PAdjust"           }
  1116. X   def @@PrependGraphic    { @Code "@PrependGraphic"    }
  1117. X   def @@Rotate            { @Code "@Rotate"            }
  1118. X   def @@Scale             { @Code "@Scale"             }
  1119. X   def @@Space             { @Code "@Space"             }
  1120. X   def @@SysDatabase       { @Code "@SysDatabase"       }
  1121. X   def @@SysInclude        { @Code "@SysInclude"        }
  1122. X   def @@SysIncludeGraphic { @Code "@SysIncludeGraphic" }
  1123. X   def @@SysPrependGraphic { @Code "@SysPrependGraphic" }
  1124. X   def @@Tag               { @Code "@Tag"               }
  1125. X   def @@Tagged            { @Code "@Tagged"            }
  1126. X   def @@Use               { @Code "@Use"               }
  1127. X   def @@VAdjust           { @Code "@VAdjust"           }
  1128. X   def @@VContract         { @Code "@VContract"         }
  1129. X   def @@VExpand           { @Code "@VExpand"           }
  1130. X   def @@VScale            { @Code "@VScale"            }
  1131. X   def @@Yield             { @Code "@Yield"             }
  1132. X   def @@Wide              { @Code "@Wide"              }
  1133. X
  1134. X
  1135. X   ###################################################
  1136. X   #                                                 #
  1137. X   #  Miscellaneous, mostly graphical definitions.   #
  1138. X   #                                                 #
  1139. X   ###################################################
  1140. X
  1141. X   def @TeX { T{ /0.2fo E}X }
  1142. X
  1143. X   export sp sb
  1144. X   def @Equation
  1145. X      body x
  1146. X   @Begin
  1147. X
  1148. X      def sp left x right y { @OneRow { | "-2p" @Font y ^/0.5fk x } }
  1149. X      def sb left x right y { @OneRow { x ^/0.5fk | "-2p" @Font y } }
  1150. X
  1151. X      Slope @Font x
  1152. X
  1153. X   @End @Equation
  1154. X
  1155. X   def @Super
  1156. X      left x
  1157. X      right y
  1158. X   { @OneRow { | -2p @Font y ^/0.5fk x }
  1159. X   }
  1160. X
  1161. X   def @NineSquare
  1162. X      right x
  1163. X   {
  1164. X      def @Three { x |0.2i x |0.2i x }
  1165. X
  1166. X      @Three /0.2i @Three /0.2i @Three
  1167. X   }
  1168. X
  1169. X   def @Leaders
  1170. X   { ..   @Leaders
  1171. X   }
  1172. X
  1173. X   def @HLine
  1174. X   {
  1175. X    { 0 0 moveto xsize 0 lineto stroke } @Graphic {}
  1176. X   }
  1177. X
  1178. X   def @VDashLine
  1179. X      right length
  1180. X   {
  1181. X      length @High {
  1182. X    { 0 0 moveto 0 ysize lineto [ 3 pt ] 0 setdash stroke } @Graphic {}
  1183. X      }
  1184. X   }
  1185. X
  1186. X   def @LBox
  1187. X      right offset
  1188. X   {  @HContract @VContract
  1189. X      {
  1190. X        {  //0.2c
  1191. X           0.6c @High 1.2c @Wide
  1192. X           { 0 0 moveto xsize 0 lineto
  1193. X         xsize ysize lineto 0 ysize lineto closepath
  1194. X         gsave 0.9 setgray fill grestore stroke }
  1195. X           @Graphic {}
  1196. X        }
  1197. X        ||offset @VDashLine 1c
  1198. X      }
  1199. X   }
  1200. X
  1201. X   def @Arrow
  1202. X      right length
  1203. X   {  @OneCol @OneRow
  1204. X      {
  1205. X       30d @Rotate {0.12c @Wide @HLine}
  1206. X       //
  1207. X       length @Wide @HLine
  1208. X       //
  1209. X       "-30d" @Rotate {0.12c @Wide @HLine}
  1210. X      }
  1211. X   }
  1212. X
  1213. X   def @DoubleArrow
  1214. X      right length
  1215. X   {  @OneCol @OneRow
  1216. X      { 
  1217. X         & 180d @Rotate @Arrow length
  1218. X         |0io @Arrow length
  1219. X      }
  1220. X   }
  1221. X
  1222. X   def @Put
  1223. X     left coord
  1224. X     right x
  1225. X   { @OneCol @OneRow
  1226. X     { coord / | @OneCol @OneRow x
  1227. X     }
  1228. X   }
  1229. X   
  1230. X   macro @At { //0io }
  1231. X
  1232. X
  1233. X   ###################################################
  1234. X   #                                                 #
  1235. X   #  Interpolated example documents.                #
  1236. X   #                                                 #
  1237. X   ###################################################
  1238. X
  1239. X   def @LittleEndRunPlace { @Galley }
  1240. X   def @LittleEndRun
  1241. X      force into { @LittleEndRunPlace&&preceding }
  1242. X   {}
  1243. X
  1244. X   def @LittleTextPlace { @Galley }
  1245. X   def @LittleText into { @LittleTextPlace&&preceding }
  1246. X      right x
  1247. X   { x
  1248. X   }
  1249. X
  1250. X   def @LittleFootPlace { @Galley }
  1251. X   def @LittleFootNote into { @LittleFootPlace&&following }
  1252. X      right x
  1253. X   { x
  1254. X   }
  1255. X
  1256. X   def @LittlePageColumn
  1257. X      right x
  1258. X   {
  1259. X        9px @Break 8p @Font
  1260. X        2.8c @Wide x
  1261. X   }
  1262. X
  1263. X   def @LittlePage
  1264. X      right x
  1265. X   {
  1266. X      @HContract @VContract {
  1267. X        { 0 0 moveto xsize 0 lineto xsize ysize lineto
  1268. X          0 ysize lineto closepath stroke } @Graphic
  1269. X        {  //0.3c ||0.3c
  1270. X           9px @Break 8p @Font
  1271. X           2.8c @Wide 3.8c @High x
  1272. X           ||0.3c //0.3c
  1273. X        }
  1274. X      }
  1275. X   }
  1276. X
  1277. X   def @LittleFootSect
  1278. X   {  1c @Wide @HLine
  1279. X      //0.3v @LittleFootPlace ||0.5c
  1280. X   }
  1281. X
  1282. X   def @LittlePageList
  1283. X     right @PageNum
  1284. X   {
  1285. X      @LittlePage { # |0.5rt @PageNum //0.8v
  1286. X        //0.3v @LittleTextPlace
  1287. X        //1rt @LittleFootSect
  1288. X         }
  1289. X      //
  1290. X      @LittlePageList @Next @PageNum
  1291. X   }
  1292. X
  1293. X   def @LittleDocument
  1294. X   {  @LittlePage
  1295. X      {  @LittleTextPlace
  1296. X         //1rt @LittleFootSect
  1297. X      }
  1298. X      // @LittlePageList 2
  1299. X      // @LittleEndRunPlace
  1300. X   }
  1301. X        
  1302. X   def @ShowMarks
  1303. X      named linewidth  { 0.015 cm }
  1304. X      named linestyle  { dashed   }
  1305. X      named dashlength { 0.15 cm  }
  1306. X      named paint      { light    }
  1307. X      right x
  1308. X   {
  1309. X      @HContract @VContract @Fig
  1310. X      {   @Box margin { 0c } linewidth { linewidth } paint { paint }
  1311. X      {   @Figure
  1312. X         shape { -0.3 cm ymark
  1313. X             {xsize ymark} ++ {0.3 cm 0}  []
  1314. X             xmark -0.3 cm
  1315. X             {xmark ysize} ++ {0 0.3 cm}
  1316. X               }
  1317. X         linewidth { linewidth }
  1318. X         linestyle { linestyle }
  1319. X         dashlength { dashlength }
  1320. X          x
  1321. X      }
  1322. X
  1323. X      }
  1324. X   }
  1325. X
  1326. X   def @ShowVMark
  1327. X      named linewidth  { 0.015 cm }
  1328. X      named linestyle  { dashed   }
  1329. X      named dashlength { 0.15 cm  }
  1330. X      named paint      { light    }
  1331. X      right x
  1332. X   {
  1333. X      @Fig
  1334. X      {   
  1335. X     @Figure
  1336. X         shape {
  1337. X             xmark -0.3 cm
  1338. X             {xmark ysize} ++ {0 0.3 cm}
  1339. X               }
  1340. X         linewidth { linewidth }
  1341. X         linestyle { linestyle }
  1342. X         dashlength { dashlength }
  1343. X     x
  1344. X      }
  1345. X   }
  1346. X
  1347. X   def @Strange
  1348. X       named @Format right @Val { [@Val] }
  1349. X       right x
  1350. X   {   @Format x
  1351. X   }
  1352. X
  1353. X   def @Box right x
  1354. X   {
  1355. X     "0 0 moveto xsize 0 lineto xsize ysize lineto 0 ysize lineto closepath stroke"
  1356. X     @Graphic x
  1357. X   }
  1358. X
  1359. X   def @GreyBox right x
  1360. X   {
  1361. X     "0 0 moveto xsize 0 lineto xsize ysize lineto 0 ysize lineto closepath 0.8 setgray fill"
  1362. X     @Graphic x
  1363. X   }
  1364. X
  1365. X@Use { @DocumentLayout
  1366. X  @MakeIndex        { Yes                  }
  1367. X  @TableOfContents  { Yes                  }
  1368. X  @AppendixGap      { 1.10b                }
  1369. X  @BookTitleFormat  { {Bold 2.0f} @Font {//2.0f @Title //0.5f} }
  1370. X}
  1371. X
  1372. X@SysDatabase @Reference { loutrefs }
  1373. END_OF_FILE
  1374.   if test 8555 -ne `wc -c <'lout/doc/tr.lout/setup'`; then
  1375.     echo shar: \"'lout/doc/tr.lout/setup'\" unpacked with wrong size!
  1376.   fi
  1377.   # end of 'lout/doc/tr.lout/setup'
  1378. fi
  1379. if test -f 'lout/z07.c' -a "${1}" != "-c" ; then 
  1380.   echo shar: Will not clobber existing file \"'lout/z07.c'\"
  1381. else
  1382.   echo shar: Extracting \"'lout/z07.c'\" \(8502 characters\)
  1383.   sed "s/^X//" >'lout/z07.c' <<'END_OF_FILE'
  1384. X/*@z07.c:Object Service:CopyObject(), DisposeObject()@************************/
  1385. X/*                                                                           */
  1386. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.03)       */
  1387. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1388. X/*                                                                           */
  1389. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1390. X/*  Basser Department of Computer Science                                    */
  1391. X/*  The University of Sydney 2006                                            */
  1392. X/*  AUSTRALIA                                                                */
  1393. X/*                                                                           */
  1394. X/*  This program is free software; you can redistribute it and/or modify     */
  1395. X/*  it under the terms of the GNU General Public License as published by     */
  1396. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1397. X/*  any later version.                                                       */
  1398. X/*                                                                           */
  1399. X/*  This program is distributed in the hope that it will be useful,          */
  1400. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1401. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1402. X/*  GNU General Public License for more details.                             */
  1403. X/*                                                                           */
  1404. X/*  You should have received a copy of the GNU General Public License        */
  1405. X/*  along with this program; if not, write to the Free Software              */
  1406. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1407. X/*                                                                           */
  1408. X/*  FILE:         z07.c                                                      */
  1409. X/*  MODULE:       Object Service                                             */
  1410. X/*  EXTERNS:      MakeWord(), DisposeObject(), CopyObject(),                 */
  1411. X/*                SplitIsDefinite()                                          */
  1412. X/*                                                                           */
  1413. X/*****************************************************************************/
  1414. X#include "externs"
  1415. X
  1416. X
  1417. X/*****************************************************************************/
  1418. X/*                                                                           */
  1419. X/*  OBJECT MakeWord(str, pos)                                                */
  1420. X/*  OBJECT MakeWordTwo(str1, str2, pos)                                      */
  1421. X/*                                                                           */
  1422. X/*  Return an unsized WORD with the given string or concatenation of         */
  1423. X/*  strings, and the given filepos.                                          */
  1424. X/*                                                                           */
  1425. X/*****************************************************************************/
  1426. X
  1427. XOBJECT MakeWord(str, pos)
  1428. Xunsigned char *str;  FILE_POS *pos;
  1429. X{ OBJECT res = NewWord(strlen(str), pos);
  1430. X  strcpy( string(res), str );
  1431. X  FposCopy(fpos(res), *pos);
  1432. X  debug2(DOS, DD, "MakeWord(%s) returning %s", str, EchoObject(null, res));
  1433. X  return res;
  1434. X} /* end MakeWord */
  1435. X
  1436. XOBJECT MakeWordTwo(str1, str2, pos)
  1437. Xunsigned char *str1, *str2;  FILE_POS *pos;
  1438. X{ int len1 = strlen(str1);
  1439. X  int len2 = strlen(str2);
  1440. X  OBJECT res = NewWord(len1 + len2, pos);
  1441. X  strcpy( string(res), str1 );
  1442. X  strcpy( &string(res)[len1], str2 );
  1443. X  FposCopy(fpos(res), *pos);
  1444. X  debug4(DOS, DD, "MakeWordTwo(%s, %s, %s) returning %s",
  1445. X    str1, str2, EchoFilePos(pos), EchoObject(null, res));
  1446. X  return res;
  1447. X} /* end MakeWordTwo */
  1448. X
  1449. X
  1450. X/*****************************************************************************/
  1451. X/*                                                                           */
  1452. X/*  DisposeObject(x)                                                         */
  1453. X/*                                                                           */
  1454. X/*  Dispose object x.  If some of x's children are shared with other         */
  1455. X/*  parents, those children are left intact.                                 */
  1456. X/*                                                                           */
  1457. X/*****************************************************************************/
  1458. X
  1459. XDisposeObject(x)
  1460. XOBJECT x;
  1461. X{ debug2(DOS,D,"[DisposeObject( %d ), type = %s, x =", (int) x, Image(type(x)));
  1462. X  ifdebug(DOS, DD, EchoObject(stderr, x));
  1463. X  assert( Up(x) == x, "DisposeObject: x has a parent!" );
  1464. X  while( Down(x) != x )  DisposeChild(Down(x));
  1465. X  Dispose(x);
  1466. X  debug0(DOS, D, "]DisposeObject returning.");
  1467. X} /* end DisposeObject */
  1468. X
  1469. X
  1470. X/*@@**************************************************************************/
  1471. X/*                                                                           */
  1472. X/*  OBJECT CopyObject(x, pos)                                                */
  1473. X/*                                                                           */
  1474. X/*  Make a copy of unsized object x, setting all file positions to *pos.     */
  1475. X/*                                                                           */
  1476. X/*****************************************************************************/
  1477. X
  1478. XOBJECT CopyObject(x, pos)
  1479. XOBJECT x;  FILE_POS *pos;
  1480. X{ OBJECT y, link, res, tmp;
  1481. X
  1482. X  debug2(DOS, DD, "CopyObject(%s,%s)", EchoObject(null, x), EchoFilePos(pos));
  1483. X  switch( type(x) )
  1484. X  {
  1485. X
  1486. X    case WORD:
  1487. X    
  1488. X      res = NewWord(strlen(string(x)), pos);
  1489. X      strcpy(string(res), string(x));
  1490. X      break;
  1491. X
  1492. X
  1493. X    case GAP_OBJ:
  1494. X    
  1495. X      res = New(type(x));
  1496. X      mark(gap(res)) = mark(gap(x));
  1497. X      join(gap(res)) = join(gap(x));
  1498. X      if( Down(x) != x )
  1499. X      {    Child(y, Down(x));
  1500. X    tmp = CopyObject(y, pos);
  1501. X    Link(res, tmp);
  1502. X      }
  1503. X      else
  1504. X      {    hspace(res) = hspace(x);
  1505. X    vspace(res) = vspace(x);
  1506. X      }
  1507. X      break;
  1508. X
  1509. X
  1510. X    case HEAD:
  1511. X    case NULL_CLOS:
  1512. X    case CROSS:
  1513. X    case ONE_COL:
  1514. X    case ONE_ROW:
  1515. X    case WIDE:
  1516. X    case HIGH:
  1517. X    case HSCALE:
  1518. X    case VSCALE:
  1519. X    case SCALE:
  1520. X    case HCONTRACT:
  1521. X    case VCONTRACT:
  1522. X    case HEXPAND:
  1523. X    case VEXPAND:
  1524. X    case PADJUST:
  1525. X    case HADJUST:
  1526. X    case VADJUST:
  1527. X    case ROTATE:
  1528. X    case CASE:
  1529. X    case YIELD:
  1530. X    case FONT:
  1531. X    case SPACE:
  1532. X    case BREAK:
  1533. X    case NEXT:
  1534. X    case OPEN:
  1535. X    case TAGGED:
  1536. X    case INCGRAPHIC:
  1537. X    case SINCGRAPHIC:
  1538. X    case GRAPHIC:
  1539. X    case VCAT:
  1540. X    case HCAT:
  1541. X    case ACAT:
  1542. X    
  1543. X      res = New(type(x));
  1544. X      for( link = Down(x);  link != x;  link = NextDown(link) )
  1545. X      {    Child(y, link);
  1546. X    tmp = CopyObject(y, pos);
  1547. X    Link(res, tmp);
  1548. X      }
  1549. X      break;
  1550. X
  1551. X
  1552. X    case ENV:
  1553. X    
  1554. X      res = x;  /* don't copy environments */
  1555. X      break;
  1556. X
  1557. X
  1558. X    case PAR:
  1559. X    
  1560. X      res = New(PAR);
  1561. X      actual(res) = actual(x);
  1562. X      assert( Down(x) != x, "CopyObject: PAR child!" );
  1563. X      Child(y, Down(x));
  1564. X      tmp = CopyObject(y, pos);
  1565. X      Link(res, tmp);
  1566. X      break;
  1567. X
  1568. X
  1569. X    case CLOSURE:
  1570. X    
  1571. X      res = New(type(x));
  1572. X      for( link = Down(x);  link != x;  link = NextDown(link) )
  1573. X      {    Child(y, link);
  1574. X    assert( type(y) != CLOSURE, "CopyObject: CLOSURE!" );
  1575. X    tmp = CopyObject(y, pos);
  1576. X    Link(res, tmp);
  1577. X      }
  1578. X      actual(res) = actual(x);
  1579. X      StyleCopy(save_style(res), save_style(x));
  1580. X      break;
  1581. X
  1582. X
  1583. X    default:
  1584. X    
  1585. X      Error(INTERN, pos, "CopyObject: %s found", Image(type(x)));
  1586. X          break;
  1587. X
  1588. X  } /* end switch */
  1589. X  if( pos == no_fpos )  FposCopy(fpos(res), fpos(x));
  1590. X  else FposCopy(fpos(res), *pos);
  1591. X  debug1(DOS, DD, "CopyObject returning %s", EchoObject(null, res));
  1592. X  return res;
  1593. X} /* end CopyObject */
  1594. X
  1595. X
  1596. X/*****************************************************************************/
  1597. X/*                                                                           */
  1598. X/*  BOOLEAN SplitIsDefinite(x)                                               */
  1599. X/*                                                                           */
  1600. X/*  Return TRUE if x is a definite SPLIT object (both children definite)     */
  1601. X/*                                                                           */
  1602. X/*****************************************************************************/
  1603. X
  1604. XBOOLEAN SplitIsDefinite(x)
  1605. XOBJECT x;
  1606. X{ OBJECT y1, y2;
  1607. X  assert( type(x) == SPLIT, "SplitIsDefinite: x not a SPLIT!" );
  1608. X  Child(y1, DownDim(x, COL));
  1609. X  Child(y2, DownDim(x, ROW));
  1610. X  return is_definite(type(y1)) && is_definite(type(y2));
  1611. X}
  1612. END_OF_FILE
  1613.   if test 8502 -ne `wc -c <'lout/z07.c'`; then
  1614.     echo shar: \"'lout/z07.c'\" unpacked with wrong size!
  1615.   fi
  1616.   # end of 'lout/z07.c'
  1617. fi
  1618. if test -f 'lout/z11.c' -a "${1}" != "-c" ; then 
  1619.   echo shar: Will not clobber existing file \"'lout/z11.c'\"
  1620. else
  1621.   echo shar: Extracting \"'lout/z11.c'\" \(8495 characters\)
  1622.   sed "s/^X//" >'lout/z11.c' <<'END_OF_FILE'
  1623. X/*@z11.c:Style Service:SpaceChange(), BreakChange(), EchoStyle()@*************/
  1624. X/*                                                                           */
  1625. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.03)       */
  1626. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1627. X/*                                                                           */
  1628. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1629. X/*  Basser Department of Computer Science                                    */
  1630. X/*  The University of Sydney 2006                                            */
  1631. X/*  AUSTRALIA                                                                */
  1632. X/*                                                                           */
  1633. X/*  This program is free software; you can redistribute it and/or modify     */
  1634. X/*  it under the terms of the GNU General Public License as published by     */
  1635. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1636. X/*  any later version.                                                       */
  1637. X/*                                                                           */
  1638. X/*  This program is distributed in the hope that it will be useful,          */
  1639. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1640. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1641. X/*  GNU General Public License for more details.                             */
  1642. X/*                                                                           */
  1643. X/*  You should have received a copy of the GNU General Public License        */
  1644. X/*  along with this program; if not, write to the Free Software              */
  1645. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1646. X/*                                                                           */
  1647. X/*  FILE:         z11.c                                                      */
  1648. X/*  MODULE:       Style Service                                              */
  1649. X/*  EXTERNS:      SpaceChange(), BreakChange(), EchoStyle()                  */
  1650. X/*                                                                           */
  1651. X/*****************************************************************************/
  1652. X#include "externs"
  1653. X
  1654. X
  1655. X/*****************************************************************************/
  1656. X/*                                                                           */
  1657. X/*  SpaceChange(style, x)                                                    */
  1658. X/*                                                                           */
  1659. X/*  Change the current break style as indicated by object x.                 */
  1660. X/*                                                                           */
  1661. X/*****************************************************************************/
  1662. X
  1663. XSpaceChange(style, x)
  1664. XSTYLE *style;  OBJECT x;
  1665. X{ GAP res_gap;  unsigned gap_inc;
  1666. X  debug2(DSS, D, "SpaceChange(%s, %s)", EchoStyle(style), EchoObject(null, x));
  1667. X  if( type(x) != WORD )
  1668. X  { Error(WARN, &fpos(x), "invalid left parameter to %s", KW_SPACE);
  1669. X  }
  1670. X  else
  1671. X  { GetGap(x, style, &res_gap, &gap_inc);
  1672. X    if( gap_inc != ABS && units(res_gap) != units(space_gap(*style)) )
  1673. X    { Error(WARN, &fpos(x), "space %s incompatible with enclosing", string(x));
  1674. X    }
  1675. X    else
  1676. X    { units(space_gap(*style)) = units(res_gap);
  1677. X      mode(space_gap(*style))  = mode(res_gap);
  1678. X      width(space_gap(*style)) = gap_inc == ABS ? width(res_gap) :
  1679. X         gap_inc == INC ? width(space_gap(*style)) + width(res_gap) :
  1680. X         max(width(space_gap(*style)) - width(res_gap), 0);
  1681. X    }
  1682. X  }
  1683. X  debug1(DSS, D, "SpaceChange returning %s", EchoStyle(style));
  1684. X} /* end SpaceChange */
  1685. X
  1686. X
  1687. X/*****************************************************************************/
  1688. X/*                                                                           */
  1689. X/*  BreakChange(style, x)                                                    */
  1690. X/*                                                                           */
  1691. X/*  Change the current break style as indicated by object x.                 */
  1692. X/*                                                                           */
  1693. X/*****************************************************************************/
  1694. X
  1695. Xstatic changebreak(style, x)
  1696. XSTYLE *style;  OBJECT x;
  1697. X{ int i; GAP res_gap;  unsigned gap_inc;
  1698. X  if( string(x)[0] >= 'a' && string(x)[0] <= 'z' )
  1699. X  {
  1700. X    /* should be a new break style option */
  1701. X    if( strcmp(string(x), "hyphen") == 0 )
  1702. X    hyph_style(*style) = HYPH_ON;
  1703. X    else if( strcmp(string(x), "nohyphen") == 0 )
  1704. X    hyph_style(*style) = HYPH_OFF;
  1705. X    else if( strcmp(string(x), "adjust") == 0 )
  1706. X    fill_style(*style) = FILL_ON, display_style(*style) = DISPLAY_ADJUST;
  1707. X    else if( strcmp(string(x), "outdent") == 0 )
  1708. X    fill_style(*style) = FILL_ON, display_style(*style) = DISPLAY_OUTDENT;
  1709. X    else if( strcmp(string(x), "ragged") == 0 )
  1710. X    fill_style(*style) = FILL_ON, display_style(*style) = DISPLAY_LEFT;
  1711. X    else if( strcmp(string(x), "cragged") == 0 )
  1712. X    fill_style(*style) = FILL_ON, display_style(*style) = DISPLAY_CENTRE;
  1713. X    else if( strcmp(string(x), "ragged") == 0 )
  1714. X    fill_style(*style) = FILL_ON, display_style(*style) = DISPLAY_RIGHT;
  1715. X    else if( strcmp(string(x), "lines") == 0 )
  1716. X    fill_style(*style) = FILL_OFF, display_style(*style) = DISPLAY_LEFT;
  1717. X    else if( strcmp(string(x), "clines") == 0 )
  1718. X    fill_style(*style) = FILL_OFF, display_style(*style) = DISPLAY_CENTRE;
  1719. X    else if( strcmp(string(x), "rlines") == 0 )
  1720. X    fill_style(*style) = FILL_OFF, display_style(*style) = DISPLAY_RIGHT;
  1721. X    else Error(WARN, &fpos(x), "invalid %s option %s", KW_BREAK, string(x));
  1722. X  }
  1723. X  else
  1724. X  {
  1725. X    /* should be a new inter-line gap */
  1726. X    GetGap(x, style, &res_gap, &gap_inc);
  1727. X    if( gap_inc != ABS && units(res_gap) != units(line_gap(*style)) )
  1728. X    { Error(WARN, &fpos(x),
  1729. X            "line spacing %s incompatible with enclosing", string(x));
  1730. X    }
  1731. X    else
  1732. X    { units(line_gap(*style)) = units(res_gap);
  1733. X      mode(line_gap(*style))  = mode(res_gap);
  1734. X      width(line_gap(*style)) = gap_inc == ABS ? width(res_gap) :
  1735. X    gap_inc == INC ? width(line_gap(*style)) + width(res_gap) :
  1736. X    max(width(line_gap(*style)) - width(res_gap), 0);
  1737. X    }
  1738. X  }
  1739. X} /* end changebreak */
  1740. X
  1741. XBreakChange(style, x)
  1742. XSTYLE *style;  OBJECT x;
  1743. X{ OBJECT link, y;
  1744. X  debug2(DSS, D, "BreakChange(%s, %s)", EchoStyle(style), EchoObject(null, x));
  1745. X  switch( type(x) )
  1746. X  {
  1747. X    case WORD:
  1748. X    
  1749. X      changebreak(style, x);
  1750. X      break;
  1751. X
  1752. X
  1753. X    case ACAT:
  1754. X    
  1755. X      for( link = Down(x);  link != x;  link = NextDown(link) )
  1756. X      {    Child(y, link);
  1757. X    if( type(y) == GAP_OBJ )  continue;
  1758. X    else if( type(y) == WORD )  changebreak(style, y);
  1759. X    else Error(WARN, &fpos(x), "invalid left parameter of %s", KW_BREAK);
  1760. X      }
  1761. X      break;
  1762. X
  1763. X
  1764. X    default:
  1765. X    
  1766. X      Error(WARN, &fpos(x), "invalid left parameter of %s", KW_BREAK);
  1767. X      break;
  1768. X
  1769. X  }
  1770. X  debug1(DSS, D, "BreakChange returning %s", EchoStyle(style));
  1771. X} /* end BreakChange */
  1772. X
  1773. X
  1774. X#if DEBUG_ON
  1775. X/*****************************************************************************/
  1776. X/*                                                                           */
  1777. X/*  unsigned char *EchoStyle(style)                                          */
  1778. X/*                                                                           */
  1779. X/*  Returns a string showing the value of the style.                         */
  1780. X/*                                                                           */
  1781. X/*****************************************************************************/
  1782. X
  1783. Xunsigned char *EchoStyle(style)
  1784. XSTYLE *style;
  1785. X{ char buff1[100], buff2[100], buff3[100], buff4[100];
  1786. X  static char res[100];
  1787. X  static char *hyphwords[] = { "hyph_undef", "hyph_off", "hyph_on" };
  1788. X  static char *fillwords[] = { "fill_undef", "fill_off", "fill_on" };
  1789. X  static char *displaywords[] = { "undef", "adjust", "outdent", "left",
  1790. X                 "centre", "right", "do" };
  1791. X  strcpy(buff1, EchoCatOp(VCAT,mark(line_gap(*style)),join(line_gap(*style))));
  1792. X  strcpy(buff2, EchoGap(&line_gap(*style)));
  1793. X  strcpy(buff3, EchoGap(&space_gap(*style)));
  1794. X  sprintf(buff4, "%s:%s:%s",
  1795. X    hyph_style(*style) < 3 ? hyphwords[hyph_style(*style)] : "?",
  1796. X    fill_style(*style) < 3 ? fillwords[fill_style(*style)] : "?",
  1797. X    display_style(*style) < 7 ? displaywords[display_style(*style)] : "?");
  1798. X  sprintf(res, "[%s%s, %d (%s), %s]", buff1, buff2, font(*style), buff3, buff4);
  1799. X  return (unsigned char *) res;
  1800. X} /* end EchoStyle */
  1801. X#endif
  1802. END_OF_FILE
  1803.   if test 8495 -ne `wc -c <'lout/z11.c'`; then
  1804.     echo shar: \"'lout/z11.c'\" unpacked with wrong size!
  1805.   fi
  1806.   # end of 'lout/z11.c'
  1807. fi
  1808. if test -f 'lout/z28.c' -a "${1}" != "-c" ; then 
  1809.   echo shar: Will not clobber existing file \"'lout/z28.c'\"
  1810. else
  1811.   echo shar: Extracting \"'lout/z28.c'\" \(8137 characters\)
  1812.   sed "s/^X//" >'lout/z28.c' <<'END_OF_FILE'
  1813. X/*@z28.c:Error Service:ErrorInit(), Error(), ErrorSeen()@*********************/
  1814. X/*                                                                           */
  1815. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.03)       */
  1816. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  1817. X/*                                                                           */
  1818. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  1819. X/*  Basser Department of Computer Science                                    */
  1820. X/*  The University of Sydney 2006                                            */
  1821. X/*  AUSTRALIA                                                                */
  1822. X/*                                                                           */
  1823. X/*  This program is free software; you can redistribute it and/or modify     */
  1824. X/*  it under the terms of the GNU General Public License as published by     */
  1825. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  1826. X/*  any later version.                                                       */
  1827. X/*                                                                           */
  1828. X/*  This program is distributed in the hope that it will be useful,          */
  1829. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  1830. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  1831. X/*  GNU General Public License for more details.                             */
  1832. X/*                                                                           */
  1833. X/*  You should have received a copy of the GNU General Public License        */
  1834. X/*  along with this program; if not, write to the Free Software              */
  1835. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  1836. X/*                                                                           */
  1837. X/*  FILE:         z28.c                                                      */
  1838. X/*  MODULE:       Error Service                                              */
  1839. X/*  EXTERNS:      ErrorInit(), Error(), ErrorSeen()                          */
  1840. X/*                                                                           */
  1841. X/*****************************************************************************/
  1842. X#include "externs"
  1843. X
  1844. X#define    MAX_BLOCKS     20        /* max number of error blocks        */
  1845. X#define    MAX_ERRORS     20        /* max number of held error messages */
  1846. X
  1847. Xstatic BOOLEAN    print_block[MAX_BLOCKS];    /* TRUE if print this block  */
  1848. Xstatic int    start_block[MAX_BLOCKS];    /* first message of block    */
  1849. Xstatic unsigned char message[MAX_ERRORS][MAX_LINE]; /* the error messages    */
  1850. Xstatic FILE    *fp = NULL;            /* file pointer of log file  */
  1851. Xstatic BOOLEAN    error_seen = FALSE;        /* TRUE after first error    */
  1852. Xstatic int    block_top = 0;            /* first free error block    */
  1853. Xstatic int    mess_top = 0;            /* first free error message  */
  1854. X
  1855. X
  1856. X/*****************************************************************************/
  1857. X/*                                                                           */
  1858. X/*  ErrorInit(str)                                                           */
  1859. X/*                                                                           */
  1860. X/*  Open log file str and initialise this module.                            */
  1861. X/*                                                                           */
  1862. X/*****************************************************************************/
  1863. X
  1864. XErrorInit(str)
  1865. Xunsigned char *str;
  1866. X{ if( fp != NULL )
  1867. X    Error(FATAL, no_fpos, "-e argument appears twice in command line");
  1868. X  fp = fopen(str, "w");
  1869. X  if( fp == NULL )
  1870. X    Error(FATAL, no_fpos, "cannot open error file \"%s\"", str);
  1871. X} /* end ErrorInit */
  1872. X
  1873. X
  1874. X/*****************************************************************************/
  1875. X/*                                                                           */
  1876. X/*  BOOLEAN ErrorSeen()                                                      */
  1877. X/*                                                                           */
  1878. X/*  TRUE once an error has been found.                                       */
  1879. X/*                                                                           */
  1880. X/*****************************************************************************/
  1881. X
  1882. XBOOLEAN ErrorSeen()
  1883. X{ return error_seen;
  1884. X} /* end ErrorSeen */
  1885. X
  1886. X
  1887. X/*****************************************************************************/
  1888. X/*                                                                           */
  1889. X/*  EnterErrorBlock(ok_to_print)                                             */
  1890. X/*                                                                           */
  1891. X/*  Start off a new block of error messages.  If ok_to_print, they do not    */
  1892. X/*  need to be held for a later commit.                                      */
  1893. X/*                                                                           */
  1894. X/*****************************************************************************/
  1895. X
  1896. XEnterErrorBlock(ok_to_print)
  1897. XBOOLEAN ok_to_print;
  1898. X{ if( block_top < MAX_BLOCKS )
  1899. X  { print_block[block_top] = ok_to_print;
  1900. X    start_block[block_top] = mess_top;
  1901. X    block_top++;
  1902. X  }
  1903. X  else Error(FATAL, no_fpos, "too many levels of error messages");
  1904. X} /* end EnterErrorBlock */
  1905. X
  1906. X
  1907. X/*@@**************************************************************************/
  1908. X/*                                                                           */
  1909. X/*  LeaveErrorBlock(commit)                                                  */
  1910. X/*                                                                           */
  1911. X/*  Finish off a block or error messages.  If commit is true, print them,    */
  1912. X/*  otherwise discard them.                                                  */
  1913. X/*                                                                           */
  1914. X/*****************************************************************************/
  1915. X
  1916. XLeaveErrorBlock(commit)
  1917. XBOOLEAN commit;
  1918. X{ int i;
  1919. X  assert( block_top > 0, "LeaveErrorBlock: no matching EnterErrorBlock!" );
  1920. X  assert( commit || !print_block[block_top - 1], "LeaveErrorBlock: commit!" );
  1921. X  if( fp == NULL )  fp = stderr;
  1922. X  if( commit )
  1923. X  { for( i = start_block[block_top - 1];  i < mess_top;  i++ )
  1924. X      fputs(message[i], fp);
  1925. X  }
  1926. X  block_top--;
  1927. X  mess_top = start_block[block_top];
  1928. X} /* end LeaveErrorBlock */
  1929. X
  1930. X
  1931. X/*****************************************************************************/
  1932. X/*                                                                           */
  1933. X/*  Error(etype, pos, str, p1, p2, p3, p4, p5, p6)                           */
  1934. X/*                                                                           */
  1935. X/*  Report error of type etype at position *pos in input.                    */
  1936. X/*  The error message is str with parameters p1 - p6.                        */
  1937. X/*                                                                           */
  1938. X/*****************************************************************************/
  1939. X
  1940. X/*VARARGS3*/
  1941. XError(etype, pos, str, p1, p2, p3, p4, p5, p6)
  1942. Xint etype;  FILE_POS *pos;  unsigned char *str, *p1, *p2, *p3, *p4, *p5, *p6;
  1943. X{ unsigned char val[MAX_LINE];
  1944. X  sprintf(val, str, p1, p2, p3, p4, p5, p6);
  1945. X  if( fp == NULL )  fp = stderr;
  1946. X  switch( etype )
  1947. X  {
  1948. X
  1949. X    case INTERN:
  1950. X    
  1951. X      while( block_top > 0 )  LeaveErrorBlock(TRUE);
  1952. X      fprintf(fp, "lout%s internal error: %s\n", EchoFilePos(pos), val);
  1953. X#ifdef DEBUG_ON
  1954. X      abort();
  1955. X#else
  1956. X      exit(1);
  1957. X#endif
  1958. X      break;
  1959. X
  1960. X
  1961. X    case FATAL:
  1962. X    
  1963. X      while( block_top > 0 )  LeaveErrorBlock(TRUE);
  1964. X      fprintf(fp, "lout%s fatal error: %s\n", EchoFilePos(pos), val);
  1965. X      exit(1);
  1966. X      break;
  1967. X
  1968. X
  1969. X    case WARN:
  1970. X    
  1971. X      if( block_top == 0 || print_block[block_top - 1] )
  1972. X    fprintf(fp, "lout%s: %s\n", EchoFilePos(pos), val);
  1973. X      else if( mess_top < MAX_ERRORS )
  1974. X    sprintf(message[mess_top++], "lout%s: %s\n", EchoFilePos(pos), val);
  1975. X      else Error(FATAL, pos, "too many error messages");
  1976. X      error_seen = TRUE;
  1977. X      break;
  1978. X
  1979. X
  1980. X    default:
  1981. X    
  1982. X      Error(INTERN, no_fpos, "invalid error type");
  1983. X      exit(1);
  1984. X      break;
  1985. X
  1986. X  }
  1987. X} /* end Error */
  1988. END_OF_FILE
  1989.   if test 8137 -ne `wc -c <'lout/z28.c'`; then
  1990.     echo shar: \"'lout/z28.c'\" unpacked with wrong size!
  1991.   fi
  1992.   # end of 'lout/z28.c'
  1993. fi
  1994. if test -f 'lout/z35.c' -a "${1}" != "-c" ; then 
  1995.   echo shar: Will not clobber existing file \"'lout/z35.c'\"
  1996. else
  1997.   echo shar: Extracting \"'lout/z35.c'\" \(7660 characters\)
  1998.   sed "s/^X//" >'lout/z35.c' <<'END_OF_FILE'
  1999. X/*@z35.c:Time Keeper: InitTime()@*********************************************/
  2000. X/*                                                                           */
  2001. X/*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.03)       */
  2002. X/*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  2003. X/*                                                                           */
  2004. X/*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  2005. X/*  Basser Department of Computer Science                                    */
  2006. X/*  The University of Sydney 2006                                            */
  2007. X/*  AUSTRALIA                                                                */
  2008. X/*                                                                           */
  2009. X/*  This program is free software; you can redistribute it and/or modify     */
  2010. X/*  it under the terms of the GNU General Public License as published by     */
  2011. X/*  the Free Software Foundation; either version 1, or (at your option)      */
  2012. X/*  any later version.                                                       */
  2013. X/*                                                                           */
  2014. X/*  This program is distributed in the hope that it will be useful,          */
  2015. X/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  2016. X/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  2017. X/*  GNU General Public License for more details.                             */
  2018. X/*                                                                           */
  2019. X/*  You should have received a copy of the GNU General Public License        */
  2020. X/*  along with this program; if not, write to the Free Software              */
  2021. X/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  2022. X/*                                                                           */
  2023. X/*  FILE:         z35.c                                                      */
  2024. X/*  MODULE:       Time Keeper                                                */
  2025. X/*  EXTERNS:      InitTime()                                                 */
  2026. X/*                                                                           */
  2027. X/*****************************************************************************/
  2028. X#include <time.h>
  2029. X#include "externs"
  2030. X
  2031. X#define load(str, typ, encl)                        \
  2032. X  sym = InsertSym(str, typ, no_fpos, DEFAULT_PREC,              \
  2033. X  FALSE, FALSE, 0, encl, MakeWord("", no_fpos));            \
  2034. X  if( typ == NPAR )  visible(sym) = TRUE
  2035. X
  2036. X#define add_par(format, val, sym)                    \
  2037. X  sprintf(buff, format, val);                        \
  2038. X  par = New(PAR);  actual(par) = sym;                    \
  2039. X  Link(current_moment, par);                        \
  2040. X  tmp = MakeWord(buff, no_fpos);                    \
  2041. X  Link(par, tmp);
  2042. X
  2043. Xstatic OBJECT current_moment = nil;
  2044. Xstatic unsigned char time_string[30] = { '\0' };
  2045. X
  2046. X
  2047. X/*****************************************************************************/
  2048. X/*                                                                           */
  2049. X/*  OBJECT MomentSym;                                                        */
  2050. X/*                                                                           */
  2051. X/*  The symbol table entry for the @Moment symbol.                           */
  2052. X/*                                                                           */
  2053. X/*****************************************************************************/
  2054. X
  2055. XOBJECT MomentSym = nil;
  2056. X
  2057. X
  2058. X/*@@**************************************************************************/
  2059. X/*                                                                           */
  2060. X/*  InitTime()                                                               */
  2061. X/*                                                                           */
  2062. X/*  Place a declaration of the @Moment symbol into the symbol table, and     */
  2063. X/*  initialize the value of the object StartMoment.                          */
  2064. X/*                                                                           */
  2065. X/*****************************************************************************/
  2066. X
  2067. XInitTime()
  2068. X{ long raw_time; struct tm *now;
  2069. X  unsigned char buff[20]; OBJECT par, tmp, sym, env;
  2070. X  OBJECT tag, second, minute, hour, weekday,
  2071. X    monthday, yearday, month, year, century, dst;
  2072. X  debug0(DTK, D, "InitTime()");
  2073. X
  2074. X  /* define @Moment symbol with its host of named parameters */
  2075. X  MomentSym = load("@Moment",         LOCAL, StartSym);
  2076. X  tag       = load(KW_TAG,            NPAR,  MomentSym);
  2077. X  second    = load("@Second",         NPAR,  MomentSym);
  2078. X  minute    = load("@Minute",         NPAR,  MomentSym);
  2079. X  hour      = load("@Hour",           NPAR,  MomentSym);
  2080. X  monthday  = load("@Day",            NPAR,  MomentSym);
  2081. X  month     = load("@Month",          NPAR,  MomentSym);
  2082. X  year      = load("@Year",           NPAR,  MomentSym);
  2083. X  century   = load("@Century",        NPAR,  MomentSym);
  2084. X  weekday   = load("@WeekDay",        NPAR,  MomentSym);
  2085. X  yearday   = load("@YearDay",        NPAR,  MomentSym);
  2086. X  dst       = load("@DaylightSaving", NPAR,  MomentSym);
  2087. X
  2088. X  /* get current time and convert to ASCII */
  2089. X  time(&raw_time);
  2090. X  now = localtime(&raw_time);
  2091. X  strcpy(time_string, asctime(now));
  2092. X
  2093. X  /* start of current_moment */
  2094. X  current_moment = New(CLOSURE);
  2095. X  actual(current_moment) = MomentSym;
  2096. X
  2097. X  /* attach its many parameters */
  2098. X  add_par("%s",   KW_NOW,                      tag);
  2099. X  add_par("%d",   now->tm_sec,                 second);
  2100. X  add_par("%d",   now->tm_min,                 minute);
  2101. X  add_par("%d",   now->tm_hour,                hour);
  2102. X  add_par("%d",   now->tm_mday,                monthday);
  2103. X  add_par("%d",   now->tm_mon + 1,             month);
  2104. X  add_par("%.2d", now->tm_year % 100,          year);
  2105. X  add_par("%d",   (now->tm_year+1900) / 100,   century);
  2106. X  add_par("%d",   now->tm_wday + 1,            weekday);
  2107. X  add_par("%d",   now->tm_yday,                yearday);
  2108. X  add_par("%d",   now->tm_isdst,               dst);
  2109. X
  2110. X  /* add a null environment */
  2111. X  env = New(ENV);
  2112. X  AttachEnv(env, current_moment);
  2113. X  debug0(DTK, D, "InitTime() returning.");
  2114. X  debug0(DTK, DD, "current_moment =");
  2115. X  ifdebug(DTK, DD, EchoObject(stderr, current_moment));
  2116. X} /* end InitTime */
  2117. X
  2118. X
  2119. X/*****************************************************************************/
  2120. X/*                                                                           */
  2121. X/*  OBJECT StartMoment()                                                     */
  2122. X/*                                                                           */
  2123. X/*  Returns a copy of the initial time.                                      */
  2124. X/*                                                                           */
  2125. X/*****************************************************************************/
  2126. X
  2127. XOBJECT StartMoment()
  2128. X{ OBJECT res;
  2129. X  debug0(DTK, D, "StartMoment()");
  2130. X  assert(current_moment != nil, "StartMoment: current_moment == nil!");
  2131. X  res = CopyObject(current_moment, no_fpos);
  2132. X  debug0(DTK, D, "StartMoment returning");
  2133. X  ifdebug(DTK, D, EchoObject(stderr, res));
  2134. X  return res;
  2135. X}
  2136. X
  2137. X
  2138. X/*****************************************************************************/
  2139. X/*                                                                           */
  2140. X/*  unsigned char *TimeString()                                              */
  2141. X/*                                                                           */
  2142. X/*  Returns a pointer to a string containing the current time.               */
  2143. X/*                                                                           */
  2144. X/*****************************************************************************/
  2145. X
  2146. Xunsigned char *TimeString()
  2147. X{ return time_string;
  2148. X} /* end TimeString */
  2149. END_OF_FILE
  2150.   if test 7660 -ne `wc -c <'lout/z35.c'`; then
  2151.     echo shar: \"'lout/z35.c'\" unpacked with wrong size!
  2152.   fi
  2153.   # end of 'lout/z35.c'
  2154. fi
  2155. echo shar: End of archive 25 \(of 30\).
  2156. cp /dev/null ark25isdone
  2157. MISSING=""
  2158. 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
  2159.     if test ! -f ark${I}isdone ; then
  2160.     MISSING="${MISSING} ${I}"
  2161.     fi
  2162. done
  2163. if test "${MISSING}" = "" ; then
  2164.     echo You have unpacked all 30 archives.
  2165.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2166. else
  2167.     echo You still must unpack the following archives:
  2168.     echo "        " ${MISSING}
  2169. fi
  2170. exit 0
  2171. exit 0 # Just in case...
  2172.