From: Norman Walsh Date: Sat, 6 Oct 2001 13:39:05 +0000 (+0000) Subject: Lots and lots and lots of changes X-Git-Tag: release/1.79.1~6^2~6231 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4edbfa236f017ad87ba3ef7fe129771b6ffa4f2;p=docbook-dsssl Lots and lots and lots of changes --- diff --git a/litprog/.cvsignore b/litprog/.cvsignore index ef6a50e1f..cce1f48ea 100644 --- a/litprog/.cvsignore +++ b/litprog/.cvsignore @@ -1,10 +1,9 @@ -wdocbook.xml wdocbook.xsl -wdocbook.html weave.xml weave.xsl weave.html tangle.xml tangle.xsl tangle.html +xtangle.xsl diff --git a/litprog/.stylesheets/fo.xsl b/litprog/.stylesheets/fo.xsl new file mode 100644 index 000000000..d8ed8ff14 --- /dev/null +++ b/litprog/.stylesheets/fo.xsl @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/litprog/.stylesheets/html.xsl b/litprog/.stylesheets/html.xsl new file mode 100644 index 000000000..01ecb4bd0 --- /dev/null +++ b/litprog/.stylesheets/html.xsl @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/litprog/Makefile b/litprog/Makefile index 90a2b7d22..c9f84079d 100644 --- a/litprog/Makefile +++ b/litprog/Makefile @@ -1,46 +1,65 @@ include ../cvstools/Makefile.incl -all: tangle.xsl weave.xsl wdocbook.xsl +all: tangle.xsl weave.xsl wdocbook.xsl xtangle.xsl $(MAKE) -C html + $(MAKE) -C example -xml: tangle.xml weave.xml wdocbook.xml +xml: tangle.xml weave.xml + $(MAKE) -C html xml + $(MAKE) -C example xml -html: xml tangle.html weave.html wdocbook.html +html: xml tangle.html weave.html + $(MAKE) -C html html + $(MAKE) -C example html -tangle.html: tangle.xml html/ldocbook.xsl +%.html: %.xml html/ldocbook.xsl $(XSLT) $< html/ldocbook.xsl $@ -tangle.xml: tangle.xweb wdocbook.xsl - $(XSLT) $< wdocbook.xsl $@ +%.fo: %.xml fo/ldocbook.xsl + $(XSLT) $< fo/ldocbook.xsl $@ + +%.pdf: %.fo + xep $< $@ + rm -f $@ # Can this rule be improved? Ideally bootstrap-tangle should only be # required if tangle.xsl doesn't exist. If it exists but is out-of-date # it can rebuild itself. -tangle.xsl: tangle.xweb bootstrap-tangle.xsl - $(XSLT) $< bootstrap-tangle.xsl .temp.xsl - $(XSLT) $< .temp.xsl tangle.xsl - rm -f .temp.xsl +xtangle.xsl: tangle.xweb bootstrap-tangle.xsl + $(XSLT) $< bootstrap-tangle.xsl .boot.tangle.xsl + $(XSLT) $< .boot.tangle.xsl $@ top=xtop + rm -f .boot.tangle.xsl + +tangle.xsl: tangle.xweb xtangle.xsl + $(XSLT) $< xtangle.xsl $@ + +tangle.xml: tangle.xweb wdocbook.xsl + $(XSLT) $< wdocbook.xsl $@ -weave.html: weave.xml html/ldocbook.xsl - $(XSLT) $< html/ldocbook.xsl $@ +weave.xsl: weave.xweb xtangle.xsl + $(XSLT) $< xtangle.xsl $@ weave.xml: weave.xweb wdocbook.xsl $(XSLT) $< wdocbook.xsl $@ xjparse $@ -weave.xsl: weave.xweb tangle.xsl - $(XSLT) $< tangle.xsl $@ +wdocbook.xsl: weave.xweb xtangle.xsl weave.xsl + $(XSLT) $< xtangle.xsl $@ top=wdocbook -wdocbook.html: wdocbook.xml wdocbook.xsl - $(XSLT) $< wdocbook.xsl $@ +realclean: clean + rm -f xtangle.xsl + rm -f weave.xsl wdocbook.xsl + rm -f tangle.xsl + $(MAKE) -C html realclean + $(MAKE) -C fo realclean + $(MAKE) -C example realclean + +clean: + rm -f weave.{xml,html,fo,pdf} + rm -f tangle.{xml,html,fo,pdf} + $(MAKE) -C html clean + $(MAKE) -C fo clean + $(MAKE) -C example clean -wdocbook.xml: wdocbook.xweb wdocbook.xsl - $(XSLT) $< wdocbook.xsl $@ -wdocbook.xsl: wdocbook.xweb tangle.xsl - $(XSLT) $< tangle.xsl $@ -clean: - rm -f weave.{xsl,xml,html} - rm -f tangle.{xsl,xml,html} - rm -f wdocbook.{xsl,xml,html} diff --git a/litprog/bootstrap-tangle.xsl b/litprog/bootstrap-tangle.xsl index 9820a53d5..2b9018090 100644 --- a/litprog/bootstrap-tangle.xsl +++ b/litprog/bootstrap-tangle.xsl @@ -10,8 +10,10 @@ + + - + @@ -20,10 +22,6 @@ - - - - diff --git a/litprog/example/.cvsignore b/litprog/example/.cvsignore new file mode 100644 index 000000000..98bca1f22 --- /dev/null +++ b/litprog/example/.cvsignore @@ -0,0 +1,8 @@ +doc.html +doc.xml +doc.xpp +doc.xsd +fib.html +fib.pl +fib.xml +fib.xpp diff --git a/litprog/example/Makefile b/litprog/example/Makefile new file mode 100644 index 000000000..268e1c5c8 --- /dev/null +++ b/litprog/example/Makefile @@ -0,0 +1,45 @@ +include ../../cvstools/Makefile.incl + +all: fib.pl doc.xsd fib.xpp doc.xpp + +html: doc.html fib.html + +xml: doc.xml fib.xml + +doc.html: doc.xml + $(XSLT) $< doc.xsl $@ + +doc.xml: doc.xweb + $(XSLT) $< ../wdocbook.xsl $@ + +doc.xsd: doc.xweb + $(XSLT) $< ../xtangle.xsl $@ + +doc.xpp: doc.xweb prettyprint.pl + perl prettyprint.pl $< > $@ + +fib.html: fib.xml + $(XSLT) $< ../html/ldocbook.xsl $@ + +fib.fo: fib.xml + $(XSLT) $< ../fo/ldocbook.xsl $@ + +fib.pdf: fib.fo + xep $< $@ + +fib.pl: fib.xweb + $(XSLT) $< ../tangle.xsl $@ + +fib.xml: fib.xweb + $(XSLT) $< ../wdocbook.xsl $@ + +fib.xpp: fib.xweb prettyprint.pl + perl prettyprint.pl $< > $@ + +realclean: + rm -f doc.{xsd,xpp} + rm -f fib.{pl,xpp} + +clean: + rm -f doc.{html,xml,fo,pdf} + rm -f fib.{html,xml,fo,pdf} diff --git a/litprog/example/doc.xsl b/litprog/example/doc.xsl new file mode 100644 index 000000000..f70b625c0 --- /dev/null +++ b/litprog/example/doc.xsl @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+          
+        
+
+
+ + + + + + + + + + + + § + + . + + + + + + + + + + +
diff --git a/litprog/example/doc.xweb b/litprog/example/doc.xweb new file mode 100644 index 000000000..8e081edb9 --- /dev/null +++ b/litprog/example/doc.xweb @@ -0,0 +1,102 @@ + + +Document Schema + + +
+

A Simple Document W3C XML Schema

+ +

This schema defines elements in the +urn:publicid:-:Norman+Walsh:Schema Example:EN namespace.

+ +

This schema defines several complex types and several elements that +are instances of those types.

+ + + + + + + +
+ +
+

The Complex Types

+ +

There are three complex types in this schema: doc, +title, and para.

+ + + + + + + +
+

The doc Type

+ + + + + + + + + + + +
+ +
+

The title Type

+ + + + + + + + +
+

The role Attribute

+ +

The role attribute is an optional string.

+ + + + +
+
+ +
+ +

The para Type

+ + + + + + + +
+
+ +
+

The Elements

+ +

This schema defines one element of each complex +type.

+ + + + + + +
+ \ No newline at end of file diff --git a/litprog/example/fib.xweb b/litprog/example/fib.xweb new file mode 100644 index 000000000..b5a5aaef2 --- /dev/null +++ b/litprog/example/fib.xweb @@ -0,0 +1,91 @@ +
+ +Calculating Members of the Fibonacci Series + + Norman + Walsh + + + +This trivial document describes a simple, recursive +implementation of the Fibonacci series in Perl. The principal +motivation for this document is to demonstrate the use of Literate XML. + + +
The <function>fib</function> Function + +The heart of this program is the recursive function that +calculates the members of the Fibonacci series. + +The first and second members of the Fibonnacci series are +1; all other values are calculated recursively. + + +sub fib { + my $n = shift; + + if ($n <= 2) { + return 1; + } else { + return + } +} + + +
Recursive Definition + +The Fibonacci series begins: 1 1 2 3 5 8 13... Each member of +the series, after the first two, is the sum of the preceding two +members. + +This can be implemented recursively by calculating the preceding +two members of the series and returning their sum: + + +&fib($n-2) + &fib($n-1); + + +
+
+ +
Preamble + +The program preamble simply establishes a default location for +the Perl executable and informs the interpreter that we want to use +the strict pragma. + + +#!/usr/bin/perl -w + +use strict; + +
+ +
Argument Checking + +This program expects its argument on the command line and it expects +that argument to be an unsigned decimal integer. + + +my $num = shift @ARGV || die; + +die "Not a number: $num\n" if $num !~ /^\d+$/; + +
+ +
The Program + +The program prints out the Fibonacci number requested: + + + + + +print "Fib($num) = ", &fib($num), "\n"; + + + +
+ +
diff --git a/litprog/example/prettyprint.pl b/litprog/example/prettyprint.pl new file mode 100644 index 000000000..5ddbecab9 --- /dev/null +++ b/litprog/example/prettyprint.pl @@ -0,0 +1,120 @@ +#!/usr/bin/perl -w + +use strict; + +my $file = shift @ARGV || die "Usage: $0 file.xml\n"; + +open (F, $file); +read (F, $_, -s $file); +close (F); + +print ""; + +if (//s) { + print &charescape($&); + &prettyprint($'); + } elsif (//) { + print &charescape($&); + &prettyprint($'); + } else { + die "Unparseable !DOCTYPE declaration.\n"; + } +} else { + &prettyprint($_); +} + +print "\n"; + +sub prettyprint { + local $_ = shift; + + while (/<(.*?)>/s) { + my $post = $'; + $_ = $1; + + print &escape($`); + + if (/^\?(.*)\?$/s) { + print &pi($1); + } elsif (/^\!--(.*)--$/s) { + print &comment($1); + } elsif (/^\/(.*)$/s) { + print &endtag($1); + } else { + print &starttag($_); + } + + $_ = $post; + } + + print &escape($_); +} + +sub escape { + local $_ = shift; + my $ret = ""; + + while (/&(\S+?);/) { + my $pre = $`; + my $ent = $1; + my $post = $'; + + $ret .= &charescape($pre); + if ($ent =~ /^\#/) { + $ret .= &sgmltag('numcharref', $ent); + } else { + $ret .= &sgmltag('genentity', $ent); + } + + $_ = $post; + } + + return $ret . &charescape($_); +} + +sub charescape { + local $_ = shift; + + s/&/&/sg; + s//>/sg; + + return $_; +} + +sub sgmltag { + my $class = shift; + my $content = shift; + +# my $tagname = "???"; +# $tagname = $1 if $content =~ s/^(\S+)/$1/s; +# $tagname =~ s/:/-/sg; + + return "$content" +} + +sub pi { + return &sgmltag('xmlpi', $_[0]); +} + +sub comment { + return &sgmltag('sgmlcomment', $_[0]); +} + +sub starttag { + my $content = shift; + + if ($content =~ /\/$/) { + return &sgmltag('emptytag', $`); + } else { + return &sgmltag('starttag', $content); + } +} + +sub endtag { + return &sgmltag('endtag', $_[0]); +} diff --git a/litprog/fo/.cvsignore b/litprog/fo/.cvsignore new file mode 100644 index 000000000..ac9bfae7d --- /dev/null +++ b/litprog/fo/.cvsignore @@ -0,0 +1 @@ +ldocbook.xsl diff --git a/litprog/fo/Makefile b/litprog/fo/Makefile new file mode 100644 index 000000000..ec1956072 --- /dev/null +++ b/litprog/fo/Makefile @@ -0,0 +1,18 @@ +include ../../cvstools/Makefile.incl + +all: ldocbook.xsl + +xml: + echo Nothing to do here, build xml in ../html instead + +html: + echo Nothing to do here, build html in ../html instead + +ldocbook.xsl: ../html/ldocbook.xweb ../xtangle.xsl + $(XSLT) $< ../xtangle.xsl $@ top=fo-top + +realclean: clean + rm -f ldocbook.xsl + +clean: + rm -f ldocbook.{html,xml} diff --git a/litprog/html/Makefile b/litprog/html/Makefile index 6ea11a0ac..865ee88cb 100644 --- a/litprog/html/Makefile +++ b/litprog/html/Makefile @@ -12,8 +12,12 @@ ldocbook.html: ldocbook.xml ldocbook.xsl ldocbook.xml: ldocbook.xweb ../wdocbook.xsl $(XSLT) $< ../wdocbook.xsl $@ -ldocbook.xsl: ldocbook.xweb ../tangle.xsl - $(XSLT) $< ../tangle.xsl $@ +ldocbook.xsl: ldocbook.xweb ../xtangle.xsl + $(XSLT) $< ../xtangle.xsl $@ + +realclean: clean + rm -f ldocbook.xsl clean: - rm -f ldocbook.html ldocbook.xml ldocbook.xsl + rm -f ldocbook.html ldocbook.xml + diff --git a/litprog/html/ldocbook.xweb b/litprog/html/ldocbook.xweb index 2493ef883..c84257af1 100644 --- a/litprog/html/ldocbook.xweb +++ b/litprog/html/ldocbook.xweb @@ -1,22 +1,151 @@ +XWEB"> + + + +]>
-Litprog.xsl + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format"> + +Literate DocBook XML Stylesheets +Part of +Literate Programming in XML +05 Oct 2001 + +$Id$ + - + + +0.1 +05 Oct 2001 +ndw +Initial draft. + + + +NormanWalsh + + + + + +The ldocbook.xsl stylesheet transforms an +&xweb; documentation file (a woven &xweb; document) +into HTML documentation. + +This stylesheet assumes that fragments appear inside DocBook +section elements. Some additional customization of +the and + will be required +to support a different organization. + +
The Stylesheets + +This document describes both the HTML and XSL Formatting Objects +versions of the stylesheet. + +
The HTML Stylesheet + +The stylesheet performs some initialization and establishes +templates for the Literate Programming elements that can appear in +the documentation. Most of the documentation elements will be +DocBook elements handled by the imported stylesheet. + + - + + + + + - + -
The Rest +
+
The FO Stylesheet - - +The stylesheet performs some initialization and establishes +templates for the Literate Programming elements that can appear in +the documentation. Most of the documentation elements will be +DocBook elements handled by the imported stylesheet. + + + + + + + + + + + + + + +
+ +
Initialization + +The stylesheet initializes the processor by loading its version +information (stored in a separate file because it is shared by several +stylesheets), importing the base DocBook stylesheet, setting some +parameters, and setting up +some internationalized text. + + + + + + + + + +
Parameters + +In DocBook Literate Programming documentation, we always number +sections and verbatim environments. + + + + + + +
+ +
Localization + +Localized text in the DocBook stylesheets makes use of an +external document to determine the nature of, among other things, +element titles and cross references. + +Cross references to src:fragments are not +supported in the stock stylesheets (since there is no such element +in DocBook). + +In order to make cross references work properly, we must provide +an appropriate localization for src:fragment titles. +We do this by pointing the local.l10n.xml +at ourselves (at the stylesheet document). + +In our local localization document, we add an +l:i18n element to provide the necessary context. + +If you want to support DocBook Literate Programming in other +languages, this section will have to be updated. + + @@ -26,28 +155,44 @@ + +
+
+
- - - +
Process HTML Fragments - +Fragments are output as verbatim environments with numbered lines, +if possible. A table is used to make the listings stand out. + + + + + - - - - + + + - - - +Fragment labels and titles must also be supported. - - ( +
Fragment Labels - - - - XRef to nonexistent id: - - - ??? - +A fragment label consists of a section mark followed by the +label of the current section and the number of the fragment within +that section. - - - - - - - - - - - - + + + - - - - - - - + § - - + + + + + + + + + + + + . + + + + + + - ) + +
- +
Fragment Titles + +A fragment title is the title of the section that contains it. + + + + - - § - - - . + - + + + +
+
+ +
Process FO Fragments + +Fragments are output as verbatim environments with numbered lines, +if possible. + + + + + + + + + + + + + + + + + + : + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
Process HTML Fragment References + +A fragment reference has exactly the same semantics as a DocBook +xref. + + + + + + + +
Fragment Cross-Reference Text - +Cross references to fragments produce the fragment label +and title. + + + - § - - + + . + + +
+
- - SRC:FRAGMENT TITLE +
Process FO Fragment References + +A fragment reference has exactly the same semantics as a DocBook +xref. + + + + + + + +
Fragment Cross-Reference Text +Cross references to fragments produce the fragment label +and title. + + + + + + + + . + + +
+
diff --git a/litprog/tangle.xweb b/litprog/tangle.xweb index bb70fe4e8..d905a77d5 100644 --- a/litprog/tangle.xweb +++ b/litprog/tangle.xweb @@ -1,99 +1,282 @@ +XWEB"> +]>
-Tangle.xsl + +Tangle +Part of +Literate Programming in XML +05 Oct 2001 + +$Id$ + - - -<!DOCTYPE xsl:stylesheet [ -<!ENTITY nl "<xsl:text> </xsl:text>"> -]> - + + +0.1 +05 Oct 2001 +ndw +Initial draft. + + + +NormanWalsh + + + + + +The tangle.xsl stylesheet transforms an +&xweb; document into a source code document. This +is a relatively straightforward process: starting with the top fragment, +all of the source fragments are simply stitched together, discarding any +intervening documentation. + +The resulting tangled document is ready for use +by the appropriate processor. + +
The Stylesheet + +This &xweb; document contains the source for two stylesheets, +tangle.xsl and xtangle.xsl. +Both stylesheets produce tangled sources, the latter is a simple +customization of the former for producing XML vocabularies. + +Each of these stylesheets performs some initialization, sets +the output method appropriately, begins processing at the root template, +and processes fragments, copying the content appropriately. + +
The <filename>tangle.xsl</filename> Stylesheet + +The tangle stylesheet produces text output. + + - + + + - - - - - + + - + +
-
Stuff +
The <filename>xtangle.xsl</filename> Stylesheet - - +The xtangle stylesheet produces XML output. + + + + + + + + + + + + + +
+
+ +
Initialization + +The stylesheet initializes the processor by loading its version +information (stored in a separate file because it is shared by several +stylesheets) and telling the processor to preserve whitespace on all +input elements. + +The stylesheet also constructs a key for the ID values used on +fragments. Because &xweb; documents do not have to be valid according +to any particular DTD or Schema, the stylesheet cannot rely on having +the IDs identified as type ID in the source document. + + + + + + + + - - +
+ +
The Root Template + +The root template begins processing at the root of the &xweb; +document. It outputs a couple of informative comments and then +directs the processor to transform the src:fragment +element with the $top ID. + +Source code fragments in the &xweb; document are not required +to be sequential, so it is necessary to distinguish one fragment +as the primary starting point. + - - - This file was generated by tangle.xsl version - - . Do not edit! - - - See http://sourceforge.net/projects/docbook/ - + +
- - - - - - - - - +
Processing Fragments - - - - +In order to tangle an &xweb; document, we need +only copy the contents of the fragments to the result tree. +Processing src:fragment elements is easy, simply copy +their children: + + +
- - - - - - - - - - - - +
Copying Elements + +Copying elements to the result tree can be divided into four +cases: copying passthrough elements, +copying fragment references, and +copying everything else. + + + + + + + +
+Copying <sgmltag>src:passthrough</sgmltag> +Passthrough elements contain text that is intended to appear +literally in the result tree. We use XSLT +disable-output-escaping to copy it without +interpretation: + + + +
+ +
+Copying <sgmltag>src:fragref</sgmltag> + +With a unique exception, copying fragment references is +straightforward: find the fragment that is identified by the +cross-reference and process it. + + +The single exception arises only in the processing of +src:fragref elements in the weave.xweb +document. There is a single template in the weave program +that needs to copy a literal src:fragref element to the +result tree. That is the only time the + branch is executed. + + + + + + + + +
Copying Normal Fragment References + +To copy a normal fragment reference, identify what the +linkend attribute points to, +make sure it is valid, and process it. + + + + + + + + +
Fragment is Unique + +Make sure that the linkend +attribute points to exactly one node in the source tree. It is an error +if no element exists with that ID value or if more than one exists. + + + + Link to fragment " + + " does not uniquely identify a single fragment. + + + +
+ +
Fragment is a <sgmltag>src:fragment</sgmltag> + +Make sure that the linkend +attribute points to a src:fragment element. + +FIXME: this code should test the namespace name of the $fragment + + + + + Link " + + " does not point to a src:fragment. + + + +
+
+
+ +
Copying Disable-Output-Escaping Fragment References + +A src:fragref that specifies +disable-output-escaping is treated +essentially as if it was +any other element. The only +exception is that the +disable-output-escaping attribute +is not copied. + +Because tangle and +weave are XSLT stylesheets that process +XSLT stylesheets, processing src:fragref poses +a unique challenge. + +In ordinary tangle processing, they +are expanded and replaced with the content of the fragment that they +point to. But when weave.xweb is tangled, they +must be copied through literally. The +disable-output-escaping attribute +provides the hook that allows this. + + + - - - - - - + + @@ -101,21 +284,101 @@ - - - - - - - + +
+ +
+Copying Everything Else + +Everything else is copied verbatim. This is a five step process: + + + +Save a copy of the context node in +$node so that we can refer to it later from +inside an xsl:for-each. + +Construct a new node in the result tree with +the same qualified name and namespace as the context node. + +Copy the namespace nodes on the context node to the +new node in the result tree. We must do this manually because the +&xweb; file may have broken the content of this element into several +separate fragments. Breaking things into separate fragments makes it +impossible for the XSLT processor to always construct the right namespace +nodes automatically. + +Copy the attributes. + +Copy the children. + + + + + + + + + + + + + + +For non-XML source docuements, this template will never match +because there will be no XML elements in the source fragments. + +
Copy Namespaces + +Copying the namespaces is a simple loop over the elements on +the namespace axis, with one wrinkle. + +It is an error to copy a namespace node onto an element if a +namespace node is already present for that namespace. The fact that +we're running this loop in a context where we've constructed the +result node explicitly in the correct namespace means that attempting +to copy that namespace node again will produce an error. We work +around this problem by explicitly testing for that namespace and not +copying it. + + + + + + + + + + +
+
+
+ +
Copy XML Constructs + +In the xtangle.xsl stylesheet, we also want +to preserve XML constructs (processing instructions and comments) that +we encounter in the fragments. + +Note that many implementations of XSLT do not provide comments in +the source document (they are discarded before building the tree), in which +case the comments cannot be preserved. + + + + + + - + +
+
diff --git a/litprog/weave.xweb b/litprog/weave.xweb index 4ab4dfbf0..9be98082f 100644 --- a/litprog/weave.xweb +++ b/litprog/weave.xweb @@ -1,49 +1,138 @@ +XWEB"> + + + +]>
-Weave.xsl + +Weave +Part of +Literate Programming in XML +05 Oct 2001 + +$Id$ + - - -<!DOCTYPE xsl:stylesheet [ -<!ENTITY nl "<xsl:text> </xsl:text>"> -]> - + + +0.1 +05 Oct 2001 +ndw +Initial draft. + + + +NormanWalsh + + + + + +The weave.xsl stylesheet transforms an +&xweb; document into a documentation document. This +is accomplished by weaving the documentation from +the &xweb; file with a pretty-printed version of the source code. + +The resulting document is ready to be processed by whatever +down-stream publishing tools are appropriate. + +
The Stylesheet + +The stylesheet performs some initialization, begins processing +at the root of the &xweb; document, and processes fragments and +elements. This stylesheet also requires some recursive templates that +are stored at the end of the stylesheet. + + + + + + + + + + - +
Initialization - +The stylesheet initializes the processor by loading its version +information (stored in a separate file because it is shared by several +stylesheets), telling the processor to preserve whitespace on all +input elements, setting the output method, and initializing +the excluded result prefixes. + +The stylesheet also constructs a key for the ID values used on +fragments. Because &xweb; documents do not have to be valid according +to any particular DTD or Schema, the stylesheet cannot rely on having +the IDs identified as type ID in the source document. + + + + + - - - - - - - + -
Whitespace Control + + - - +
+Default Exclude Result Prefixes + +Generally, the namespace declarations for namespaces used by +the source code portion of the &xweb; file are not needed in the +woven documentation. To reduce the size of the documentation +file, and to reduce the clutter of unnecessary declarations, you can +specify prefixes that should be excluded. + +This is done as a parameter so that it can be adjusted dynamically, +though it rarely needs to be. The initial value comes from the +mundane-result-prefixes +attribute on the &xweb; file's top src:fragment. + + + +
-
Default Exclude Result Prefixes +
Named Templates - - +Correctly copying elements requires the ability to calculate +applicable namespaces and output the appropriate namespace psuedo-attributes +and attributes. These templates accomplish those tasks. + + + + + + + + +
+
Root Template +The root template begins processing at the root of the &xweb; +document. It outputs a couple of informative comments and then +processes the document. + +Source code fragments in the &xweb; document are not required +to be sequential, we assume that they appear in the order in which +they should be documented. + @@ -59,98 +148,431 @@
-
Default Template - - - - - - - - - - - - +
Fragments + +The goal when copying the source code fragments +is to preserve the src:fragment +elements in the documentation file (so that they can be formatted +appropriately) but to escape all of the fragment content so that +it appears simply as text in the documentation. + +For example, if the following fragment appears in the &xweb; file: + + +<src:fragment id="foo"> + <emphasis>some code</emphasis> +</src:fragment> + +the documentation must contain: + +<src:fragment id="foo"> + &lt;emphasis&gt;some code&lt;/emphasis&gt; +</src:fragment> + +The significance of this escaping is less obvious when the +fragment contains non-XML code, but it is in fact still relevant. + +This task is accomplished by constructing a literal +src:fragment element and then copying the content +of the source document's src:fragment element +in a mode that escapes all markup characters. + + + + + + + + + + + + +
Copying Content + +The copy-content template +could be as simple as: + +<xsl:apply-templates mode="copy"/> + +but we play one more trick for the convenience of &xweb; authors. + + +It's convenient for authors to use newlines at the beginning +and end of each program fragment, producing fragments that look like +the one shown above. The problem is that white space is significant +inside fragments, so the resulting documenation will contain a listing +like this: + + 1 | + 2 | <emphasis>some code</emphasis> + 3 | + +The leading and trailing blank lines in this listing are distracting +and almost certainly insignificant. Authors can avoid this problem by +removing the offending newlines: + +<src:fragment id="foo"><emphasis>some code</emphasis></src:fragment> + +but this makes the source document more difficult to read and +introduces tedious cut-and-paste problems. To avoid this problem, the +copy-content template takes special +pains to trim off one optional leading newline and one optional +trailing newline. It does this by dealing with the first, last, and +middle nodes of the src:fragment elements +separately: + + + + + + + +
Convenience Variables + +For convenience, we store subexpressions containing the first, +last, and all the middle nodes in variables. + + + + + + +
-
Fragments - - - +
Handle First Node + +Handling the leading newline is conceptually a simple matter of +looking at the first character on the line and skipping it if it is +a newline. A slight complexity is introduced by the fact that if the +fragment contains only a single text node, the first node is also the +last node and we have to possibly trim off a trialing newline as well. +We separate that out as a special case. + + + - - + + + + + + +
Handle A Fragment that Contains a Single Node + +If the $first-node is a text node and the +fragment contains only a single child, then it is also the last node. + +In order to deal with a single text node child, we must address +four cases: the node has both leading and trailing newlines, the node +has only leading newlines, only trailing newlines, or no newlines at +all. + + + + + + + + + + + + +
More Convenience Variables + +For convenience, we calculate whether or not the node in question +has leading and/or trailing newlines and store those results in variables. + + + + + + +
+ +
Handle a Single Node With Leading and Trailing Newlines + +If the node has both leading and trailing newlines, trim a character +off each end. + + + + + + +
+ +
Handle a Single Node With Only Leading Newlines + +If the node has only leading newlines, trim off the first character. + + + + + + + +
+ +
Handle a Single Node with Only Trailing Newlines + +If the node has only trailing newlines, trim off the last character. + + + + + + + +
+ +
Handle a Single Node with No Newlines + +Otherwise, the node has no newlines and it is simply printed. + + + + + + + +
+
+ +
Handle a First Node with a Leading Newline + +If the first node is a text node and begins with a newline, +trim off the first character. + + + + + + +
+ +
Handle a First Node without a Leading Newline + +Otherwise, the first node is not a text node or does not begin +with a newline, so use the copy mode to copy it to +the result tree. + + - + - - - +
+
- - - +
Handle Last Node + +Handling the last node is roughly analagous to handling the first +node, except that we know this code is only evaluated if the last node +is not also the first node. + +If the last node is a text node and ends with a newline, strip +it off. Otherwise, just copy the content of the last node +using the copy mode. + + + - - + + - + - -
-
Rest - +
Handle the Middle Nodes - +The middle nodes are easy, just copy them +using the copy mode. + + + + + +
+
+
+ +
Fragment References - - +Fragment references, like fragments, are simply copied to the +documentation file. The use of +disable-output-escaping is +unique to this template (it instructs the tangle +stylesheet to make a literal copy of the src:fragref, +rather than expanding it, as it usually would). + + + - +
Copying Elements + +Copying elements to the result tree can be divided into four +cases: copying passthrough elements, +copying fragment references and +copying everything else. + + + + + + + +
+Copying <sgmltag>src:passthrough</sgmltag> + +Passthrough elements contain text that is intended to appear +literally in the result tree. We simply copy it through. + + + + + + + +
+ +
+Copying <sgmltag>src:fragref</sgmltag> + +Because tangle and +weave are XSLT stylesheets that process +XSLT stylesheets, processing src:fragref poses +a unique challenge. + +In ordinary tangle processing, they +are expanded and replaced with the content of the fragment that they +point to. But when weave.xweb is tangled, they +must be copied through literally. The +disable-output-escaping attribute +provides the hook that allows this. + + +When we're weaving, if the +disable-output-escaping attribute +is yes, the src:fragref is treated literally. +When it isn't, the element is copied through literally. + + + + + + <src:fragref linkend=" + + "/> + + </src:fragref> + + + + + + + +
+ +
+Copying Everything Else + +There are two kinds of everything else: elements and other +nodes. + + + + + + +This element template is quite complex, but it's goal is simple: +to translate bona-fide elements in the source document into text in +the result document. In other words, where the element +<foo> occurs in the source +document, the result document should contain +&lt;foo&gt;. + +Three things make this tricky: + + +Elements in the source documents may have namespace +nodes associated with them that are not explicitly declared on them. +To the best of our ability, we must avoid copying these namespace +nodes to the result tree. + +Attributes must be copied and formatted in some reasonable +way in order to avoid excessively long lines in the documentation. + +Empty elements must be printed using the appropriate +empty-element syntax. (It is simply impossible to determine what syntax +was used in the source document, the best we can do is always use the +empty-element syntax in the result as it is likely to be more common +in the soruce.) + + + +The plan of attack is: + + +Calculate what namespaces should be excluded (by prefix). + +Calculate the applicable namespaces. + +Output the leading < and the element +name. + +Output the applicable namespaces. + +Output the attributes. + +If the element is not empty, finish the start tag, +copy the element contents, and output and end tag. If the element is +empty, finish the start tag with the empty-element syntax. + + + + + + <? + + + ?> + + + + <!-- + + --> + - - - - - - - - - - - - - + - < - - @@ -160,6 +582,9 @@ + < + + @@ -169,19 +594,7 @@ - - - - - - - - - - - - - + @@ -196,53 +609,98 @@ + - - - +The preceding template handles elements. Everything else is simply +copied. - - <!-- - - --> + + + + + + - - +
Calculate Excluded Prefixes + +Calculating the excluded prefixes requires evaluating the following +conditions: + + +If the element we are copying is inside a +src:fragment element that specifies a set of +exclude-result-prefixes, use +those prefixes. + +Otherwise, use the +$mundane-result-prefixes we +calculated earlier. + + + +Note that in every case we exclude the namespace associated +with xml. + + + + + + + + + + + +
+ +
Output Attributes + +The mechanics of outputting the applicable attributes is +described in . The +only wrinkle here is that if we have already output +xmlns declarations for namespaces, +the first real attribute is not really the first thing that looks +like an attribute in the result. + + - - <src:fragref linkend=" - - "/> - - </src:fragref> + + + + + - + + + - + +
+
+
- - - +
Count Applicable Namespaces - - - - - +The applicable namespaces are determined by walking recursively +over the list of namespace nodes associated with an element. - - - - - - - - - +For each namespace node, if it has a prefix that is in the list +of excluded prefixes or if it is the Literate Programming namespace, +it is not counted (because it will not be output). Otherwise, it is +counted. +The recursion bottoms out when the list of namespace nodes has +been exhausted. The total number of counted namespaces is then +returned. + + @@ -250,26 +708,6 @@ select="'http://nwalsh.com/xmlns/litprog/fragment'"/> - - @@ -297,7 +735,47 @@ + +
+ +
+Output Applicable Attributes and Pseudo-Attributes + +Outputing the attributes (or namespace psuedo-attributes) is +straightforward, the only tricky part is pretty-printing the resulting +document. + +Pretty-printing has three cases: + + +Before outputting the very first +attribute or psuedo-attribute, we want to output only a single space, +to separate the result from the preceding element name. + +Before outputting any additional attribute or +psuedo-attribute, we want to output a line-feed and then indent the +result appropriately. This prevents the attributes and psuedo-attributes +from appearing as one huge, long line in the result. + +If the element has no attributes or psuedo attributes, +we don't want to output anything; we want the closing tag delimiter +to appear immediately after the element name. + + +
Output Applicable Namespaces + +The applicable namespaces are determined by walking recursively +over the list of namespace nodes associated with an element. + +For each namespace node, if it has a prefix that is in the list +of excluded prefixes or if it is the Literate Programming namespace, +it is not output, otherwise, it is. + +The recursion bottoms out when the list of namespace nodes has +been exhausted. + + @@ -305,39 +783,13 @@ select="'http://nwalsh.com/xmlns/litprog/fragment'"/> - - - + + + - - - - - - - - - + xmlns : @@ -363,23 +815,15 @@ + - - - +
Indent Attribute - +If this is not the first attribute or pseudo-attribute, output a +newline and then indent an appropriate amount. Otherwise, simply output +a space. - - - + @@ -389,6 +833,91 @@ + + +Indenting is accomplished by outputting a series of spaces. The +number of spaces is determined by the length of the name of the current +element plus two (one for the leading < and one for +the space that separates the name from the first attribute). + + + + + + + + + + + + + + + + + + + + +Spaces is a recursive template that outputs a specified +number of spaces. + + + + + + + + + + + + + +Given a string, this template walks it recursively counting +and returning the number of trailing spaces. + + + + + + + + + + + + + + + + + + + + +
+
+ +
Output Applicable Attributes + +This template walks recursively over the attributes associated +with a node and outputs each one of them in turn. (All attributes +are applicable.) + + + + + + + + + + + + =" @@ -401,16 +930,138 @@ + +
+
+
- - - - +
Other Content + +The remaining elements, processing instructions, and comments are +part of the documentation and must simply be copied to the result: + + + + + + + +
Elements + +The default template handles copying elements. +It is a five step process: + + + +Save a copy of the context node in +$node so that we can refer to it later from +inside an xsl:for-each. + +Construct a new node in the result tree with +the same qualified name and namespace as the context node. + +Copy the namespace nodes on the context node to the +new node in the result tree. We must do this manually because the +&xweb; file may have broken the content of this element into several +separate fragments. Breaking things into separate fragments makes it +impossible for the XSLT processor to always construct the right namespace +nodes automatically. + +Copy the attributes. + +Copy the children. + + + + + + + + + + + + - +
Copy Namespaces + +Copying the namespaces is a simple loop over the elements on +the namespace axis, with one wrinkle. + +It is an error to copy a namespace node onto an element if a +namespace node is already present for that namespace. The fact that +we're running this loop in a context where we've constructed the +result node explicitly in the correct namespace means that attempting +to copy that namespace node again will produce an error. We work +around this problem by explicitly testing for that namespace and not +copying it. + + + + + + + +
+
+ +
Processing Instructions + +Processing instructions are simply copied through. + + + + + + + +
+
Comments + +Comments are simply copied through. Note, however, that many +processors do not preserve comments in the source document, so this +template may never be matched. + + + + + + + +
+
+ +
Weaving DocBook + +It's no secret (and probably no surprise) that I use DocBook for +most of my document authoring. Web files are no exception, and I have +DocBook customization layer that validates woven &xweb; documentation +files. + +In order to validate my woven documentation, I need to make sure +that the appropriate document type declaration is associated with the +documents. This is a simple change to the xsl:output +instruction. +This stylesheet imports weave.xsl for the +weaving functionality and simply sets the public and system identifiers. + + + + + + + + + +