diff options
author | Andy Wingo <wingo@pobox.com> | 2013-01-28 10:48:42 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2013-01-28 10:52:44 +0100 |
commit | 3e31e75a462fc05f425b887105ccd6607a56ca3b (patch) | |
tree | 8e37a895d2008e3c0cb5010366dd11ee4dcb8ffe | |
parent | 2b6fcf5b1f6f3cf8d94cada4f00885b275f1a7c5 (diff) | |
download | guile-3e31e75a462fc05f425b887105ccd6607a56ca3b.tar.gz |
begin rewriting SXML docs
* doc/ref/sxml.texi (SXML): Reorder and begin rewriting. Fix formatting
throughout, provide a new introduction, and the beginning of proper
SSAX documentation.
* doc/ref/sxml-match.texi:
* doc/ref/texinfo.texi:
* doc/ref/web.texi: Update references to new node names.
-rw-r--r-- | doc/ref/sxml-match.texi | 10 | ||||
-rw-r--r-- | doc/ref/sxml.texi | 945 | ||||
-rw-r--r-- | doc/ref/texinfo.texi | 14 | ||||
-rw-r--r-- | doc/ref/web.texi | 6 |
4 files changed, 514 insertions, 461 deletions
diff --git a/doc/ref/sxml-match.texi b/doc/ref/sxml-match.texi index 7a1a9ac7c..d2795a5f7 100644 --- a/doc/ref/sxml-match.texi +++ b/doc/ref/sxml-match.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 2010 Free Software Foundation, Inc. +@c Copyright (C) 2010, 2013 Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @c @c Based on the documentation at @@ -16,10 +16,10 @@ @cindex pattern matching (SXML) @cindex SXML pattern matching -The @code{(sxml match)} module provides syntactic forms for pattern matching of -SXML trees, in a ``by example'' style reminiscent of the pattern matching of the -@code{syntax-rules} and @code{syntax-case} macro systems. @xref{sxml simple, -the @code{(sxml simple)} module}, for more information on SXML. +The @code{(sxml match)} module provides syntactic forms for pattern +matching of SXML trees, in a ``by example'' style reminiscent of the +pattern matching of the @code{syntax-rules} and @code{syntax-case} macro +systems. @xref{SXML}, for more information on SXML. The following example@footnote{This example is taken from a paper by Krishnamurthi et al. Their paper was the first to show the usefulness of the diff --git a/doc/ref/sxml.texi b/doc/ref/sxml.texi index 3ce6062f4..ab9881567 100644 --- a/doc/ref/sxml.texi +++ b/doc/ref/sxml.texi @@ -6,257 +6,157 @@ @node SXML @section SXML -@menu -* sxml apply-templates:: A more XSLT-like approach to SXML transformations -* sxml fold:: Fold-based SXML transformation operators -* sxml simple:: Convenient XML parsing and serializing -* sxml ssax:: Functional-style XML parsing for Scheme -* sxml ssax input-parse:: The SSAX tokenizer, optimized for Guile -* sxml transform:: A higher-order SXML transformation operator, @code{pre-post-order} -* sxml xpath:: XPath for SXML -@end menu - -@node sxml apply-templates -@subsection (sxml apply-templates) -@subsubsection Overview -Pre-order traversal of a tree and creation of a new tree: - -@smallexample - apply-templates:: tree x <templates> -> <new-tree> -@end smallexample - -where - -@smallexample - <templates> ::= (<template> ...) - <template> ::= (<node-test> <node-test> ... <node-test> . <handler>) - <node-test> ::= an argument to node-typeof? above - <handler> ::= <tree> -> <new-tree> -@end smallexample - -This procedure does a @emph{normal}, pre-order traversal of an SXML -tree. It walks the tree, checking at each node against the list of -matching templates. - -If the match is found (which must be unique, i.e., unambiguous), the -corresponding handler is invoked and given the current node as an -argument. The result from the handler, which must be a @code{<tree>}, -takes place of the current node in the resulting tree. The name of the -function is not accidental: it resembles rather closely an -@code{apply-templates} function of XSLT. - -@subsubsection Usage -@anchor{sxml apply-templates apply-templates}@defun apply-templates tree templates -@end defun - -@node sxml fold -@subsection (sxml fold) -@subsubsection Overview -@code{(sxml fold)} defines a number of variants of the @dfn{fold} -algorithm for use in transforming SXML trees. Additionally it defines -the layout operator, @code{fold-layout}, which might be described as a -context-passing variant of SSAX's @code{pre-post-order}. - -@subsubsection Usage -@anchor{sxml fold foldt}@defun foldt fup fhere tree -The standard multithreaded tree fold. - -@var{fup} is of type [a] -> a. @var{fhere} is of type object -> a. - -@end defun - -@anchor{sxml fold foldts}@defun foldts fdown fup fhere seed tree -The single-threaded tree fold originally defined in SSAX. @xref{sxml -ssax,,(sxml ssax)}, for more information. +SXML is a native representation of XML in terms of standard Scheme data +types: lists, symbols, and strings. For example, the simple XML +fragment: -@end defun - -@anchor{sxml fold foldts*}@defun foldts* fdown fup fhere seed tree -A variant of @ref{sxml fold foldts,,foldts} that allows pre-order tree -rewrites. Originally defined in Andy Wingo's 2007 paper, -@emph{Applications of fold to XML transformation}. - -@end defun - -@anchor{sxml fold fold-values}@defun fold-values proc list . seeds -A variant of @ref{SRFI-1 Fold and Map,fold} that allows multi-valued -seeds. Note that the order of the arguments differs from that of -@code{fold}. - -@end defun - -@anchor{sxml fold foldts*-values}@defun foldts*-values fdown fup fhere tree . seeds -A variant of @ref{sxml fold foldts*,,foldts*} that allows multi-valued -seeds. Originally defined in Andy Wingo's 2007 paper, @emph{Applications -of fold to XML transformation}. - -@end defun - -@anchor{sxml fold fold-layout}@defun fold-layout tree bindings params layout stylesheet -A traversal combinator in the spirit of SSAX's @ref{sxml transform -pre-post-order,,pre-post-order}. - -@code{fold-layout} was originally presented in Andy Wingo's 2007 paper, -@emph{Applications of fold to XML transformation}. - -@example -bindings := (<binding>...) -binding := (<tag> <bandler-pair>...) - | (*default* . <post-handler>) - | (*text* . <text-handler>) -tag := <symbol> -handler-pair := (pre-layout . <pre-layout-handler>) - | (post . <post-handler>) - | (bindings . <bindings>) - | (pre . <pre-handler>) - | (macro . <macro-handler>) +@example +<parrot type="African Grey"><name>Alfie</name></parrot> @end example -@table @var -@item pre-layout-handler -A function of three arguments: - -@table @var -@item kids -the kids of the current node, before traversal - -@item params -the params of the current node - -@item layout -the layout coming into this node - -@end table +may be represented with the following SXML: -@var{pre-layout-handler} is expected to use this information to return a -layout to pass to the kids. The default implementation returns the -layout given in the arguments. - -@item post-handler -A function of five arguments: - -@table @var -@item tag -the current tag being processed - -@item params -the params of the current node - -@item layout -the layout coming into the current node, before any kids were processed - -@item klayout -the layout after processing all of the children - -@item kids -the already-processed child nodes - -@end table - -@var{post-handler} should return two values, the layout to pass to the -next node and the final tree. +@example +(parrot (@@ (type "African Grey)) (name "Alfie")) +@end example -@item text-handler -@var{text-handler} is a function of three arguments: +SXML is very general, and is capable of representing all of XML. +Formally, this means that SXML is a conforming implementation of the +@uref{XML Information Set,http://www.w3.org/TR/xml-infoset/} standard. -@table @var -@item text -the string +Guile includes several facilities for working with XML and SXML: +parsers, serializers, and transformers. -@item params -the current params +@menu +* SXML Overview:: XML, as it was meant to be +* Reading and Writing XML:: Convenient XML parsing and serializing +* SSAX:: Custom functional-style XML parsers +* Transforming SXML:: Munging SXML with @code{pre-post-order} +* SXML Tree Fold:: Fold-based SXML transformations +* SXPath:: XPath for SXML +* sxml apply-templates:: A more XSLT-like approach to SXML transformations +* sxml ssax input-parse:: The SSAX tokenizer, optimized for Guile +@end menu -@item layout -the current layout +@node SXML Overview +@subsection SXML Overview -@end table +(This section needs to be written; volunteers welcome.) -@var{text-handler} should return two values, the layout to pass to the -next node and the value to which the string should transform. -@end table +@node Reading and Writing XML +@subsection Reading and Writing XML -@end defun +The @code{(sxml simple)} module presents a basic interface for parsing +XML from a port into the Scheme SXML format, and for serializing it back +to text. -@node sxml simple -@subsection (sxml simple) -@subsubsection Overview -A simple interface to XML parsing and serialization. +@example +(use-modules (sxml simple)) +@end example -@subsubsection Usage -@anchor{sxml simple xml->sxml}@defun xml->sxml [port] +@deffn {Scheme Procedure} xml->sxml [port] Use SSAX to parse an XML document into SXML. Takes one optional argument, @var{port}, which defaults to the current input port. +@end deffn -@end defun - -@anchor{sxml simple sxml->xml}@defun sxml->xml tree [port] -Serialize the sxml tree @var{tree} as XML. The output will be written to +@deffn {Scheme Procedure} sxml->xml tree [port] +Serialize the SXML tree @var{tree} as XML. The output will be written to the current output port, unless the optional argument @var{port} is present. +@end deffn -@end defun - -@anchor{sxml simple sxml->string}@defun sxml->string sxml +@deffn {Scheme Procedure} sxml->string sxml Detag an sxml tree @var{sxml} into a string. Does not perform any formatting. - -@end defun - -@node sxml ssax -@subsection (sxml ssax) -@subsubsection Overview -@subheading Functional XML parsing framework -@subsubheading SAX/DOM and SXML parsers with support for XML Namespaces and validation -This is a package of low-to-high level lexing and parsing procedures -that can be combined to yield a SAX, a DOM, a validating parser, or a -parser intended for a particular document type. The procedures in the -package can be used separately to tokenize or parse various pieces of -XML documents. The package supports XML Namespaces, internal and -external parsed entities, user-controlled handling of whitespace, and -validation. This module therefore is intended to be a framework, a set -of "Lego blocks" you can use to build a parser following any discipline -and performing validation to any degree. As an example of the parser -construction, this file includes a semi-validating SXML parser. - -The present XML framework has a "sequential" feel of SAX yet a -"functional style" of DOM. Like a SAX parser, the framework scans the -document only once and permits incremental processing. An application -that handles document elements in order can run as efficiently as -possible. @emph{Unlike} a SAX parser, the framework does not require an -application register stateful callbacks and surrender control to the -parser. Rather, it is the application that can drive the framework -- -calling its functions to get the current lexical or syntax element. -These functions do not maintain or mutate any state save the input port. -Therefore, the framework permits parsing of XML in a pure functional -style, with the input port being a monad (or a linear, read-once -parameter). - -Besides the @var{port}, there is another monad -- @var{seed}. Most of +@end deffn + +@node SSAX +@subsection SSAX: A Functional XML Parsing Toolkit + +Guile's XML parser is based on Oleg Kiselyov's powerful XML parsing +toolkit, SSAX. + +@subsubsection History + +Back in the 1990s, when the world was young again and XML was the +solution to all of its problems, there were basically two kinds of XML +parsers out there: DOM parsers and SAX parsers. + +A DOM parser reads through an entire XML document, building up a tree of +``DOM objects'' representing the document structure. They are very easy +to use, but sometimes you don't actually want all of the information in +a document; building an object tree is not necessary if all you want to +do is to count word frequencies in a document, for example. + +SAX parsers were created to give the programmer more control on the +parsing process. A programmer gives the SAX parser a number of +``callbacks'': functions that will be called on various features of the +XML stream as they are encountered. SAX parsers are more efficient, but +much harder to user, as users typically have to manually maintain a +stack of open elements. + +Kiselyov realized that the SAX programming model could be made much +simpler if the callbacks were formulated not as a linear fold across the +features of the XML stream, but as a @emph{tree fold} over the structure +implicit in the XML. In this way, the user has a very convenient, +functional-style interface that can still generate optimal parsers. + +The @code{xml->sxml} interface from the @code{(sxml simple)} module is a +DOM-style parser built using SSAX, though it returns SXML instead of DOM +objects. + +@subsubsection Implementation + +@code{(sxml ssax)} is a package of low-to-high level lexing and parsing +procedures that can be combined to yield a SAX, a DOM, a validating +parser, or a parser intended for a particular document type. The +procedures in the package can be used separately to tokenize or parse +various pieces of XML documents. The package supports XML Namespaces, +internal and external parsed entities, user-controlled handling of +whitespace, and validation. This module therefore is intended to be a +framework, a set of ``Lego blocks'' you can use to build a parser +following any discipline and performing validation to any degree. As an +example of the parser construction, this file includes a semi-validating +SXML parser. + +SSAX has a ``sequential'' feel of SAX yet a ``functional style'' of DOM. +Like a SAX parser, the framework scans the document only once and +permits incremental processing. An application that handles document +elements in order can run as efficiently as possible. @emph{Unlike} a +SAX parser, the framework does not require an application register +stateful callbacks and surrender control to the parser. Rather, it is +the application that can drive the framework -- calling its functions to +get the current lexical or syntax element. These functions do not +maintain or mutate any state save the input port. Therefore, the +framework permits parsing of XML in a pure functional style, with the +input port being a monad (or a linear, read-once parameter). + +Besides the @var{port}, there is another monad -- @var{seed}. Most of the middle- and high-level parsers are single-threaded through the -@var{seed}. The functions of this framework do not process or affect the -@var{seed} in any way: they simply pass it around as an instance of an -opaque datatype. User functions, on the other hand, can use the seed to -maintain user's state, to accumulate parsing results, etc. A user can -freely mix his own functions with those of the framework. On the other -hand, the user may wish to instantiate a high-level parser: -@code{SSAX:make-elem-parser} or @code{SSAX:make-parser}. In the latter +@var{seed}. The functions of this framework do not process or affect +the @var{seed} in any way: they simply pass it around as an instance of +an opaque datatype. User functions, on the other hand, can use the seed +to maintain user's state, to accumulate parsing results, etc. A user +can freely mix his own functions with those of the framework. On the +other hand, the user may wish to instantiate a high-level parser: +@code{SSAX:make-elem-parser} or @code{SSAX:make-parser}. In the latter case, the user must provide functions of specific signatures, which are called at predictable moments during the parsing: to handle character -data, element data, or processing instructions (PI). The functions are +data, element data, or processing instructions (PI). The functions are always given the @var{seed}, among other parameters, and must return the new @var{seed}. From a functional point of view, XML parsing is a combined -pre-post-order traversal of a "tree" that is the XML document itself. +pre-post-order traversal of a ``tree'' that is the XML document itself. This down-and-up traversal tells the user about an element when its -start tag is encountered. The user is notified about the element once -more, after all element's children have been handled. The process of XML -parsing therefore is a fold over the raw XML document. Unlike a fold -over trees defined in [1], the parser is necessarily single-threaded -- -obviously as elements in a text XML document are laid down sequentially. -The parser therefore is a tree fold that has been transformed to accept -an accumulating parameter [1,2]. +start tag is encountered. The user is notified about the element once +more, after all element's children have been handled. The process of +XML parsing therefore is a fold over the raw XML document. Unlike a +fold over trees defined in [1], the parser is necessarily +single-threaded -- obviously as elements in a text XML document are laid +down sequentially. The parser therefore is a tree fold that has been +transformed to accept an accumulating parameter [1,2]. Formally, the denotational semantics of the parser can be expressed as @@ -287,20 +187,22 @@ The real parser created by @code{SSAX:make-parser} is slightly more complicated, to account for processing instructions, entity references, namespaces, processing of document type declaration, etc. -The XML standard document referred to in this module -is@uref{http://www.w3.org/TR/1998/REC-xml-19980210.html} +The XML standard document referred to in this module is +@uref{http://www.w3.org/TR/1998/REC-xml-19980210.html} The present file also defines a procedure that parses the text of an XML document or of a separate element into SXML, an S-expression-based model -of an XML Information Set. SXML is also an Abstract Syntax Tree of an -XML document. SXML is similar but not identical to DOM; SXML is +of an XML Information Set. SXML is also an Abstract Syntax Tree of an +XML document. SXML is similar but not identical to DOM; SXML is particularly suitable for Scheme-based XML/HTML authoring, SXPath -queries, and tree transformations. See SXML.html for more details. SXML -is a term implementation of evaluation of the XML document [3]. The -other implementation is context-passing. +queries, and tree transformations. See SXML.html for more details. +SXML is a term implementation of evaluation of the XML document [3]. +The other implementation is context-passing. + +The present frameworks fully supports the XML Namespaces Recommendation: +@uref{http://www.w3.org/TR/REC-xml-names/}. -The present frameworks fully supports the XML Namespaces -Recommendation:@uref{http://www.w3.org/TR/REC-xml-names/} Other links: +Other links: @table @asis @item [1] @@ -319,175 +221,109 @@ Pearl. Proc ICFP'00, pp. 186-197. @end table @subsubsection Usage -@anchor{sxml ssax current-ssax-error-port}@defun current-ssax-error-port -@end defun +@deffn {Scheme Procedure} current-ssax-error-port +@end deffn -@anchor{sxml ssax with-ssax-error-to-port}@defun with-ssax-error-to-port port thunk -@end defun +@deffn {Scheme Procedure} with-ssax-error-to-port port thunk +@end deffn -@anchor{sxml ssax xml-token?}@defun xml-token? _ +@deffn {Scheme Procedure} xml-token? _ @verbatim -- Scheme Procedure: pair? x Return `#t' if X is a pair; otherwise return `#f'. @end verbatim +@end deffn -@end defun - -@anchor{sxml ssax xml-token-kind}@defspec xml-token-kind token -@end defspec +@deffn {Scheme Syntax} xml-token-kind token +@end deffn -@anchor{sxml ssax xml-token-head}@defspec xml-token-head token -@end defspec +@deffn {Scheme Syntax} xml-token-head token +@end deffn -@anchor{sxml ssax make-empty-attlist}@defun make-empty-attlist -@end defun +@deffn {Scheme Procedure} make-empty-attlist +@end deffn -@anchor{sxml ssax attlist-add}@defun attlist-add attlist name-value -@end defun +@deffn {Scheme Procedure} attlist-add attlist name-value +@end deffn -@anchor{sxml ssax attlist-null?}@defun attlist-null? _ +@deffn {Scheme Procedure} attlist-null? _ @verbatim -- Scheme Procedure: null? x Return `#t' iff X is the empty list, else `#f'. @end verbatim +@end deffn -@end defun +@deffn {Scheme Procedure} attlist-remove-top attlist +@end deffn -@anchor{sxml ssax attlist-remove-top}@defun attlist-remove-top attlist -@end defun +@deffn {Scheme Procedure} attlist->alist attlist +@end deffn -@anchor{sxml ssax attlist->alist}@defun attlist->alist attlist -@end defun +@deffn {Scheme Procedure} attlist-fold kons knil lis1 +@end deffn -@anchor{sxml ssax attlist-fold}@defun attlist-fold kons knil lis1 -@end defun - -@anchor{sxml ssax define-parsed-entity!}@defun define-parsed-entity! entity str -Define a new parsed entity. @var{entity} should be a symbol. +@deffn {Scheme Procedure} define-parsed-entity! entity str +Define a new parsed entity. @var{entity} should be a symbol. Instances of &@var{entity}; in XML text will be replaced with the string @var{str}, which will then be parsed. +@end deffn -@end defun - -@anchor{sxml ssax reset-parsed-entity-definitions!}@defun reset-parsed-entity-definitions! +@deffn {Scheme Procedure} reset-parsed-entity-definitions! Restore the set of parsed entity definitions to its initial state. +@end deffn -@end defun +@deffn {Scheme Procedure} ssax:uri-string->symbol uri-str +@end deffn -@anchor{sxml ssax ssax:uri-string->symbol}@defun ssax:uri-string->symbol uri-str -@end defun +@deffn {Scheme Procedure} ssax:skip-internal-dtd port +@end deffn -@anchor{sxml ssax ssax:skip-internal-dtd}@defun ssax:skip-internal-dtd port -@end defun +@deffn {Scheme Procedure} ssax:read-pi-body-as-string port +@end deffn -@anchor{sxml ssax ssax:read-pi-body-as-string}@defun ssax:read-pi-body-as-string port -@end defun +@deffn {Scheme Procedure} ssax:reverse-collect-str-drop-ws fragments +@end deffn -@anchor{sxml ssax ssax:reverse-collect-str-drop-ws}@defun ssax:reverse-collect-str-drop-ws fragments -@end defun +@deffn {Scheme Procedure} ssax:read-markup-token port +@end deffn -@anchor{sxml ssax ssax:read-markup-token}@defun ssax:read-markup-token port -@end defun +@deffn {Scheme Procedure} ssax:read-cdata-body port str-handler seed +@end deffn -@anchor{sxml ssax ssax:read-cdata-body}@defun ssax:read-cdata-body port str-handler seed -@end defun +@deffn {Scheme Procedure} ssax:read-char-ref port +@end deffn -@anchor{sxml ssax ssax:read-char-ref}@defun ssax:read-char-ref port -@end defun +@deffn {Scheme Procedure} ssax:read-attributes port entities +@end deffn -@anchor{sxml ssax ssax:read-attributes}@defun ssax:read-attributes port entities -@end defun +@deffn {Scheme Procedure} ssax:complete-start-tag tag-head port elems entities namespaces +@end deffn -@anchor{sxml ssax ssax:complete-start-tag}@defun ssax:complete-start-tag tag-head port elems entities namespaces -@end defun +@deffn {Scheme Procedure} ssax:read-external-id port +@end deffn -@anchor{sxml ssax ssax:read-external-id}@defun ssax:read-external-id port -@end defun +@deffn {Scheme Procedure} ssax:read-char-data port expect-eof? str-handler seed +@end deffn -@anchor{sxml ssax ssax:read-char-data}@defun ssax:read-char-data port expect-eof? str-handler seed -@end defun +@deffn {Scheme Procedure} ssax:xml->sxml port namespace-prefix-assig +@end deffn -@anchor{sxml ssax ssax:xml->sxml}@defun ssax:xml->sxml port namespace-prefix-assig -@end defun +@deffn {Scheme Syntax} ssax:make-parser . kw-val-pairs +@end deffn -@anchor{sxml ssax ssax:make-parser}@defspec ssax:make-parser . kw-val-pairs -@end defspec +@deffn {Scheme Syntax} ssax:make-pi-parser orig-handlers +@end deffn -@anchor{sxml ssax ssax:make-pi-parser}@defspec ssax:make-pi-parser orig-handlers -@end defspec +@deffn {Scheme Syntax} ssax:make-elem-parser my-new-level-seed my-finish-element my-char-data-handler my-pi-handlers +@end deffn -@anchor{sxml ssax ssax:make-elem-parser}@defspec ssax:make-elem-parser my-new-level-seed my-finish-element my-char-data-handler my-pi-handlers -@end defspec - -@node sxml ssax input-parse -@subsection (sxml ssax input-parse) -@subsubsection Overview -A simple lexer. - -The procedures in this module surprisingly often suffice to parse an -input stream. They either skip, or build and return tokens, according to -inclusion or delimiting semantics. The list of characters to expect, -include, or to break at may vary from one invocation of a function to -another. This allows the functions to easily parse even -context-sensitive languages. - -EOF is generally frowned on, and thrown up upon if encountered. -Exceptions are mentioned specifically. The list of expected characters -(characters to skip until, or break-characters) may include an EOF -"character", which is to be coded as the symbol, @code{*eof*}. - -The input stream to parse is specified as a @dfn{port}, which is usually -the last (and optional) argument. It defaults to the current input port -if omitted. - -If the parser encounters an error, it will throw an exception to the key -@code{parser-error}. The arguments will be of the form @code{(@var{port} -@var{message} @var{specialising-msg}*)}. - -The first argument is a port, which typically points to the offending -character or its neighborhood. You can then use @code{port-column} and -@code{port-line} to query the current position. @var{message} is the -description of the error. Other arguments supply more details about the -problem. - -@subsubsection Usage -@anchor{sxml ssax input-parse peek-next-char}@defun peek-next-char [port] -@end defun - -@anchor{sxml ssax input-parse assert-curr-char}@defun assert-curr-char expected-chars comment [port] -@end defun - -@anchor{sxml ssax input-parse skip-until}@defun skip-until arg [port] -@end defun - -@anchor{sxml ssax input-parse skip-while}@defun skip-while skip-chars [port] -@end defun - -@anchor{sxml ssax input-parse next-token}@defun next-token prefix-skipped-chars break-chars [comment] [port] -@end defun - -@anchor{sxml ssax input-parse next-token-of}@defun next-token-of incl-list/pred [port] -@end defun - -@anchor{sxml ssax input-parse read-text-line}@defun read-text-line [port] -@end defun - -@anchor{sxml ssax input-parse read-string}@defun read-string n [port] -@end defun - -@anchor{sxml ssax input-parse find-string-from-port?}@defun find-string-from-port? _ _ . _ -Looks for @var{str} in @var{<input-port>}, optionally within the first -@var{max-no-char} characters. - -@end defun - -@node sxml transform -@subsection (sxml transform) +@node Transforming SXML +@subsection Transforming SXML @subsubsection Overview @heading SXML expression tree transformers @subheading Pre-Post-order traversal of a tree and creation of a new tree @@ -508,11 +344,11 @@ where @end smallexample The pre-post-order function visits the nodes and nodelists -pre-post-order (depth-first). For each @code{<Node>} of the form +pre-post-order (depth-first). For each @code{<Node>} of the form @code{(@var{name} <Node> ...)}, it looks up an association with the -given @var{name} among its @var{<bindings>}. If failed, -@code{pre-post-order} tries to locate a @code{*default*} binding. It's -an error if the latter attempt fails as well. Having found a binding, +given @var{name} among its @var{<bindings>}. If failed, +@code{pre-post-order} tries to locate a @code{*default*} binding. It's +an error if the latter attempt fails as well. Having found a binding, the @code{pre-post-order} function first checks to see if the binding is of the form @@ -520,14 +356,14 @@ of the form (<trigger-symbol> *preorder* . <handler>) @end smallexample -If it is, the handler is 'applied' to the current node. Otherwise, the +If it is, the handler is 'applied' to the current node. Otherwise, the pre-post-order function first calls itself recursively for each child of the current node, with @var{<new-bindings>} prepended to the -@var{<bindings>} in effect. The result of these calls is passed to the -@var{<handler>} (along with the head of the current @var{<Node>}). To be +@var{<bindings>} in effect. The result of these calls is passed to the +@var{<handler>} (along with the head of the current @var{<Node>}). To be more precise, the handler is _applied_ to the head of the current node -and its processed children. The result of the handler, which should also -be a @code{<tree>}, replaces the current @var{<Node>}. If the current +and its processed children. The result of the handler, which should also +be a @code{<tree>}, replaces the current @var{<Node>}. If the current @var{<Node>} is a text string or other atom, a special binding with a symbol @code{*text*} is looked up. @@ -537,60 +373,182 @@ A binding can also be of a form (<trigger-symbol> *macro* . <handler>) @end smallexample -This is equivalent to @code{*preorder*} described above. However, the +This is equivalent to @code{*preorder*} described above. However, the result is re-processed again, with the current stylesheet. @subsubsection Usage -@anchor{sxml transform SRV:send-reply}@defun SRV:send-reply . fragments +@deffn {Scheme Procedure} SRV:send-reply . fragments Output the @var{fragments} to the current output port. The fragments are a list of strings, characters, numbers, thunks, -@code{#f}, @code{#t} -- and other fragments. The function traverses the +@code{#f}, @code{#t} -- and other fragments. The function traverses the tree depth-first, writes out strings and characters, executes thunks, -and ignores @code{#f} and @code{'()}. The function returns @code{#t} if +and ignores @code{#f} and @code{'()}. The function returns @code{#t} if anything was written at all; otherwise the result is @code{#f} If @code{#t} occurs among the fragments, it is not written out but causes the result of @code{SRV:send-reply} to be @code{#t}. +@end deffn + +@deffn {Scheme Procedure} foldts fdown fup fhere seed tree +@end deffn + +@deffn {Scheme Procedure} post-order tree bindings +@end deffn + +@deffn {Scheme Procedure} pre-post-order tree bindings +@end deffn + +@deffn {Scheme Procedure} replace-range beg-pred end-pred forest +@end deffn + +@node SXML Tree Fold +@subsection SXML Tree Fold +@subsubsection Overview +@code{(sxml fold)} defines a number of variants of the @dfn{fold} +algorithm for use in transforming SXML trees. Additionally it defines +the layout operator, @code{fold-layout}, which might be described as a +context-passing variant of SSAX's @code{pre-post-order}. + +@subsubsection Usage +@deffn {Scheme Procedure} foldt fup fhere tree +The standard multithreaded tree fold. + +@var{fup} is of type [a] -> a. @var{fhere} is of type object -> a. +@end deffn + +@deffn {Scheme Procedure} foldts fdown fup fhere seed tree +The single-threaded tree fold originally defined in SSAX. @xref{SSAX}, +for more information. +@end deffn + +@deffn {Scheme Procedure} foldts* fdown fup fhere seed tree +A variant of @code{foldts} that allows pre-order tree +rewrites. Originally defined in Andy Wingo's 2007 paper, +@emph{Applications of fold to XML transformation}. +@end deffn + +@deffn {Scheme Procedure} fold-values proc list . seeds +A variant of @code{fold} that allows multi-valued seeds. Note that the +order of the arguments differs from that of @code{fold}. @xref{SRFI-1 +Fold and Map}. +@end deffn + +@deffn {Scheme Procedure} foldts*-values fdown fup fhere tree . seeds +A variant of @code{foldts*} that allows multi-valued +seeds. Originally defined in Andy Wingo's 2007 paper, @emph{Applications +of fold to XML transformation}. +@end deffn + +@deffn {Scheme Procedure} fold-layout tree bindings params layout stylesheet +A traversal combinator in the spirit of @code{pre-post-order}. +@xref{Transforming SXML}. + +@code{fold-layout} was originally presented in Andy Wingo's 2007 paper, +@emph{Applications of fold to XML transformation}. + +@example +bindings := (<binding>...) +binding := (<tag> <bandler-pair>...) + | (*default* . <post-handler>) + | (*text* . <text-handler>) +tag := <symbol> +handler-pair := (pre-layout . <pre-layout-handler>) + | (post . <post-handler>) + | (bindings . <bindings>) + | (pre . <pre-handler>) + | (macro . <macro-handler>) +@end example + +@table @var +@item pre-layout-handler +A function of three arguments: + +@table @var +@item kids +the kids of the current node, before traversal + +@item params +the params of the current node + +@item layout +the layout coming into this node + +@end table + +@var{pre-layout-handler} is expected to use this information to return a +layout to pass to the kids. The default implementation returns the +layout given in the arguments. + +@item post-handler +A function of five arguments: + +@table @var +@item tag +the current tag being processed + +@item params +the params of the current node + +@item layout +the layout coming into the current node, before any kids were processed + +@item klayout +the layout after processing all of the children + +@item kids +the already-processed child nodes + +@end table -@end defun +@var{post-handler} should return two values, the layout to pass to the +next node and the final tree. -@anchor{sxml transform foldts}@defun foldts fdown fup fhere seed tree -@end defun +@item text-handler +@var{text-handler} is a function of three arguments: -@anchor{sxml transform post-order}@defun post-order tree bindings -@end defun +@table @var +@item text +the string -@anchor{sxml transform pre-post-order}@defun pre-post-order tree bindings -@end defun +@item params +the current params -@anchor{sxml transform replace-range}@defun replace-range beg-pred end-pred forest -@end defun +@item layout +the current layout + +@end table + +@var{text-handler} should return two values, the layout to pass to the +next node and the value to which the string should transform. + +@end table +@end deffn -@node sxml xpath -@subsection (sxml xpath) +@node SXPath +@subsection SXPath @subsubsection Overview @heading SXPath: SXML Query Language SXPath is a query language for SXML, an instance of XML Information set -(Infoset) in the form of s-expressions. See @code{(sxml ssax)} for the -definition of SXML and more details. SXPath is also a translation into +(Infoset) in the form of s-expressions. See @code{(sxml ssax)} for the +definition of SXML and more details. SXPath is also a translation into Scheme of an XML Path Language, @uref{http://www.w3.org/TR/xpath,XPath}. XPath and SXPath describe means of selecting a set of Infoset's items or their properties. To facilitate queries, XPath maps the XML Infoset into an explicit tree, and introduces important notions of a location path and a current, -context node. A location path denotes a selection of a set of nodes -relative to a context node. Any XPath tree has a distinguished, root +context node. A location path denotes a selection of a set of nodes +relative to a context node. Any XPath tree has a distinguished, root node -- which serves as the context node for absolute location paths. Location path is recursively defined as a location step joined with a -location path. A location step is a simple query of the database -relative to a context node. A step may include expressions that further -filter the selected set. Each node in the resulting set is used as a -context node for the adjoining location path. The result of the step is +location path. A location step is a simple query of the database +relative to a context node. A step may include expressions that further +filter the selected set. Each node in the resulting set is used as a +context node for the adjoining location path. The result of the step is a union of the sets returned by the latter location paths. The SXML representation of the XML Infoset (see SSAX.scm) is rather -suitable for querying as it is. Bowing to the XPath specification, we +suitable for querying as it is. Bowing to the XPath specification, we will refer to SXML information items as 'Nodes': @example @@ -610,124 +568,217 @@ An (ordered) set of nodes is just a list of the constituent nodes: <Nodeset> ::= (<Node> ...) @end example -Nodesets, and Nodes other than text strings are both lists. A <Nodeset> -however is either an empty list, or a list whose head is not a symbol. A +Nodesets, and Nodes other than text strings are both lists. A <Nodeset> +however is either an empty list, or a list whose head is not a symbol. A symbol at the head of a node is either an XML name (in which case it's a -tag of an XML element), or an administrative name such as '@@'. This +tag of an XML element), or an administrative name such as '@@'. This uniform list representation makes processing rather simple and elegant, -while avoiding confusion. The multi-branch tree structure formed by the +while avoiding confusion. The multi-branch tree structure formed by the mutually-recursive datatypes <Node> and <Nodeset> lends itself well to processing by functional languages. A location path is in fact a composite query over an XPath tree or its -branch. A singe step is a combination of a projection, selection or a -transitive closure. Multiple steps are combined via join and union -operations. This insight allows us to @emph{elegantly} implement XPath +branch. A singe step is a combination of a projection, selection or a +transitive closure. Multiple steps are combined via join and union +operations. This insight allows us to @emph{elegantly} implement XPath as a sequence of projection and filtering primitives -- converters -- -joined by @dfn{combinators}. Each converter takes a node and returns a +joined by @dfn{combinators}. Each converter takes a node and returns a nodeset which is the result of the corresponding query relative to that -node. A converter can also be called on a set of nodes. In that case it +node. A converter can also be called on a set of nodes. In that case it returns a union of the corresponding queries over each node in the set. The union is easily implemented as a list append operation as all nodes -in a SXML tree are considered distinct, by XPath conventions. We also -preserve the order of the members in the union. Query combinators are +in a SXML tree are considered distinct, by XPath conventions. We also +preserve the order of the members in the union. Query combinators are high-order functions: they take converter(s) (which is a Node|Nodeset -> -Nodeset function) and compose or otherwise combine them. We will be +Nodeset function) and compose or otherwise combine them. We will be concerned with only relative location paths [XPath]: an absolute location path is a relative path applied to the root node. Similarly to XPath, SXPath defines full and abbreviated notations for -location paths. In both cases, the abbreviated notation can be -mechanically expanded into the full form by simple rewriting rules. In +location paths. In both cases, the abbreviated notation can be +mechanically expanded into the full form by simple rewriting rules. In case of SXPath the corresponding rules are given as comments to a sxpath -function, below. The regression test suite at the end of this file shows +function, below. The regression test suite at the end of this file shows a representative sample of SXPaths in both notations, juxtaposed with -the corresponding XPath expressions. Most of the samples are borrowed +the corresponding XPath expressions. Most of the samples are borrowed literally from the XPath specification, while the others are adjusted for our running example, tree1. @subsubsection Usage -@anchor{sxml xpath nodeset?}@defun nodeset? x -@end defun +@deffn {Scheme Procedure} nodeset? x +@end deffn -@anchor{sxml xpath node-typeof?}@defun node-typeof? crit -@end defun +@deffn {Scheme Procedure} node-typeof? crit +@end deffn -@anchor{sxml xpath node-eq?}@defun node-eq? other -@end defun +@deffn {Scheme Procedure} node-eq? other +@end deffn -@anchor{sxml xpath node-equal?}@defun node-equal? other -@end defun +@deffn {Scheme Procedure} node-equal? other +@end deffn -@anchor{sxml xpath node-pos}@defun node-pos n -@end defun +@deffn {Scheme Procedure} node-pos n +@end deffn -@anchor{sxml xpath filter}@defun filter pred? +@deffn {Scheme Procedure} filter pred? @verbatim -- Scheme Procedure: filter pred list Return all the elements of 2nd arg LIST that satisfy predicate PRED. The list is not disordered - elements that appear in the result list occur in the same order as they occur in the argument - list. The returned list may share a common tail with the argument - list. The dynamic order in which the various applications of pred + list. The returned list may share a common tail with the argument + list. The dynamic order in which the various applications of pred are made is not specified. (filter even? '(0 7 8 8 43 -4)) => (0 8 8 -4) @end verbatim +@end deffn -@end defun +@deffn {Scheme Procedure} take-until pred? +@end deffn -@anchor{sxml xpath take-until}@defun take-until pred? -@end defun +@deffn {Scheme Procedure} take-after pred? +@end deffn -@anchor{sxml xpath take-after}@defun take-after pred? -@end defun +@deffn {Scheme Procedure} map-union proc lst +@end deffn -@anchor{sxml xpath map-union}@defun map-union proc lst -@end defun +@deffn {Scheme Procedure} node-reverse node-or-nodeset +@end deffn -@anchor{sxml xpath node-reverse}@defun node-reverse node-or-nodeset -@end defun +@deffn {Scheme Procedure} node-trace title +@end deffn -@anchor{sxml xpath node-trace}@defun node-trace title -@end defun +@deffn {Scheme Procedure} select-kids test-pred? +@end deffn -@anchor{sxml xpath select-kids}@defun select-kids test-pred? -@end defun - -@anchor{sxml xpath node-self}@defun node-self pred? +@deffn {Scheme Procedure} node-self pred? @verbatim -- Scheme Procedure: filter pred list Return all the elements of 2nd arg LIST that satisfy predicate PRED. The list is not disordered - elements that appear in the result list occur in the same order as they occur in the argument - list. The returned list may share a common tail with the argument - list. The dynamic order in which the various applications of pred + list. The returned list may share a common tail with the argument + list. The dynamic order in which the various applications of pred are made is not specified. (filter even? '(0 7 8 8 43 -4)) => (0 8 8 -4) @end verbatim +@end deffn + +@deffn {Scheme Procedure} node-join . selectors +@end deffn + +@deffn {Scheme Procedure} node-reduce . converters +@end deffn + +@deffn {Scheme Procedure} node-or . converters +@end deffn + +@deffn {Scheme Procedure} node-closure test-pred? +@end deffn + +@deffn {Scheme Procedure} node-parent rootnode +@end deffn + +@deffn {Scheme Procedure} sxpath path +@end deffn + +@node sxml ssax input-parse +@subsection (sxml ssax input-parse) +@subsubsection Overview +A simple lexer. + +The procedures in this module surprisingly often suffice to parse an +input stream. They either skip, or build and return tokens, according to +inclusion or delimiting semantics. The list of characters to expect, +include, or to break at may vary from one invocation of a function to +another. This allows the functions to easily parse even +context-sensitive languages. + +EOF is generally frowned on, and thrown up upon if encountered. +Exceptions are mentioned specifically. The list of expected characters +(characters to skip until, or break-characters) may include an EOF +"character", which is to be coded as the symbol, @code{*eof*}. + +The input stream to parse is specified as a @dfn{port}, which is usually +the last (and optional) argument. It defaults to the current input port +if omitted. + +If the parser encounters an error, it will throw an exception to the key +@code{parser-error}. The arguments will be of the form @code{(@var{port} +@var{message} @var{specialising-msg}*)}. + +The first argument is a port, which typically points to the offending +character or its neighborhood. You can then use @code{port-column} and +@code{port-line} to query the current position. @var{message} is the +description of the error. Other arguments supply more details about the +problem. + +@subsubsection Usage +@deffn {Scheme Procedure} peek-next-char [port] +@end deffn + +@deffn {Scheme Procedure} assert-curr-char expected-chars comment [port] +@end deffn + +@deffn {Scheme Procedure} skip-until arg [port] +@end deffn -@end defun +@deffn {Scheme Procedure} skip-while skip-chars [port] +@end deffn -@anchor{sxml xpath node-join}@defun node-join . selectors -@end defun +@deffn {Scheme Procedure} next-token prefix-skipped-chars break-chars [comment] [port] +@end deffn -@anchor{sxml xpath node-reduce}@defun node-reduce . converters -@end defun +@deffn {Scheme Procedure} next-token-of incl-list/pred [port] +@end deffn -@anchor{sxml xpath node-or}@defun node-or . converters -@end defun +@deffn {Scheme Procedure} read-text-line [port] +@end deffn -@anchor{sxml xpath node-closure}@defun node-closure test-pred? -@end defun +@deffn {Scheme Procedure} read-string n [port] +@end deffn -@anchor{sxml xpath node-parent}@defun node-parent rootnode -@end defun +@deffn {Scheme Procedure} find-string-from-port? _ _ . _ +Looks for @var{str} in @var{<input-port>}, optionally within the first +@var{max-no-char} characters. +@end deffn + +@node sxml apply-templates +@subsection (sxml apply-templates) +@subsubsection Overview +Pre-order traversal of a tree and creation of a new tree: + +@smallexample + apply-templates:: tree x <templates> -> <new-tree> +@end smallexample + +where + +@smallexample + <templates> ::= (<template> ...) + <template> ::= (<node-test> <node-test> ... <node-test> . <handler>) + <node-test> ::= an argument to node-typeof? above + <handler> ::= <tree> -> <new-tree> +@end smallexample + +This procedure does a @emph{normal}, pre-order traversal of an SXML +tree. It walks the tree, checking at each node against the list of +matching templates. + +If the match is found (which must be unique, i.e., unambiguous), the +corresponding handler is invoked and given the current node as an +argument. The result from the handler, which must be a @code{<tree>}, +takes place of the current node in the resulting tree. The name of the +function is not accidental: it resembles rather closely an +@code{apply-templates} function of XSLT. + +@subsubsection Usage +@deffn {Scheme Procedure} apply-templates tree templates +@end deffn -@anchor{sxml xpath sxpath}@defun sxpath path -@end defun diff --git a/doc/ref/texinfo.texi b/doc/ref/texinfo.texi index b2947fc30..b5ef393c1 100644 --- a/doc/ref/texinfo.texi +++ b/doc/ref/texinfo.texi @@ -152,8 +152,8 @@ interested in @code{replace-titles} and @code{filter-empty-elements}. @xref{texinfo docbook replace-titles,,replace-titles}, and @ref{texinfo docbook filter-empty-elements,,filter-empty-elements}. -Returns a nodeset, as described in @ref{sxml xpath}. That is to say, -this function returns an untagged list of stexi elements. +Returns a nodeset; that is to say, an untagged list of stexi elements. +@xref{SXPath}, for the definition of a nodeset. @end defun @@ -184,10 +184,12 @@ For example: This module implements transformation from @code{stexi} to HTML. Note that the output of @code{stexi->shtml} is actually SXML with the HTML vocabulary. This means that the output can be further processed, and -that it must eventually be serialized by @ref{sxml simple -sxml->xml,sxml->xml}. References (i.e., the @code{@@ref} family of -commands) are resolved by a @dfn{ref-resolver}. @xref{texinfo html -add-ref-resolver!,add-ref-resolver!}, for more information. +that it must eventually be serialized by @code{sxml->xml}. +@xref{Reading and Writing XML}. + +References (i.e., the @code{@@ref} family of commands) are resolved by a +@dfn{ref-resolver}. @xref{texinfo html +add-ref-resolver!,add-ref-resolver!}. @subsubsection Usage @anchor{texinfo html add-ref-resolver!}@defun add-ref-resolver! proc diff --git a/doc/ref/web.texi b/doc/ref/web.texi index 0f69089d0..6c33f3225 100644 --- a/doc/ref/web.texi +++ b/doc/ref/web.texi @@ -127,8 +127,8 @@ basic idea is that HTML is either text, represented by a string, or an element, represented as a tagged list. So @samp{foo} becomes @samp{"foo"}, and @samp{<b>foo</b>} becomes @samp{(b "foo")}. Attributes, if present, go in a tagged list headed by @samp{@@}, like -@samp{(img (@@ (src "http://example.com/foo.png")))}. @xref{sxml -simple}, for more information. +@samp{(img (@@ (src "http://example.com/foo.png")))}. @xref{SXML}, for +more information. The good thing about SXML is that HTML elements cannot be confused with text. Let's make a new definition of @code{para}: @@ -1769,7 +1769,7 @@ message body is long enough.) The web handler interface is a common baseline that all kinds of Guile web applications can use. You will usually want to build something on top of it, however, especially when producing HTML. Here is a simple -example that builds up HTML output using SXML (@pxref{sxml simple}). +example that builds up HTML output using SXML (@pxref{SXML}). First, load up the modules: |