3 <style|<tuple|source|std-utils|tmdoc-markup>>
8 <src-style-file|fake-page|0.5>
11 Presenting fake pages to aid the demonstration of document creation,
12 with convenient isolation of page numbers, references, links etc.
20 This <TeXmacs> style file falls under the <hlink|GNU general public
21 license|$TEXMACS_PATH/LICENSE> and comes WITHOUT ANY WARRANTY
22 WHATSOEVER. If you do not have a copy of the license, then write to
23 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA.
29 <active*|<assign|ignore|<macro|x|>>>
31 <if|<not|<provides|show-active>>|<assign|show-active|<macro|x|<surround|<arg|x>||<rewrite-inactive|<arg|x>|>>>>><active*|<active*|<assign|show-active|<macro|x|<surround|<arg|x>||<rewrite-inactive|<arg|x>|>>>>>>
33 Sometimes when explaining the use of sophisticated <active*|<TeXmacs>>
34 style sheets it is helpful to lead the reader through the development of an
35 example document that makes use of that style sheet.
37 Rather than merely instruct the reader in the creation of the example
38 document, it can be helpful to show the state of the example document as it
39 would appear at the different stages during development.
41 To visually distinguish the sample page from the explanation, it might be
42 rendered in an ornamented border.
44 <active*|<show-active|<assign|render-simple-fake-page|<macro|x|<with|ornament-color|#eeeeee|ornament-sunny-color|#000000|ornament-shadow-color|#000000|ornament-borderx|2l|ornament-hpadding|2ex|ornament-vpadding|2ex|<ornament|<surround||<htab|0spc>|<indent-both|1cm|1cm|<arg|x>>>>>>>>>
49 <\render-simple-fake-page>
52 Should be able to contain all normal page elements, etc...
53 </render-simple-fake-page>
58 The fake page might also have a fake caret, or text insertion point, so
59 that this may be represented. This fake caret is calculated according to
60 the current font size and unlike the real cared, it does not change size
61 according to the height of the character that preceded it.
63 <show-active|<assign|fake-caret|<macro|<space|0.5spc><with|gr-mode|<tuple|edit|line>|gr-frame|<tuple|scale|1fs|<tuple|0.5gw|0.5gh>>|gr-geometry|<tuple|geometry|3ln|1.5ex|bottom>|gr-color|red|gr-auto-crop|false|<graphics||<with|color|red|<line|<point|0gw|1ln>|<point|1gw|1ln>>>|<with|color|red|<line|<point|0.5gw|1ln>|<point|0.5gw|1gh>>>|<with|color|red|<line|<point|0gw|1gh>|<point|1gw|1gh>>>>><space|0.5spc>>>>
66 <\render-simple-fake-page>
67 Example fake page with the fake caret<fake-caret>
69 The fake caret can be troublesome when passed as an argument to some
71 </render-simple-fake-page>
74 A difficulty arises, however, which is that the fake pages share the same
75 environment with each-other and with the main document.
77 How would it look if repeated section headings from revisions of fake pages
78 appeared in the real table of contents? Further revisions of the same fake
79 page might conflict labels, references, section numbers and other counters,
80 with each-other, and with the main document.\
82 We might enclose the fake page in a with block
83 <inactive*|<with|...|...|<fake-page|...>>> shadowing most global variables,
84 so that the fake page had it's own environment.\
86 Consider also that a fake page might be broken into annotaed fragments that
87 share the same private environment, so that a second fragment of a fake
88 page might demonstrate a new section, which should be numbered as following
89 on from the section in the previous fragment, like this (we use a fake page
90 to enclose the example document that contains two fake pages):
93 <\render-simple-fake-page>
94 The first section would look like this
96 <\render-simple-fake-page>
97 Section 1. Example fake page
100 </render-simple-fake-page>
104 <\render-simple-fake-page>
105 Section 2. Using closures
108 </render-simple-fake-page>
109 </render-simple-fake-page>
114 This requires that the state of the environment, counters, labels, etc, be
115 preserved and restored at the start of the following fragment of the same
118 We therefore require a form of closure that preserves essential variables
119 and allows continuation macros to be invoked in that saved context.
123 An enclosed macro would be of this form, invoking <src-arg|x> within the
126 <style-only*|<inactive*|<macro|x|<with|...|...|<arg|x>>>>>
128 so we need to emit such a macro where ... are filled in with the closed
131 <style-only*|<inactive*|<macro|x|<with|a|AHA|<arg|x>>>>>
133 So the constructing macro will be an xmacro, taking a list like
134 <style-only*|<inactive*|<with|...|...|...>>> does, from which it will
135 construct the <src-macro|with> statement.
137 <show-active|<assign|make-enclosure|<xmacro|w|<quasiquote|<macro|x|<with|<unquote*|<quote-arg|w>>|<arg|x>>>>>>>
139 But it would be simpler to just to specify the names of the variables to
140 preserve, and have their values looked up automatically instead of having
141 to specify the values too. So we need to be able to generate a
142 <style-only*|<inactive*|<with|var|val|...>>> style list from just a list of
145 This macro converts a variable name into a tuple of the name and it's
148 <show-active|<assign|enclose-single|<macro|x|<tuple|<arg|x>|<value|<arg|x>>>>>>
150 Many of these pair-tuples could \ be merged into a single long tuple and
151 then <src-macro|unquote*>'d with <src-arg|x>, as arguments for
152 <src-macro|make-enclosure>
154 <show-active|<assign|enclose|<xmacro|x|<quasi|<make-enclosure|<unquote*|<map-args|enclose-single|merge|x>>>>>>>
156 We can demonstrate the value of the closure here, by assigning a value to
159 <show-active|<assign|message|hello>>
161 We then create a closure called <src-var|saved-message>
163 <show-active|<assign|saved-message|<enclose|message>>>
165 If we then update message to something else, like this,
166 <show-active|<assign|message|missed>>, we can then use the closure to emit
169 <show-active|<saved-message|Hello there: <value|message>>>
171 It should be clear then, that as long as a list of variables to be saved is
172 ready at the end of the fake page, a closure may be created which could be
173 used to restore the environment at the start of a subsequent fragment.
175 Such variables would include <src-var|page-nr>, <src-var|item-nr> and
176 <src-var|the-label>. These values would also want initialising for the
177 first fake-page fragment, so it becomes clear that a default closure need
178 to be established as the basis for each new fake-page.
180 Other <TeXmacs> packages may introduce further variables that need
181 enclosing for the fake page.
183 Therefore we introduce a mechanism so that such enclosed variables may be
184 declared as such pages are used.\
188 <src-var|fake-page-defaults> will hold a list of variable names, usually
189 one per package. Each variable will hold a tuple of variable names and
192 As some of those packages may get initialised before the fake page package,
193 we need a way for them to register these values that can be picked up
194 later. We can't define a macro to help with this, as the fake page package
195 might not be loaded at that time.
197 A package would declare it's closure variables by storing their names and
198 values in a tuple. For instance, the widget package might do this:
200 <inactive*|<assign|enclose-widget|<tuple|widget-nr|<value|widget-nr>|widget-states|<value|widget-states>>>>
202 The name of this list is added to the list of names --- we add the name of
203 the variable (enclose-widget) containing the enclosed variables, not it's
204 value (<src-var|enclose-wudget>)<compound|src-value|>.
206 <inactive*|<assign|enclose-defaults|<merge|<if|<provides|enclose-defaults>|<value|enclose-defaults>|<tuple|>>|<tuple|enclose-widget>>>>
208 It's a bit clumsy, but <src-macro|merge> fails when invoked on the value of
209 an undefined variable.
213 Each package registers a callback that will be invoked when the fake-page
216 The widget would define it's callback like this:
218 <inactive*|<assign|fake-page-init-widget|<macro|version|<fake-page-init|widget|<tuple|widget-nr|widget-states>>>>>
220 And invoke the callback if fake page has already loaded, otherwise register
221 the callback in <src-value|fake-page-init-> so that the fake page package
222 will invoke it later:
224 <inactive*|<if|<provides|fake-page-version>|<fake-page-init-widget|<value|fake-page-version>>|<assign|fake-page-init-|<merge|<if|<provides|fake-page-init->|<value|fake-page-init->|<tuple|>>|<tuple|fake-page-init->>>>>
228 If a fake page fragment were to terminate part way through a nested enum,
229 the nested structure could not be re-created by means of the closure. Each
230 fragment has to be fully normal, with all open tags closed at the end of
231 the fake page chunk. This type of fragment could be permitted if the entire
232 fake page were present within each fragment but with rendering disabled
233 except between certain checkpoints, but at present I have no mechanism to
234 divert rendering to a null device which can also cross document tag
235 structure --- i.e. comment rendering after a section heading and halt
236 rendering halfway through an enum nest.
240 Variables are not the only items that need isolating, references create
241 entries in the document aux section. Two stages of revision of the same
242 fake page might re-define the same labels. Clearly some further isolation
243 is needed so that references in one fake page revision to not refer to
244 labels in subsequent revisions of the same page.
246 Each fake page needs to be uniquely defined, so that it's closure
247 preserving the final values can be named. This definition can be used to
248 prefix labels and references, as we re-define <src-macro|label>,
249 <src-macro|reference>, etc, to use the fake page identifier as a prefix.
251 We will call this prefix <src-var|fake-page-base-name> and it will be part
252 of the closure. An initial empty value is defined here:
253 <show-active|<assign|fake-page-base-name|>>
255 Thus we can override the <src-macro|label> macro within the fake page like
258 <show-active|<assign|fake-page-label|<macro|x|<with|the-label|<tuple|<value|the-label>|<value|page-no>>|<quasi|<old-label|<unquote|<fake-page-make-new-label|<arg|x>>>>>>>>>
260 We have overridden <src-var|the-label> be a tuple of the original
261 <src-var|the-label> and <src-var|page-no>. This is because we need to be
262 able to recover the fake page number later, but <TeXmacs> will insert the
263 real page number during pagination.
265 After faking <src-var|the-label> we then fake the label name with
266 <src-macro|fake-page-make-new-label> which prefixes the label name with our
269 <show-active|<assign|fake-page-make-new-label|<macro|x|<merge|<value|fake-page-base-name>|-|<arg|x>>>>>
271 Of course, now we have "fixed" the <src-macro|label> macro, we need to fix
272 the <src-macro|reference> macro to match.
274 BUG: Normally <src-macro|reference> will emit a locus whose displayed value
275 is the original value of <src-var|the-label> and whose action navigates to
276 that location. We stored the original <src-var|the-label> as the first
277 member of a tuple. Thus we show the correct label text --- which is good
278 for type-setting, but this is not yet active as a link.
280 <show-active|<assign|fake-page-reference|<macro|x|<quasi|<with|b|<get-binding|<unquote|<fake-page-make-new-label|<arg|x>>>|0>|<compound|look-up-default|<value|b>|0|<uninit>>>>>>>
282 We use a tuple helper macro <src-macro|look-up-default> to return the first
283 tuple member, or if that fails, to return uninit rather than an error.
285 <show-active|<assign|look-up-default|<macro|x|i|o|<if|<and|<equal|<get-label|<arg|x>>|tuple>|<greater|<length|<arg|x>>|<arg|i>>>|<look-up|<arg|x>|<arg|i>>|<arg|o>>>>>
289 As a fake page is used in document development, there is a hierachy of
290 relationships between revisions and chunks.
292 Typically the example document will be developed in parts, and each part
293 will undergo revisions. In the diagram shown, only the outlined elements
294 represent fake pages, the other elements are just to help label the
295 hierachy of closure inheritance.
297 <tree|Tutorial 1 |<tree|Part 1|<tree|<render-simple-fake-page|Revision
298 1>|>|<tree|<render-simple-fake-page|Revision
299 2>|>|<tree|<render-simple-fake-page|Revision 3>|<tree|Part
300 2|<tree|<render-simple-fake-page|Revision
301 1>|>|<tree|<render-simple-fake-page|Revision
302 2>|>|<tree|<render-simple-fake-page|Revision
303 3>|>>>|<tree|<render-simple-fake-page|Revision 4>|<tree|Part
304 2|<tree|<render-simple-fake-page|Revision 4>|>>>>>
306 Once a part is completed with it's final revision, it will serve as the
307 basis for the next part which will inherit it's labels and counters. Of
308 course any revision of any part could serve as the basis for another part,
309 and in some cases a further revision of Part 1 may be shown, perhaps
310 followed by further revisions of further parts.
312 A fake page is emitted with the tag: <inactive*|<new-fake-page|from-name|new-name|...>>
314 The first argument is the name of the fake page to continue from, but can
315 be empty --- meaning the default closure. The second arument is the name
316 given to this fake page, which is important if a further page would
317 continue from this page. Any remaining argument pairs are like the pairs of
318 a <src-macro|with> clause with the final argument being the page contents.
320 As a convenience a new revision can be emitted with:
321 <inactive*|<revise-fake-page|from-name|new-name|...>>
323 This is like <src-macro|new-fake-page> except instead of continuing from
324 <src-var|from-name> it continues from what <src-var|from-name> continued
325 from, thus it is a replacement.
327 Thus, to contrive the relationships shown in the diagram, these macros
328 would have been executed in this order:\
331 <new-fake-page||part-1-revision-1|...>
333 <revise-fake-page|part-1-revision-1|part-1-revision-2|...>
335 <revise-fake-page|part-1-revision-1|part-1-revision-3|...>
337 <new-fake-page|part-1-revision-3|part-2-revision-1|...>
339 <revise-fake-page|part-2-revision-1|part-2-revision-2|...>
341 <revise-fake-page|part-2-revision-1|part-2-revision-3|...>
343 <revise-fake-page|part-1-revision-1|part-1-revision-4|...>
345 <new-fake-page|part-1-revision-4|part-2-revision-4|...>
348 Of course you could re-use the <src-var|old-name> as the
349 <src-var|new-name>, though this would make it impossible to reference the
350 <src-var|old-name> in any way.
370 <assign|default-to|<macro|x|d|<if|<or|<equal|<get-label|<arg|x>>|error>|<equal|<uninit>|<arg|x>>>|<arg|d>|<arg|x>>>>
374 <assign|fake-page-environment|<macro|x|<with|old-label|<value|label>|label|<value|fake-page-label>|pagerefpage|<value|fake-page-pagerefpage>|old-reference|<value|reference>|reference|<value|fake-page-reference>|this-page-no|<macro|<value|page-no>>|<arg|x>>>>
376 <assign|render-fake-page|<macro|x|<render-simple-fake-page|<arg|x>>>>
378 <assign|fake-page|<macro|content|doc|page-no|instance|<with|doc|<default-to|<arg|doc>|>|page-no|<default-to|<arg|page-no>|0>|instance|<init-or|<arg|instance>|0>|fake-page-base-name|<merge|fake-page-|<arg|doc>|-|<arg|page-no>|-|<arg|instance>>|<render-fake-page|<surround|<new-counter|<nf-id|nf-chunk>>||<fake-page-environment|<arg|content>>>>>>>
380 <assign|this-page-no|<macro|<auto-label><get-binding|<the-auto>|1>>>
389 <associate|preamble|false>