home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / lout2.lzh / LOUT2 / DOC / TR.LOUT / ch2.06 < prev    next >
Text File  |  1994-01-25  |  10KB  |  264 lines

  1. @Section
  2.    @Title { Galleys and targets }
  3.    @Tag { targets }
  4. @Begin
  5. @PP
  6. The behaviour of galleys and their targets, as described in Section
  7. galley.feature.in.detail @SubIndex { in detail }
  8. targets.in.detail @SubIndex { in detail }
  9. {@NumberOf galleys}, can be summarized in three laws:
  10. @DP
  11. {@I {First Law}}:  The first target is the closest invocation of the
  12. target symbol, either preceding or following the invocation point of the
  13. galley as required, which has sufficient space to receive the first
  14. component;
  15. @DP
  16. {@I {Second Law}}:  Each subsequent target is the closest invocation of
  17. the target symbol, following the previous target and lying within the same
  18. galley, which has sufficient space to receive the first remaining component;
  19. @DP
  20. {@I {Third Law}}:  A receptive symbol that does not receive at least one
  21. component of any galley is replaced by @@Null.
  22. @DP
  23. The terms `closest,' `preceding,' and `following' refer to position in
  24. the final printed document.  This section explains the operation of
  25. these laws in Basser Lout.
  26. @PP
  27. When a galley cannot be fitted into just one target, Lout must find
  28. points in the galley where it can be split in two.  The object lying
  29. between two neighbouring potential split points is called a @I component
  30. component @Index { Components of a galley }
  31. of the galley.  By definition, a component cannot be split.
  32. @PP
  33. To determine the components of a galley, expand all symbols other than
  34. recursive and receptive ones, discard all @@Font, @@Break, and @@Space
  35. symbols, perform paragraph breaking as required, and discard all
  36. redundant braces.  Then view the galley as a sequence of one or more
  37. objects separated by vertical concatenation symbols; these are the
  38. components and split points.  For example, given the definition
  39. @ID @Code {
  40. "def @Section into { @SectionPlace&&preceding }"
  41. "    named @Title {}"
  42. "    right @Body"
  43. "{"
  44. "    15p @Font { @Title //0.7f }"
  45. "    //"
  46. "    @Body"
  47. "}"
  48. }
  49. the galley
  50. @ID @Code {
  51. "@Section"
  52. "    @Title { Introduction }"
  53. "{ This is a subject that really"
  54. "needs no introduction. }"
  55. }
  56. becomes
  57. @ID @Code {
  58. "Introduction"
  59. "//0.7f"
  60. "{}"
  61. "//"
  62. "This is a subject that really needs"
  63. "//1vx"
  64. "no introduction."
  65. }
  66. with four components.  If @Code "@Body" was preceded by @Code "|1.0c" in
  67. the definition, the result would be
  68. @ID @Code {
  69. "Introduction"
  70. "//0.7f"
  71. "{}"
  72. "//"
  73. "|1.0c { This is a subject that really needs //1vx no introduction. }"
  74. }
  75. and now @Code "//1vx" is buried within one component and is not a
  76. potential split point.  In fact, in this case the broken paragraph as
  77. a whole is enclosed in @@OneRow.  This highlights a deficiency of
  78. Basser Lout:  an indented paragraph cannot be split.
  79. @PP
  80. The lines of a paragraph become separate components if the paragraph
  81. occupies an entire component before breaking; otherwise they are
  82. enclosed in a @@OneRow symbol within one component.  The same is true of
  83. incoming components of other galleys.  If a @@Galley symbol occupies an
  84. entire component by the rules above, then the incoming components that
  85. replace it become components of their new home:
  86. @ID @Tab
  87.   @Fmta { @Col @Code A ! @Col lines @Break B ! @Col @Code C }
  88. {
  89. @Rowa
  90.    A {
  91. "An example"
  92. "//0.5c"
  93. "@Galley"
  94. "//0.5c"
  95. "@SomethingList"
  96. }
  97.   B {
  98. ""
  99. @Eq { ==> }
  100. }
  101.    C {
  102. "An example"
  103. "//0.5c"
  104. "Incoming components"
  105. "//0.2c"
  106. "from some other galley"
  107. "//0.5c"
  108. "@SomethingList"
  109. }
  110. }
  111. Otherwise the incoming components are grouped within a @@OneRow symbol
  112. and lie within one component.
  113. @PP
  114. This distinction has a marked effect on the vertical concatenation
  115. b.unit.use @SubIndex { use in @Code "//1.1b" }
  116. symbol {@Code "//1.1b"}, which calls for more space than is available
  117. (Section {@NumberOf concatenation}).  There is no room for this symbol
  118. within any component, so it will force a split and be discarded in that
  119. case.  But it can be promoted to between two components.
  120. @PP
  121. Components may be separated by @Code "/" as well as by {@Code "//"},
  122. giving rise to column mark alignment between adjacent components:
  123. @ID @ShowVMark {
  124. @HContract @GreyBox { 1c @Wide ^| 1c @Wide 0.6c @High }
  125. /0.3c
  126. @HContract @GreyBox { 2c @Wide 0.6c @High }
  127. /0.3c
  128. @HContract @GreyBox { 0.5c @Wide ^| 0.8c @Wide 0.6c @High }
  129. }
  130. When aligned components are promoted into different targets, the meaning
  131. of alignment becomes very doubtful.  For example, what if the targets
  132. mark.alignment.in.detail @SubIndex { in detail }
  133. are in different columns of one page, or what if one lies within
  134. {@Code "90d @Rotate"}?
  135. @PP
  136. The truth is that @Code "/" causes all the objects that share a mark to
  137. have equal width:
  138. @ID @ShowVMark {
  139. @Box @HContract @GreyBox { 1c @Wide ^| 1c @Wide 0.6c @High }
  140. /0.3c
  141. @Box @HContract @GreyBox { 2c @Wide 0.6c @High }
  142. /0.3c
  143. @Box @HContract @GreyBox { 0.5c @Wide ^| 0.8c @Wide 0.6c @High }
  144. }
  145. This is a consequence of the `as wide as possible' rule (Section
  146. {@NumberOf size}).  Mark alignment occurs {@I incidentally}, whenever
  147. the fragments are placed into similar contexts.
  148. @PP
  149. In this connection we must also consider the special case of a @@Galley
  150. symbol which shares its column mark with some other object:
  151. @ID @Code {
  152. "@Galley"
  153. "/0.2c"
  154. "@SomethingList"
  155. }
  156. (The @@Galley may or may not occupy an entire component; that doesn't
  157. matter here.)  If incoming components are separated by @Code "//" rather
  158. than by {@Code "/"}, the meaning is so doubtful that this is forbidden.  In
  159. fact, a galley whose components replace such a @@Galley must have a
  160. single column mark running its full length; that is, its components must
  161. all share a single column mark.  This mark will be merged with the
  162. column mark passing through each @@Galley that these components replace;
  163. all the objects on the resulting merged mark will have equal width.
  164. @PP
  165. The root galley, where everything collects immediately prior to output,
  166. root.galley.in.detail @SubIndex { in detail }
  167. is created automatically, not by a definition.  Its target is the output
  168. file, and its object is the entire input, which typically looks like this:
  169. @ID @Code {
  170. "@PageList"
  171. "//"
  172. "@Text {"
  173. "  Body text of the document ..."
  174. "}"
  175. }
  176. where @Code "@PageList" expands to a sequence of pages containing
  177. @Code "@TextPlace" symbols (see Section {@NumberOf definitions}), and
  178. @Code "@Text" is a galley:
  179. @ID @Code {
  180. "def @TextPlace { @Galley }"
  181. ""
  182. "def @Text into { @TextPlace&&preceding }"
  183. "    right x"
  184. "{"
  185. "    x"
  186. "}"
  187. }
  188. The spot vacated by a galley -- its invocation point -- becomes a @@Null
  189. object, so this root galley is effectively @Code "@PageList" alone, as
  190. required.  The @Code "@Text" galley will find its first target preceding
  191. its invocation point, within {@Code "@PageList"}.
  192. @PP
  193. Printing {@PageMark rootg} the root galley on the output file is somewhat problematical,
  194. root.galley.printing @SubIndex { printing of }
  195. because Lout has no way of knowing how large the paper is.  Basser Lout
  196. simply prints one root galley component per page (except it skips
  197. components of height zero), and the user is responsible for ensuring
  198. that each component is page-sized.
  199. @PP
  200. Basser Lout will promote a component only after any receptive symbols
  201. components.promotion @SubIndex { promotion of }
  202. promotion @Index { Promotion of components }
  203. within it have been replaced, either by galleys or by @@Null, since
  204. until then the component is not complete.  A component which shares a
  205. mark with following components is held up until they are all complete,
  206. since until then their width is uncertain.
  207. @PP
  208. Consider a page with @Code "@TextPlace" and @Code "@FootSect" receptive
  209. symbols.  The rule just given will prevent the page from being printed
  210. until @Code "@TextPlace" is replaced by body text, quite rightly; but
  211. @Code "@FootSect" will also prevent its printing, even when there are no
  212. footnotes.
  213. @PP
  214. Basser Lout is keen to write out pages as soon as possible, to save memory,
  215. and it cannot afford to wait forever for non-existent footnotes.  A variant
  216. of the galley concept, called a {@I {forcing galley}},
  217. forcing.galley @Index { Forcing galley } {@PageMark forcing}
  218. is introduced to solve this problem.  A forcing galley is defined like this:
  219. @ID @Code {
  220. "def @Text force into { @TextPlace&&preceding }"
  221. "   ..."
  222. }
  223. and so on.  When such a galley replaces a @@Galley symbol, Lout replaces
  224. every receptive symbol preceding the @@Galley by @@Null, thus ensuring that
  225. as soon as text enters a page, for example, everything up to and including
  226. the preceding page can be printed.  This does not take care of the very last
  227. page, but Basser Lout replaces all receptive symbols by @@Null when it realizes
  228. that its input has all been read, thus allowing the last page to print.
  229. @PP
  230. A forcing galley causes the Third Law to be applied earlier than
  231. expected, and this creates two problems.  First, the replacement by
  232. @@Null may be premature:  a galley may turn up later wanting one of the
  233. defunct targets.  Such galleys (entries in tables of contents are
  234. typical examples) are copied into the cross reference database and read
  235. in during the next run just before their targets are closed, and so they
  236. find their targets in the end.  Care must be taken to ensure that
  237. large galleys such as chapters and sections do not have defunct targets,
  238. since the cost of copying them to and from the database is unacceptably high.
  239. @PP
  240. A @Code "following" galley may fail to find a first target lying in a
  241. following component of the same galley as its invocation point.  This is
  242. a deficiency of Basser Lout, which occurs if the target has not been
  243. read from input at the time the galley tries to find it.  A workaround
  244. is to use a @Code "preceding" galley instead, defined like this:
  245. @ID @Code {
  246. "def @AGalley into { @AGalleyPlace&&preceding }"
  247. "    right @Body"
  248. "{"
  249. "    //1.1b"
  250. "    @Body"
  251. "}"
  252. }
  253. and invoked like this:
  254. @ID @Code {
  255. "@AGalleyPlace | @AGalley { content of galley }"
  256. "//"
  257. "..."
  258. "@AGalleyPlace"
  259. }
  260. The first @Code "@AGalleyPlace" receives only the initial empty object,
  261. since the @Code "//1.1b" forces a split; and the Second Law puts Basser
  262. Lout on the right track thereafter.
  263. @End @Section
  264.