@Section @Title { Galleys and targets } @Tag { targets } @Begin @PP The behaviour of galleys and their targets, as described in Section galley.feature.in.detail @SubIndex { in detail } targets.in.detail @SubIndex { in detail } {@NumberOf galleys}, can be summarized in three laws: @DP {@I {First Law}}: The first target is the closest invocation of the target symbol, either preceding or following the invocation point of the galley as required, which has sufficient space to receive the first component; @DP {@I {Second Law}}: Each subsequent target is the closest invocation of the target symbol, following the previous target and lying within the same galley, which has sufficient space to receive the first remaining component; @DP {@I {Third Law}}: A receptive symbol that does not receive at least one component of any galley is replaced by @@Null. @DP The terms `closest,' `preceding,' and `following' refer to position in the final printed document. This section explains the operation of these laws in Basser Lout. @PP When a galley cannot be fitted into just one target, Lout must find points in the galley where it can be split in two. The object lying between two neighbouring potential split points is called a @I component component @Index { Components of a galley } of the galley. By definition, a component cannot be split. @PP To determine the components of a galley, expand all symbols other than recursive and receptive ones, discard all @@Font, @@Break, @@Space, @@SetColor, @@SetColour, and @@Language symbols, perform paragraph breaking as required, and discard all redundant braces. Then view the galley as a sequence of one or more objects separated by vertical concatenation symbols; these are the components and split points, except that concatenation symbols whose gaps are unbreakable (Section {@NumberOf concatenation}) are not eligible to be split points. For example, given the definition @ID @OneRow @Code { "def @Section into { @SectionPlace&&preceding }" " named @Title {}" " right @Body" "{" " 15p @Font { @Title //0.7f }" " //" " @Body" "}" } the galley @ID @OneRow @Code { "@Section" " @Title { Introduction }" "{ This is a subject that really" "needs no introduction. }" } becomes @ID @OneRow @Code { "Introduction" "//0.7f" "{}" "//" "This is a subject that really needs" "//1vx" "no introduction." } with four components. If @Code "@Body" had been preceded by @Code "|1.0c" in the definition, the result would have been @ID @OneRow @Code { "Introduction" "//0.7f" "{}" "//" "|1.0c { This is a subject that really needs //1vx no introduction. }" } with @Code "//1vx" buried within one component and hence not a potential split point. If @Code "0.7f" had been {@Code "0.7fu"}, the gap would have been unbreakable and @Code "//0.7fu" would not have been a potential split point. @PP Version 3.03 has liberalized this somewhat in the following way. When a component consists of a horizontal sequence of two or more objects @Eq { A sub 1 ,..., A sub n } separated by @Code "|" (not {@Code "||"}, not {@Code "&"}), Lout will investigate the component to see whether it can be broken up. It looks at each @Eq { A sub i } to see whether it is a vertical concatenation of objects @Eq { A sub i1 ,..., A sub im }; if two or more of the @Eq { A sub i } satisfy this condition, the component will not be broken up. So now suppose we have just one @Eq { A sub i } which is a vertical concatenation. Lout will break the component into one component for each of the @Eq { A sub i1 ,..., A sub im }, provided that they are separated by @Code "//" symbols (not {@Code "/"}), and provided this can be done without introducing any apparent change into the appearance of the component (this second rule will be satisfied if the other @Eq { A sub j } are not very large). The example above satisfies all these rules and will be broken up into two components, so the @Code "//1vx" becomes a potential split point after all. @PP The lines of a paragraph become separate components if the paragraph occupies an entire component before breaking; otherwise they are enclosed in a @@OneRow symbol within one component. The same is true of incoming components of other galleys. If a @@Galley symbol occupies an entire component by the rules above, then the incoming components that replace it become components of their new home: @ID @Tab @Fmta { @Col @Code A ! @Col lines @Break B ! @Col @Code C } { @Rowa A { "An example" "//0.5c" "@Galley" "//0.5c" "@SomethingList" } B { "" @Eq { ==> } } C { "An example" "//0.5c" "Incoming components" "//0.2c" "from some other galley" "//0.5c" "@SomethingList" } } Otherwise the incoming components are grouped within a @@OneRow symbol and lie within one component. @PP This distinction has a marked effect on the vertical concatenation b.unit.use @SubIndex { use in @Code "//1.1b" } symbol {@Code "//1.1b"}, which calls for more space than is available (Section {@NumberOf concatenation}). There is no room for this symbol within any component, so it will force a split and be discarded in that case. But it can be promoted to between two components. @PP Components may be separated by @Code "/" as well as by {@Code "//"}, giving rise to column mark alignment between adjacent components: @ID @ShowVMark { @HContract @GreyBox { 1c @Wide ^| 1c @Wide 0.6c @High } /0.3c @HContract @GreyBox { 2c @Wide 0.6c @High } /0.3c @HContract @GreyBox { 0.5c @Wide ^| 0.8c @Wide 0.6c @High } } When aligned components are promoted into different targets, the meaning of alignment becomes very doubtful. For example, what if the targets mark.alignment.in.detail @SubIndex { in detail } are in different columns of one page, or what if one lies within {@Code "90d @Rotate"}? @PP The truth is that @Code "/" causes all the objects that share a mark to have equal width: @ID @ShowVMark { @TightBox @HContract @GreyBox { 1c @Wide ^| 1c @Wide 0.6c @High } /0.3c @TightBox @HContract @GreyBox { 2c @Wide 0.6c @High } /0.3c @TightBox @HContract @GreyBox { 0.5c @Wide ^| 0.8c @Wide 0.6c @High } } This is a consequence of the `as wide as possible' rule (Section {@NumberOf size}). Mark alignment occurs {@I incidentally}, whenever the fragments are placed into similar contexts. @PP In this connection we must also consider the special case of a @@Galley symbol which shares its column mark with some other object: @ID @OneRow @Code { "@Galley" "/0.2c" "@SomethingList" } (The @@Galley may or may not occupy an entire component; that doesn't matter here.) If incoming components are separated by @Code "//" rather than by {@Code "/"}, the meaning is so doubtful that this is forbidden. In fact, a galley whose components replace such a @@Galley must have a single column mark running its full length; that is, its components must all share a single column mark. This mark will be merged with the column mark passing through each @@Galley that these components replace; all the objects on the resulting merged mark will have equal width. @PP The root galley, where everything collects immediately prior to output, root.galley.in.detail @SubIndex { in detail } is created automatically, not by a definition. Its target is the output file, and its object is the entire input, which typically looks like this: @ID @OneRow @Code { "@PageList" "//" "@Text {" " Body text of the document ..." "}" } where @Code "@PageList" expands to a sequence of pages containing @Code "@TextPlace" symbols (see Section {@NumberOf definitions}), and @Code "@Text" is a galley: @ID @OneRow @Code { "def @TextPlace { @Galley }" "" "def @Text into { @TextPlace&&preceding }" " right x" "{" " x" "}" } The spot vacated by a galley -- its invocation point -- becomes a @@Null object, so this root galley is effectively @Code "@PageList" alone, as required. The @Code "@Text" galley will find its first target preceding its invocation point, within {@Code "@PageList"}. @PP Printing {@PageMark rootg} the root galley on the output file is somewhat problematical, root.galley.printing @SubIndex { printing of } because Lout has no way of knowing how large the paper is. Basser Lout simply prints one root galley component per page (except it skips components of height zero), and the user is responsible for ensuring that each component is page-sized. Gaps between root galley components, even unbreakable ones, have no effect on the result. @PP Basser Lout will promote a component only after any receptive symbols components.promotion @SubIndex { promotion of } promotion @Index { Promotion of components } within it have been replaced, either by galleys or by @@Null, since until then the component is not complete. A component which shares a mark with following components is held up until they are all complete, since until then their width is uncertain. @PP Consider a page with @Code "@TextPlace" and @Code "@FootSect" receptive symbols. The rule just given will prevent the page from being printed until @Code "@TextPlace" is replaced by body text, quite rightly; but @Code "@FootSect" will also prevent its printing, even when there are no footnotes. @PP Basser Lout is keen to write out pages as soon as possible, to save memory, and it cannot afford to wait forever for non-existent footnotes. A variant of the galley concept, called a @I {forcing galley}, forcing.galley @Index { Forcing galley } {@PageMark forcing} is introduced to solve this problem. A forcing galley is defined like this: @ID @OneRow @Code { "def @Text force into { @TextPlace&&preceding }" " ..." } and so on. When such a galley replaces a @@Galley symbol, Lout replaces every receptive symbol preceding the @@Galley by @@Null, thus ensuring that as soon as text enters a page, for example, everything up to and including the preceding page can be printed. This does not take care of the very last page, but Basser Lout replaces all receptive symbols by @@Null when it realizes that its input has all been read, thus allowing the last page to print. @PP A forcing galley causes the Third Law to be applied earlier than expected, and this creates two problems. First, the replacement by @@Null may be premature: a galley may turn up later wanting one of the defunct targets. Such galleys (entries in tables of contents are typical examples) are copied into the cross reference database and read in during the next run just before their targets are closed, and so they find their targets in the end. Care must be taken to ensure that large galleys such as chapters and sections do not have defunct targets, since the cost of copying them to and from the database is unacceptably high. @PP It is actually an over-simplification to say that these replacements occur when the forcing galley replaces its @@Galley. What really happens is that from this moment on Lout understands that it has the right to make these replacements, and it will do each one at the first moment when not doing it would hold things up. So there is a short period of grace when galleys, such as the entries in tables of contents just alluded to, can sneak into these receptive symbols. @PP The @Code "into" and @Code "force into" forms are actually just abbreviations for the true way that galleys are defined, which is by giving the symbol that is to be a galley a parameter or nested target.sym @Index { @Code "@Target" symbol } definition with the special name {@Code "@Target"}: @ID @Code { "def @Text" " right x" "{" " def @Target { @TextPlace&&preceding }" "" " x" "}" } A forcing galley is obtained by using @Code "&&&" instead of {@Code "&&"}. @Code "@Target" may be an arbitrary object, provided that it yields such a cross reference when evaluated. In this way, different invocations may have different targets. @PP The forcing galley effect can be obtained in another way, by replacing the @Code "@Galley" symbol to which the galley is attached by {@Code "@ForceGalley"}. The advantage of this form is that the galley can then be forcing at some places and not at others, using the formula @ID @OneRow @Code { "def @SomePlace right x" "{" " x @Case {" " noforce @Yield @Galley" " force @Yield @ForceGalley" " }" "}" } Now a galley may have @Code "@SomePlace" for its target, and if it happens to attach to @ID @Code "@SomePlace force" it will have the effect of a forcing galley, while if it happens to attach to @ID @Code "@SomePlace noforce" it will not. @PP Although it doesn't matter whether a galley is declared as a forcing galley or merely arrives at a {@Code "@ForceGalley"} symbol from the point of view of the effect on nearby targets, there is one way in which Lout treats the two cases differently. If a forcing galley's first component does not fit into the available space, that component will be scaled vertically until it does. The rationale for this is that forcing galleys are meant to carry the bulk of the document and cannot afford to be held up because the user has inadvertently included an over-high component, which for all Lout knows to the contrary may not fit on any page. If this scaling is not wanted but forcing is, the galley may be declared not forcing but all its targets may be set to contain {@Code "@ForceGalley"}. @PP Within a galley, a symbol whose name is @@Enclose has a special enclose.sym @Index @@Enclose meaning: when components of the galley replace a @@Galley or @@ForceGalley symbol, that symbol is first replaced by @@Enclose @@Galley or @@Enclose @@ForceGalley. For example, @ID @Code { "def @Enclose" " right x" "{" " @Box x" "}" } within some galley definition causes each @@Galley or @@ForceGalley symbol that receives components of the galley to be replaced by {@Code "@Box @Galley"} or {@Code "@Box @ForceGalley"}, assuming an appropriate definition of @Code "@Box". This is useful, for example, when producing multi-page boxed displays, figures, and tables. @PP An @@Enclose symbol may have only one parameter, which must be a right parameter. It would not make sense to allow more parameters, since there is no suitable value to assign to them. However, the @@Enclose symbol may contain inner definitions, and it may make use of any symbol that is available at that point, in the usual way. @PP A @Code "following" galley may fail to find a first target lying in a following component of the same galley as its invocation point. This is a deficiency of Basser Lout, which occurs if the target has not been read from input at the time the galley tries to find it. A workaround is to use a @Code "preceding" galley instead, defined like this: @ID @OneRow @Code { "def @AGalley into { @AGalleyPlace&&preceding }" " right @Body" "{" " //1.1b" " @Body" "}" } and invoked like this: @ID @OneRow @Code { "@AGalleyPlace | @AGalley { content of galley }" "//" "..." "@AGalleyPlace" } The first @Code "@AGalleyPlace" receives only the initial empty object, since the @Code "//1.1b" forces a split; and the Second Law puts Basser Lout on the right track thereafter. @End @Section