From 673376416361a0e8b2df17d7f1783410b997f683 Mon Sep 17 00:00:00 2001 From: Sam Liddicott Date: Thu, 31 May 2012 22:17:46 +0100 Subject: [PATCH] WIP --- fake-page.ts | 391 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fangle.ts | 34 ++++-- 2 files changed, 412 insertions(+), 13 deletions(-) create mode 100644 fake-page.ts diff --git a/fake-page.ts b/fake-page.ts new file mode 100644 index 0000000..a7969ff --- /dev/null +++ b/fake-page.ts @@ -0,0 +1,391 @@ + + +> + +<\body> + <\active*> + <\src-title> + + + <\src-purpose> + Presenting fake pages to aid the demonstration of document creation, + with convenient isolation of page numbers, references, links etc. + + + <\src-copyright|2012> + Sam Liddicott + + + <\src-license> + This style file falls under the and comes WITHOUT ANY WARRANTY + WHATSOEVER. If you do not have a copy of the license, then write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + + + + >> + + >||||>>>>>|||>>>>>> + + Sometimes when explaining the use of sophisticated > + style sheets it is helpful to lead the reader through the development of an + example document that makes use of that style sheet. + + Rather than merely instruct the reader in the creation of the example + document, it can be helpful to show the state of the example document as it + would appear at the different stages during development. + + To visually distinguish the sample page from the explanation, it might be + rendered in an ornamented border. + + |>>>>>>>> + + \; + + <\active*> + <\render-simple-fake-page> + Example fake page + + Should be able to contain all normal page elements, etc... + + + + \; + + The fake page might also have a fake caret, or text insertion point, so + that this may be represented. This fake caret is calculated according to + the current font size and unlike the real cared, it does not change size + according to the height of the character that preceded it. + + |gr-frame|>|gr-geometry||gr-color|red|gr-auto-crop|false||>>||>>||>>>>>>> + + <\active*> + <\render-simple-fake-page> + Example fake page with the fake caret + + The fake caret can be troublesome when passed as an argument to some + macros. + + + + A difficulty arises, however, which is that the fake pages share the same + environment with each-other and with the main document. + + How would it look if repeated section headings from revisions of fake pages + appeared in the real table of contents? Further revisions of the same fake + page might conflict labels, references, section numbers and other counters, + with each-other, and with the main document.\ + + We might enclose the fake page in a with block + >> shadowing most global variables, + so that the fake page had it's own environment.\ + + Consider also that a fake page might be broken into annotaed fragments that + share the same private environment, so that a second fragment of a fake + page might demonstrate a new section, which should be numbered as following + on from the section in the previous fragment, like this (we use a fake page + to enclose the example document that contains two fake pages): + + <\active*> + <\render-simple-fake-page> + The first section would look like this + + <\render-simple-fake-page> + Section 1. Example fake page + + ... + + + and so, blah blah... + + <\render-simple-fake-page> + Section 2. Using closures + + ... + + + + + \; + + This requires that the state of the environment, counters, labels, etc, be + preserved and restored at the start of the following fragment of the same + fake-page. + + We therefore require a form of closure that preserves essential variables + and allows continuation macros to be invoked in that saved context. + + Closures + + An enclosed macro would be of this form, invoking within the + defined environment: + + >>>> + + so we need to emit such a macro where ... are filled in with the closed + values; e.g. + + >>>> + + So the constructing macro will be an xmacro, taking a list like + >> does, from which it will + construct the statement. + + >|>>>>>> + + But it would be simpler to just to specify the names of the variables to + preserve, and have their values looked up automatically instead of having + to specify the values too. So we need to be able to generate a + >> style list from just a list of + variable names. + + This macro converts a variable name into a tuple of the name and it's + value. + + |>>>>> + + Many of these pair-tuples could \ be merged into a single long tuple and + then 'd with , as arguments for + + + >>>>>> + + We can demonstrate the value of the closure here, by assigning a value to + : + + > + + We then create a closure called + + >> + + If we then update message to something else, like this, + >, we can then use the closure to emit + the saved value: + + >> + + It should be clear then, that as long as a list of variables to be saved is + ready at the end of the fake page, a closure may be created which could be + used to restore the environment at the start of a subsequent fragment. + + Such variables would include , and + . These values would also want initialising for the + first fake-page fragment, so it becomes clear that a default closure need + to be established as the basis for each new fake-page. + + Other packages may introduce further variables that need + enclosing for the fake page. + + Therefore we introduce a mechanism so that such enclosed variables may be + declared as such pages are used.\ + + Simple Way + + will hold a list of variable names, usually + one per package. Each variable will hold a tuple of variable names and + default values. + + As some of those packages may get initialised before the fake page package, + we need a way for them to register these values that can be picked up + later. We can't define a macro to help with this, as the fake page package + might not be loaded at that time. + + A package would declare it's closure variables by storing their names and + values in a tuple. For instance, the widget package might do this: + + |widget-states|>>> + + The name of this list is added to the list of names --- we add the name of + the variable (enclose-widget) containing the enclosed variables, not it's + value (). + + ||>|>>> + + It's a bit clumsy, but fails when invoked on the value of + an undefined variable. + + Advanced Way + + Each package registers a callback that will be invoked when the fake-page + package loads. + + The widget would define it's callback like this: + + >>>> + + And invoke the callback if fake page has already loaded, otherwise register + the callback in so that the fake page package + will invoke it later: + + |>|||>|>>>> + + Bugs + + If a fake page fragment were to terminate part way through a nested enum, + the nested structure could not be re-created by means of the closure. Each + fragment has to be fully normal, with all open tags closed at the end of + the fake page chunk. This type of fragment could be permitted if the entire + fake page were present within each fragment but with rendering disabled + except between certain checkpoints, but at present I have no mechanism to + divert rendering to a null device which can also cross document tag + structure --- i.e. comment rendering after a section heading and halt + rendering halfway through an enum nest. + + References + + Variables are not the only items that need isolating, references create + entries in the document aux section. Two stages of revision of the same + fake page might re-define the same labels. Clearly some further isolation + is needed so that references in one fake page revision to not refer to + labels in subsequent revisions of the same page. + + Each fake page needs to be uniquely defined, so that it's closure + preserving the final values can be named. This definition can be used to + prefix labels and references, as we re-define , + , etc, to use the fake page identifier as a prefix. + + We will call this prefix and it will be part + of the closure. An initial empty value is defined here: + > + + Thus we can override the macro within the fake page like + this: + + |>|>>>>>>>> + + We have overridden be a tuple of the original + and . This is because we need to be + able to recover the fake page number later, but will insert the + real page number during pagination. + + After faking we then fake the label name with + which prefixes the label name with our + fake page base name. + + |-|>>>> + + Of course, now we have "fixed" the macro, we need to fix + the macro to match. + + BUG: Normally will emit a locus whose displayed value + is the original value of and whose action navigates to + that location. We stored the original as the first + member of a tuple. Thus we show the correct label text --- which is good + for type-setting, but this is not yet active as a link. + + >>|0>||0|>>>>>> + + We use a tuple helper macro to return the first + tuple member, or if that fails, to return uninit rather than an error. + + >|tuple>|>|>>||>|>>>> + + Fake page hierachy + + As a fake page is used in document development, there is a hierachy of + relationships between revisions and chunks. + + Typically the example document will be developed in parts, and each part + will undergo revisions. In the diagram shown, only the outlined elements + represent fake pages, the other elements are just to help label the + hierachy of closure inheritance. + + |>||>|||>||>||>>>|||>>>>> + + Once a part is completed with it's final revision, it will serve as the + basis for the next part which will inherit it's labels and counters. Of + course any revision of any part could serve as the basis for another part, + and in some cases a further revision of Part 1 may be shown, perhaps + followed by further revisions of further parts. + + A fake page is emitted with the tag: > + + The first argument is the name of the fake page to continue from, but can + be empty --- meaning the default closure. The second arument is the name + given to this fake page, which is important if a further page would + continue from this page. Any remaining argument pairs are like the pairs of + a clause with the final argument being the page contents. + + As a convenience a new revision can be emitted with: + > + + This is like except instead of continuing from + it continues from what continued + from, thus it is a replacement. + + Thus, to contrive the relationships shown in the diagram, these macros + would have been executed in this order:\ + + <\inactive*> + + + + + + + + + + + + + + + + + + Of course you could re-use the as the + , though this would make it impossible to reference the + in any way. + + \; + + \; + + \; + + \; + + \; + + \; + + \; + + \; + + \; + + >|error>||>>||>>> + + \; + + |label||pagerefpage||old-reference||reference||this-page-no|>|>>> + + >>> + + |>|page-no||0>|instance||0>|fake-page-base-name||-||-|>|>||>>>>>> + + |1>>> + + \; + + \; + + +<\initial> + <\collection> + + + \ No newline at end of file diff --git a/fangle.ts b/fangle.ts index 4b34c09..2a3fe0a 100644 --- a/fangle.ts +++ b/fangle.ts @@ -167,31 +167,39 @@ - >|tuple>|>|>>||>|>>> + >|tuple>|>|>>||>|>>> - |gr-frame|>|gr-geometry||gr-color|red|gr-auto-crop|false||>>||>>||>>>>>> + |gr-frame|>|gr-geometry||gr-color|red|gr-auto-crop|false||>>||>>||>>>>>> - |>>>>>> + |>>>>>> - + - |-|>>> + |-|>>> - |>|>>>>>>> + |>|>>>>>>> - >>|0>|1|>>>> + >>|0>||0|>>>>> - >>|0>||0|>>>>> + |label||pagerefpage||old-reference||reference||this-page-no|>|>>> - |label||pagerefpage||old-reference||reference||this-page-no|>|>>> + |>>||>>> - |>>||>>> + |>>||>>> - |>>||>>> + |>|page-no||0>|instance||0>|fake-page-base-name||-||-|>|>||>>>>>> - |>|page-no||0>|instance||0>|fake-page-base-name||-||-|>|>||>>>>>> + |1>>> - |1>>> + \; + + \; + + \; + + \; + + >>|0>|1|>>>> <\active*> <\src-comment> -- 2.11.4.GIT