aboutsummaryrefslogtreecommitdiffstats
path: root/doc/expert/exa_para
diff options
context:
space:
mode:
Diffstat (limited to 'doc/expert/exa_para')
-rw-r--r--doc/expert/exa_para236
1 files changed, 236 insertions, 0 deletions
diff --git a/doc/expert/exa_para b/doc/expert/exa_para
new file mode 100644
index 0000000..6b9f60f
--- /dev/null
+++ b/doc/expert/exa_para
@@ -0,0 +1,236 @@
+@Section
+ @Title { Paragraphs, displays, and lists }
+ @Tag { paras }
+@Begin
+@PP
+The remaining sections of this chapter are all based on Version 2 of
+the DocumentLayout package. Version 3, which is similar but more elaborate,
+is described from the user's perspective in the
+document.layout @Index { DocumentLayout package }
+User's Guide @Cite { $kingston1995lout.user }. In 26 pages of Lout, the
+DocumentLaytout package defines many features required in the formatting
+of simple documents, technical reports, and books, including displays,
+lists, page layout, cross references, tables of contents, footnotes,
+figures, tables, references, chapters, sections, and sorted indexes.
+@PP
+The symbols used for separating paragraphs and producing displays and
+document.layout.paras @SubIndex { paragraphs }
+lists may lack the excitement of more exotic features, but they can
+teach some important lessons about robust design. The following macro
+for separating paragraphs produces a 0.3 cm vertical space and a 1 cm
+indent on the following line, and is clearly on the right track:
+@ID @Code "macro @PP { //0.3c &1c }"
+Nevertheless it has several major problems.
+@PP
+The @Code "&" symbol is subject to widening during line adjustment, so
+it should be replaced by {@Code "1c @Wide {}"}. But then white space
+following the symbol will affect the result, so an extra @Code "&0i" must
+be added. If the document is printed double spaced, this paragraph gap
+will fail to widen: it should be expressed in terms of the @Code "v" unit,
+with mark-to-mark spacing mode. Similarly, the paragraph indent should
+probably be made proportional to the font size.
+@PP
+`Magic numbers' like @Code "0.3c" should not be buried in definitions
+where they cannot be changed easily, or kept consistent with similar
+definitions during tuning. They are much better placed as symbols,
+possibly parameters of the enclosing package:
+@ID @Code {
+"def @DocumentLayout" pp.example @Index { @Code "@PP" example }
+" named @ParaGap { 1.3vx }"
+" named @ParaIndent { 2f }"
+" ..."
+"@Begin"
+""
+" macro @PP { //@ParaGap @ParaIndent @Wide &0i }"
+" macro @LP { //@ParaGap }"
+" ..."
+"@End @DocumentLayout"
+}
+and we have arrived at the definition of @Code "@PP" as it appears in
+the DocumentLayout package.
+@PP
+A display is a table in which the first column is blank:
+document.layout.displays @SubIndex { displays }
+@ID lines @Break {
+@I { preceding text }
+@Code "//@DispGap |@DispIndent" @I display
+@Code "//@DispGap"
+@I { following text }
+}
+Edge-to-edge is the appropriate spacing mode before and after displays,
+since the display could be a table or figure whose mark does not
+correspond to a baseline. Thus, @Code "1v" is a reasonable value for
+{@Code "@DispGap"}.
+@PP
+The ordinary user cannot be expected to type the Lout source shown
+above; a more appropriate syntax is
+indented.display.example @Index { @Code "@IndentedDisplay" example }
+@ID lines @Break {
+@I { preceding text }
+@Code "@IndentedDisplay {" @I display @Code "}"
+@I { following text }
+}
+This presents a problem: if @Code "@IndentedDisplay" is made a definition
+with a right parameter, its result will be an object separated from the
+surrounding text only by white space, hence part of the paragraph; while
+if it is a macro, the final @Code "//@DispGap" cannot be included in it.
+ The solution adopted in the DocumentLayout package uses a galley and a macro:
+@ID @Code {
+" def @DispPlace { @Galley }"
+" def @Disp into { @DispPlace&&preceding }"
+" right x"
+" {"
+" @OneRow x"
+" }"
+""
+" macro @IndentedDisplay"
+" {"
+" //@DispGap |@DispIndent @DispPlace |"
+" //@DispGap // @Disp"
+" }"
+}
+@Code "@DispPlace" and @Code "@Disp" are not exported, so there is
+no danger of a name clash with some other symbol. The ordinary user's
+syntax expands to
+@ID lines @Break {
+@I { preceding text }
+@Code "//@DispGap |@DispIndent @DispPlace |"
+@Code "//@DispGap // @Disp {" @I display @Code "}"
+@I { following text }
+}
+and the @Code "@Disp" galley appears at the preceding
+{@Code "@DispPlace"}, being itself replaced by @@Null. The @Code "//"
+symbol protects the preceding @Code "//@DispGap" from being deleted by
+this @@Null when there is no following text.
+@PP
+An automatically numbered list
+document.layout.lists @SubIndex { lists }
+numbered @Index { Numbered list }
+could have an arbitrarily large number of
+items, so, by analogy with sequences of pages, we see immmediately that
+recursion must be involved:
+@ID @Code {
+"def @List right num"
+"{"
+" @DispIndent @Wide num. | @ItemPlace"
+" //@DispGap @List @Next num"
+"}"
+}
+Notice how the @@Next symbol works in conjunction with the recursion to
+produce an ascending sequence of numbers; the result of @Code "@List 1"
+will be
+@ID @Code {
+"1. @ItemPlace"
+"2. @ItemPlace"
+"3. @ItemPlace"
+"..."
+}
+We can follow this with items which are galleys targeted to
+{@Code "@ItemPlace&&preceding"}, and @Code "@List" will expand just
+enough to accommodate them.
+@PP
+The usual problem with recursive-receptive symbols now arises: there is
+always one unexpanded {@Code "@List"}, and until it can be removed the
+galley containing it will appear to be incomplete and will be prevented at
+that point from flushing into its parent (see page {@PageOf forcing}). We
+adopt the usual solution: a forcing galley into a later target will
+replace the last @Code "@List" by @@Null. This brings us to the
+definitions as they appear in DocumentLayout:
+indented.list.example @Index { @Code "@IndentedList" example }
+@IndentedList
+@LI @Code {
+"def @ItemPlace { @Galley }"
+"def @ListItem into { @ItemPlace&&preceding }"
+" right x"
+"{ x }"
+}
+@LI @Code {
+"def @EndListPlace { @Galley }"
+"def @EndList force into { @EndListPlace&&preceding }"
+"{}"
+}
+@LI @Code {
+"def @RawIndentedList"
+" named style right tag {}"
+" named indent { @DispIndent }"
+" named gap { @DispGap }"
+" named start { 1 }"
+"{"
+" def @IList right num"
+" {"
+" indent @Wide {style num} | @ItemPlace"
+" //gap @IList @Next num"
+" }"
+""
+" @IList start // @EndListPlace"
+"}"
+}
+@EndList
+Now given the input
+@ID @Code {
+"@RawIndentedList"
+"@ListItem { first item }"
+"@ListItem { second item }"
+"..."
+"@ListItem { last item }"
+"@EndList"
+}
+@Code "@RawIndentedList" will expand to receive the items, and will be
+closed off by {@Code "@EndList"}.
+@PP
+The {@Code indent}, {@Code gap}, and {@Code start} parameters are
+straightforward (note that the burden of typing @Code 1 has been lifted
+from the ordinary user), but the @Code style parameter has a parameter
+of its own (see page {@PageOf strange}). It is used like this:
+@ID @Code {
+"def @RawNumberedList { @RawIndentedList style { tag. } }"
+"def @RawParenNumberedList { @RawIndentedList style { (tag) } }"
+}
+In {@Code "@RawNumberedList"}, @Code "style" is given the value
+{@Code "tag."}, where @Code tag is its own right parameter, so the value
+of @Code "{style num}" within @Code "@IList" is {@Code "num."}; while in
+{@Code "@RawParenNumberedList"}, @Code "{style num}" is {@Code "(num)"}. In
+this way we achieve an unlimited variety of numbering formats without
+having to rewrite @Code "@RawIndentedList" over and over.
+@PP
+These list symbols are objects without surrounding space, so macros
+similar to those used for displays are needed:
+@ID @Code {
+"macro @NumberedList { //@DispGap @RawNumberedList //@DispGap }"
+"macro @ParenNumberedList { //@DispGap @RawParenNumberedList //@DispGap }"
+}
+and so on.
+@PP
+Lists numbered by Roman numerals
+roman @Index { Roman numerals }
+present a problem, because @@Next will
+not increment Roman numerals. Instead, they must be stored in a
+database:
+@ID @Code {
+"def @Roman"
+" left @Tag"
+" right @Val"
+"{ @Val }"
+""
+"@SysDatabase @Roman { standard }"
+}
+@Code "@SysDatabase" is preferred over @Code "@Database" here because
+this database should be kept in a standard place and shared by
+everyone. The database itself, a file called @Code "standard.ld" in
+Basser Lout, contains invocations of {@Code "@Roman"}, each enclosed in
+braces:
+@ID @Code {
+"{ 1 @Roman i }"
+"{ 2 @Roman ii }"
+"..."
+"{ 100 @Roman c }"
+}
+Then @Code "@Roman&&12" for example has value {@Roman&&12}, and
+@ID @Code {
+"def @RawRomanList { @RawIndentedList style { {@Roman&&tag}. } }"
+}
+produces a list numbered by Roman numerals. The counting still
+proceeds in Arabic, but each Arabic numeral is converted to Roman by the
+cross reference. Since arbitrary objects may be stored in databases,
+arbitrary finite sequences of objects may be `counted' in this way.
+@End @Section