<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE recdescent-xml SYSTEM "recdescent.dtd" [
<!ENTITY IDre "[a-zA-Z_][a-zA-Z0-9_]*">
<!ENTITY XSH "XSH2">
]>
<recdescent-xml>
  <doc>
    <title>&XSH;</title>
    <shortdesc>XML Editing Shell (generation 2)</shortdesc>
    <description>
      <para>
	&XSH; acts as a command interpreter. Individual commands must
	be separated with a semicolon. 
	In the interactive shell, backslash may be used at the end of a line to
	indicate that a command continues on the next line.
	Output redirection can be used to pipe output of some XSH <xref
	  linkend="command"/> to some external program, or to capture the output
	to a variable. See <xref linkend="Redirection"/> for more info.
      </para>
      <para>
	&XSH; command <xref linkend="help_command"/> provides a complete
	reference, instantly from the command-line:
      </para>
      <para>
	<literal>help command</literal>
	gives a list of all &XSH; <link linkend="command">commands</link>.
      </para>
      <para>
	<literal>help type</literal> gives a
	list of all argument types.
      </para>
      <para>
	<literal>help topic</literal> followed by
	documentation chapter gives more information on a given topic.
      </para>
      <para>
	<literal>help toc</literal> displays the table of contents.
      </para>
    </description>
    <section id="Documents">
      <title>Files/Documents</title>
      <para>
	&XSH; is designed as an environment for querying and manipulating XML and
	HTML documents. Use <xref linkend="open_command"/> or <xref
	  linkend="create_command"/> commands to load an XML or HTML
	document from a local file, external URL (such as http:// or ftp://),
	string or pipe. &XSH; can optionally validate the document during parse
	process (see <xref linkend="validation" /> and
	<xref linkend="load_ext_dtd"/>). Parsed documents are stored in memory
	as <ulink url="http://www.w3.org/DOM/">DOM</ulink> trees, that can be
	<link linkend="Navigation">navigated</link> and <link
	  linkend="Manipulation">manipulated</link> with &XSH; commands and XPath
	language, whose names and syntax make working with
	the DOM tree a flavor of working in a UNIX filesystem.
      </para>
      <para>
	A parsed document is usually stored in a variable. 
	&XSH; shares variables
	with the XPath engine, so if e.g. <literal>$doc</literal> is a &XSH;
	variable holding a document (or, more generally any node-set), then
	<literal>$doc//section/title</literal> is an
	XPath expression selecting all <literal>title</literal> 
	subelements of all
	<literal>section</literal> elements within the (sub)tree of $doc.
      </para>
      <para>
	Although &XSH; is able to parse remote documents via
	<literal>http://</literal> or <literal>ftp://</literal>, it is only
	able to save them locally.  To upload a document to a remote server
	(e.g. using FTP) or to store it into a database, use <xref
	  linkend="save_command" /> command with a <literal>--pipe</literal>
	parameter, in connection with an external program able to store
	its standard input (XML) to the desired location. 
	You can also use similar
	parameter with <xref linkend="open_command"/> in order to parse
	documents from standard output of some external program.
      </para>
      <example>
	<title>Store a &XSH; document 
	  on a remote machine using the Secure Shell</title>
	<code>xsh&gt; <userinput> save --pipe "ssh my.remote.org 'cat &gt; test.xml'" $doc</userinput></code>
      </example>
    </section>
    <section id="Navigation">
      <title>Tree navigation</title>
      <para>
	With &XSH;, it is possible to browse a <link
	linkend="Documents">document tree</link> 
	(XML data represented as a DOM-tree) as if it was a local
        filesystem, except that <link
	linkend="xpath">XPath</link> 
	expressions are used instead of ordinary directory paths.
      </para> 
      <para>
	To mimic the filesystem navigation as closely as
	possible, &XSH; contains several commands named by analogy of
	UNIX filesystem commands, such as <xref linkend="chxpath_command"/>, <xref linkend="list_command"/> and
	<xref linkend="pwd_command"/>.	
      </para>
      <para>The current position in the document tree
	is called the <emphasis>current node</emphasis>. Current node's XPath
	may be queried with <xref
	linkend="pwd_command"/> command.  In the interactive shell, current
	node is also displayed in the command line prompt. 
	(Since there may be
	multiple document trees open at the same time, &XSH; tries to locate a
	variable holding the current document and use it to fully qualify
	current node's XPath in the &XSH; prompt.) Remember, that beside <xref
	linkend="chxpath_command"/> command, current node (and document) is
	also silently changed by <xref
	linkend="open_command"/> command, <xref
	linkend="create_command"/> command and temporarily also by the
	node-list variant of the <xref linkend="foreach"/> loop without
	a loop variable.
      </para>
      <para>XPath expressions are always evaluated in context
	of the current node. Different documents can be accessed
	through variables: <literal>$doc/foo[1]/bar</literal>.</para>
      <example>
	<title>&XSH; shell</title>
	<code>$scratch:/&gt; <userinput>$docA := open &quot;testA.xml&quot;</userinput>
	  $docA/&gt; <userinput>$docB := open &quot;testB.xml&quot;</userinput>
	  $docB/&gt; <userinput>pwd</userinput>
	  /
	  $docB/&gt; <userinput>cd $docA/article/chapter[title='Conclusion']</userinput>
	  $docA/article/chapter[5]&gt; <userinput>pwd</userinput>
	  /article/chapter[5]
	  $docA/article/chapter[5]&gt; <userinput>cd previous-sibling::chapter</userinput>
	  $docA/article/chapter[4]&gt; <userinput>cd ..</userinput>
	  $docA/article&gt; <userinput>cd $docB</userinput>
	  $docB:/&gt; <userinput>ls</userinput>
          &lt;?xml version="1.0" encoding="utf-8"?&gt;
          &lt;article&gt;...&lt;/article&gt;
	</code>
      </example>
    </section>
    <section id="Manipulation">
      <title>Tree modification</title>
      <para>
	&XSH; not only provides ways to browse and inspect the DOM tree but also
	many commands to modify its content by various operations,
	such as copying,
	moving, and deleting its nodes as well as creating completely new nodes
	or XML fragments and attaching them to it. It is quite easy to learn
	these commands since their names or aliases mimic their well-known
	filesystem analogies.  On the other hand, many of these commands have
	two versions one of which is prefixed with a letter &quot;x&quot;. This
	&quot;x&quot; stands for &quot;cross&quot;, thus e.g. <xref linkend="xcopy_command" /> should be read as &quot;cross copy&quot;.
	Let's explain the difference on the example of <xref
	  linkend="xcopy_command"/>.</para>
      <para>
	In a copy operation, you have to specify what nodes are to be
	copied and where to, in other words, you have to specify the
	<emphasis>source</emphasis> and the
	<emphasis>target</emphasis>.  &XSH; is very much XPath-based so,
	XPath is used here to specify both of them. However, there
	might be more than one node that satisfies an XPath expression. So,
	the rule of thumb is that the "cross" variant of a
	command places <emphasis>one and every</emphasis> of the source nodes
	to the location of <emphasis>one and every</emphasis> destination
	node, while the plain variant works one-by-one, placing the
	first source node to the first destination, the second source
	node to the second destination, and so on (as long as there
	are both source nodes and destinations left).
      </para>
      <example>
	<code>$scratch/&gt; <userinput>$a := create &quot;&lt;X&gt;&lt;A/&gt;&lt;Y/&gt;&lt;A/&gt;&lt;/X&gt;&quot;;</userinput>
	  $a/&gt; <userinput>$b := create &quot;&lt;X&gt;&lt;B/&gt;&lt;C/&gt;&lt;B/&gt;&lt;C/&gt;&lt;B/&gt;&lt;/X&gt;&quot;;</userinput>
	  $b/&gt; <userinput>xcopy $a//A replace $b//B;</userinput>
	  $b/&gt; <userinput>copy $b//C before $a//A;</userinput>
	  $b/&gt; <userinput>ls $a;</userinput>
	  &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
	  &lt;X&gt;&lt;C/&gt;&lt;A/&gt;&lt;Y/&gt;&lt;C/&gt;&lt;A/&gt;&lt;/X&gt;

	  $b/&gt; <userinput>ls $b;</userinput>
	  &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
	  &lt;X&gt;&lt;A/&gt;&lt;A/&gt;&lt;C/&gt;&lt;A/&gt;&lt;A/&gt;&lt;C/&gt;&lt;A/&gt;&lt;A/&gt;&lt;/X&gt;
	</code>
      </example>
      <para>
	As already indicated by the example, another issue of tree modification
	is the way in which the destination node determines the target
	location. Should the source node be placed before, after, or somewhere
	among the children of the resulting node? Or maybe, should it replace
	it completely? This information has to be given in the
	<xref linkend="loc"/> argument that usually precedes the destination
	XPath.
      </para>
      <para>
	Now, what happens if source and destination nodes are of
	incompatible types? &XSH; tries to avoid this by implicitly
	converting between node types when necessary.  For example, if
	a text, comment, and attribute node is copied into, before or
	after an attribute node, the original value of the
	attribute is replaced, prepended or appended respectively with
	the textual content of the source node. Note however, that
	<emphasis>element nodes are never converted</emphasis> into
	text, attribute or any other textual node.  There
	are many combinations here, so try yourself and see the
	results.
      </para>
      <para>You may even use some more sophisticated way to convert
	between node types, as shown in the following example, where
	an element is first commented out and than again uncommented.
	Note, that the particular approach used for resurrecting the
	commented XML material works only for well-balanced chunks of
	XML.
      </para>
      <example>
	<title>Using string variables to convert between different
	  types of nodes</title>
	<code><userinput>$doc := create &lt;&lt;EOF;
	  &lt;?xml version='1.0'?&gt;
	    &lt;book&gt;
	    <tab count="1"/>&lt;chapter&gt;
	  <tab count="2"/>&lt;title&gt;Intro&lt;/title&gt;
	  <tab count="1"/>&lt;/chapter&gt;
	  <tab count="1"/>&lt;chapter&gt;
	    <tab count="2"/>&lt;title&gt;Rest&lt;/title&gt;
	  <tab count="1"/>&lt;/chapter&gt;
	    &lt;/book&gt;
	  EOF
	  </userinput>

	  # comment out the first chapter
	  <userinput>ls //chapter[1] |&gt; $chapter_xml;</userinput>
	  <userinput>insert comment $chapter_xml replace //chapter[1];</userinput>
	  <userinput>ls / 0;</userinput>
	  # OUTPUT:
	  &lt;?xml version="1.0"?&gt;
	  &lt;book&gt;
	  &lt;!--<tab count="1"/>&lt;chapter&gt;
	  <tab count="2"/>&lt;title&gt;Intro&lt;/title&gt;
	  <tab count="1"/>&lt;/chapter&gt;
	  --&gt;
	  <tab count="1"/>&lt;chapter&gt;
	  <tab count="2"/>&lt;title&gt;Rest&lt;/title&gt;
	  <tab count="1"/>&lt;/chapter&gt;
	  &lt;/book&gt;


	  # un-comment the chapter
	  <userinput>$comment = string(//comment()[1]);</userinput>
	  <userinput>insert chunk $comment replace //comment()[1];</userinput>
	  <userinput>ls / 0;</userinput>
	  # OUTPUT:
	  &lt;?xml version="1.0"?&gt;
	  &lt;book&gt;
	  <tab count="1"/>&lt;chapter&gt;
	  <tab count="2"/>&lt;title&gt;Intro&lt;/title&gt;
	  <tab count="1"/>&lt;/chapter&gt;

	  <tab count="1"/>&lt;chapter&gt;
	  <tab count="2"/>&lt;title&gt;Rest&lt;/title&gt;
	  <tab count="1"/>&lt;/chapter&gt;
	  &lt;/book&gt;
	</code>
      </example>
    </section>
    <section id="Flow">
      <title>Flow control</title>
      <para>
	As almost every scripting language, &XSH; supports subroutines,
	various conditional statements, loops and even exceptions.
      </para>
    </section>
    <section id="Information">
      <title>Retrieving more information</title>
      <para> Beside the possibility to browse the DOM tree and
	list some parts of it (as described in <xref linkend="Navigation"/>), 
        &XSH; provides commands to obtain other
	information related to open documents as well as the &XSH;
	interpreter itself. These commands are listed bellow.
      </para>
    </section>
    <section id="Namespaces">
      <title>Namespaces in XML and XPath</title> <para>Namespaces provide a
	simple method for qualifying element and attribute names in
	XML documents.  Namespaces are represented by a namespace URI
	but, since the URI can be very long, element and attribute
	names are associated with a namespace using a namespace prefix
	(see the <ulink url="http://www.w3.org/TR/REC-xml-names/">W3C
	recommendation</ulink> for details). In an XML document, a
	prefix can be associated with a namespace URI using a
	declaration which takes form of special attribute of the form
	<literal>xmlns:prefix="namespace uri"</literal> on an element.
	The scope of the namespace declaration is then the subtree of the
	element carrying the special <literal>xmlns:prefix</literal> attribute (and includes
	attributes of the element). Moreover, a default namespace can
	be declared using just <literal>xmlns="namespace
	uri"</literal>.  In that case all unprefixed element names
	in the scope of such a
	declaration belong to the namespace. 
	An unprefixed element which is not in scope of 
	a default namespace declaration does not belong to any namespace.
	It is recommended not to combine namespaced elements and
	non-namespaced elements in a single document.
	Note that regardless of default
	namespace declarations, unprefixed attributes do not belong to any namespace
	(because they are uniquely determined by their name
	and the namespace and name of the the element which carries them).
      </para>
      <para>&XSH; tries to deal namespace declarations transparently
	(creating them if necessary when nodes are copied between
	different documents or scopes of namespace declarations). 
	Most commands which create new elements or attributes provide
	means to indicate a namespace. In addition, &XSH; provides commands <xref
	linkend="declare_namespace_command"/>, <xref
	linkend="set_namespace_command"/>, <xref
	linkend="change_namespace_uri_command"/>, and <xref
	linkend="change_namespace_prefix_command"/> to
	directly manipulate XML namespace declarations on the current
	node.
      </para>
      <para>
	Since &XSH; is heavily XPath-based, it is important to
	remember that XPath 1.0 maps prefixes to namespaces
	independently of the declarations in the current document. The
	mapping is instead provided via so called XPath context.
	Namespaces can be tested in XPath either using the built-in
	<literal>namespace-uri()</literal> function, but it is more
	convenient to use namespace prefixes associated with namespace
	URIs in the XPath context.  This association is independent of
	the documents to which the XPath expression is applied and can
	be established using the command <xref
	linkend="registerns_command"/>.  Additional, &XSH;
	automatically propagates the namespace association in the
	scope of the current node to the XPath context, so that
	per-document prefixes in the current scope can also be used.
      </para>
      <para>
	IMPORTANT: <ulink url="http://www.w3.org/TR/xpath">XPath 1.0</ulink> has no concept of a default namespace.
	Unprefixed names in XPath only match names which have no
	namespace. So, if the document uses a default namespace,
	it is required to associate a
	non-empty prefix with the default namespace
        via  <xref linkend="registerns_command"/>
	and add that prefix to names in XPath expressions intended to match 
	nodes in the default namespace.
      </para>
      <example>
	<title>Manipulating nodes in XHTML documents</title>
	<code>open "index.xhtml";
$xhtmlns = "http://www.w3.org/1999/xhtml";
register-namespace x $xhtmlns;
wrap --namespace $xhtmlns '&lt;font color="blue">' //x:a[@href];
# or 
wrap '&lt;x:font color="blue">' //x:a[@href];</code>
      </example>
      <para>In the preceding example we associate the (typically
	default) namespace of XHTML documents with the prefix
	<literal>x</literal>.  We than use this prefix to match all
	links (<literal>a</literal> elements) in the document.  Note
	that we do not write <literal>@x:href</literal> to match the
	<literal>@href</literal> attribute because unprefixed
	attributes do not belong to the default namespace.  The <xref
	linkend="wrap_command"/> command is used to create new containing
	elements for the nodes matched by the XPath expression. We may
	either specify the namespace of the containing element
	explicitly, using <literal>--namespace</literal> option, or
	implicitly, by using a prefix associated with the namespace in
	the XPath context.  In the latter case, &XSH; chooses a
	suitable prefix declared for the namespace in the document
	scope (in this case the default, i.e. no, prefix), adding a
	new namespace declaration if necessary.
      </para>
    </section>
    <section id="Argtypes">
      <title>Argument Types</title>
      <para>
	&XSH; commands accept arguments of various types,
	usually expressed as Perl or XPath
	<xref linkend="exp"/>s. Unlike in most languages,
	individual &XSH; commands may evaluate the same expression differently, 
	usually
	to enforce a result
	of a certain type (such as a node-list, a string, a number,
	a filename, a node name, etc.).
	See <xref linkend="exp"/> and
	individual argument types for more information.
      </para>
    </section>
    <section id="Variables">
      <title>Variables</title>
      <para>
	In &XSH;, like in Perl and XPath, 
	<link linkend="varname">variable names</link> are are prefixed
        with a dollar sign ($). 
        Variables can
        contain arbitrary Perl Scalar (string, number, array
        reference, hash reference or an object reference).  XPath
        objects are transparently mapped to Perl objects via
        XML::LibXML objects. 
        Values can be assigned to variables
        either by simple <link linkend="assign_command">assignments</link> of the form
	<literal>$variable = <xref linkend="exp"/></literal>,
        where the right hand side is an expression, or by command 
        <link linkend="assign_command">assignments</link> of the form
	<literal>$variable := <xref linkend="command"/></literal>,
        where the right hand side is a &XSH; command, or by
	capturing the output of some command with a variable
	redirection of the following form:</para>
      <code>command |&gt; $variable;</code>
      <para>
	&XSH; expressions are evaluated either by XPath
	engine or by Perl (the latter only happens if the entire
	expression is enclosed with braces
	<literal>{...}</literal>), and
	both Perl and XPath can access all &XSH; variables
	transparently (Perl expressions may even assign to them).
      </para>
      <para>
	A simple simple expression consisting of a variable name
        (e.g. <literal>$variable</literal>) is always evaluated by the
        XPath engine and the result is the content of the variable as
        it appears to the XPath data model.  Since in XPath object
        cannot be void (undefined), XPath engine complains, if the
        value of the variable is undefined. On the other hand,
        expressions like <literal>{$variable}</literal> are evaluated by
        Perl, which results in the value of the variable as seen
	by Perl.
      </para>
      <para>
	Variables can also be used as macros for complicated XPath
	expressions. Any occurrence of a substring of the form
	<literal>${variable}</literal> in an XPath expression is
	interpolated to the value of <literal>$variable</literal> (if
	<literal>$variable</literal> contains an object rather than a
	string or number, then the object is cast to string first) before the
	entire expression is evaluated.  So, for example, if
	<literal>${variable}</literal> contains string
	"<literal>chapter[title]</literal>" (without the quotes), then
	the XPath expression
	<literal>//sect1/${variable}/para</literal> interpolates to 
	<literal>//sect1/chapter[title]/para</literal> prior
	to evaluation. 
      </para>
      <para>
	To display the current value of a variable, use either
	<xref linkend="print_command"/>
	or (in case of a global variables - the distinction is discussed below)
	the command <xref linkend="var_command"/>:
      </para>
      <example>
	  <code>xsh&gt; <userinput>$b="my_document";</userinput>
	    xsh&gt; <userinput>$file="${b}s.xml";</userinput>
	    xsh&gt; <userinput>$f := open $file;</userinput>
	    xsh&gt; <userinput>ls //$b[count(descendant::para)&gt;10]</userinput>
	    xsh&gt; <userinput>print $b</userinput>
	    my_document
	    xsh&gt; <userinput>variables</userinput>
            ...
	    $b='my_document';
            ...
	    $file='my_documents.xml';
            ...
	  </code>
	</example>
      <para>
	Variables can also serve as containers for documents and can be used to
	store lists of nodes that result from evaluating an XPath
	expression (a.k.a. XPath node-sets). This is especially useful
	when a sequence of commands is to be performed on some fixed
        set of nodes and repetitive evaluation of the same XPath 
	expression would be lengthy.  XPath
	node-sets are represented by
	<literal>XML::LibXML::NodeList</literal> Perl objects (which
	is simply a array reference blessed to the above class, which
	provides some simple operator overloading). In XPath, by a
	node-set by definition can only contain a single copy of each
	node and the nodes within a node-set are processed in the same
	order as they appear in the XML document. Having XPath
	node-sets represented by a list gives us the advantage of having
	the possibility to process the list in a different order than
	the one implied by the document (which is what happens
	if a variable containing a node-list is evaluated by Perl 
	rather than XPath), see an example below.
      </para>
      <example>
	<code>xsh&gt; <userinput>$creatures = //creature[@status='alive']</userinput>
          # process creatures in the document order: 
	  xsh&gt; <userinput>foreach $creature print @name;</userinput>
          # process creatures in the reverse document order: 
	  xsh&gt; <userinput>foreach { reverse @$creature } print @name;</userinput>
          # append some more nodes to a node-list (using a variant of
	  # a simple assignment)
	  xsh&gt; <userinput>$creatures += //creature[@status='dead'];</userinput>
	  # again, we can process creatures in order implied by the document:
	  xsh&gt; <userinput>foreach $creature print @name;</userinput>
	  # but we can also process first living and then dead creatures,
          # since this is how they are listed in $creature
	  xsh&gt; <userinput>foreach {$creature} print @name;</userinput>
	  # same as the above is
	  xsh&gt; <userinput>foreach {@$creature} print @name;</userinput>
	</code>
      </example>
      <para>
	&XSH; variables are either globally or lexically scoped.
	Global variables need not to be declared (they can be directly
	assigned to), whereas lexical variables must be declared
	using the command <xref linkend="my_command"/>. Global variable
	assignment may also be made temporal for the enclosing block,
	using <xref linkend="local_command"/>.
      </para>
      <example>
	<code>$var1 = "foo";           # a global variable requires no declaration
	  local $var1 $var2 $var3; # localizes global variables
          $var1 = "bar";           # assignment to a localized variable is temporary
	  local $var4 = "foo";     # localized assignment
          my $var1 $var $var3;     # declares lexical variables
	  my $var1 = "foo";        # lexical variable declaration with assignment
	</code>
      </example>
      <para>
	Lexical variables are only defined in the scope of current
	block or subroutine. There is no way to refer to a lexical
	variable form outside of the block it was declared in, nor
	from within a nested subroutine call. Of course, lexical
	variables can be referred to from nested blocks or Perl
	expressions (where they behave just like Perl's lexical
	variables).
      </para>
      <para>
	On the other hand, global or localized &XSH; variables are just
	Perl Scalar variables belonging to the
	<literal>XML::XSH2::Map</literal> namespace, which is also the
	default namespace for any Perl code evaluated from &XSH; (so
	there's no need to use this prefix explicitly in Perl expressions,
	unless of course there is a lexical variable in the current
	scope with the same).
      </para>
      <para>Localizing a variable using the <literal>local</literal>
	keyword makes all assignments to it occurring in the enclosing block
	temporary. The variable itself remains global, only its
	original value is restored at the end of the block that localized it.
      </para>
      <para> 
	In all above cases, it is possible to arbitrarily
	intermix &XSH; and Perl assignments:
      </para>
      <example>
	  <code>xsh&gt; <userinput>ls //chapter[1]/title</userinput>
	  &lt;title&gt;Introduction&lt;/title&gt;
	  xsh&gt; <userinput>$a=string(//chapter[1]/title)</userinput>
	  xsh&gt; <userinput>perl { $b="CHAPTER 1: ".uc($a); }</userinput>
	  xsh&gt; <userinput>print $b</userinput>
	  CHAPTER 1: INTRODUCTION
	</code>
      </example>
      <para>
	Although all &XSH; variables are in fact Perl Scalars, it is
	still possible to store Perl Array or Hash value to a &XSH;
	variable via reference. The following example demonstrates
	using Perl Hashes to collect and print some simple racial
	statistics about the population of Middle-Earth:
      </para>
      <example>
	<code>my $races;
	  foreach a:/middle-earth/creature { 
	  <tab count="1"/>my $race=string(@race);
	  <tab count="1"/>perl { $races->{$race}++ };
	  }
	  print "Middle-Earth Population (race/number of creatures)"
	  print { map "$_/$races->{$_}\n" keys(%$races); };
	  </code>
      </example>
    </section>
    <section id="Redirection">
      <title>Command output redirection</title>
      <para>WARNING: XSH2 redirection syntax is not
	yet finished. It is currently the same as in XSH1
	but this may be changed in the future releases.
      </para>
      <para>
	Output redirection can be used to pipe output of some XSH <xref
	linkend="command"/> to some external program, or to capture it
	to a variable. Redirection of output of more than one XSH
	command can be achieved using the <xref linkend="do_command"/> command.
      </para> 
      <section id="Redirection_pipe">
	<title>Redirect output to an external program</title>
	<para>The syntax for redirecting the output of a XSH command to
	  an external program, is <literal>xsh-command | shell-command
	    ;</literal>, where <literal>xsh-command</literal> is any &XSH;
	  command and <literal>shell-command</literal> is any command
	  (or code) recognized by the default shell interpreter of the
	  operating system (i.e. on UNIX systems by
	  <literal>/bin/sh</literal> or <literal>/bin/csh</literal>, on
	  Windows systems by <literal>cmd</literal>).  The shell command
	  may contain further redirections (as supported by the system
	  shell interpreter), but should not contain semicolons, except when
	  the whole shell command is enclosed in brackets.
	</para>
	<example>
	  <title>Use well-known UNIX commands to filter XPath-based XML
	    listing from a document and count the results</title>
	  <code>xsh&gt; <userinput>ls //something/* | grep foo | wc</userinput></code>
	</example>
      </section>
      <section id="Redirection_variable">
	<title>Capture output to a variable</title>
	<para>
	  The syntax for capturing the output of an XSH command to a variable is
	  <literal>xsh-command |&gt; $variable</literal>, 
	  where <literal>xsh-command</literal> is
	  any XSH <xref linkend="command"/> and 
	  <literal>$variable</literal> is any valid
	  name for a <link linkend="Variables">variable</link>.
	</para>
	<example>
	  <title>Store the number of all words in a variable named count.</title>
	  <code>xsh&gt; <userinput>count //words |&gt; $count</userinput></code>
	</example>
      </section>
    </section>
    <section id="Configuration">
      <title>Global settings</title> <para>The commands listed below
      can be used to modify the default behavior of the XML parser or
      &XSH; itself.  Some of the commands switch between two different
      modes according to a given expression (which is expected to
      result either in zero or non-zero value). Other commands also
      working as a flip-flop have their own explicit counterparts
      (e.g.  <xref linkend="verbose"/> and <xref linkend="quiet"/> or
      <xref linkend="debug"/> and <xref linkend="nodebug"/>).  This
      inconsistency is due to historical reasons.
      </para>
      <para>
	The <xref linkend="encoding"/> and <xref linkend="query_encoding"/>
	settings 
	allow to specify character
	encodings of user's input and &XSH;'s own output. This is particularly
	useful when you work with UTF-8 encoded documents on a console
	which only supports 8-bit characters.
      </para>
      <para>
	The <xref linkend="options_command"/> command
	displays current settings by means of &XSH; commands.
	Thus it can not only be used to review current values, but
	also to store them for future use, e.g. in ~/.xsh2rc file.
      </para>
      <example>
	<code>xsh&gt; <userinput>settings | cat &gt; ~/.xsh2rc</userinput></code>
      </example>
    </section>
    <section id="Perl_shell">
      <title>Interacting with Perl and Shell</title>
      <para>
	Along with XPath, Perl is one of two &XSH; expression languages,
	and borrows &XSH; its great expressive power.
	Perl is a language optimized for scanning arbitrary text
	files, extracting information from those text files, and
	printing reports based on that information. It has built-in
	regular expressions and powerful yet easy to learn 
	data structures (scalars, arrays, hash tables). It's also a
	good language for many system management tasks.
	&XSH; itself is written in Perl (except for the XML engine,
	which uses libxml2 library written in C by Daniel Veillard).
      </para>
      <section id="binding_perl">
	<title>Calling Perl</title>
	<para>
	  Perl <link linkend="perl_code">expressions or blocks of
	  code</link> can either be used as arguments to any &XSH; command.
	  One of them is 
	  <xref linkend="perl_command"/> command
	  which simply evaluates the given Perl block.
	  Other commands, such as <xref linkend="map_command"/>,
	  even require Perl expression argument and allow
	  quickly change DOM node content.
	  Perl expressions may also provide lists of strings to iterate over
	  with a <xref linkend="foreach"/> loop, or serve as
	  conditions for <xref linkend="if"/>, <xref linkend="unless"/>, and 
	  <xref linkend="while"/> statements.
	</para>
	<para>
	  To prevent conflict between &XSH; internals and the evaluated
	  Perl code, &XSH; runs such code in the context of a special
	  namespace <literal>XML::XSH2::Map</literal>. As described in
	  the section <xref linkend="Variables"/>, &XSH; string
	  variables may be accessed and possibly assigned from Perl
	  code in the most obvious way, since they actually
	  <emphasis>are</emphasis> Perl variables defined in the
	  <literal>XML::XSH2::Map</literal> namespace.</para>
	<para>
	  The interaction between &XSH; and Perl actually works the
	  other way round as well, so that you may call back &XSH; from the
	  evaluated Perl code.  For this, Perl function
	  <literal>xsh</literal> is defined in the
	  <literal>XML::XSH2::Map</literal> namespace.  All parameters
	  passed to this function are interpreted as &XSH; commands.</para>
	<para>Moreover, the following Perl helper functions are defined:
	</para>
	<para><literal>xsh(string,....)</literal> - evaluates
	  given string(s) as &XSH; commands.
	</para>
	<para><literal>call(name)</literal> - call a given
	  &XSH; subroutine.
	</para>
	<para><literal>count(string)</literal> - evaluates
	  given string as an XPath expression and returns
	  either literal value of the result (in case of
	  boolean, string and float result type) or
	  number of nodes in a returned node-set.
	</para>
	<para><literal>literal(string|object)</literal> -
	  if passed a string, evaluates it as a &XSH; expression 
	  and returns the literal value of the result;
	  if passed an object, returns literal value of
	  the object.
	  For example,
	  <literal>literal('$doc/expression')</literal> returns the same
	  value as <literal>count('string($doc/expression)')</literal>.
	</para>
	<para>
	  <literal>serialize(string|object)</literal> - 
	  if passed a string, it first evaluates the string
	  as a &XSH; expression to obtain a node-list object. 
	  Then it serializes the object into XML.
	  The resulting string is equal to the output of the &XSH; command <xref
	    linkend="list_command"/> applied on the same expression or object
	  expression only without indentation and folding.
	</para>
	<para>
	  <literal>type(string|object)</literal> - 
	  if passed a string, it first evaluates
	  the string as &XSH; expression to obtain a node-list object.
	  It returns a list of strings representing
	  the types of nodes in the node-list
	  (ordered in the canonical document order).
	  The returned type strings are: 
	  <literal>element</literal>,
	  <literal>attribute</literal>,
	  <literal>text</literal>,
	  <literal>cdata</literal>,
	  <literal>pi</literal>,
	  <literal>entity_reference</literal>,
	  <literal>document</literal>,
	  <literal>chunk</literal>,
	  <literal>comment</literal>,
	  <literal>namespace</literal>,
	  <literal>unknown</literal>.
	</para>
	<para>
	  <literal>nodelist(string|object,...)</literal> - 
	  converts its arguments to objects if necessary
	  and returns a node-list consisting of the objects.
	</para>
	<para>
	  <literal>xpath(string, node?)</literal> - 
	  evaluates a given string as an XPath expression
	  in the context of a given node and returns
	  the result.
	</para>
	<para>
	  <literal>echo(string,...)</literal> - prints
	  given strings on &XSH; output.
	  Note, that in the interactive mode,
	  &XSH; redirects all output to a specific terminal file handle
	  stored in the variable <literal>$OUT</literal>.
	  So, if you for example mean to pipe the result 
	  to a shell command, you should avoid using STDOUT filehandle
	  directly. You may either use the usual <literal>print</literal>
	  without a filehandle, 
	  use the <literal>echo</literal> function,
	  or use <literal>$OUT</literal> as a filehandle.
	</para>
	<para>
	  In the following examples we use Perl to populate the
	  Middle-Earth with Hobbits whose names are read from a text
	  file called <literal>hobbits.txt</literal>, unless there are
	  some Hobbits in Middle-Earth already.
	</para>
	<example>
	  <title>Use Perl to read text files</title>
	  <code>unless (//creature[@race='hobbit']) {
	    <tab count="1"/>perl {
	    <tab count="2"/>open my $fh, "hobbits.txt" };
	    <tab count="2"/>@hobbits=&lt;$file&gt;;
	    <tab count="2"/>close $fh;
	    <tab count="1"/>}
	    <tab count="1"/>foreach { @hobbits } {
	    <tab count="2"/>copy xsh:new-element("creature","name",.,"race","hobbit")
	    <tab count="3"/>into m:/middle-earth/creatures;
	    <tab count="1"/>}
	    }
	  </code>
	</example>
	<example>
	  <title>The same code as a single Perl block</title>
	  <code>perl {
	    <tab count="1"/>unless (count(//creature[@race='hobbit'])) {
	    <tab count="2"/>open my $file, "hobbits.txt";
	    <tab count="2"/>foreach (&lt;$file&gt;) {
	    <tab count="3"/>xsh(qq{insert element "&lt;creature name='$_' race='hobbit'&gt;"
	    <tab count="4"/>into m:/middle-earth/creatures});
	    <tab count="2"/>}
	    <tab count="2"/>close $file;
	    <tab count="1"/>}
	    };</code>
	</example>
      </section>
      <section id="binding_perl_xpathextensions">
        <title>Writing your own XPath extension functions in Perl</title>
        <para>
	  &XSH; allows users to extend the set of XPath functions by
	  providing extension functions written in Perl.  This can
	  be achieved using the <xref linkend="registerfunc_command"/>
	  command. The perl code implementing an extension function
	  works as a usual perl routine accepting its arguments in
	  <literal>@_</literal> and returning the result. The
	  following conventions are used:
	</para>
	<para>
	  The arguments passed to the perl implementation by the XPath
	  engine are simple scalars for string, boolean and float
	  argument types and
	  <literal>XML::LibXML::NodeList</literal> objects for node-set
	  argument types. The implementation is
	  responsible for checking the argument number and types. The
	  implementation may use general Perl functions as well as
	  <literal>XML::LibXML</literal>
	  methods to process the arguments and return the result.
	  Documentation for the <literal>XML::LibXML</literal> Perl module
	  can be found for example at <ulink url="http://search.cpan.org/~pajas/XML-LibXML/">http://search.cpan.org/~pajas/XML-LibXML/</ulink>.
	</para>
	<para>
	  Extension functions SHOULD NOT MODIFY the document DOM tree.
	  Doing so could not only confuse the XPath engine but possibly 
	  even result in an critical error (such as segmentation fault).
	  Calling &XSH; commands from extension function implementations
	  is also dangerous and isn't generally recommended.
	</para>
	<para>
	  The extension function implementation must return 
	  a single value, which can be of
	  one of the following types: simple scalar (a number or
	  string), <literal>XML::LibXML::Boolean</literal> object
	  reference (result is a boolean value),
	  <literal>XML::LibXML::Literal</literal> object reference
	  (result is a string), <literal>XML::LibXML::Number</literal>
	  object reference (result is a float),
	  <literal>XML::LibXML::Node</literal> (or derived) object
	  reference (result is a node-set consisting of a single node),
	  or <literal>XML::LibXML::NodeList</literal> (result is a
	  node-set). For convenience, simple (non-blessed) array
	  references consisting of
	  <literal>XML::LibXML::Node</literal> objects can also be
	  used for a node-set result instead of a
	  <literal>XML::LibXML::NodeList</literal>.
        </para>
      </section>
      <section id="binding_shell">
	<title>Calling the System Shell</title>
	<para>
	  In the interactive mode, &XSH; interprets all lines starting
	  with the exclamation mark (<literal>!</literal>) as shell
	  commands and invokes the system shell to interpret the line
	  (this is to mimic FTP and similar command-line interpreters).
	</para>
	<example>
	  <code>xsh&gt; <userinput>!ls -l</userinput>
-rw-rw-r--    1 pajas    pajas        6355 Mar 14 17:08 Artistic
drwxrwxr-x    2 pajas    users         128 Sep  1 10:09 CVS
-rw-r--r--    1 pajas    pajas       14859 Aug 26 15:19 ChangeLog
-rw-r--r--    1 pajas    pajas        2220 Mar 14 17:03 INSTALL
-rw-r--r--    1 pajas    pajas       18009 Jul 15 17:35 LICENSE
-rw-rw-r--    1 pajas    pajas         417 May  9 15:16 MANIFEST
-rw-rw-r--    1 pajas    pajas         126 May  9 15:16 MANIFEST.SKIP
-rw-r--r--    1 pajas    pajas       20424 Sep  1 11:04 Makefile
-rw-r--r--    1 pajas    pajas         914 Aug 26 14:32 Makefile.PL
-rw-r--r--    1 pajas    pajas        1910 Mar 14 17:17 README
-rw-r--r--    1 pajas    pajas         438 Aug 27 13:51 TODO
drwxrwxr-x    5 pajas    users         120 Jun 15 10:35 blib
drwxrwxr-x    3 pajas    users        1160 Sep  1 10:09 examples
drwxrwxr-x    4 pajas    users          96 Jun 15 10:35 lib
-rw-rw-r--    1 pajas    pajas           0 Sep  1 16:23 pm_to_blib
drwxrwxr-x    4 pajas    users         584 Sep  1 21:18 src
drwxrwxr-x    3 pajas    users         136 Sep  1 10:09 t
-rw-rw-r--    1 pajas    pajas          50 Jun 16 00:06 test
drwxrwxr-x    3 pajas    users         496 Sep  1 20:18 tools
-rwxr-xr-x    1 pajas    pajas        5104 Aug 30 17:08 xsh</code>
	</example>
	<para>
	  To invoke a system shell command or program
	  from the non-interactive mode or from a complex
	  &XSH; construction, use the <xref linkend="exec_command"/>
	  command.
	</para>
	<para>
	  Since UNIX shell commands are very powerful tool for
	  processing textual data, &XSH; supports direct redirection of
	  &XSH; commands output to system shell command.  This is very
	  similarly to the redirection known from UNIX shells, except
	  that here, of course, the first command in the pipe-line
	  colone is an &XSH; <xref linkend="command"/>. Since semicolon (<literal>;</literal>)
	  is used in &XSH; to separate commands, it has to be prefixed
	  with a backslash if it should be used for other purposes.
	</para>
	<example>
	  <title>Use grep and less to display context of `funny'</title>
	  <code>xsh&gt; ls //chapter[5]/para | grep funny | less</code>
	</example>
	<example>
	  <title>The same on Windows 2000/XP systems</title>
	  <code>xsh&gt; ls //chapter[5]/para | find "funny" | more</code>
	</example>
      </section>
    </section>
    <section id="Prompt">
      <title>Prompt in the interactive shell</title>
      <para>
	Like many other shells, &XSH; provides means for customizing
	the format of its interactive shell prompt.  The prompt is
	displayed according to the content of the variable
	<literal>$PROMPT</literal> on which the following
	substitutions and interpolations are performed
	(in this order):
      </para>
<para>1. Prompt-string replacements</para>
<code>
    %% - percent sign
    %p - XPath location of the current node
    %P - like %p but without an initial document variable
    %l - XPath location of the current node with ID-shortcuts
    %L - like %l but without an initial document variable
    %n - name of the current node
    %N - local name of the current node
    %c - canonical XPath name of the current node
    %y - type of the current node (element,attribute,...)
    %i - ID of the current node
    %d - current document variable
    %h - the hostname up to the first '.'
    %H - the hostname
    %s - XSH shell name (basename of $0)
    %t - the current time in 24-hour HH:MM:SS format
    %T - the current time in 12-hour HH:MM:SS format
    %@ - the current time in 12-hour am/pm format
    %A - the current time in 24-hour HH:MM format
    %u - the username of the current user
    %v - the version of XSH2 (e.g., 2.1.0)
    %V - the revision number of XML::XSH2::Functions (e.g. 2.40)
    %w - current working directory (on the local filesystem)
    %W - basename of %w
</code>
<para>2. Variable, XPath and Perl interpolations</para>
<para>
Substrings of the forms <literal>${variable}</literal>,
<literal>${{...perl...}}</literal> and
<literal>${(...xpath...)}</literal> are interpolated as in &XSH;
<link linkend="exp">expressions</link>.
</para>
      <para>3. Special character substitution</para>
<code>
    \n - newline character
    \r - line-feed character
    \t - tab character
    \a - bell character
    \b - backspace character
    \f - form feed character
    \e - escape character (\033)
    \\ - backslash character
    \nnn - the character corresponding to the octal number nnn
           (useful for non-printable terminal control characters)
</code>
<para>The default value of <literal>$PROMPT</literal> is <literal>"%p>"</literal>.</para>
      <para>Note that you must escape <literal>${...}</literal>
	interpolators like <literal>\${...}</literal> if you
	want them to be evaluated at each prompt
	rather than at the time of the assignment to <literal>$PROMPT</literal>.
	For example:
      </para>
      <example>
	<title>Let `uname` be computed once, `date` at every prompt</title>
	<code>$PROMPT="[${{ chomp($u=`uname`);$u }} \${{ chomp($d=`date`);$d }}] %p>"</code>
      </example>
    </section>
    <section id="xsh2delta">
      <title>Changes since XSH 1.x</title>
      <para>
	This section briefly describes 
	differences between XSH2 and previous XSH 1.x releases.
	The list should not be considered complete.
	Some syntax variations or amendments in 
	the semantics of various commands may not be documented
	in this section, neither are various improvements in the
	XSH interpreter.
      </para>
      <section id="new_in_xsh2">
	<title>Changes in XSH2</title>
	<enumerate>
	  <listitem>
	<para>
	  In XSH2, subroutines can be called without a 
	  <xref linkend="call_command"/>. They can be 
	  <link linkend="def">redefined</link> and 
	  <link linkend="undef">undefined</link>.
	  The command <xref linkend="call_command"/>
	  can still be used, but it's use only makes sense
	  in indirect calls, where subroutine's name is computed
	  from an expression.
	</para>
	<code>def foo $param1 $param2 { 
	  <tab/># param1 and $param2 are lexical (a.k.a. my)
	  <tab/>ls $param1; 
	  <tab/>echo $param2 
	  }
	  foo (//chapter)[1] (//chapter)[1]/title
	  
	  def inc $param1 { return ($param1 + 1) }
	  $two := inc 1;
	</code>
	  </listitem>
	  <listitem>
	    <para>
	  XSH2 uses variables of the form <xref linkend="varname"/> 
	  for all kinds of objects, including node-sets
	  (which, if evaluated as Perl expressions, preserve node order).
	  Node-list variables of XSH 1.x have been deprecated.
	</para>
	<code>$var = //foo/bar;                 # node set
	  $var = "hallo world";             # string
	  $var = xsh:new-element("foo");    # node object
	  $var = { ['a','b','c'] };         # Perl array reference
	  $var = {{ 'a'=>'A', 'b'=>'B' }};  # Perl hash reference
	</code>
	  </listitem>
	  <listitem>
	    <para>
	  XSH2 allows variables to be used in XPath just as they are used in XSLT:
	</para>
	<code>$var = //foo/bar;
	  ls //baz[ . = $var[@test=1]/any ]
	</code>
	    <para>
	  Variable interpolation is still available in XSH2 via ${var},
	  but it's importance is diminished compared to XSH 1.x, 
	  because the XPath engine now evaluates
	  variables directly. Interpolation can still be used for
	  things like "XPath-macros":
	</para>
	<code>$filter = "[ . = $var[@test=1]/any ]";
	  ls //baz${filter};
	</code>
	  </listitem>
	  <listitem>
	    <para>
	  XSH2 equally supports XPath and
	  Perl <link linkend="exp">expressions</link> 
	  (written in braces { ... }).
	  Unfortunately, Perl expressions can't be embedded in XPath 
	  <link linkend="exp">expressions</link>,
	  but one can still use variables as an agent:
	</para>
	<code>perl { use MIME::Base64 };
	  my $encoded = { encode_base64('open sesame') }
	  ls //secret-cave[string(password) = $encoded]
	</code>
	<para>We can, however, use Perl-only expressions complemented with auto-conversion
	      to do things like:</para>
	<code>copy { encode_base64('Pe do mellon a minno!') } replace //secret-cave/password/text();
	</code>
	  </listitem>
	  <listitem>
	    <para>
	  Commands return values 
	  (see <link linkend="assign_command">:= assignment</link>, 
	  or <link linkend="exp">&amp;{ } expressions</link>).
	</para>
	<code>$moved_paras := xmove //para replace .;
	  $chapter := wrap chapter $moved_paras;
	  ls $chapter;

	  # or just
	  
	  ls &amp;{ wrap chapter &amp;{ xmove //para replace . } };
	</code>
	  </listitem>
	  <listitem>
	    <para>
	  XSH2 deprecates "string" expressions of XSH 1.x.  However,
	  for convenience, some XSH2 commands interpret name-like
	  XPath expressions on certain argument positions as strings
	  (mostly commands that expect file-name or node-name
	  arguments):
	</para>
	<code>insert element my_document into .;
	  insert text "foo" into my_document;
	  
	  $doc := open my_document;         # opens file named "my_document"
	  $doc := open "my_document";       # same
	  $doc := open (my_document);       # opens file named "foo"
	  $doc := open string(my_document); # same
	</code>
	  </listitem>
	  <listitem>
	<para>
	  In XSH2, XML documents
	  have no ID. 
	  They are referred to using variables (which fits in well with the unified variable concept):
	</para>
	<code>$doc1 := open "foo1.xml";
	  $doc2 := open "foo2.xml";
	  ls ($doc1//para|$doc2//para);
	  cd $doc1;
	  ls id('intro');             # finds ID intro in the current document ($doc1)
	  ls xsh:id2($doc2, 'intro'); # finds ID intro in $doc2
	</code>
	  </listitem>
	  <listitem>
	    <para>
	      XSH2 commands have options and flags instead of many optional (positional) arguments.
	      Options/flags usually have both long forms (like --flag) and equivalent
	      short forms (like :f) (colon is borrowed from Scheme, because dash is reserved for XPath minus).
	    </para>
	<code>$doc := open --format html "version1.html";
	  save --file "version2.xml" $doc;

	  ls --fold /;
	  ls :f /;
	  ls --depth 1 /;
	  ls :d 1 /;
	  
	  # all the same:
	  $sorted = sort --key @name --locale --descending //user;
	  $sorted = sort :l:d:k@name //user;
	  $sorted = sort --key @name --compare { use locale; $b cmp $a } //user;
	  
	  validate --relaxng --file "test.rng" $mydoc;
	  validate --public "-//OASIS//DTD DocBook XML V4.1.2//EN" $mydoc;
	  validate --yesno $mydoc;
	</code>
	  </listitem>
	  <listitem>
	    <para>Finally, <xref linkend="eval_command"/> is no longer
	      an alias for <xref linkend="perl_command"/> in &XSH;,
	      but instead evaluates strings containing &XSH; commands
	      (so <literal>eval $string</literal> now practically works like old ugly
	      <literal>perl { xsh($string) }</literal>). See the documentation for 
	      <xref linkend="eval_command"/> for a handy usage example
	      (no more PHP, XSTL and XPathScript :-)).
	    </para>
	  </listitem>
	</enumerate>
      </section>
      <section id="xsh2delta_examples">
	<title>Examples</title>
	<example>
	  <title>Open command has changed.</title>
	  <code>XSH1:
	    foo = file.xml;
	    or
	    foo = "file.xml";
	  </code>
	  <code>XSH2:
	    $foo := open file.xml;        # file.xml is a bareword in file-name context
	    or
	    $foo := open "file.xml";      # "file.xml" is a XPath string
	    or
	    $foo := open {"file.xml"};    # "file.xml" is a Perl string
	    or
	    $foo = xsh:open("file.xml");  # righthand side is an XPath extension function
	  </code>
	</example>
	<example>
	  <title>XSH2 commands have options</title>
	  <code>XSH1:
	    open HTML FILE foo2 = "file.html";
	  </code>
	  <code>XSH2:
	    $foo2 := open --format html "file.html";
	  </code>
	</example>


	<example>
	  <title>documents</title>
	  <code>XSH1:
	    foo = file.xml;
	    ls foo:(//bar|//baz);
	  </code>
	  <code>XSH2:
	    $foo := open file.xml;
	    ls ($foo//bar|$foo//baz);
	  </code>
	</example>


	<example>
	  <title>variable interpretation</title>
	  <code>XSH1:
	    $family = "Arial";
	    ls //font[@family="$family"];   # interpolation
	    or
	    ls //font[@family="${family}"]; # interpolation
	  </code>
	  <code>XSH2:
	    $family = "Arial";
	    ls //font[@family=$family];     # evaluation by XPath engine
	    or
	    ls //font[@family="${family}"]; # interpolation
	  </code>
	</example>



	<example>
	  <title>adding new nodes</title>
	  <code>XSH1:
	    insert attribute "foo=bar" into /scratch;
	  </code>
	  <code>XSH2:
	    insert attribute "foo=bar" into /scratch;
	    or
	    copy xsh:new-attribute("foo","bar") into /scratch;
	  </code>
	</example>


	<example>
	  <title>foreach with perl expression</title>
	  <code>XSH1:
	    foreach { glob('*.xml') } {
	    <tab/>open doc = $__;
	    <tab/>...
	    }
	  </code>
	  <code>XSH2:
	    foreach { glob('*.xml') } {
	    <tab/>my $doc := open .;
	    <tab/>...
	    } 
	  </code>
	</example>
	<example>
	  <title>foreach (perl expression) with variable</title>
	  <code>XSH2:
	    foreach my $filename in { glob('*.xml') } {
	    <tab/>my $doc := open $filename;
	    <tab/>...
	    } 
	  </code>
	</example>
	<example>
	  <title>sorting nodes</title>
	  <code>XSH1:
	    %list = //player;
	    sort @best_score { $a &lt;=> $b } %list;
	    copy %list into .;
	  </code>
	  <code>XSH2:
	    $list := sort --numeric --key @best_score //player;
	    copy { $list } into .;
	    or
	    copy &amp;{ sort --numeric --key @best_score //player } into .;
	    or (using short options)
	    copy &amp;{ sort :n :k @best_score //player } into .;
	  </code>
	</example>
      </section>
    </section>
  </doc>
  <preamb>
<![CDATA[
package XML::XSH2::Grammar;

use strict;
use Parse::RecDescent;
use vars qw/$grammar/;

$Parse::RecDescent::skip = '(\s|\n|#[^\n]*)*';
$grammar=<<'_EO_GRAMMAR_';
]]>
  </preamb>
  <postamb>
<![CDATA[

_EO_GRAMMAR_

sub compile {
  my @opts = ( { -standalone => 1 },
               $grammar,
               "XML::XSH2::Parser",
             );
  shift @opts
      if $Parse::RecDescent::VERSION < 1.967_005; # Standalone not supported.
  Parse::RecDescent->Precompile(@opts);
}

sub new {
  return new Parse::RecDescent ($grammar);
}

1;
]]>
  </postamb>
  <rules>
    <!-- ================== commands and options ====================== -->
    <rule id="command" type="argtype" inline="no">
      <production>
	<regexp>(?=\s*[}{;]|\s*\Z)</regexp>
	<directive type="commit"/>
	<directive type="reject"/>
      </production>
      <ruleref ref="assign_command" arguments=""/>
      <ruleref ref="my_command" arguments=""/>
      <ruleref ref="local_command" arguments=""/>
      <ruleref ref="do_command" arguments=""/>
      <ruleref ref="if_command" arguments=""/>
      <ruleref ref="unless_command" arguments=""/>
      <ruleref ref="while_command" arguments=""/>
      <ruleref ref="foreach_command" arguments=""/>
      <ruleref ref="stream_process_command" arguments=""/>
      <ruleref ref="undef" arguments=""/>
      <ruleref ref="ignore_use_command" arguments=""/>
      <ruleref ref="test_mode" arguments=""/>
      <ruleref ref="run_mode" arguments=""/>
      <!-- ADD NEW COMMANDS HERE -->
      <production>
	<regexp>(?!(?:iterate|try|def|define)\b)</regexp>
	<regexp>\.|[a-zA-Z_][-a-zA-Z0-9_]*</regexp>
	<ruleref ref="exp_or_opt" rep="s?" arguments=""/>
	<action>
	  bless
	  [<lineinfo/>,$item[2],@{$item[3]}],
	  'XML::XSH2::Command'
	</action>
      </production>
      <documentation sections="Argtypes">
	<title>command</title>
	<shortdesc>List of &XSH; commands and their general syntax</shortdesc>
	<description>
	  <para>
	    &XSH; command consists of a command name
	    and possibly command parameters separated
	    by whitespace. Individual <link linkend="command">&XSH; commands</link> are
	    separated with a semicolon. 
	    A command may optionally be followed
	    by an output redirection directive
	    (see <xref linkend="binding_shell"/> for output
	    redirection to a command
	    and <xref linkend="Variables"/> for output
	    redirection to variable).
	    Most commands have aliases, so for example
	    <xref linkend="prune_command"/> command
	    may also be invoked as <literal>del</literal> or
	    <literal>rm</literal>.
	  </para>
	  <para>&XSH; recognizes the following commands
	    (not including aliases):
	    <typeref types="command"/></para>
	</description>
	<see-also>
	  <ruleref ref="block" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="statement" inline="no">
      <production>
	<regexp>(?=\s*[}{;])</regexp>
	<directive type="commit"/>
	<directive type="reject"/>
      </production>
      <ruleref ref="if" arguments=""/>
      <ruleref ref="unless" arguments=""/>
      <ruleref ref="while" arguments=""/>
      <ruleref ref="foreach" arguments=""/>
      <ruleref ref="try_catch" arguments=""/>
      <ruleref ref="iterate" arguments=""/>
      <ruleref ref="def" arguments=""/>
    </rule>

    <rule id="complex_command" inline="no">
      <production>
	<regexp>(?=\s*[{}]|\s*\Z)</regexp>
	<directive type="commit"/>
	<directive type="reject"/>
      </production>
      <production>
	<regexp>\s*;</regexp>
	<directive type="commit"/>
      </production>
      <production>
	<regexp>(?=(?:foreach|for|if|unless|iterate|while|try|def|define)\b)</regexp>
	<ruleref ref="statement" arguments=""/>
	<directive type="commit"/>
	<ruleref ref="trail" rep="?" arguments=""/>
	<action>
	  if (scalar(@{$item[4]})) {
	    if ($item[4][0][0] eq 'pipe') {
  	      $return=[<lineinfo/>,'pipe_command',[$item[2]],$item[4][0][1]]
	    } else {
   	      $return=[<lineinfo/>,'string_pipe_command',[$item[2]],$item[4][0][1]]
	    }
          } else {
            $return=$item[2]
          }
	</action>
      </production>
      <production>
	<ruleref ref="command" arguments=""/>
	<directive type="commit"/>
	<ruleref ref="trail" rep="?" arguments=""/>
	<regexp>\s*;|(?=\s*}|\s*\Z)</regexp>
	<action>
	  if (scalar(@{$item[3]})) {
	    if ($item[3][0][0] eq 'pipe') {
  	      $return=[<lineinfo/>,'pipe_command',[$item[1]],$item[3][0][1]]
	    } else {
   	      $return=[<lineinfo/>,'string_pipe_command',[$item[1]],$item[3][0][1]]
	    }
          } else {
            $return=$item[1]
          }
	</action>
      </production>      
      <production>
	<directive type="error">Parse error near: "}.substr($text,0,40).qq{ ..."</directive>
      </production>
    </rule>
    <rule id="block" type="argtype" name="block" inline="no">
      <production>
	<string>{</string>
	<directive type="commit"/>
	<ruleref ref="complex_command" rep="s" arguments=""/>
	<string>}</string>
	<action>[grep ref,@{$item[3]}]</action>
      </production>
      <documentation sections="Argtypes Flow">
	<title>block argument type</title>
	<shortdesc>a block of &XSH; commands</shortdesc>
	<description>
	  <para>
	    a block of semicolon-separated
	     &XSH; commands enclosed within braces.
	  </para>
	  <example>
	    <title>Count paragraphs in each chapter</title>
	    <code>$i=0;
	      foreach //chapter {
	      <tab count="1"/>$c=count(./para);
	      <tab count="1"/>$i=$i+1;
	      <tab count="1"/>print "$c paragraphs in chapter no.$i";
	      }
	    </code>
	  </example>
	</description>	
      </documentation>
    </rule>

    <!-- ================== help on types ====================== -->
    <rule id="type" type="list" inline="no">
      <documentation>
	<title>List of command argument types</title>
	<description>
	  <para><typeref types="argtype"/></para>
	</description>
      </documentation>
    </rule>
    <!-- ================== exp/rule ====================== -->
    <rule id="exp_or_opt" inline="no">
      <production>
	<regexp>(?=\s*[};]|\s*\Z)</regexp>
	<directive type="commit"/>
	<directive type="reject"/>
      </production>
      <production>
	<ruleref ref="option" arguments=""/>
      </production>
      <production>
	<ruleref ref="exp" arguments=""/>
      </production>
    </rule>
    <rule id="option" inline="no">
      <production>
	<regexp>:[[:alnum:]]|--[-_[:alnum:]]+</regexp>
      </production>
    </rule>
    <!-- ================== expressions ====================== -->
    <rule id="inline_doc_string" inline="no">
      <production>
	<regexp>'[a-zA-Z_][a-zA-Z0-9_]*'|"[a-zA-Z_][a-zA-Z0-9_]*"|\([a-zA-Z_][a-zA-Z0-9_]*\)|\{[a-zA-Z_][a-zA-Z0-9_]*\}|[a-zA-Z_][a-zA-Z0-9_]*</regexp>
	<action>[($item[1]=~/^(['"({])?(.*?)(['")}])?$/)]</action>
      </production>
    </rule>
    <rule id="inline_doc" inline="no">
      <production>
	<regexp>&lt;&lt;</regexp>
	<ruleref ref="inline_doc_string" arguments=""/>
	<directive type="skip">""</directive> 
	<regexp>.*\n</regexp>
	<regexp>(.|\n)*?\n$item[2][1]\s*(\n|$)</regexp>
	<action>
	  $text=$item[4].$text;
	  local $_=$item[5]; s/\n$item[2][1]\s*$//;
	  my $paren = $item[2][0];
	  $paren = '"' if $paren eq "";
	  if ($paren eq "'") {
	      $paren = '"';
	      s{(\\)(.|\n)|(\$)}{ (defined($3) and $3 eq '$') ? "\\\$"
	        : ((defined($2) and $2 eq "\\")
	        ? "\\\\" : ((defined($2) and $2 eq "'") ? "'" : (
	        (defined($2) and $2 eq '$') ? "\\\\\\$2" :
	        "\\\\$2"))) }eg;
	  } "&lt;&lt;".$paren.$_;
	</action>
      </production>
    </rule>
    <!-- ================== encoding string ====================== -->
    <rule id="enc_string" type="argtype" name="encoding" inline="no">
      <production>
	<ruleref ref="exp" arguments=""/>
      </production>
      <documentation sections="Argtypes Configuration">
	<title>enc_string argument type</title>
	<shortdesc>character encoding (codepage) identifier</shortdesc>
	<description>
	  <para>
	    An <xref linkend="exp"/> which evaluates to a valid encoding
	    name, e.g. to utf-8, utf-16, iso-8859-1, iso-8859-2,
	    windows-1250 etc. As with <xref linkend="filename"/>,
	    as long as the expression doesn't contain special characters
	    like braces, brackets, quotes, <literal>$</literal>, nor
	    <literal>@</literal>, it is taken as a literal and
	    evaluates to itself.
	  </para>
	</description>
      </documentation>
    </rule>
    <!-- ================== identifyer ====================== -->
    <rule id="ID" inline="no">
      <production>
	<regexp>[a-zA-Z_][a-zA-Z0-9_]*</regexp>
      </production>
    </rule>
    <rule id="varname" type="argtype" name="$variable" inline="no">
      <documentation sections="Argtypes Variables Documents">
	<title>variable name</title>
	<description>
	  <para>
	    Variable names start with a dollar-sign (<literal>$</literal>)
	    followed by an identifier. The identifier must
	    match the following regular
	    expression <literal>[a-zA-Z_][a-zA-Z0-9_]*</literal>,
	    i.e., it must be at least one character long, must
	    beginning with a letter or
	    underscore, and may only containing letters, underscores, and
	    digits.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="Variables"/>
	  <ruleref ref="assign_command"/>
	  <ruleref ref="my_command"/>
	  <ruleref ref="local_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="subname" type="argtype" name="subroutine" inline="no">
      <documentation sections="Argtypes Variables Documents">
	<title>sub-routine name</title>
	<shortdesc>name of a sub-routine</shortdesc>
	<description>
	  <para>
	    A sub-routine name is an identifier
	    matching the following regular
	    expression <literal>[a-zA-Z_][a-zA-Z0-9_]*</literal>,
	    i.e., it must be at least one character long, must
	    beginning with a letter or
	    underscore, and may only containing letters, underscores, and
	    digits.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="document" type="argtype" name="document" inline="no">
      <documentation sections="Argtypes Documents Variables">
	<title>document</title>
	<shortdesc>specifying documents</shortdesc>
	<description>
	  <para>
	    A document is specified by arbitrary
	    <xref linkend="exp"/> which evaluates
	    to a non-empty node-list.
	    From this node-list, the first node
	    is taken and its owner document is used.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="Variables"/>
	  <ruleref ref="assign_command"/>
	  <ruleref ref="my_command"/>
	  <ruleref ref="local_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="filename" type="argtype" inline="no">
      <production>
	<ruleref ref="exp" arguments=""/>
      </production>
      <documentation sections="Argtypes Documents">
	<title>Filename argument type</title>
	<shortdesc>specifying filenames</shortdesc>
	<description>
	  <para>An <xref linkend="exp"/> which evaluates to a valid
	    filename or URL. As long as the expression contains no
	    whitespace, no brackets of any type, quotes,
	    double-quotes, <literal>$</literal> character nor
	    <literal>@</literal> character, it is treated as a literal token
	    which evaluates to itself.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="nodename" type="argtype" inline="no">
      <production>
	<ruleref ref="exp" arguments=""/>
      </production>
      <documentation sections="Argtypes Documents">
	<title>Node-name argument type</title>
	<shortdesc>specifying names of DOM nodes</shortdesc>
	<description>
	  <para>An <xref linkend="exp"/> which evaluates to a valid
	    name of an element, attribute or processing-instruction
	    node. As long as the expression contains no
	    whitespace, no brackets of any type, quotes,
	    double-quotes, <literal>$</literal> character,
	    nor <literal>@</literal> character, it is treated as a literal token
	    which evaluates to itself.
	  </para>
	</description>
      </documentation>
    </rule>

    <!-- ================== XPATH ====================== -->
    <!-- 
    XPath accepted by &XSH; are either string constants "...", '...'
    or
    more compliex expressions of the form xpsimple xpcont?
    -->
    <rule id="xpath" type="argtype" inline="no">
      <production>
	<regexp>(?=['"])</regexp>
	<directive type="commit"/>
	<ruleref ref="xpstring" arguments=""/>
	<action>$item[3]</action>
      </production>
      <production>
	<ruleref ref="xpsimple" arguments=""/>
	<directive type="skip">""</directive>
	<ruleref ref="xpcont" rep="?" arguments=""/>
	<action>$item[1].join("",@{$item[3]})</action>
      </production>
      <production>
	<directive type="error">expected XPath, but got "}.substr($text,0,40).qq{ ..."</directive>
      </production>
      <documentation sections="Argtypes Navigation Manipulation Variables">
	<title>XPath argument type</title>
	<shortdesc>XPath expression</shortdesc>
	<description>
	  <para>
	    &XSH; can evaluate XPath expressions as defined in W3C
	    recommendation at <ulink
	    url="http://www.w3.org/TR/xpath">http://www.w3.org/TR/xpath</ulink>
	    with only a little limitation on use of syntactically
	    ignorable whitespace. 
	    (Nice interactive XPath tutorials and references
	    can be found at <ulink url="http://www.zvon.org">http://www.zvon.org</ulink>.)
	  </para>
	  <para>
	    In order to allow &XSH; to use white-space as a command
	    argument delimiter (which is far more convenient to type
	    than, say, commas), the use of white-space in XPath is
	    slightly restricted. Thus, in &XSH;, white-space can only occur in
	    those parts of an XPath expression, that are surrounded by
	    either brackets, square brackets, single or double quotes.
	    So, for example, otherwise valid XPath expression like
	  </para>
	  <code>/ foo / bar [ @baz = "bar" ]</code> 
	  <para>
	    should in &XSH; be written as either of
	  </para>
	  <code>/foo/bar[ @baz = "bar" ]</code> 
	  <para>
	    avoiding any white-space outside the square brackets,
	    or completely enclosed in brackets as in
	  </para>
	  <code>( / foo / bar [ @baz = "bar" ] ).</code>
	  <para>
	    &XSH; provides a number of powerful XPath extension
	    functions, listed below and described in separate
	    sections. XPath extension
	    functions by default belong to &XSH; namespace
	    <literal>http://xsh.sourceforge.net/xsh/</literal> with
	    a namespace prefix set to <literal>xsh</literal>. A
	    program may however call the <xref
	    linkend="xpath_extensions_command"/> command to map &XSH;
	    XPath extension functions into the default namespace, so
	    that they may be used directly without any prefix.
	  </para>
	  <para>
	    XPath extension functions defined in &XSH;:
	    <typeref types="function"/>
	  </para>
	  <example>
	    <title>Open a document and count all sections containing a
	      subsection
	    </title>
	    <code>xsh $scratch/&gt; <userinput>$v := open mydocument1.xml;</userinput>
	      xsh $v/&gt; <userinput>$k := open mydocument2.xml;</userinput>
	      xsh $k/&gt; <userinput>count //section[subsection];</userinput> # searches k
	      xsh $k/&gt; <userinput>count $v//section[subsection];</userinput> # searches v
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <!-- 
    xpsimple : start of an XPath expression
    -->
    <rule id="xpsimple" inline="no">
      <production>
	<regexp mod="x">
	  (?: 
              \$\{ (?: \$?[a-zA-Z_][a-zA-Z0-9_]* | \{.*?\} | \(.+?\) ) \} |
              \$(?!\{) |
              [^-:\$\[\]{}|"'\ \s();] |
              -[^-\[\]{}|"'\ \s();]
          )
          (?:
              \$\{ (?: \$?[a-zA-Z_][a-zA-Z0-9_]* | \{.*?\} | \(.+?\) ) \} |
              \$(?!\{) |
              [^\[\]\${}|"'\ \s();]
          )*</regexp>
      </production>
      <production>
	<ruleref ref="xpbrackets" arguments=""/>
      </production>
    </rule>    
    <!-- 
    xpcont : continuation XPath expression: filters or brackets
    -->
    <rule id="xpcont" inline="no">
      <production>
	<group>
	  <production>
	    <ruleref ref="xpfilters" arguments=""/>
	  </production>
	  <production>
	    <ruleref ref="xpbrackets" arguments=""/>
	  </production>
	</group>
	<directive type="skip">""</directive>
	<ruleref ref="xpath" rep="?" arguments=""/>
	<action>$item[1].join("",@{$item[3]})</action>
      </production>
      <production>
	<ruleref ref="xpath" arguments=""/>
	<action>$item[1]</action>
      </production>
    </rule>
    <!-- 
    xpfilters : one or more filters enclosed in [...]
    -->
    <rule id="xpfilters" inline="no">
      <production>
	<regexp>(?=\[)</regexp>
	<ruleref ref="xpfilter" rep="s" arguments=""/>
	<action>join("",@{$item[2]})</action>
      </production>
    </rule>
    <rule id="xpfilter" inline="no">
      <production>
	<string>[</string>
	<ruleref ref="xpinter" arguments=""/>
	<string>]</string>
	<action>"[$item[2]]"</action>
      </production>
    </rule>
    <!-- 
    xpbracket : balanced (...)
    -->
    <rule id="xpbracket" inline="no">
      <production>
	<string>(</string>
	<directive type="skip">&quot;&quot;</directive>
	<ruleref ref="xpinter" arguments=""/>
	<string>)</string>
	<action>&quot;($item[3])&quot;</action>
      </production>
    </rule>
    <rule id="xpbrackets" inline="no">
      <production>
	<regexp>(?=\()</regexp>
	<ruleref ref="xpbracket" arguments=""/>
	<directive type="skip">""</directive>
	<ruleref ref="xpfilters" rep="?" arguments=""/>
	<action>join "",$item[2],@{$item[4]}</action>
      </production>
    </rule>
    <!-- 
    xpinter : XPath expression occuring within (...) or [...]
    -->
    <rule id="xpinter" inline="no">
      <production>
	<ruleref ref="xps" arguments=""/>
	<directive type="skip">""</directive>
	<ruleref ref="xpintercont" rep="?" arguments=""/>
	<action>join("",$item[1],@{$item[3]})</action>
      </production>
    </rule>
    <!-- 
    xpintercont : continuation of an XPath expression within (...) or [...]
    -->
    <rule id="xpintercont" inline="no">
      <production>
	<group>
	  <production>
	    <ruleref ref="xpfilters" arguments=""/>
	  </production>
	  <production>
	    <ruleref ref="xpbrackets" arguments=""/>
	  </production>
	</group>
	<directive type="skip">""</directive>
	<ruleref ref="xpinter" rep="?" arguments=""/>
	<action>join("",$item[1],@{$item[3]})</action>
      </production>
    </rule>
    <!-- 
    xps : XPath fragment not containing brackets and closed upon strings
    -->
    <rule id="xps" inline="no">
      <production>
	<regexp mod="x">
	  (?: [^\$\[\]()'"};]+ |
              \$(?!\{) |
              \$\{ (?:\$?[a-zA-Z_][a-zA-Z0-9_]* |
                       \{.*?\} |
                       \(.+?\)
                   )
               \} |
              '(?:\$\{ (?: \$?[a-zA-Z_][a-zA-Z0-9_]* | \{.*?\} | \(.+?\)) \} | 
                  \$(?!\{) | [^\$'] | \\\$
               )*' |
              "(?:\$\{ (?: \$?[a-zA-Z_][a-zA-Z0-9_]* | \{.*?\} | \(.+?\)) \} |
                  \$(?!\{) | [^\$"] | \\\$
               )*"
          )*</regexp>
      </production>
    </rule>
    <!-- 
    xpstring : XPath string constant
    -->
    <rule id="xpstring" inline="no">
      <production>
	<regexp mod="x">
              '(?:\$\{(?:\$?[a-zA-Z_][a-zA-Z0-9_]*|\{.*?\}|\(.+?\))\}|\$(?!\{)|[^\$']|\\\$)*' |
              "(?:\$\{(?:\$?[a-zA-Z_][a-zA-Z0-9_]*|\{.*?\}|\(.+?\))\}|\$(?!\{)|[^\$"]|\\\$)*"
	</regexp>
      </production>
    </rule>
    <!-- ================== perl expression=expression ====================== -->
    <rule id="perl_expression" inline="no">
      <production>
	<action>$main::myline = $thisline;</action>
	<directive type="reject"/>
      </production>
      <production>
	<ruleref ref="exp" arguments=""/>
	<action>{local $^W=0; "\n# line $main::myline \"$XML::XSH2::Functions::SCRIPT\"\n".$item[1]}</action>
      </production>
    </rule>
    <rule id="perl_block" inline="no">
      <production>
	<action>$main::myline = $thisline;</action>
	<directive type="reject"/>
      </production>
      <production>
	<action>$main::myline = $thisline;</action>
	<directive type="reject"/>
      </production>
      <production>
	<directive type="perl_codeblock"/>
	<action>{
	  $return=$item[1];
	  {
  	    local $^W = 0; # don't warn about undefined contants
	    my $pos="# line $main::myline \"$XML::XSH2::Functions::SCRIPT\"\n";
	    $return=~s/^\{/\{\n$pos/;
          }
	  }</action>
      </production>
    </rule>
    <!-- ================== general expression ======================
    -->
    <rule id="loose_exp" inline="no">
      <production>
	<regexp>^(?={)</regexp>
	<ruleref ref="perl_block" arguments=""/>
	<action>$item[2]</action>
      </production>
      <production>
	<string>&amp;</string>
	<ruleref ref="block" arguments=""/>
	<action>$item[2]</action>
      </production>
      <production>
	<regexp>^(?=&lt;&lt;)</regexp>
	<ruleref ref="inline_doc" arguments=""/>
	<action>$item[2]</action>
      </production>
      <production>
	<ruleref ref="xpinter" arguments=""/>
      </production>
    </rule>
    <rule id="exp" type="argtype" name="expression" inline="no">
      <production>
	<regexp>^(?={)</regexp>
	<ruleref ref="perl_block" arguments=""/>
	<action>$item[2]</action>
      </production>
      <production>
	<string>&amp;</string>
	<ruleref ref="block" arguments=""/>
	<action>$item[2]</action>
      </production>
      <production>
	<regexp>^(?=&lt;&lt;)</regexp>
	<ruleref ref="inline_doc" arguments=""/>
	<action>$item[2]</action>
      </production>
      <production>
	<ruleref ref="xpath" arguments=""/>
      </production>
      <documentation sections="Argtypes Variables Manipulation Perl_shell">
	<title>expression</title>
	<shortdesc>expression argument type</shortdesc>
	<description>
	  <para>An &XSH; expression can be one of the following constructs:</para>
	  <enumerate>
	    <listitem>
	      <para>
		XPath 1.0 expression with the following restriction: 
		whitespace is only allowed within parts the expression
		enclosed in quotes (literal strings) or brackets (XPath
		has two types of brackets - plain and square). Thus, while
		<literal>/ foo / bar</literal> is a valid XPath expression
		matching element named bar under root element foo, in &XSH; this
		expression must be written as <literal>/foo/bar</literal> or
		<literal>(/ foo / bar)</literal> or
		<literal>(/foo/bar)</literal> etc.
		The reason for this restriction is simple: 
                &XSH;, like most shell
		languages, uses whitespace as argument delimiter so it must
		be able to determine expression boundaries
		(otherwise, <literal>/ bar / foo</literal> could be
		anything between one and four expressions).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		In certain contexts, usually when a filename or a node
		name is
		expected as an argument, bareword (otherwise XPath) 
		expressions are
		evaluated in a non-standard way: as long as the
		expression contains no whitespace, no brackets of any
		kind, quotes, double-quotes, <literal>$</literal>
		character, nor <literal>@</literal> character, 
		it is treated as a literal
		token which evaluates to itself. 
		This usually happens if a file name or element
		name is expected, but some other commands, like
		<xref linkend="print_command"/>,
		evaluate its arguments in this way. In order to force an
		XPath evaluation in such situations, the entire expression
		should be enclosed with brackets <literal>(...)</literal>.
		For example, with
		<xref linkend="open_command"/> command, <literal>open
		file</literal> or <literal>open "file"</literal> both
		open a file whose name is <literal>file</literal>
		(literally) whereas <literal>open (file)</literal> or
		<literal>open @file</literal> compute the file name
		by evaluating <literal>(file)</literal> or
		<literal>@file</literal> respectively, as XPath
		expressions.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
  		Perl blocks. These are enclosed in braces like: 
		<literal>{ perl-code }</literal>.
		Perl expressions can be used to evaluate more complicated
		things, like complex string expressions, regexp matches,
		perl commands, etc. In short, arbitrary perl.
		Of course, things like <literal>{`ls`}</literal> work
		too, and that's why we don't need to define shell-like backticks
		in &XSH; itself.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Result of one &XSH; command can be directly passed as an argument
		to another. This is done using &amp;{ xsh-code } expressions.
		Most &XSH; commands always return <literal>undef</literal> or 1,
		but some do return a value, usually a node-list. Examples of
		such commands are
		<xref linkend="open_command" />, <xref
		  linkend="copy_command"/>, <xref
		  linkend="move_command"/>, <xref
		  linkend="wrap_command"/>, <xref
		  linkend="edit_command"/>, or <xref
		  linkend="xslt_command"/>.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Large blocks of literal data can be passed to commands
		via "here document" expressions
		<literal>&lt;&lt;EOF</literal>,
		<literal>&lt;&lt;'EOF'</literal>,
		&lt;&lt;"EOF"<literal></literal>, where
		<literal>EOF</literal> is an arbitrary
		<literal>ID</literal> string.
		<literal>&lt;&lt;EOF</literal> and
		<literal>&lt;&lt;"EOF"</literal> are equivalent, and
		are subject to interpolation of
		<literal>${...}</literal> constructs, where as
		<literal>&lt;&lt;'EOF'</literal> does not. The result
		of evaluation of these three is the literal content
		(with <literal>${...}</literal> possibly interpolated)
		of the script starting at the following line and
		ending at a line containing just
		<literal>EOF</literal>. <literal>&lt;&lt;{EOF}</literal>
		and <literal>&lt;&lt;(EOF)</literal> are implemented
		too, but I'm not sure they are of any use since
		putting the expression in ( ) or { } has the same
		effect.
	      </para>
	    </listitem>
	  </enumerate>
	  <para>
	    XPath expressions (and their filename variant) are subject
	    to interpolation of substrings of the form
	    <literal>${...}</literal> (called interpolators), where
	    <literal>...</literal> can be of several different forms,
	    described below. The interpolation can be suppressed
	    by preceding the <literal>$</literal> sign with a backslash.
	  </para>
	  <para>
	    Substrings of the form <literal>${id}</literal> or
	    <literal>${$id}</literal> are interpolated with the
	    value of the variable named <literal>$id</literal>.
	  </para>
	  <para>
	    Interpolators of the form
	    <literal>${{</literal> and <literal>}}</literal>
	    evaluate their contents
	    as a Perl expression (in very much the same way as the
	    <xref linkend="perl_command"/> command) and interpolate
	    to the resulting value.
	  </para>
	  <para>
	    Interpolators of the form
	    <literal>${(</literal> and <literal>)}</literal>
	    evaluate their contents as an XPath expression and interpolates to
	    a string value of the result.
	  </para>
	  <para>
	    Substrings of the form <literal>\${</literal>
	    interpolate to <literal>${</literal>
	    (as a means for escaping <literal>${...}</literal>
	    in an expression).
	  </para>
	  <para>
	    Expressions are evaluated by &XSH; commands themselves, so
	    the exact value an expression evaluates to, is also
	    command-dependent. There are commands that can handle
	    all data types, but some commands expect their arguments to
	    evaluate only to specific kinds of values.
	    As already mentioned above, commands
	    expecting a filename or a node name usually evaluate
	    simple expressions not containing any special characters
	    as literal strings, whereas commands expecting strings
	    evaluate all expressions so that they get a string value
	    (e.g. by converting a node-set to its text content).
	    Similarly, commands expecting a node-set usually convert
	    strings to a small XML fragments, while commands
	    expecting a single document node usually convert
	    node-sets to a document node by taking the owner
	    document of the first element in the node-set.
	  </para>
	  <example>
	    <code>$a = "bar";              # $a contains: bar</code>
    	    <code>$b = $a;                 # $b contains: bar</code>
	    <code>$b = "$a";               # $b contains: $a</code>
	    <code>$b = "${a}";             # $b contains: bar</code>
            <code>$b = {$a};               # $b contains: bar</code>
            <code>$b = //creature;         # $b contains a node-set</code>
            <code>ls $b;                   # prints the node-set as XML in document order</code>
            <code>count $b;                # prints number of nodes in the node-set</code>
            <code>echo count($b);          # the same</code>
            <code>$c = string($b[1]/@name) # $c contains string value of //creature[1]/@name (e.g. Bilbo)</code>
            <code>echo //creature          # prints: //creature</code>
            <code>echo (//creature)        # evaluates (//creature) as XPath and prints the
                                           # text content of the resulting node-set</code>
	    <code></code>
	    <code>echo { join(",",split(//,$a)) }              # prints: b,a,r</code>
	    <code>echo ${{ join(",",split(//,$a)) }}           # the same</code>
	    <code>echo "${{ join(",",split(//,$a)) }}"         # the same</code>
	    <code>echo "${(//creature[1]/@name)}"              # prints e.g.: Bilbo</code>
	    <code>echo ${(//creature[1]/@name)}                # the same</code>
	    <code>echo //creature[1]/@name                     # the same</code>
	    <code>echo string(//creature[1]/@name)             # the same</code>
	    <code>echo (//creature[1]/@name)                   # the same</code>
	  </example>
	  <example>
	    <title>In-line documents</title>
	    <code>$a="bar"</code>
	    <code>echo foo &lt;&lt;END baz;
xx ${a} yy
END
	# prints foo xx bar yy baz</code>
	    <code>echo foo &lt;&lt;"END" baz;
xx ${a} yy
END
	# same as above</code>
	    <code>echo foo &lt;&lt;'END' baz;
xx ${a} yy
END
	# prints foo xx $a yy baz</code>
	  </example>
	  <example>
	    <title>Expressions returning result of a &XSH; command</title>
	    <code>copy &amp;{ sort --key @best_score --numeric //player } into .;</code>
	  </example>
	</description>
      </documentation>
    </rule>
    <!-- ================== variables ====================== -->
    <rule id="variable" inline="no">
      <production>
	<regexp>\$[a-zA-Z_][a-zA-Z0-9_]*</regexp>
      </production>
    </rule>
    <!-- ================== EOF ====================== -->
    <rule id="eof" inline="no">
      <production>
	<regexp>\Z</regexp>
	<action>1;</action>
      </production>
    </rule>
    <!-- ================== STARTRULE and such ====================== -->
    <rule id="startrule" inline="no">
      <production>
	<ruleref ref="shell" arguments=""/>
	<directive type="commit"/>
	<ruleref ref="eof" arguments=""/>
	<action>$item[1]</action>
      </production>
      <production>
	<ruleref ref="complex_command" rep="s" arguments=""/>
	<directive type="commit"/>
	<ruleref ref="eof" arguments=""/>
	<action>$item[1]</action>
      </production>
    </rule>
    <rule id="trail" inline="no">
      <production>
	<regexp>(?=\s*[};]|\s*\Z)</regexp>
	<directive type="commit"/>
	<directive type="reject"/>
      </production>
      <production>
	<string>|&gt;</string>
	<directive type="commit"/>
	<ruleref ref="variable" arguments=""/>
	<action>['var',$item[3]]</action>
      </production>
      <production>
	<string>|</string>
	<directive type="commit"/>
	<ruleref ref="shline" arguments=""/>
	<action>['pipe',$item[3]]</action>
      </production>
    </rule>
    <rule id="shline_nosc" inline="no">
      <production>
	<regexp>([^;()\\"'\|]|\|[^&gt;]|\\.|\"([^\"\\]|\\.)*\"|\'([^\'\\]|\\\'|\\\\|\\[^\'\\])*\')*</regexp>
      </production>
    </rule>
    <rule id="shline_inter" inline="no">
      <production>
	<regexp>([^()\\"']|\\.|\"([^\"\\]|\\.)*\"|\'([^\'\\]|\\\'|\\\\|\\[^\'\\])*\')*</regexp>
      </production>
    </rule>
    <rule id="shline_bracket" inline="no">
      <production>
	<string>(</string>
	<ruleref ref="shline_inter" arguments=""/>
	<ruleref ref="shline_bracket" rep="?" arguments=""/>
	<ruleref ref="shline_inter" arguments=""/>
	<string>)</string>
	<action>join("",'(',$item[2],@{$item[3]},$item[4],')')</action>
      </production>      
    </rule>
    <rule id="shline" inline="no">
      <production>
	<ruleref ref="shline_nosc" arguments=""/>
	<ruleref ref="shline_bracket" rep="?" arguments=""/>
	<ruleref ref="shline_nosc" arguments=""/>
	<action>join("",$item[1],@{$item[2]},$item[3])</action>
      </production>
    </rule>
    <rule id="shell" inline="no">
      <production>
	<regexp>!\s*</regexp>
	<directive type="commit"/>
	<regexp>.*</regexp>
	<action>[[<lineinfo/>,'sh_noev',$item[3]]]</action>
      </production>
      <production>
	<directive type="error-if-committed">Parse error near: "! }.substr($text,0,40).qq{ ..."</directive>
	<directive type="reject"/>
      </production>
    </rule>
    <!-- ================== STATEMENTS ====================== -->
    <rule id="elsif_block" name="elsif" inline="no">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<ruleref ref="elsif_block" arguments=""/>
	<action>[[$item[3],$item[4]],@{$item[5]}]</action>
      </production>
      <production>
	<regexp>(?!elsif)</regexp>
	<action>[]</action>
      </production>
      <production>
	<directive type="uncommit"/>
	<directive type="error">Parse error near keyword elsif: "}.substr($text,0,40).qq{ ..."</directive>
      </production>
    </rule>
    <rule id="else_block" name="else" inline="no">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="block" arguments=""/>
	<action>[[undef,$item[3]]]</action>
      </production>
      <production>
	<regexp>(?!else)</regexp>
	<action>[]</action>
      </production>
      <production>
	<directive type="uncommit"/>
	<directive type="error">Parse error near keyword else: "}.substr($text,0,40).qq{ ..."</directive>
      </production>
    </rule>
    <!-- try/catch -->
    <rule id="local_var" inline="no">
      <production>
	<group rep="?">
	  <production>
	    <regexp>(local|my)\s</regexp>
	  </production>
	</group>
	<ruleref ref="variable" arguments=""/>
	<action>[$item[2],@{$item[1]}]</action>
      </production>
    </rule>
    <rule id="try_catch" type="command" name="try" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="block" arguments=""/>
	<string>catch</string>
	<ruleref ref="local_var" rep="?" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<action>[<lineinfo/>,'try_catch',$item[3],$item[6],@{$item[5]}]</action>
      </production>
      <documentation sections="Flow">
	<usage>try <xref linkend="block"/> catch [[local|my] <xref linkend="varname"/>] <xref linkend="block"/></usage>
	<shortdesc>try/catch statement</shortdesc>
	<description>
	  <para>
	    Execute the <xref linkend="block"/> following the
	    <literal>try</literal> keyword.  If an error or exception
	    occurs during the evaluation, execute the
	    <literal>catch</literal> <xref linkend="block"/>.  If the
	    <literal>catch</literal> keyword is followed by a 
	    variable (possibly localized for the following block using
	    <xref linkend="my_command"/> or <xref linkend="local_command"/>)
	    and the <literal>try</literal> block fails
	    with an exception, the error message of
	    the exception is stored to the variable before the
	    <literal>catch</literal> block is executed.
	  </para>
	  <para>
	    The <xref linkend="throw_command"/> command as well as an equivalent
	    Perl construction <literal>perl { die "error message" }</literal> allow user to throw custom exceptions.
	  </para>
	  <para>
	    Unless exception is raised or error occurs, this command
	    returns the return value of the <literal>try</literal> block;
	    otherwise it returns the return value of 
	    the <literal>catch</literal> block.
	  </para>
	  <example>
	    <title>Handle parse errors</title>
	    <code>try {
	      <tab count="1"/>$doc:=open --format xml $input;
	      } catch {
	      <tab count="1"/>try {
	      <tab count="2"/>echo "XML parser failed, trying HTML";
	      <tab count="2"/>$doc := open --format html $input;
	      <tab count="1"/>} catch my $error {
	      <tab count="2"/>echo "Stopping due to errors: $error";
	      <tab count="2"/>exit 1;
	      <tab count="1"/>}
	      }
	    </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="throw_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <!-- if -->
    <rule id="if" type="command" name="if" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<ruleref ref="elsif_block" arguments=""/>
	<ruleref ref="else_block" arguments=""/>
	<action>[<lineinfo/>,'if_statement',[$item[3],$item[4]],@{$item[5]},@{$item[6]}]</action>
      </production>
      <documentation sections="Flow">
	<usage>if <xref linkend="exp"/> <xref linkend="command"/>
	</usage>
	<usage>
          if <xref linkend="exp"/>
	  <xref linkend="block"/> [ elsif <xref linkend="block"/> ]* [ else <xref linkend="block"/> ]
	</usage>
	<shortdesc>if statement</shortdesc>
	<description>
	  <para>
	    Executes <xref linkend="command"/> or <xref linkend="block"/> if a given <xref linkend="exp"/>
	    expression evaluates to a non-emtpty node-list, true
	    boolean-value, non-zero number or non-empty literal. If
	    the first expression fails, then 
	    <literal>elsif</literal> conditions are tested (if any) and the
	    <xref linkend="block"/> corresponding to the first one of
	    them which is true is executed. If none of the conditions is satisfied, an
	    optional <literal>else</literal> <xref linkend="block"/> is executed.
	  </para>
	  <example>
	    <title>Display node type</title>
	    <code>def node_type %n {
	      <tab count="1"/>foreach (%n) {
	      <tab count="2"/>if ( . = self::* ) { # XPath trick to check if . is an element
	      <tab count="3"/>echo 'element';
	      <tab count="2"/>} elsif ( . = ../@* ) { # XPath trick to check if . is an attribute
	      <tab count="3"/>echo 'attribute';
	      <tab count="2"/>} elsif ( . = ../processing-instruction() ) {
	      <tab count="3"/>echo 'pi';
              <tab count="2"/>} elsif ( . = ../text() ) {
	      <tab count="3"/>echo 'text';
              <tab count="2"/>} elsif ( . = ../comment() ) {
              <tab count="3"/>echo 'comment'
	      <tab count="2"/>} else { # well, this should not happen, but anyway, ...
              <tab count="3"/>echo 'unknown-type';
              <tab count="2"/>}
              <tab count="1"/>}
	      }
	    </code>
	  </example>
	  <example>
	    <title>Check a environment variable</title>
	    <code>if { defined($ENV{HOME}) } lcd { $ENV{HOME} }</code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="if_command" name="if" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="command" arguments=""/>
	<action>[<lineinfo/>,'if_statement',[$item[3],[$item[4]]]]</action>
      </production>
    </rule>
    <!-- unless -->
    <rule id="unless" type="command" name="unless" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<ruleref ref="else_block" rep="?" arguments=""/>
	<action>[<lineinfo/>,'unless_statement',$item[3],$item[4],@{$item[5]}]</action>
      </production>
      <documentation sections="Flow">
	<usage>unless <xref linkend="exp"/>
	  <xref linkend="command"/>
	</usage>
	<usage>
          unless <xref linkend="exp"/>
	  <xref linkend="block"/> [ else <xref linkend="block"/> ]
	</usage>
	<shortdesc>negated if statement</shortdesc>
	<description>
	  <para>Like if but negating the result of the expression.
	    Also, unlike if, <literal>unless</literal> has no
	    <literal>elsif</literal> block.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="if" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="unless_command" name="unless" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="command" arguments=""/>
	<action>[<lineinfo/>,'unless_statement',$item[3],[$item[4]]]</action>
      </production>
    </rule>
    <!-- while -->
    <rule id="while_command" name="while" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="command" arguments=""/>
	<action>[<lineinfo/>,'while_statement',$item[3],[$item[4]]]</action>
      </production>
    </rule>
    <rule id="while" type="command" name="while" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<action>[<lineinfo/>,'while_statement',$item[3],$item[4]]</action>
      </production>
      <documentation sections="Flow">
	<usage>while <xref linkend="exp"/> <xref linkend="block"/></usage>
	<shortdesc>simple while loop</shortdesc>
	<description>
	  <para> Execute the <xref linkend="command"/> or <xref linkend="block"/> as long as
	    the given <xref linkend="exp"/> evaluates to a non-emtpty
	    node-list, true boolean-value, non-zero number or
	    non-empty literal.
	  </para>
	  <example>
	    <title>The commands in this example do the same thing</title>
	    <code>xsh&gt; <userinput>while /table/row remove /table/row[1];</userinput>
	      xsh&gt; <userinput>remove /table/row;</userinput>
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <!-- do -->
    <rule id="do_command" type="command" name="do" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="block" arguments=""/>
	<action>[<lineinfo/>,'run_commands',$item[3],0]</action>
      </production>
      <documentation sections="Flow">
	<usage>do <xref linkend="block"/></usage>
	<shortdesc>execute a given block of commands</shortdesc>
	<description>
	  <para>
	    Execute <xref linkend="block"/>.
	    This command is probably only useful when one wants to
	    redirect output of more than one command.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="block"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="eval_command" type="command" name="eval" inline="yes">
      <command minargs="1" maxargs="1" func="run_exp"/>
      <documentation sections="Flow">
	<usage>eval <xref linkend="exp"/></usage>
	<shortdesc>evaluate given expression as XSH commands</shortdesc>
	<description>
	  <para>NOTE: This command has very different behavior from XSH1,
	    where it used to be an alias for <xref linkend="perl_command"/>.
	  </para>
	  <para>This command first evaluates a given <xref linkend="exp"/> to obtain a string,
	    then evaluates this string as &XSH; code in the current context, returning
	    the return value of the last evaluated command.
	    This command raises
	    an exception if either <xref linkend="exp"/> evaluates to
	    invalid &XSH; code or if evaluating the code raises an exception.
	  </para>
	  <example>
	    <title>Evaluate "in-line" XSH snippets within a XML document</title>
	    <code>foreach //inline-xsh eval .;</code>
	  </example>
	</description>
      </documentation>
    </rule>
    <!-- foreach -->
    <rule id="local_var_in" inline="no">
      <production>
	<ruleref ref="local_var" arguments=""/>
	<string>in</string>
	<action>$item[1]</action>
      </production>
    </rule>
    <rule id="foreach_command" name="foreach" inline="yes">
      <aliases>
	<alias name="for"/>
      </aliases>
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="local_var_in" rep="?" arguments=""/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="command" arguments=""/>
	<action>[<lineinfo/>,'foreach_statement',$item[4],[$item[5]],@{$item[3]}]</action>
      </production>
    </rule>
    <rule id="foreach" type="command" name="foreach" inline="yes">
      <aliases>
	<alias name="for"/>
      </aliases>
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="local_var_in" rep="?" arguments=""/>
	<ruleref ref="exp" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<action>[<lineinfo/>,'foreach_statement',@item[4,5],@{$item[3]}]</action>
      </production>
      <documentation sections="Flow">
	<usage>foreach <xref linkend="exp"/> 
	  <xref linkend="command"/>|<xref linkend="block"/>
	</usage>
	<usage>foreach [my|local] <xref linkend="varname"/> in <xref linkend="exp"/>
	  <xref linkend="command"/>|<xref linkend="block"/>
	</usage>
	<shortdesc>loop iterating over a node-list or a perl array</shortdesc>
	<description>
	  <para>
	    Evaluate given <xref linkend="exp" /> to a node-list and for each
	    resulting node execute given <xref linkend="command"/> or 
	    <xref linkend="block"/>. If used without a loop <xref
	      linkend="varname"/>, the loop temporarily sets current node to
	    the node being processed. Otherwise, the processed node is assigned
	    to the loop variable.
	  </para>
	  <para>
	    The <xref linkend="exp" /> may be <xref linkend="xpath"/> as well as
	    a <xref linkend="perl_code"/>.
	    In the latter case, if used without a loop variable, 
	    the loop automatically converts Perl objects to
	    nodes. No conversion is performed when
	    a loop variable is used.
	  </para>
	  <example>
	    <title>Move all employee sub-elements in a company element
	      into the first staff subelement of the same company</title>
	    <code>xsh&gt; <userinput>foreach //company xmove employee into staff[1];</userinput></code>
	  </example>
	  <example>
	    <title>List content of all XML files in current directory</title>
	    <code>xsh&gt; <userinput>foreach my $filename in { glob('*.xml') } {
		<tab/>$f := open $filename;
		<tab/>do_something $f; 
              }</userinput>
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <!-- def -->
    <rule id="undef" type="command" name="undef" inline="no">
      <aliases>
	<alias name="undefine"/>
      </aliases>
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<regexp>\$?[a-zA-Z_][a-zA-Z0-9_]*</regexp>
	<action>
	  [<lineinfo/>,'undefine',$item[3]];
	</action>
      </production>
      <documentation sections="Flow">
	<usage>undef [<xref linkend="subname"/> | <xref linkend="varname"/>]</usage>
	<shortdesc>undefine sub-routine or variable</shortdesc>
	<description>
	  <para>
	    This command can be used to undefine previously defined
	    &XSH; subroutines and variables.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="close_command"/>
	  <ruleref ref="def"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="def" type="command" name="def" inline="yes">
      <aliases>
	<alias name="define"/>
      </aliases>
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="ID" arguments=""/>
	<action>XML::XSH2::Functions::is_command($item[3])?undef:1</action>
	<ruleref ref="variable" rep="s?" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<action>
	  [<lineinfo/>,'def',$item[3],$item[6],$item[5]]
	</action>
      </production>
      <documentation sections="Flow">
	<usage>def <xref linkend="subname"/> [<xref linkend="varname"/> ...] <xref linkend="block"/>
	</usage>
	<shortdesc>sub-routine declaration</shortdesc>
	<description>
	  <para>
	    Define a new &XSH; sub-routine named <xref linkend="subname"/>.
	    The subroutine may require zero or more parameters. 
	    These are declared as a
	    whitespace-separated list of <emphasis>parametric
	    variables</emphasis>. The body of the
	    subroutine is specified as a <xref linkend="block"/>.
	  </para>
	  <para>A sub-routine can be invoked directly by its name
	    followed by its arguments
	    just as any &XSH; command, or indirectly
	    using the <xref linkend="call_command" />
	    command followed by an expression evaluating
	    to the routine name and sub-routine arguments. 
	    Sub-routine arguments can be arbitrary 
	    expressions. These expressions are evaluated
	    <emphasis>prior</emphasis> the sub-routine's code
	    execution and are assigned to the sub-routine's 
	    parametric variables in the respective order.
	    The number of parameter variables in a sub-routine
	    definition and the number of arguments in a call to it
	    must match.
	    Calling a sub-routine with less or more arguments
	    than declared is a run-time error.
	  </para>
	  <para>	    
	    Parametric variables are lexical 
	    variables within the sub-routine body as if they
	    were declared with <xref linkend="my_command" />.
	  </para>
	  <para>
	    Note that a subroutine has to be defined before it is
	    first called (in terms of execution -- depending on the structure
	    of the program, the actual definition of the sub-routine
	    must not necessarily precede all references to it).
	  </para>
	  <example>
	    <code>def l3 $nodes {
<tab count="1"/>ls --depth 3 $nodes; # list given nodes upto depth 3
}
l3 //chapter;           # direct call
$subref = 'l3';
call $subref //chapter; # in-direct call
	    </code>
	  </example>
	  <example>
	    <title>Commenting and un-commenting pieces of document</title>
	    <code>def comment
<tab count="1"/><tab count="1"/>$n      # nodes to move to comments
<tab count="1"/><tab count="1"/>$mark   # maybe some handy mark to recognize such comments
{
<tab count="1"/>foreach $n {
<tab count="1"/><tab count="1"/>if ( . = ../@* ) {
<tab count="1"/><tab count="1"/><tab count="1"/>echo "Warning: attribute nodes are not supported!";
<tab count="1"/><tab count="1"/>} else {
<tab count="1"/><tab count="1"/><tab count="1"/>echo "Commenting out:";
<tab count="1"/><tab count="1"/><tab count="1"/>ls --depth 0 .;
<tab count="1"/><tab count="1"/><tab count="1"/>add comment concat($mark,xsh:serialize(.)) replace .;
<tab count="1"/><tab count="1"/>}
<tab count="1"/>}
}

def uncomment $n $mark {
<tab count="1"/>foreach $n {
<tab count="1"/><tab count="1"/>if (. = ../comment()) { # is this node a comment node
<tab count="1"/><tab count="1"/><tab count="1"/>local $string = substring-after(.,"$mark");
<tab count="1"/><tab count="1"/><tab count="1"/>add chunk $string replace .;
<tab count="1"/><tab count="1"/>} else {
<tab count="1"/><tab count="1"/><tab count="1"/>echo "Warning: Ignoring non-comment node:";
<tab count="1"/><tab count="1"/><tab count="1"/>ls --depth 0 .;
<tab count="1"/><tab count="1"/>}
<tab count="1"/>}
}

# comment out all chapters with no paragraphs
comment //chapter[not(para)] "COMMENT-NOPARA";

# uncomment all comments stamped with COMMENT-NOPARA
$mark="COMMENT-NOPARA";
uncomment //comment()[starts-with(.,"$mark")] $mark;
</code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="call_command" arguments=""/>
	  <ruleref ref="return_command" arguments=""/>
	  <ruleref ref="my_command" arguments=""/>
	  <ruleref ref="local_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <!-- ================== COMMANDS ====================== -->
    <rule id="assign_command" type="command" name="assign" inline="yes">
      <production>
	<regexp>assign\b|(?:local\b|my\b)?(?=\s*\$[a-zA-Z_][a-zA-Z0-9_]*\s*\s*(?:[\-\+\*\/%x.]|\|\||\&amp;\&amp;)?:?=)</regexp>
	<directive type="commit"></directive>
	<ruleref ref="variable" arguments=""/>
	<group>
	  <production>
	    <regexp>(?:[\-\+\*\/%x.]|\|\||\&amp;\&amp;)?=</regexp>
	    <directive type="commit"/>
	    <ruleref ref="loose_exp" arguments=""/>
	    <action>['xpath_assign',$item[3],$item[1]]</action>
	  </production>
	  <production>
	    <regexp>\s*(?:[\-\+\*\/%x.]|\|\||\&amp;\&amp;)?:=</regexp>
	    <ruleref ref="command"/>
	    <action>['command_assign',$item[2],$item[1]]</action>
	  </production>
	</group>
	<action>[<lineinfo/>,@{$item[4]},$item[1],$item[3]]</action>
      </production>
      <documentation sections="Variables">
	<usage>[assign] <xref linkend="varname"/> = <xref
	    linkend="exp"/></usage>
	<usage>[assign] <xref linkend="varname"/> := <xref linkend="command"/></usage>
	<usage>[assign]
	  <xref linkend="varname"/> [-= | += | *= | /= | %= | x= | .= | ||= | &amp;&amp;= ] <xref linkend="exp"/></usage>
	<usage>[assign]
	  <xref linkend="varname"/> [-:= | +:= | *:= | /:= | %:= | x:= | .:= | ||:= | &amp;&amp;:= ] <xref linkend="command"/></usage>
	<shortdesc>variable assignment</shortdesc>
	<description>
	  <para>Evaluate the expression (= assignment) 
	    or command (:= assignment) on the right 
	    side of the assignment and store the result in 
	    a given variable. Optionally a Perl operator
	    (- subtraction, + addition, * multiplication,
	    / division, % modulo, x repeat string n-times,
	    . concatenation, || logical OR, &amp;&amp; logical AND)
	    can precede the assignment, in which
	    case the variable is assigned the result
	    of applying given operator on its previous
	    value and the value of the right side of the assignment.
	  </para>
	  <example>
	    <title>Assign XPath (node-set, string), or Perl results</title>
	    <code>xsh&gt; <userinput>$a=chapter/title;</userinput>
	      xsh&gt; <userinput>$b="hallo world";</userinput>
	      xsh&gt; <userinput>$c={ `uname` };</userinput>
	      xsh&gt; <userinput>ls $a;</userinput>
	    </code>
	  </example>
	  <example>
	    <title>Arithmetic expressions (XPath)</title>
	    <code>xsh&gt; <userinput>$a=5*100 </userinput> # assign 500 to $a
	      xsh&gt; <userinput>$a += 20 </userinput>     # add 20 to $a
	      xsh&gt; <userinput>$a = (($a+5) div 10) </userinput>
	    </code>
	  </example>
	  <example>
	    <title>Arithmetic expressions (Perl)</title>
	    <code>xsh&gt; <userinput>$a={ 5*100 } </userinput>
	      xsh&gt; <userinput>$a = { join ';', split //,"hallo" } </userinput> # assigns "h;a;l;l;o" to $a
	    </code>
	  </example>
	  <example>
	    <title>Command result assignment</title>
	    <code>xsh&gt; <userinput>$doc := open "file.xml" </userinput> # open a document
	      xsh&gt; <userinput>$copies := xcopy //foo into //bar </userinput> # copy elements and store the copies
	      xsh&gt; <userinput>$wrappers := wrap "wrapper" $copies </userinput> # wrap each node from $copies to a new element "wrapper" and store the wrapping elements
	    </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="var_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="my_command" type="command" name="my" inline="yes">
      <production>
	<selfref sep="yes"/>
	<ruleref ref="variable" rep="s" arguments=""/>
	<action>[<lineinfo/>,'store_lex_variables',0,@{$item[2]}]</action>
      </production>
      <documentation>
	<usage>my <xref linkend="varname"/> [$var2 ...];</usage>
	<usage>my <xref linkend="varname"/> = <xref
	    linkend="exp"/>;</usage>
	<shortdesc>Create a new lexically scoped variable</shortdesc>
	<description>
	  <para>Same as in Perl: a "my" declares the listed variables to be local
	    (lexically) to the enclosing block, or sub-routine.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="local_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="local_command" type="command" name="local" inline="yes">
      <production>
	<selfref sep="yes"/>
	<ruleref ref="variable" rep="s" arguments=""/>
	<action>[<lineinfo/>,'make_local',@{$item[2]}]</action>
      </production>
      <documentation sections="Variables">
	<usage>local <xref linkend="varname"/> = <xref linkend="xpath"/></usage>
	<usage>local <xref linkend="varname"/> [ <xref linkend="varname"/> ... ] </usage>
	<shortdesc>temporarily assign new value to a variable</shortdesc>
	<description>
	  <para> 
	    This command acts in a very similar way as
	    <xref linkend="assign_command"/> does, except
	    that the variable assignment is done temporarily
	    and lasts only for the rest of its enclosing
	    <xref linkend="block"/> or subroutine. At the end of the
	    enclosing block or subroutine, the original value
	    is restored. This also reverts any later usual assignments to the
	    variable done occurring before the end of the block.
	    This command may also be used without the assignment part.
	  </para>
	  <para>Note, that the variable itself remains
	    global in the sense that it is still visible to any
	    subroutine called subsequently from the same block.
	    Unlike <xref linkend="my_command"/>
	    declaration, it does not <emphasis>create</emphasis> a
	    new lexically scoped variable.
	  </para>
	  <para>
	    Hint for Perl programmers: <literal>local</literal>
	    in &XSH; works exactly as <literal>local</literal>
	    in Perl.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="assign_command" arguments=""/>
	  <ruleref ref="my_command" arguments=""/>
	  <ruleref ref="def" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="options_command" type="command" name="settings" inline="yes">
      <command maxargs="0" func="list_flags">
	<param name="variables" short="v"/>
      </command>
      <documentation sections="Information Configuration">
	<usage>settings</usage>
	<shortdesc>list current settings using &XSH; syntax</shortdesc>
	<description>
	  <para>List current values of all &XSH; settings (such as
	    validation flag or query-encoding).</para>
	  <para><literal>--variables</literal> or <literal>:v</literal>
	    flag enforces syntax which makes use of variable assignments.
	    Otherwise, settings are listed in the form of XSH commands.
	  </para>
	  <example>
	    <title>Store current settings in your .xsh2rc</title>
	    <code>xsh&gt; <userinput>settings | cat &gt; ~/.xsh2rc</userinput></code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="list_defs_command" type="command" name="defs" inline="yes">
      <command maxargs="0" func="list_defs"/>
      <documentation sections="Information">
	<usage>defs</usage>
	<shortdesc>list all user-defined subroutines</shortdesc>
	<description>
	  <para>List names and parametric variables for all user-defined &XSH; subroutines.</para>
	</description>
	<see-also>
	  <ruleref ref="def" arguments=""/>
	  <ruleref ref="var_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="ifinclude_command" type="command" name="ifinclude" inline="yes">
      <command minargs="1" maxargs="1" func="include" extraargs="1">
	<param name="encoding" short="e" type="string" argument="enc_string"/>
      </command>
      <documentation sections="Flow">
	<usage>ifinclude [--encoding|:e <xref linkend="enc_string"/>] <xref linkend="filename"/></usage>
	<shortdesc>conditionally include another &XSH; source in current position</shortdesc>
	<description>
	  <para>
	    Unless the file <xref linkend="filename"/> has already
	    been included using either <xref linkend="include_command"/> of
	    <xref linkend="ifinclude_command"/>, load the file and
	    execute it as a &XSH; script.
	  </para>
	  <para>Use <literal>--encoding</literal> or <literal>:e</literal>
	    parameter to specify character encoding used in
	    the included file.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="include_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="include_command" type="command" name="include" inline="yes">
      <aliases>
	<alias name="." regexp="\."/>
      </aliases>
      <command minargs="1" maxargs="1" func="include">
	<param name="encoding" short="e" type="string"
	argument="enc_string"/>
      </command>
      <documentation sections="Flow">
	<usage>include [--encoding|:e <xref linkend="enc_string"/>] <xref linkend="filename"/></usage>
	<shortdesc>include another &XSH; source in current position</shortdesc>
	<description>
	  <para>
	    Load a file named <xref linkend="filename"/> and execute it as a &XSH;
	    script.
	  </para>
	  <para>Use <literal>--encoding</literal> or <literal>:e</literal>
	    parameter to specify character encoding used in
	    the included file.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="ifinclude_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="apropos_command" type="command" name="apropos" inline="yes">
      <command minargs="1" maxargs="1" func="apropos">
	<param name="regexp" short="r"/>
	<param name="fulltext" short="f"/>
      </command>
      <documentation sections="Information">
	<usage>apropos [--fulltext] [--regexp] <xref linkend="exp"/></usage>
	<shortdesc>search the documentation</shortdesc>
	<description>
	  <para>
	    Print all help topics containing given expression
	    in their short description. The
	    <literal>--fulltext</literal> flag forces
	    the search to be performed over the full text
	    of help. 
	    <literal>--regexp</literal> indicates,
	    that the given <xref linkend="exp"/>
	    is a regular expression instead of a literal string.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="help_command" type="command" name="help" inline="yes">
      <command minargs="0" maxargs="1" func="help"/>
      <documentation sections="Information">
	<usage>help <xref linkend="command"/>|argument-type|xsh:xpath-function</usage>
	<shortdesc>on-line documentation</shortdesc>
	<description>
	  <para>Print help on a given command, argument type or
	    XPath extension function 
	    (use <literal>xsh:</literal> as a prefix to XPath extensions
	    function names, e.g <literal>help xsh:id2</literal>).
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="exec_command" type="command" name="exec" inline="yes">
      <aliases>
	<alias name="system"/>
      </aliases>
      <command minargs="1" func="sh"/>
      <documentation sections="Perl_shell">
	<usage>exec <xref linkend="exp"/> [<xref linkend="exp"/> ...]</usage>
	<shortdesc>execute a shell command</shortdesc>
	<description>
	  <para>This command executes given <xref linkend="exp"/>(s)
	    as a system command and returns the exit code.
	  </para>
	  <example>
	    <title>Count words in "hallo wold" string, then print name
	      of your machine's operating system.</title>
	    <code>exec echo hallo world;             # prints hallo world
	      exec "echo hallo word" | wc;       # counts words in hallo world
	      exec uname;                        # prints operating system name
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="xslt_command" type="command" name="xslt" inline="yes">
      <aliases>
	<alias name="transform"/>
	<alias name="xsl"/>
	<alias name="xsltproc"/>
	<alias name="process"/>
      </aliases>
      <command minargs="1" func="xslt">
	<param name="doc" short="d"/>
	<param name="string" short="s"/>
	<param name="compile" short="c"/>
	<param name="precompiled" short="p"/>
      </command>
      <documentation sections="Manipulation">
	<usage>$result := xslt [--doc|:d | --precompiled|:p] [--string] <xref linkend="exp"/> [<xref
	linkend="document"/> name=<xref linkend="xpath"/> [name=<xref linkend="xpath"/> ...]]</usage>
	<usage>$pre_compiled := xslt [--compile|:c] <xref linkend="exp"/></usage>
	<shortdesc>compile a XSLT stylesheet and/or transform a document with XSLT</shortdesc>
	<description>
	  <para>
	    This function compiles a given XSLT stylesheet 
	    and/or transforms a given document with XSLT.
	  </para>
	  <para>A XSLT stylesheet is specified in the
	    first argument either as a file name (default), or as a
	    document (<literal>--doc</literal> or
	    <literal>:d</literal>), or as a precompiled XSLT
	    stylesheet object (<literal>--precompiled</literal> or
	    <literal>:p</literal> - see <literal>--compile</literal>
	    above).</para>
	  <para>
	    If <literal>--compile</literal> or <literal>:c</literal>
	    is used, compile a given XSLT stylesheet and return a
	    compiled XSLT stylesheet object. This object can be later
	    passed as a XSLT stylesheet to <literal>xslt
	    --precompiled</literal>.
	  </para>
	  <para>
	    Without <literal>--compile</literal> or
	    <literal>:c</literal>, transform a given <xref
	    linkend="document"/> (or - if used with
	    only the stylesheet argument - the current document) 
	    using a given XSLT stylesheet and
	    return the result.</para>
	  <para>
	    All arguments following the second (document) argument are
	    considered to be stylesheet parameters and (after
	    expanding <literal>${...}</literal> interpolators) are
	    directly passed to the XSLT engine without being evaluated
	    by &XSH;. All stylesheet parameters should be of the form
	    <literal>name=<xref linkend="xpath"/></literal> (possibly
	    in brackets).
	  </para>
	  <example>
	    <title>Process current document with XSLT</title>
	    <code>$result := xslt stylesheet.xsl . font='14pt' color='red'</code>
	  </example>
	  <example>
	    <title>Same for several documents, reusing the XSLT stylesheet</title>
	    <code>$xslt := xslt --compile stylesheet.xsl;
               foreach my $file in {qw(f1.xml f2.xml f3.xml)} {
               <tab/>save --file {"out_$file"} &amp;{xslt --precompiled $xslt &amp;{ open $file } font='14pt' color='red'};
               }
            </code>
	  </example>

	</description>
      </documentation>
    </rule>
    <rule id="param" inline="no">
      <production>
	<regexp>[^=\s]+</regexp>
	<string>=</string>
	<ruleref ref="exp"/>
	<action>[$item[1],$item[3]]</action>
      </production>
    </rule>
    <rule id="files_command" type="command" name="documents" inline="yes">
      <aliases>
	<alias name="files"/>
	<alias name="docs"/>
      </aliases>
      <command maxargs="0" func="files"/>
      <documentation sections="Information Documents">
	<usage>documents</usage>
	<shortdesc>display a list of open documents</shortdesc>
	<description>
	  <para>Try to identify open documents and list their URIs
	    and variables that contain them.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="open_command" arguments=""/>
	  <ruleref ref="close_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="set_filename_command" type="command" name="set_filename" inline="yes">
      <command minargs="1" maxargs="2" func="set_filename"/>
      <documentation sections="Documents">
	<usage>set_filename <xref linkend="exp"/> [<xref linkend="document"/>]</usage>
	<shortdesc>change filename or URL associated with a document</shortdesc>
	<description>
	  <para>Changes filename or URL associated with a 
	    given document (or the current document, if only
	    one argument is specified). Document filename is initialized
	    by the <xref linkend="open_command" /> command
	    and used e.g. by <xref linkend="save_command"/>.
	    It can be queried in XPath expressions using the
	    <xref linkend="filename_function"/> function.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="open_command" arguments=""/>
	  <ruleref ref="save_command" arguments=""/>
	  <ruleref ref="filename_function" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="var_command" type="command" name="variables" inline="yes">
      <aliases>
	<alias name="vars"/>
	<alias name="var"/>
      </aliases>
      <command maxargs="0" func="variables"/>
      <documentation sections="Information">
	<usage>variables</usage>
	<shortdesc>list global variables</shortdesc>
	<description>
	  <para>List all global variables and their current values.</para>
	</description>
	<see-also>
	  <ruleref ref="files_command" arguments=""/>
	  <ruleref ref="list_defs_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="copy_command" type="command" name="copy" inline="yes">
      <aliases>
	<alias name="cp"/>
      </aliases>
      <command minargs="3" maxargs="3" func="copy" extraargs="0">
	<param name="respective" short="r"/>
      </command>
      <documentation sections="Manipulation">
	<usage>copy [--respective|:r] <xref linkend="exp"/> <xref linkend="loc"/> <xref
	    linkend="exp"/></usage>
	<usage>$results := copy [--respective|:r] <xref linkend="exp"/> <xref linkend="loc"/> <xref linkend="exp"/></usage>
	<shortdesc>copy nodes (in the one-to-one mode)</shortdesc>
	<description>
	  <para>
	    Copies nodes in the first node-list <xref linkend="exp"/>
	    (source nodes) to the destinations determined by the 
	    the <xref linkend="loc"/> directive
	    applied to nodes in the second node-list <xref linkend="exp"/>
	    (target nodes). If the source node-list contains
	    more than one node, than N'th node in the source node-list
	    is copied to the location relative to the N'th node in
	    the target node-list.
          </para>
	  <para>
	    If <literal>--respective|:r</literal> option
	    is used, then the target node-list <xref linkend="exp"/>
	    is evaluated in the context of the source node
	    being copied.
	  </para>
          <para>Possible values for <xref linkend="loc"/> are:
	    <literal>after</literal>, <literal>before</literal>,
	    <literal>into</literal>, <literal>replace</literal>,
	    <literal>append</literal> and <literal>prepend</literal>. The first
	    three location directives cause making a copy of the source nodes
	    after, before, and within (as the last child-node) the target
	    nodes, respectively. 
	    If <literal>replace</literal> location directive is used,
            source node are copied before the respective
	    target nodes and target nodes are removed.
	    The <literal>append</literal> and <literal>prepend</literal>
	    location directives allow,
	    depending on the destination node type,
	    either inserting copies of the
	    source nodes as the first or last child nodes of
	    a destination element or appending/prepending
	    destination node data in case of non-element destination nodes.
	    See <xref linkend="loc"/> argument type
	    for more detail.
	  </para>
	  <para>The command returns a node-list consisting of 
	    the copies of all source nodes created by the command.
	  </para>
	  <para>Despite the fact the command is named "copy", 
	    nodes resulting from copying
	    the source nodes may pass through certain type conversion before
	    they are inserted at the appointed destinations. This, however,
	    only happens in cases where the types of the source and target
	    nodes are not compatible with the location
	    directive. See <xref linkend="loc" /> argument
	    type for more detail.
	  </para>
	  <para>Note that &XSH; refuses to create multiple top-level
	    elements using <literal>copy</literal>, 
	    <xref linkend="move_command"/> and similar commands.</para>
	  <example>
	    <title>Replace living-thing elements in the document b with copies
	      of the corresponding creature elements from the document $a.</title>
	    <code>xsh&gt; <userinput>copy $a//creature replace $b//living-thing</userinput></code>             
	  </example>
	  <example>
	    <title>Copy every element into itself</title>
	    <code>xsh&gt; <userinput>copy --respective $a//* into .</userinput></code>
	    <code>xsh&gt; <userinput>copy $a//* into $a//*</userinput> #same as
	    above</code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="xcopy_command" arguments=""/>
	  <ruleref ref="move_command" arguments=""/>
	  <ruleref ref="xmove_command" arguments=""/>
	  <ruleref ref="insert_command" arguments=""/>
	  <ruleref ref="xinsert_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="xcopy_command" type="command" name="xcopy" inline="yes">
      <aliases>
	<alias name="xcp"/>
      </aliases>
      <command minargs="3" maxargs="3" func="copy" extraargs="1">
	<param name="respective" short="r"/>
	<param name="preserve-order" short="p"/>
      </command>
      <documentation sections="Manipulation">
	<usage>xcopy [--respective|:r] [--preserve-order|:p] <xref linkend="exp"/> <xref linkend="loc"/> <xref linkend="exp"/></usage>
	<shortdesc>copy nodes (in the all-to-every mode)</shortdesc>
	<description>
	  <para>
	    xcopy is similar to <xref linkend="copy_command"/>, but copies
	    <emphasis>all</emphasis> nodes in the first node-list
	    <xref linkend="exp"/> to <emphasis>all</emphasis>
	    destinations determined by the
	    <xref linkend="loc"/> directive relative 
	    to the second node-list <xref linkend="exp"/>. 
	    See <xref linkend="copy_command"/> for detailed description of
	    <literal>xcopy</literal> arguments.
	  </para>
	  <para>
	    If <literal>--respective|:r</literal> option
	    is used, then the target node-list <xref linkend="exp"/>
	    is evaluated in the context of the source node
	    being copied.
	  </para>
	  <para>
	    The <literal>--preserve-order|:p</literal> option can be
	    used to ensure that the copied nodes are in the same
	    relative order as the corresponding source nodes.
	    Otherwise, if <xref linkend="loc"/> is
	    <literal>after</literal> or <literal>prepend</literal>,
	    the relative order of the copied nodes will be reversed,
	    because source nodes are placed to the target location one
	    by one.
	  </para>
	  <example>
	    <title>Copy all middle-earth creatures within the document $a
	      into every world of the document $b.</title>
	    <code>xsh&gt; <userinput>xcopy $a/middle-earth/creature into $b//world</userinput></code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="copy_command" arguments=""/>
	  <ruleref ref="move_command" arguments=""/>
	  <ruleref ref="xmove_command" arguments=""/>
	  <ruleref ref="insert_command" arguments=""/>
	  <ruleref ref="xinsert_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="cd_command" type="command" name="lcd" inline="yes">
      <aliases>
	<alias name="chdir"/>
      </aliases>
      <command maxargs="1" func="cd"/><documentation sections="Perl_shell">
	<usage>lcd <xref linkend="exp"/></usage>
	<shortdesc>change system working directory</shortdesc>
	<description>
	  <para>
	    Changes the filesystem working directory 
	    to <xref linkend="exp"/>, if possible.  
	    If <xref linkend="exp"/> is omitted, changes to the directory
	    specified in HOME environment variable, if set; if not,
	    changes to the directory specified by LOGDIR environment
	    variable.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="insert_command" type="command" name="insert" inline="yes">
      <aliases>
	<alias name="add"/>
      </aliases>
      <command minargs="4" maxargs="4" func="insert" extraargs="0">
	<param name="namespace" short="n" type="exp" argument="exp"/>
      </command>
      <documentation sections="Manipulation">
	<usage>insert [--namespace|:n <xref linkend="exp"/>] <xref linkend="nodetype"/> <xref linkend="exp"/> <xref linkend="loc"/> <xref linkend="xpath"/>
	</usage>
	<shortdesc>create a node in on a given target location</shortdesc>
	<description>
	  <para>
	    Works just like <xref linkend="xinsert_command"/>, 
	    except that the new node is attached
	    only the first node matched.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="xinsert_command" arguments=""/>
	  <ruleref ref="move_command" arguments=""/>
	  <ruleref ref="xmove_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="wrap_command" type="command" name="wrap" inline="yes">
      <command minargs="2" maxargs="2" func="wrap">
	<param name="namespace" short="n" type="exp" argument="exp"/>
	<param name="while" short="W" type="xpath" argument="exp"/>
	<param name="until" short="U" type="xpath" argument="exp"/>
	<param name="skip-whitespace" short="w"/>
	<param name="skip-comments" short="c"/>
	<param name="skip-pi" short="p"/>
	<param name="inner" short="i"/>
      </command>
      <documentation sections="Manipulation">
	<usage>wrap [--namespace <xref linkend="exp"/>] 
	  [ [--inner] | [--while|:W <xref linkend="exp"/>] [--until|:U <xref linkend="exp"/>]
	    [--skip-whitespace|:w] [--skip-comments|:c] [--skip-pi|:p] ]
	  <xref linkend="exp"/> <xref linkend="xpath"/>
	</usage>
	<shortdesc>wrap given nodes into elements</shortdesc>
	<description>
	  <para>
	    For each node matching the <xref linkend="xpath"/> argument,
	    this command creates a new element node according to a
	    given <xref linkend="exp"/> (in the same
	    way as <xref linkend="xinsert_command"/> does)
	    which replaces the matching node, and
	    moves the matching node into this newly created element.
	    If namespace <xref linkend="exp"/> is given,
	    the namespace is applied on the created element.
	    The command returns a node-list consisting
	    of the elements created.
	  </para>
	  <para>
	    With <literal>--inner</literal> (or <literal>:i</literal>)
	    flag the command 
	    wraps children nodes of the matching node
	    rather than the node it self
	    the following sense:
	    for each matching node
	    a new element node is created,
	    but this time it is placed into 
	    the matching node and 
	    all previous children of the matching node
	    are moved into the newly created node.
	    In this mode, all non-element matching
	    nodes are ignored. This flag cannot be used together
	    with <literal>--while</literal>
	    and <literal>--until</literal>, which we describe next.
	  </para>
	  <para>
	    <literal>--while</literal> (<literal>:W</literal>)
	    and/or <literal>--until</literal> (<literal>:U</literal>) 
	    arguments can be provided in order to move a sequence
	    of adjacent siblings following the matching node into
	    the newly created element. In this way the newly created element wraps
	    not just the matching node itself but a range of nodes starting
	    at the matching node and ending either before a first following node matching
	    the expression of <literal>--until</literal>, or
	    before a first following node not matching the expression
	    of <literal>--while</literal>, or at the last sibling if
	    neither of the prior apply. Both these expressions are
	    evaluated in the context of the currently tested sibling and prior to
	    the creation of the wrapping element. The context
	    position for these expressions is 1 at the first sibling
	    following the matching node and increases with each tested
	    sibling; the context size is the number of all
	    siblings following the matching node.
	    It is important to mention that siblings wrapped in this
	    way are excluded from further processing by <xref
	    linkend="wrap_command"/> even if included in the node-list
	    produced by the <xref
	    linkend="xpath"/> argument. This allows to easily wrap
	    certain adjacent elements without worrying about some
	    elements being wrapped multiple times
	    (for example, <literal>wrap :W x y //x</literal> wraps
	    each sequence of adjacent elements <literal>&lt;x></literal> in a <literal>&lt;y></literal>).
	  </para>
	  <para><literal>--skip-whitespace</literal> (<literal>:w</literal>),
	    <literal>--skip-comments</literal> (<literal>:c</literal>), and 
	    <literal>--skip-pi</literal> (<literal>:p</literal>) can be used
	    in combination with <literal>--while</literal> (<literal>:W</literal>)
	    and/or <literal>--until</literal> (<literal>:U</literal>)
	    to skip testing the expressions on white-space text
	    nodes, comments, and/or processing instruction, respectively.
	    Such nodes are only included in the wrapped range if
	    followed by a sibling that is to be wrapped.
	  </para>
	  <example>
	    <code>$scratch/&gt; ls /;
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;scratch/&gt;

$scratch/&gt; wrap 'foo' *;
$scratch/&gt; insert attribute 'bar=baz' into /foo;
$scratch/&gt; insert text 'some text' into //scratch;
$scratch/&gt; wrap --namespace 'http://foo/bar' 'a:A' //@*;
$scratch/&gt; $wrapper := wrap 'text aaa="bbb"' //text();
$scratch/&gt; wrap '&lt;elem ccc=ddd&gt;' //*;
$scratch/&gt; ls /;
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;elem ccc="ddd"&gt;
<tab count="1"/>&lt;foo xmlns:a="http://foo/bar"&gt;
<tab count="1"/><tab count="1"/>&lt;elem ccc="ddd"&gt;
<tab count="1"/><tab count="1"/><tab count="1"/>&lt;scratch&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;elem ccc="ddd"&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;text aaa="bbb"&gt;some text&lt;/text&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;/elem&gt;
<tab count="1"/><tab count="1"/><tab count="1"/>&lt;/scratch&gt;
<tab count="1"/><tab count="1"/>&lt;/elem&gt;
<tab count="1"/><tab count="1"/>&lt;elem ccc="ddd"&gt;
<tab count="1"/><tab count="1"/><tab count="1"/>&lt;a:A xmlns:a="http://foo/bar" bar="baz"/&gt;
<tab count="1"/><tab count="1"/>&lt;/elem&gt;
<tab count="1"/>&lt;/foo&gt;
&lt;/elem&gt;

$scratch/&gt; ls $wrapper;
&lt;text aaa="bbb"&gt;some text&lt;/text&gt;


$scratch/&gt; wrap --inner bar //foo
$scratch/&gt; ls /;
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;elem ccc="ddd"&gt;
<tab count="1"/>&lt;foo xmlns:a="http://foo/bar"&gt;
<tab count="1"/><tab count="1"/>&lt;bar&gt;
<tab count="1"/><tab count="1"/><tab count="1"/>&lt;elem ccc="ddd"&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;scratch&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;elem ccc="ddd"&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;text aaa="bbb"&gt;some text&lt;/text&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;/elem&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;/scratch&gt;
<tab count="1"/><tab count="1"/><tab count="1"/>&lt;/elem&gt;
<tab count="1"/><tab count="1"/><tab count="1"/>&lt;elem ccc="ddd"&gt;
<tab count="1"/><tab count="1"/><tab count="1"/><tab count="1"/>&lt;a:A xmlns:a="http://foo/bar" bar="baz"/&gt;
<tab count="1"/><tab count="1"/><tab count="1"/>&lt;/elem&gt;
<tab count="1"/><tab count="1"/>&lt;/bar&gt;
<tab count="1"/>&lt;/foo&gt;
&lt;/elem&gt;
 </code>
	  </example>
	  <example>
	    <title>Wrapping a range of adjacent nodes</title>
	    <code># prepare the test document
$scratch/> rm /scratch/node(); # cleanup the document
$scratch/> set /scratch/li[5]; # create 5 &lt;li> elements
$scratch/> set /scratch/li[3]/following-sibling::li; # add &lt;br/> after the 3rd &lt;li>
$scratch/> for //li set . position(); # number the &lt;li> elements 
$scratch/> ls /
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;scratch>
<tab/>&lt;li>1&lt;/li>
<tab/>&lt;li>2&lt;/li>
<tab/>&lt;li>3&lt;/li>
<tab/>&lt;br/>
<tab/>&lt;li>4&lt;/li>
<tab/>&lt;li>5&lt;/li>
&lt;/scratch>
# wrap adjacent elements &lt;li> into an &lt;ol>
$scratch/> wrap --skip-whitespace --while self::li ol //li;
$scratch/> ls /
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;scratch>
<tab/>&lt;ol>
<tab count="2"/>&lt;li>1&lt;/li>
<tab count="2"/>&lt;li>2&lt;/li>
<tab count="2"/>&lt;li>3&lt;/li>
<tab/>&lt;/ol>
<tab/>&lt;br/>
<tab/>&lt;ol>
<tab count="2"/>&lt;li>4&lt;/li>
<tab count="2"/>&lt;li>5&lt;/li>
<tab/>&lt;/ol>
&lt;/scratch>
 </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="xinsert_command" arguments=""/>
	  <ruleref ref="insert_command" arguments=""/>
	  <ruleref ref="move_command" arguments=""/>
	  <ruleref ref="xmove_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="wrap_span_command" type="command" name="wrap-span" inline="yes">
      <aliases>
	<alias name="wrap_span"/>
      </aliases>
      <command minargs="3" maxargs="3" func="wrap_span">
	<param name="namespace" short="n" type="exp" argument="exp"/>
      </command>
      <documentation sections="Manipulation">
	<usage>wrap-span [--namespace <xref linkend="exp"/>] <xref linkend="exp"/> <xref linkend="exp"/> <xref linkend="exp"/></usage>
	<shortdesc>wrap spans of nodes into elements</shortdesc>
	<description>
	  <para>
	    This command is very similar to <xref linkend="wrap_command"/>
	    command, except that it works on spans of nodes.
	    It wraps spans (i.e. sequence of adjacent nodes between (and including)
	    a start node and an end node) with a new element
	    whose name is specified as the first argument. 
	    Nodes within each span must have the same parent node.
	    The spans to be wrapped are defined
	    by a pair of node-lists in the second and third argument.
	    The first node-list specifies the
	    start node of one or more spans, while
	    the second node-list should contain the corresponding 
	    end nodes.
	    The two node-lists must evaluate to the exactly same number of
	    nodes, otherwise a runtime error is reported.
	    The N'th span is then defined as a span
	    starting on the N'th node in the start node-list
	    and ending at the N'th node in the end node-list.
	  </para>
	  <para>
	    All nodes within the spans are removed from
	    the document and placed into the newly generated elements.
	    The wrapping elements are put back into the document tree
	    at the positions previously occupied by the node-spans.</para>
	  <para>
	    The command returns a node-list containing the newly created
	    wrapping elements.
	  </para>
	  <example>
	    <code>xsh $scratch/&gt; $foo := create { "&lt;root&gt;\n&lt;a/&gt;&lt;b/&gt;\n&lt;a/&gt;&lt;b/&gt;\n&lt;a/&gt;&lt;b/&gt;\n&lt;/root&gt;" };
xsh $foo/&gt; wrap-span 'span' //a //b;
xsh $foo/&gt; ls /;
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;root&gt;
&lt;span&gt;&lt;a/&gt;&lt;b/&gt;&lt;/span&gt;
&lt;span&gt;&lt;a/&gt;&lt;b/&gt;&lt;/span&gt;
&lt;span&gt;&lt;a/&gt;&lt;b/&gt;&lt;/span&gt;
&lt;/root&gt;
 </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="xinsert_command" arguments=""/>
	  <ruleref ref="insert_command" arguments=""/>
	  <ruleref ref="move_command" arguments=""/>
	  <ruleref ref="xmove_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="xinsert_command" type="command" name="xinsert" inline="yes">
      <aliases>
	<alias name="xadd"/>
      </aliases>
      <command minargs="4" maxargs="4" func="insert" extraargs="1">
	  <param name="namespace" short="n" type="exp" argument="exp"/>
      </command>
      <documentation sections="Manipulation">
	<usage>xinsert [--namespace <xref linkend="exp"/>] <xref linkend="nodetype"/> <xref linkend="exp"/> <xref linkend="loc"/> <xref linkend="xpath"/></usage>
	<shortdesc>create nodes on all target locations</shortdesc>
	<description>
	  <para>
	    Create new nodes of the 
	    <xref linkend="nodetype"/> given in the 1st argument
	    of name specified in the 2nd argument and insert them 
	    to <xref linkend="loc"/>s  relative to nodes
	    in the node-list specified in the 4th argument.
	  </para>
	  <para>
	    For element nodes, the the 2nd argument <xref
	      linkend="exp"/> 
	    should evaluate to something like
	      "&lt;element-name att-name='attvalue' ...&gt;".  The
	      <literal>&lt;</literal> and <literal>&gt;</literal>
	      characters are optional. If no attributes are used, the
	      expression may simply consist the element name. Note,
	      that in the first case, the quotes are required since
	      the expression contains spaces.
	  </para>
	  <para>
	    Attribute nodes use the following syntax:
	    "att-name='attvalue' [...]".
	  </para>
	  <para>
	    For the other types of nodes (text, cdata, comments) the
	    expression should contain the node's literal content. Again,
	    it is necessary to quote all whitespace and special
	    characters as in any expression argument.
	  </para>
	  <para>
	    The <xref linkend="loc"/> argument should be one of:
	    <literal>after</literal>, <literal>before</literal>,
	    <literal>into</literal>,
	    <literal>replace</literal>, <literal>append</literal>
	    or <literal>prepend</literal>. See documentation
	    of the <xref linkend="loc"/> argument type for more detail.
	  </para>
	  <para>
	    Optionally, for element and attribute nodes,
	    a namespace may be specified with <literal>--namespace</literal>
	    or <literal>:n</literal>. If used, 
	    the expression should evaluate to the desired namespace
	    URI and the name of the element or attribute being inserted 
	    <emphasis>must have a prefix</emphasis>.
	  </para>
	  <para>
	    The command returns a node-list consisting of nodes it created.
	  </para>
	  <para>
	    Note, that instead of <literal>xinsert</literal>, you can alternatively use 
	    one of <xref linkend="new_attribute_function"/>,
	    <xref linkend="new_cdata_function"/>,
	    <xref linkend="new_chunk_function"/>,
	    <xref linkend="new_comment_function"/>,
	    <xref linkend="new_element_function"/>,
	    <xref linkend="new_element_ns_function"/>,
	    <xref linkend="new_pi_function"/>, and
	    <xref linkend="new_text_function"/>
	    together with the command <xref linkend="xcopy_command"/>.
	  </para>
	  <example>
	    <title>Give each chapter a provisional title element.</title>
	    <code>xsh&gt; <userinput>my $new_titles := xinsert element "&lt;title font-size=large underline=yes&gt;" \
		<tab count="1"/>into /book/chapter</userinput>
	      xsh&gt; <userinput>xinsert text "Change me!" into $new_titles;</userinput></code>
	  </example>
	  <example>
	    <title>Same as above, using xcopy and xsh:new-... instead of xinsert</title>
	    <code>xsh&gt; <userinput>my $new_titles := xcopy xsh:new-element("title","font-size","large","underline","yes") \
		<tab count="1"/>into /book/chapter</userinput>
	      xsh&gt; <userinput>xcopy xsh:new-text("Change me!") into $new_titles;</userinput></code>
	  </example>

	</description>
	<see-also>
	  <ruleref ref="insert_command" arguments=""/>
	  <ruleref ref="move_command" arguments=""/>
	  <ruleref ref="xmove_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="nodetype" name="node-type" type="argtype" inline="no">
      <production>
	<regexp>element|attribute|attributes|text|cdata|pi|comment|chunk|entity_reference</regexp>
      </production>
      <documentation sections="Argtypes Manipulation">
	<title>Node-type argument type</title>
	<shortdesc>node type specification (such as element, attribute, etc.)</shortdesc>
	<description>
	  <para>
	    One of: element, attribute, text, cdata, comment, chunk
	    and (EXPERIMENTALLY!) entity_reference.  A
	    chunk is a character string which forms a well-balanced
	    piece of XML.
	  </para>
	  <example>
	    <code>add element hobbit into //middle-earth/creatures;
	      add attribute 'name="Bilbo"' into //middle-earth/creatures/hobbit[last()];
	      add chunk '&lt;hobbit name="Frodo"&gt;A small guy from &lt;place&gt;Shire&lt;/place&gt;.&lt;/hobbit&gt;' 
	      <tab count="1"/>into //middle-earth/creatures;
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="loc" type="argtype" name="location" inline="no">
      <production><regexp>after\s</regexp>
	<action>"after"</action>
</production>
      <production><regexp>before\s</regexp>
	<action>"before"</action>
</production>
      <production><regexp>(in)?to\s</regexp>
	<action>"into"</action>
      </production>
      <production><regexp>(append(ing)?|as\s+(a\s+)child(\s+of)?)\s</regexp>
	<action>"append"</action>
      </production>
      <production><regexp>(prepend(ing)?|(as\s+)(the\s+)first(\s+child(\s+of)?)?)\s</regexp>
	<action>"prepend"</action>
      </production>
      <production><regexp>(replace|instead( of)?)\s</regexp>
	<action>"replace"</action>
      </production>
      <documentation sections="Argtypes Manipulation">
	<title>Location argument type</title>
	<shortdesc>relative destination specification (such as after, before, etc.)</shortdesc>
	<description>
	  <para>One of: 
	    <literal>after</literal>, 
	    <literal>before</literal>, 
	    <literal>into</literal>,
	    <literal>append</literal>,
	    <literal>prepend</literal>,
	    <literal>replace</literal>.
	  </para>
	  <para>
	    This argument is required by all commands that insert
	    nodes to a document in some way to a destination described
	    by an XPath expression. The meaning of the values listed
	    above is supposed be obvious in most cases, however the
	    exact semantics for location argument values depends on
	    types of both the source node and the target node.
	  </para>
	  <para>
	    <literal>after/before</literal> place the node right
	    after/before the destination node, except for when the
	    destination node is a document node or one of the source
	    nodes is an attribute: If the destination node is a
	    document node, the source node is attached to the
	    end/beginning of the document (remember: there is no
	    "after/before a document").  If both the source and
	    destination nodes are attributes, then the source node is
	    simply attached to the element containing the destination
	    node (remember: there is no order on attribute nodes). If
	    the destination node is an attribute but the source node
	    is of a different type, then the textual content of the
	    source node is appended to the value of the destination
	    attribute (i.e. in this case after/before act just as
	    append/prepend).
	  </para>
	  <para>
	    <literal>append/prepend</literal> appends/prepends the
	    source node to the destination node. If the destination
	    node can contain other nodes (i.e. it is an element or a
	    document node) then the entire source node is attached to
	    it. In case of other destination node types, the textual
	    content of the source node is appended/prepended to the
	    content of the destination node.
	  </para>
	  <para>
	    <literal>into</literal> can also be used to place
	    the source node to the end of an element (in the same way
	    as <literal>append</literal>), to attach an attribute
	    to an element, or, if the destination node is a text node,
	    cdata section, processing-instruction, attribute or comment,
	    to replace its textual content with the textual content of 
	    the source node.
	  </para>
	  <para>
	    <literal>replace</literal> replaces the entire destination
	    node with the source node except for the case when the
	    destination node is an attribute and the source node is
	    not. In such a case only the value of the destination
	    attribute is replaced with the textual content of the
	    source node. Note also that document node can never be
	    replaced.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="move_command" type="command" name="move" inline="yes">
      <aliases>
	<alias name="mv"/>
      </aliases>
      <command minargs="3" maxargs="3" func="move" extraargs="0">
	<param name="respective" short="r"/>
      </command>
      <documentation sections="Manipulation">
	<usage>move <xref linkend="xpath"/> <xref linkend="loc"/> <xref linkend="xpath"/></usage>
	<shortdesc>move nodes (in the one-to-one mode)</shortdesc>
	<description>
	  <para><literal>move</literal> command acts exactly like
	      <xref linkend="copy_command"/>, except that it
	      <emphasis>removes</emphasis> the source nodes after a
	      successful copy. Remember that the moved nodes are
	      actually <emphasis>different nodes</emphasis> from the
	      original ones (which may not be obvious when moving
	      nodes within a single document into locations that do
	      not require type conversion). So, after the move, the
	      original nodes don't belong to any document
	      and are automatically destroyed unless some
	      variable still contains to them.
	  </para>
	  <para>
	    This command returns a node-list consisting of nodes
	    it created on the target locations.
	  </para>
	  <para>
	    See <xref linkend="copy_command"/> for more details on how
	    the copies of the moved nodes are created.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="xmove_command" arguments=""/>
	  <ruleref ref="copy_command" arguments=""/>
	  <ruleref ref="xcopy_command" arguments=""/>
	  <ruleref ref="insert_command" arguments=""/>
	  <ruleref ref="xinsert_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="xmove_command" type="command" name="xmove" inline="yes">
      <aliases>
	<alias name="xmv"/>
      </aliases>
      <command minargs="3" maxargs="3" func="move" extraargs="1">
	<param name="respective" short="r"/>
	<param name="preserve-order" short="p"/>
      </command>
      <documentation sections="Manipulation">
	<usage>xmove [--respective|:r] [--preserve-order|:p] <xref linkend="xpath"/> <xref linkend="loc"/> <xref linkend="xpath"/></usage>
	<shortdesc>move nodes (in the all-to-every mode)</shortdesc>
	<description>
	  <para>Like <xref linkend="xcopy_command" />, except that
	    <literal>xmove</literal> <emphasis>removes</emphasis> the source
	    nodes after a successful copy.  Remember that the moved nodes are
	    actually <emphasis>different nodes</emphasis> from the original
	    ones (which may not be obvious when moving nodes within a single
	    document into locations that do not require type conversion). So,
	    after the move, the original nodes don't belong to any document and
	    are automatically destroyed unless still contained in some variable.
	  </para>
	  <para>
	    This command returns a node-list consisting of all nodes
	    it created on the target locations.
	  </para>
	  <para>
	    If <literal>--respective|:r</literal> option
	    is used, then the target node-list <xref linkend="exp"/>
	    is evaluated in the context of the source node
	    being copied.
	  </para>
	  <para>
	    The <literal>--preserve-order|:p</literal> option can be
	    used to ensure that the copied nodes are in the same
	    relative order as the corresponding source nodes.
	    Otherwise, if <xref linkend="loc"/> is
	    <literal>after</literal> or <literal>prepend</literal>,
	    the relative order of the copied nodes will be reversed,
	    because source nodes are placed to the target location one
	    by one.
	  </para>
	  <para>
	    See <xref linkend="xcopy_command"/> for more details on
	    how the copies of the moved nodes are created.
	  </para>
	  <para>
	    The following example demonstrates how <literal>xmove</literal>
	    can be used to get rid of HTML <literal>&lt;font&gt;</literal>
	    elements while preserving their content. As an exercise,
	    try to figure out why simple
	    <literal>foreach //font { xmove node() replace . }</literal>
	    would not work here.
	  </para>
	  <example>
	    <title>Get rid of all &lt;font&gt; tags</title>
	    <code>while //font {
	      <tab count="1"/>foreach //font {
	      <tab count="1"/><tab count="1"/>xmove node() replace .;
	      <tab count="1"/>}
	      }
	    </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="move_command" arguments=""/>
	  <ruleref ref="copy_command" arguments=""/>
	  <ruleref ref="xcopy_command" arguments=""/>
	  <ruleref ref="insert_command" arguments=""/>
	  <ruleref ref="xinsert_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="clone_command" type="command" name="clone" inline="yes">
      <aliases>
	<alias name="dup"/>
      </aliases>
      <command minargs="0" maxargs="1" func="clone" />
      <documentation sections="Manipulation Documents">
	<usage>$doc := clone <xref linkend="document" /></usage>
	<shortdesc>clone a given document</shortdesc>
	<description>
	  <para>
	    Create and return a copy of a given <xref linkend="document"/>.
	    Unless <xref linkend="cdonopen" />
	    configuration flag is turned off,
	    the root node of the new document
	    becomes the current node.
	  </para>
	  <para>Calling this command only makes sense if
	    either
	    <xref linkend="cdonopen" /> is set, or
	    if the result is assigned to a variable or
	    passed to another &XSH; command using the <literal>&amp;{...}</literal>
	    syntax, since otherwise the newly 
	    created copy of the document is automatically garbage-collected and
	    destroyed.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="open_command" arguments="" />
	  <ruleref ref="close_command" arguments=""/>
	  <ruleref ref="print_enc_command" arguments=""/>
	  <ruleref ref="files_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="normalize_command" type="command" name="normalize" inline="yes">
      <command minargs="1" maxargs="1" func="normalize_nodes"/><documentation sections="Manipulation">
	<usage>normalize <xref linkend="exp"/></usage>
	<shortdesc>normalizes adjacent textnodes</shortdesc>
	<description>
	  <para><literal>normalize</literal> 
	    evaluates given <xref linkend="exp"/> to a node-list
	    and puts all text nodes in the full depth of the sub-tree
	    underneath each node in the node-list 
	    into a "normal" form where only structure (e.g., elements,
	    comments, processing instructions, CDATA sections, and
	    entity references) separates text nodes, i.e., there are
	    neither adjacent text nodes nor empty text nodes.
	  </para>
	  <para>
	    Note, that most &XSH; commands automatically join adjacent text nodes.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="strip_ws_command" type="command" name="strip-whitespace" inline="yes">
      <aliases>
	<alias name="strip_whitespace"/>
      </aliases>
      <command minargs="1" maxargs="1" func="strip_ws"/><documentation sections="Manipulation">
	<usage>strip-whitespace <xref linkend="exp"/></usage>
	<shortdesc>strip leading and trailing whitespace</shortdesc>
	<description>
	  <para><literal>strip-whitespace</literal> removes all leading and
	    trailing whitespace from given nodes. If applied to an
	    element node, it removes all leading and trailing child
	    whitespace-only text nodes and CDATA sections.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="list_command" type="command" name="ls" inline="yes">
      <aliases>
	<alias name="list"/>
      </aliases>
      <command maxargs="1" func="list">
	<param name="fold" short="f"/>
	<param name="fold-attrs" short="A"/>
	<param name="indent" short="i"/>
	<param name="no-indent" short="I"/>
	<param name="depth" short="d" type="exp" argument="exp"/>
      </command>
      <documentation sections="Navigation Information">
	<usage>ls [--fold|:f] [--fold-attrs|:A] [--indent|:i | --no-indent|:I]
	  [--depth|:d <xref linkend="exp"/>] [<xref linkend="exp"/>]</usage>
	<shortdesc>list a given part of a document as XML</shortdesc>
	<description>
	  <para>
	    Print XML representation of a given
	    <xref linkend="exp"/>, in particular,
	    if used with an <xref linkend="xpath"/>,
	    list parts of the document matching given expression.
	  </para>
	  <para>
	    If used without an argument,
	    current node is listed to the depth 1 (see below).
	  </para>
	  <para>
	    <literal>--depth</literal> or <literal>:d</literal>
	    argument may be used to specify depth of the XML listing.
	    If negative, the listing depth is unlimited.
	    All content below the specified depth is replaced with
	    an ellipsis (<literal>...</literal>).
	  </para>
	  <para>
	    <literal>--fold</literal> or <literal>:f</literal>
	    option makes the listing fold elements marked using the
	    <xref linkend="fold_command"/> command are folded, i.e. listed
	    only to the depth specified in the folding mark.
	  </para>
	  <para>
	    <literal>--fold-attrs</literal> or <literal>:A</literal>
	    option avoids listing of attributes of the folded
	    elements (i.e. elements on the lowest level of listing).
	    Folded attributes are replaced with
	    ellipsis (<literal>...</literal>).
	  </para>
	  <para>
	    <literal>--indent</literal> (<literal>:i</literal>)
	    and 
	    <literal>--no-indent</literal> (<literal>:I</literal>)
	    may be used to enforce/suppress
	    indentation, overriding current setting
	    (see command <xref linkend="indent"/>).
	  </para>
	  <para>
	    Unless in <xref linkend="quiet"/> mode, 
	    this command also prints the number of
	    (top-level) nodes listed.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="count_command" arguments=""/>
	  <ruleref ref="fold_command" arguments=""/>
	  <ruleref ref="unfold_command" arguments=""/>
	</see-also>
      </documentation>    
    </rule>
    <rule id="c14n_command" type="command" name="canonical" inline="yes">
      <command maxargs="1" func="c14n">
	<param name="comments" short="c"/>
	<param name="filter" short="f" type="xpath" argument="xpath"/>
      </command>
      <documentation sections="Navigation Information">
	<usage>canonical [--comments|:c] [--filter|:f <xref linkend="xpath"/>] [<xref linkend="exp"/>]</usage>
	<shortdesc>serialize nodes as to canonical XML</shortdesc>
	<description>
	  <para>
	    This commands prints a canonical XML representing nodes specified
	    by its argument (or current node, if no argument is given).</para>
	  <para><literal>--comments</literal> or
	    <literal>:c</literal> removes comments
	    from the resulting XML.</para>
	  <para>
	    <literal>--filter</literal> or <literal>:f</literal>
	    can be used to filter
	    the resulting XML so that it only contains
	    nodes explicitly included in the given node-set.</para>
	  <para>
	    For
	    details see <ulink url="http://www.w3.org/TR/xml-c14n">"Canonical
	      XML"</ulink> or <ulink
	      url="http://www.w3.org/TR/xml-exc-c14n">"Exclusive XML Canonicalization"</ulink> W3C recommendations.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="list_command" arguments=""/>
	</see-also>
      </documentation>    
    </rule>
    <rule id="count_command" type="command" name="count" inline="yes">
      <command minargs="1" maxargs="1" func="print_count">
	<param name="quiet" short="q"/>
      </command>
      <documentation sections="Information">
	<usage>count [--quiet|:q] <xref linkend="xpath"/></usage>
	<shortdesc>calculate a <xref linkend="exp"/> and enumerate node-lists</shortdesc>
	<description>
	  <para>
	    Calculates a given <xref linkend="exp"/> expression. If
	    the result is a node-list, print number of nodes in the
	    node-list.  If the <xref linkend="exp"/> results in a
	    boolean, numeric or literal value, print the value.
	  </para>
	  <para>
	    If <literal>--quiet</literal> or <literal>:q</literal>
	    option is used, output is suppressed and the value
	    is returned.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="expression_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="change_namespace_uri_command" type="command" name="change-ns-uri" inline="yes">
      <command minargs="1" maxargs="2" func="change_namespace_uri"/>
      <documentation sections="Namespaces Manipulation">
	<usage>change-ns-uri <xref linkend="exp"/> [<xref linkend="exp"/>]</usage>
	<shortdesc>change namespace URI (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>
	    This command takes one or two arguments.  The first
	    argument is a new namespace URI and the second, optional,
	    argument is a namespace prefix. It changes the URI value
	    of a namespace declaration of the context node to the new
	    value. If no prefix is given, the change applies to a
	    declaration on the context node whose prefix equals to the
	    prefix of the context node, otherwise the change applies
	    to a declaration with the given prefix.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="change_namespace_prefix_command"/>
	  <ruleref ref="set_namespace_command"/>
	  <ruleref ref="declare_namespace_command"/>
	  <ruleref ref="namespaces_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="change_namespace_prefix_command" type="command" name="change-ns-prefix" inline="yes">
      <command minargs="1" maxargs="2" func="change_namespace_prefix"/>
      <documentation sections="Namespaces Manipulation">
	<usage>change-ns-prefix <xref linkend="exp"/> [<xref linkend="exp"/>]</usage>
	<shortdesc>change namespace prefix (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>
	    This command takes one or two arguments.  The first
	    argument is a new prefix and the second, optional,
	    argument is an old namespace prefix. It changes the prefix
	    of a namespace declaration of the context node to the new
	    value. If no old prefix is given, the change applies to a
	    declaration on the context node whose prefix equals to the
	    prefix of the context node, otherwise the command changes
	    the declaration with the given old prefix.
	  </para>
	  <para>
	    The command throws an exception if the new prefix is
	    already taken by some other declaration in the scope.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="change_namespace_uri_command"/>
	  <ruleref ref="set_namespace_command"/>
	  <ruleref ref="declare_namespace_command"/>
	  <ruleref ref="namespaces_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="set_namespace_command" type="command" name="set-ns" inline="yes">
      <command minargs="1" maxargs="2" func="set_namespace">
	<param name="prefix" short="p" type="string" argument="exp"/>
      </command>
      <documentation sections="Namespaces Manipulation">
	<usage>set-ns [:p|--prefix <xref linkend="exp"/>] <xref linkend="exp"/></usage>
	<shortdesc>set namespace of the current node (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>
	    This command takes one argument, the namespace URI,
	    possibly accompanied by a prefix provided in
	    the option <literal>--prefix</literal> <literal>:p</literal>;
	    both these expressions are evaluated as names.
	    The command changes the namespace of the current element to a given
	    namespace URI. The current node must be in the scope
	    of a namespace declaration associating the namespace URI
	    with a prefix; if prefix option is given, then
	    one of such declarations must associate the particular given prefix
	    with the namespace URI. If this condition
	    is not met or the current node is neither element nor
	    attribute, an error is issued.
	    The command also changes the prefix of the current element accordingly.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="declare_namespace_command"/>
	  <ruleref ref="change_namespace_uri_command"/>
	  <ruleref ref="change_namespace_prefix_command"/>
	  <ruleref ref="namespaces_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="declare_namespace_command" type="command" name="declare-ns" inline="yes">
      <command minargs="2" maxargs="2" func="declare_namespace"/>
      <documentation sections="Namespaces Manipulation">
	<usage>declare-ns <xref linkend="exp"/> <xref linkend="exp"/></usage>
	<shortdesc>create a special attribute declaring an XML namespace (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>
	    This command takes one or two arguments: prefix and URI,
	    both evaluated as names.
	    It creates a namespace declaration
	    of the form <literal>xmlns:prefix="URI"</literal>
	    on the current node.
	    The command produces an error if
	    the prefix is already declared in the scope of the current node
	    with a different namespace URI.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="set_namespace_command"/>
	  <ruleref ref="change_namespace_uri_command"/>
	  <ruleref ref="change_namespace_prefix_command"/>
	  <ruleref ref="namespaces_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="set_command" type="command" name="set" inline="yes">
      <command minargs="1" maxargs="2" func="xpath_set"/>
      <documentation sections="Manipulation">
	<usage>set <xref linkend="xpath"/> [<xref linkend="xpath"/>]</usage>
	<shortdesc>create or modify document content (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>This command provides very easy way to create
            or modify content of a document.
            It takes two XPath expressions. The first one
	    should be a node location path which specifies the target node,
	    the second is optional and provides new content for the target
            node.
	    If a node matches the first XPath expression, then its content
	    is replaced with the given value. If no node matches, then XSH2 tries
	    to magically extend the current document by adding nodes in order to
            add missing steps of the location path so as to make the expression
	    match a node. This node is then populated with
	    a copy of the content value (either text or, if the content <xref
            linkend="xpath"/> results in a node-list and the target
            node is an element, nodes).
	  </para>
	  <example>
	    <title>Try the following on an empty scratch document</title>
	    <code>$scratch/> ls /
&lt;scratch/>
$scratch/> set scratch/@say "hallo world"
&lt;scratch say="hello world"/>

$scratch/> set scratch/foo[2]/../foo[1]/following-sibling::bar/baz[3] "HALLO"
$scratch/> ls /
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;scratch say="hello world">
<tab/>&lt;foo/>
<tab/><tab/>&lt;bar>
<tab/><tab/><tab/>&lt;baz/>
<tab/><tab/><tab/>&lt;baz/>
<tab/><tab/><tab/>&lt;baz>HALLO&lt;/baz>
<tab/><tab/>&lt;/bar>
<tab/>&lt;foo/>
&lt;scratch/>
	    </code>
	  </example>
	  <para>
	    Only a limited subset of XPath is currently supported by
	    this command. Namely, the XPath expression must be a
	    location path consisting of a /-separated sequence of one
	    or more location steps and new nodes
	    can only be magically created along the child, sibling, or
	    attribute axes.
	    The node-test part of the expression
	    can neither be a wildcard (<literal>*</literal>,
	    <literal>@*</literal>, <literal>prefix:*</literal>, ...),
	    nor the <literal>node()</literal> function. If a namespace
	    prefix is used, then either the namespace must already be
	    declared in the document or registered with XSH. 
	  </para>
	  <para>
	    Location steps may contain arbitrary predicates (filters), however,
	    only a limited subset is supported for magically created
	    nodes.
	    In particular, if a filter predicate of a location step
	    specifies a position of a node (e.g. with
	    <literal>[4]</literal>, or
	    <literal>[position()&gt;3]</literal>, etc), then the
	    parser tries to automatically create empty siblings nodes
	    until it finally creates one with for which the predicate
	    is true.
	  </para>
	  <para>
	    Note, that this command only processes one location step
	    at a time and always picks the first matching node. So,
	    expressions like <literal>/root/a/b</literal> are treated
	    as <literal>/root/a[1]/b[1]</literal>.  This means that an
	    expression <literal>/root/a/b</literal> will magically
	    create element <literal>&lt;b&gt;</literal> in a first
	    matching <literal>&lt;a&gt;</literal> even if some
	    following <literal>&lt;a&gt;</literal> already contains a
	    <literal>&lt;b&gt;</literal>.
	  </para>
	  <para>
	    To prevent this, either explicitly state that <literal>b</literal> must
	    exist with e.g. <literal>/root/a[b]/b</literal> or make the corresponding
	    element <literal>&lt;a&gt;</literal> the context
	    node and use a relative location path:
	  </para>
	  <example>
	    <code>for /root/a/b set b 'foo'</code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="expression_command" type="command" name="get" inline="yes">
      <aliases>
	<alias name="exp"/>
	<alias name="expr"/>
      </aliases>
      <command minargs="1" maxargs="1" func="expr"/>
      <documentation sections="Information">
	<usage>get <xref linkend="exp"/></usage>
	<shortdesc>calculate a given expression and return the result.</shortdesc>
	<description>
	  <para>
	    Calculate a given <xref linkend="exp"/> and return the value.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="count_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="perl_code" type="argtype" name="perl-code" inline="no">
      <documentation sections="Argtypes Perl_shell">
	<title>Perl-code argument type</title>
	<shortdesc>in-line code in Perl programming language</shortdesc>
	<description>
	  <para>
	    A block of Perl code enclosed in braces. 
	    All &XSH; variables are transparently accessible from
	    the Perl code as well.
	  </para>
	  <para>
	    For more information about embedded Perl code in &XSH;, predefined
	    functions etc., see <xref linkend="Perl_shell"/>.
	  </para>
	  <example>
	    <code>xsh&gt; <userinput>$i={ "foo" };</userinput>
	      xsh&gt; <userinput>perl { echo "$i-bar\n"; }</userinput> # prints foo-bar
	      xsh&gt; <userinput>echo { "$i-bar" }</userinput>         # very much the same as above
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="perl_command" type="command" name="perl" inline="yes">
      <command minargs="1" maxargs="1" func="perl_eval_command"/>
      <documentation sections="Perl_shell">
	<usage>perl <xref linkend="perl_code"/></usage>
	<shortdesc>evaluate in-line Perl code</shortdesc>
	<description>
	  <para>Evaluate a given perl expression and return
	    the result.</para>
	</description>
	<see-also>
	  <ruleref ref="count_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="prune_command" type="command" name="remove" inline="yes">
      <aliases>
	<alias name="rm"/>
	<alias name="prune"/>
	<alias name="delete"/>
	<alias name="del"/>
      </aliases>
      <command minargs="1" maxargs="1" func="prune"/><documentation sections="Manipulation">
	<usage>remove <xref linkend="exp"/></usage>
	<shortdesc>remove given nodes</shortdesc>
	<description>
	  <para>Unlink all nodes in a given node-list
	    from their respective documents. Nodes, which
	    are neither attached to a document or stored in a variable
	    are automatically garbage-collected.
	  </para>
	  <para>Returns a number of nodes removed.</para>
	  <example>
	    <title>Get rid of all evil creatures.</title>
	    <code>xsh&gt; <userinput>del //creature[@manner='evil']</userinput></code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="print_command" type="command" name="print" inline="yes">
      <aliases>
	<alias name="echo"/>
      </aliases>
      <command func="echo">
	<param name="nonl" short="n"/>
	<param name="nospace" short="s"/>
	<param name="stderr" short="e"/>
      </command>
      <documentation sections="Information">
	<usage>print [--nonl|:n] [--nospace|:s] [--stderr|:e] <xref linkend="exp"/> [<xref linkend="exp"/> ...]</usage>
	<shortdesc>print stuff on standard or standard error output</shortdesc>
	<description>
	  <para>Evaluate given expression(s) and print the results
	    (separated by a single space character).
	    Expressions not containing any special characters, such as
	    brackets, quotes, $, or @ are considered as bare words
	    and evaluate to themselves.
	  </para>
	  <para>
	    <literal>--nonl</literal> or <literal>:n</literal>
	    can be used to avoid printing a trailing new-line.
	  </para>
	  <para>
	    <literal>--nospace</literal> or <literal>:s</literal>
	    suppresses printing additional spaces between individual arguments.
	  </para>
	  <para>
	    <literal>--stderr</literal> or <literal>:e</literal>
	    causes the command to print on standard error output.
	  </para>
	  <example>
	    <code>print foo   bar;  # prints "foo bar"</code>
	    <code>print "foo   bar";  # prints "foo   bar"</code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="sort_command" type="command" name="sort" inline="yes">
      <command minargs="1" maxargs="1" func="perlsort">
	<param name="compare" short="c" type="perl" argument="perl_code"/>
	<param name="key" short="k" type="exp" argument="exp"/>
	<param name="numeric" short="n"/>
	<param name="locale" short="l"/>
	<param name="descending" short="d"/>
      </command>
      <documentation sections="Manipulation">
	<usage>$result := sort [ --key|:k <xref linkend="exp"/> ]
	  --compare|:c <xref linkend="perl_code"/> <xref linkend="exp"/></usage>
	<usage>$result := sort [ --key|:k <xref linkend="exp"/> ]
	  [ --numeric|:n ] [ --descending|:d ] [ --locale|:l]  <xref linkend="exp"/>
	  </usage>
	<shortdesc>sort a given node-list by given criteria</shortdesc>
	<description>
	  <para>This command sorts a given node-list,
	    returning a node-list ordered according to a given
	    key and ordering function.
	  </para>
	  <para>
	    <literal>--key|:k</literal> followed by an expression
	    specifies the key to be computed for each member of the
	    node-list and the result used as the sorting key. If omitted,
	    keys are created by converting the nodes
	    to string as if XPath expression <literal>string(.)</literal>
	    was used.
	  </para>
	  <para>
	    <literal>--numeric|:n</literal> specifies, that
	    keys should be compared by their numerical values
	    (the default is string comparison).
	  </para>
	  <para>
	    <literal>--descending|:d</literal> specifies,
	    that the result should be ordered in descending order
	    (default is ascending).
	  </para>
	  <para>
	    <literal>--locale|:l</literal> forces using
	    current locale settings for string comparison
	    (default is no locale).
	  </para>
	  <para>
	    <literal>--compare</literal> argument followed
	    by a <xref linkend="perl_code" /> allows to define a custom
	    comparison method in a similar way to Perl <literal>sort</literal>
	    command. The keys to be compared are passed
	    to the code in variables <literal>$a</literal> and 
	    <literal>$b</literal>. The code is supposed to return 1 if
	    the key in <literal>$a</literal> is  greater than
	    <literal>$b</literal>, 0 if the keys are equal
	    and <literal>-1</literal> if <literal>$a</literal>
	    is less than <literal>$b</literal>, depending
            on how the corresponding elements are to be ordered.
	    It is a run-time error to use
	    <literal>--compare</literal> together with either
	    <literal>--numeric</literal> or
	    <literal>--descending</literal>. 
	  </para>
	  <example>
	    <title>Case-insensitive sort of a given node-list</title>
	    <code>$ordered := sort --key xsh:lc(.) $unordered;</code>
	  </example>
	  <example>
	    <title>Reorder creature elements by name attribute
	      in ascending order using Czech locale settings
	    </title>
	    <code>perl {
                # setup locale collating function
	        # Note, that the collating function must be UTF8 aware.
                use POSIX qw(locale_h);
                setlocale(LC_COLLATE,'cs_CZ.UTF-8');
              };

	      xmove &amp;{ sort :k@name :l * } into /middle-earth[1]/creatures;
	    </code>
	  </example>
	  <example>
	    <title>Sort a node-list by a pre-computed score (Perl-based sort)</title>
	    <code>$results := sort --numeric --descending --key { $scores{literal('@name')} } $players;
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="map_command" type="command" name="map" inline="yes">
      <command minargs="2" maxargs="2" func="perlmap">
	<param name="in-place" short="i"/>
	<param name="reverse" short="r"/>
      </command>
      <documentation sections="Perl_shell Manipulation">
	<usage>map <xref linkend="exp"/> <xref linkend="exp"/></usage>
	<shortdesc>transform node value/data using Perl or XPath expression</shortdesc>
	<description>
	  <para>
	    NOTE: THE SEMANTICS OF COMMAND HAS CHANGED IN 2.1.0
	  </para>
	  <para>
	    This command provides an easy way to transform node's data
	    (content) using arbitrary expression.
	    It takes two arguments: a mapping expression
	    and a node-list.
	  </para>
	  <para>
	    First the second argument is evaluated to a node-list.
	    For each of the nodes,
	    the mapping expression is evaluated 
	    and the result is used to replace the original content
	    of the node. 
	    The node is made the context node for the time
	    of evaluation of the mapping expression.
	    Moreover, if the expression is a Perl code,
	    it gets the original text content in 
	    the variable <literal>$_</literal>.
	  </para>
	  <para>
	    Note that if the processed node is an element
	    than the mapping expression may even produce nodes
	    which are then copied into the element discarding
	    any previous content of the element.
	  </para>
	  <para>
	    If the mapping expression returns an undefined value
	    for a node, then its content is kept untouched.
	  </para>
	  <para>
	    <literal>--in-place</literal> (<literal>:i</literal>) flag:
	    if the expression is a Perl code, then
	    it is sometimes convenient to change the value
	    in place. In that case use this flag to indicate that the result
	    should to be taken from the <literal>$_</literal> variable
	    rather than from the value of the expression itself.
	    Without this flag, <literal>$_</literal> is read-only.
	  </para>
	  <para>
	    <literal>--reverse</literal> (<literal>:r</literal>) flag
	    instruct the map to process the nodelist
	    in reversed order.
	  </para>
	  <example>
	    <title>Capitalizes all hobbit names</title>
	    <code>map { ucfirst($_) } //hobbit/@name;</code>	  
	  </example>
	  <example>
	    <title>Changes Goblins to Orcs in all hobbit tales (\b matches word boundary).</title>
	    <code>map :i { s/\bgoblin\b/orc/gi } //hobbit/tale/text();</code>
	  </example>
	  <example>
	    <title>Recompute column sums in the last row of row-oriented table</title>
	    <code>map sum(/table/row[position()&lt;last()]/
                            cell[count(xsh:current()/preceding-sibling::cell)+1])
                     /table/row[last()]/cell;</code>
	  </example>
	  <example>
	    <title>The following commands do all about the same:</title>
	    <code>wrap --inner Z //*;
	      map --reverse xsh:parse(concat("&lt;Z>",xsh:serialize(node()),"&lt;/Z>")) //*;
	      map xsh:parse(concat("&lt;Z>",xsh:serialize(node()),"&lt;/Z>")) { reverse xpath('//*') };
	    </code>
	  </example>
	  <para>Note that in the last example we use
	    <literal>:r</literal> (or Perl <literal>reverse</literal>
	    function) to reverse the node list order so that child
	    nodes get processed before their parents. Otherwise, the child
	    nodes would be replaced by parent's new content before the
	    processing could reach them.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="rename_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="rename_command" type="command" name="rename" inline="yes">
      <command minargs="2" maxargs="2" func="perlrename">
      	<param name="namespace" short="n" type="exp" argument="exp"/>
	<param name="in-place" short="i"/>
	<param name="reverse" short="r"/>
      </command>
      <documentation sections="Perl_shell Manipulation">
	<usage>rename <xref linkend="nodename"/> <xref linkend="exp"/></usage>
	<shortdesc>quickly rename nodes with in-line Perl code</shortdesc>
	<description>
	  <para>
	    NOTE: THE SEMANTICS OF COMMAND HAS CHANGED IN 2.1.0
	  </para>
	  <para>
	    This command is very similar to the <xref linkend="map_command"/>
	    command, except that it operates on nodes' names rather
	    than their content. It changes
	    name of every element, attribute or
	    processing-instruction contained
	    in the node-list specified in the second argument <xref
	      linkend="exp"/>, according to the value of the 
	    <xref linkend="nodename"/> expression,
	    which is evaluated in the context of each node in turn.
	  </para>
	  <para>If the <xref linkend="nodename"/> is a Perl
	    expression, then the name of the node is also stored into Perl's
	    <literal>$_</literal> variable prior to evaluation.
	  </para>
	  <para>The flag <literal>--in-place</literal> (<literal>:i</literal>)
	    can be used to indicate that
	    the new name should be collected from the <literal>$_</literal>
	    variable rather than from the result of the expression itself.
	  </para>
	  <para>
	    The <literal>--namespace</literal> (<literal>:n</literal>) argument
	    may be used to provide namespace for the renamed nodes.
	  </para>
	  <para>
	    <literal>--reverse</literal> (<literal>:r</literal>) flag
	    instruct the map to process the nodelist
	    in reversed order.
	  </para>
	  <para>Note: if the expression <xref linkend="nodename"/>
	    returns an undefined value for a particular node, the
	    node's original name and namespace are preserved.
	  </para>
	  <example>
	    <title>Renames all Hobbits to Halflings</title>
	    <code>xsh&gt; <userinput>rename halfling //hobbit</userinput></code>
	  </example>
	  <example>
	    <title>Make all elements and attributes uppercase (yack!)</title>
	    <code>xsh&gt; <userinput>rename { uc } (//*|//@*)</userinput></code>	  
	  </example>
	  <example>
	    <title>Substitute dashes with underscores in all node names</title>
	    <code>xsh&gt; <userinput>rename :i { s/-/_/g } (//*|//@*)</userinput></code>	  
	  </example>
	  <example>
	    <title>Make all elements start with the name of their parents</title>
	    <code>xsh&gt; <userinput>rename concat(local-name(parent::*),'.',local-name(.)) //*[parent::*]</userinput></code>	  
	  </example>
	</description>
	<see-also>
	  <ruleref ref="map_command" arguments="" />
	</see-also>
      </documentation>
    </rule>
    <rule id="hash_command" type="command" name="hash" inline="yes">
      <command minargs="2" maxargs="2" func="hash"/>
      <documentation sections="Perl_shell Manipulation">
	<usage>$hash := hash <xref linkend="exp"/> <xref linkend="exp"/></usage>
	<shortdesc>index selected nodes by some key value</shortdesc>
	<description>
	  <para>
	    This command takes two arguments: an expression computing
	    a key from a given node (1st argument) and a node-set (2nd
	    argument). For each node in the node-set, the key value is
	    computed and the node is stored under the given key in
	    the resulting hash. For a given key, the value stored
	    in the hash table is a node-list consisting of all nodes
	    for which the 1st expression evaluated to an object
	    string-wise equal to the key. It is therefore possible to
	    index more than one node under the same key.
	  </para>
	  <para>
	    The XPath function
	    <literal>xsh:lookup(varname,key)</literal> can
            be used to retrieve values from hashes in XPath expressions.
	  </para>
	  <example>
	    <title>Index books by author</title>
	    <code>my $books_by_author := hash concat(author/firstname," ",author/surname) //book;</code>
	  </example>
	  <example>
	    <title>Lookup books by Jack London.</title>
	    <code>ls { $books_by_author->{'Jack London'} };
ls xsh:lookup('books_by_author','Jack London');</code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="lookup_function"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="close_command" type="command" name="close" inline="yes">
      <command maxargs="1" func="close_doc" /><documentation sections="Documents">
	<usage>close [<xref linkend="document"/>]</usage>
	<shortdesc>close document (without saving)</shortdesc>
	<description>
	  <para>
	    Close a given <xref linkend="document"/>
	    (or, if called with no argument,
	    the current document)
	    by trying to remove all references
	    from &XSH; variables to nodes
	    belonging to the document. If no references
	    to the document are left,
	    the garbage-collector destroys
	    the DOM tree and frees the memory it occupied
	    for later reuse (depending on architecture, this
	    may or may not give the allocated memory back
	    to the system).
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="index_command" type="command" name="index" inline="yes">
      <command maxargs="1" func="index_doc"/><documentation sections="Documents">
	<usage>index [<xref linkend="document"/>]</usage>
	<shortdesc>index a static document for faster XPath lookup</shortdesc>
	<description>
	  <para>
	    This command makes <literal>libxml2</literal> library to remember
	    document-order position of every element node in the <xref
	      linkend="document" />. Such indexation makes XPath queries
	    considerably faster on large documents (with thousands of nodes).
	    The command should only be used on documents which don't change;
	    modifying an indexed document might possibly lead to non-conformant
	    behavior of later XPath queries on the document.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="open_command" type="command" name="open" inline="yes">
      <command minargs="1" maxargs="1" func="open_doc">
	<param name="format" short="F" type="string" argument="exp"/>
	<param name="file" short="f"/>
	<param name="pipe" short="p"/>
	<param name="string" short="s"/>

	<param name="switch-to" short="w"/>
	<param name="no-switch-to" short="W"/>
	<param name="validate" short="v"/>
	<param name="no-validate" short="V"/>
	<param name="recover" short="r"/>
	<param name="no-recover" short="R"/>
	<param name="expand-entities" short="e"/>
	<param name="no-expand-entities" short="E"/>
	<param name="xinclude" short="x"/>
	<param name="no-xinclude" short="X"/>
	<param name="keep-blanks " short="b"/>
	<param name="no-keep-blanks " short="B"/>
	<param name="pedantic " short="n"/>
	<param name="no-pedantic " short="N"/>
	<param name="load-ext-dtd " short="d"/>
	<param name="no-load-ext-dtd " short="D"/>
	<param name="complete-attributes" short="a"/>
	<param name="no-complete-attributes" short="A"/>

      </command>
      <documentation sections="Documents">
	<usage>$doc := open [--format|:F html|xml|docbook]
          [--file|:f | --pipe|:p | --string|:s]
	  [--switch-to|:w | --no-switch-to|:W]
	  [--validate|:v | --no-validate|:V]
	  [--recover|:r | --no-recover|:R]
	  [--expand-entities|:e | --no-expand-entities|:E]
	  [--xinclude|:x | --no-xinclude|:X]
	  [--keep-blanks|:b  | --no-keep-blanks|:B]
	  [--pedantic|:n | --no-pedantic|:N]
	  [--load-ext-dtd|:d | --no-load-ext-dtd|:D]
	  [--complete-attributes|:a | --no-complete-attributes|:A]
	  <xref linkend="exp"/></usage>
	<shortdesc>load an XML, HTML, or Docbook SGML document from a
	file, pipe or URI</shortdesc>
	<description>
	  <para>
	    Parse a XML, HTML or SGML DOCBOOK document from a file or URL,
	    command output or string and return a node-set consisting
	    of the root of the resulting DOM tree.
	  </para>
	  <para><literal>--format</literal> (<literal>:F</literal>)
	    option may be used
	    to specify file format. Possible values are
	    <literal>xml</literal> (default), 
	    <literal>html</literal>, and 
	    <literal>docbook</literal>. Note, however,
	    that the support for parsing <literal>DocBook</literal> SGML
	    files has been deprecated in recent <literal>libxml2</literal>
	    versions.
	  </para>
	  <para><literal>--file</literal> (<literal>:f</literal>)
	    instructs the parser to consider a given <xref linkend="exp"/>
	    as a file name or URL.
	  </para>
	  <para>
	    <literal>--pipe</literal> (<literal>:p</literal>)
	    instructs the parser to consider a given <xref linkend="exp"/>
	    as a system command and parse its output.
	  </para>
	  <para>
	    <literal>--string</literal> (<literal>:s</literal>)
	    instructs the parser to consider a given <xref linkend="exp"/>
	    as a string of XML or HTML to parse.
	  </para>
	  <para>
	  <literal>--switch-to</literal> (<literal>:w</literal>)
	    and <literal>--no-switch-to</literal> (<literal>:W</literal>)
	    control whether the new document's root should
	    become current node. These option override
	    current global setting of
	    <xref linkend="cdonopen"/>.
	  </para>
          <para>
	  <literal>--validate</literal> (<literal>:v</literal>)
	    and <literal>--no-validate</literal> (<literal>:V</literal>)
	    turn on/off DTD-validation of the parsed document.
	    These option override
	    current global setting of
	    <xref linkend="validation"/>.
	  </para>
          <para>
	  <literal>--recover</literal> (<literal>:r</literal>)
	    and <literal>--no-recover</literal> (<literal>:R</literal>)
	    turn on/off parser's ability to recover from
	    non-fatal errors.
	    These option override
	    current global setting of
	    <xref linkend="recovering"/>.	    
	  </para>
          <para>
	  <literal>--expand-entities</literal> (<literal>:e</literal>)
	    and <literal>--no-expand-entities</literal> (<literal>:E</literal>)
	    turn on/off entity expansion, overriding current global
	    setting of <xref linkend="parser_expands_entities"/>.
	  </para>
          <para>
	  <literal>--xinclude</literal> (<literal>:x</literal>) and
	    <literal>--no-xinclude</literal> (<literal>:X</literal>) turn
	    on/off XInclude processing, overriding current global settings of
	    <xref linkend="parser_expands_xinclude"/>.
	  </para>
          <para>
	  <literal>--keep-blanks</literal> (<literal>:b</literal>) 
	    and <literal>--no-keep-blanks</literal> (<literal>:B</literal>)
	    control whether the parser should preserve so called ignorable
	    whitespace. These option override
	    current global setting of <xref linkend="keep_blanks"/>.
	  </para>
          <para>
	  <literal>--pedantic</literal> (<literal>:n</literal>)
	    and <literal>--no-pedantic</literal> (<literal>:N</literal>)
	    turn on/off pedantic parser flag.
	  </para>
          <para>
	  <literal>--load-ext-dtd</literal> (<literal>:d</literal>)
	    and <literal>--no-load-ext-dtd</literal> (<literal>:D</literal>)
	    control whether the external DTD subset should be loaded
	    with the document. 
	    These option override
	    current global setting of <xref linkend="load_ext_dtd"/>.
	  </para>
          <para>
	  <literal>--complete-attributes</literal> (<literal>:a</literal>)
	    and <literal>--no-complete-attributes</literal>
	    (<literal>:A</literal>)
	    turn on/off parse-time default attribute completion
	    based on default values specified in the DTD.
	    These option override
	    current global setting of <xref linkend="complete_attributes"/>.	    
	  </para>
	  <example>
	    <code>$scratch/&gt; <userinput>$x := open mydoc.xml # open an XML document</userinput>

              # open a HTML document from the Internet
	      <userinput>$h:=open --format html "http://www.google.com/?q=xsh"</userinput>
	      # quote file name if it contains whitespace
	      <userinput>$y := open "document with a long name with spaces.xml"</userinput>

	      # use --format html or --format docbook to load these types
	      $z := open --format html <userinput>index.htm</userinput>

	      # use --pipe flag to read output of a command
	      $z := open --format html --pipe <userinput>'wget -O - xsh.sourceforge.net/index.html'</userinput>

	      # use document variable to restrict XPath search to a
	      # given document
	      <userinput>ls $z//chapter/title</userinput>
	    </code>
	  </example>
	</description>
      </documentation>
    </rule>
    <rule id="create_command" type="command" name="create" inline="yes">
      <aliases>
	<alias name="new"/>
      </aliases>
      <command minargs="1" maxargs="1" func="new_doc">
	<param name="format" short="F" type="string" argument="exp"/>
      </command>
      <documentation sections="Documents">
	<usage>$doc := create <xref linkend="nodename"/>|<xref linkend="exp"/></usage>
	<shortdesc>make a new document from a given XML fragment</shortdesc>
	<description>
	  <para>
	    Returns a new document object. The
	    argument must evaluate either to 
	    a valid element name (possibly followed
	    by some attribute declarations) to be used
	    for the document element, or to 
	    a well-formed XML string.
	  </para>
	  <para>
	    Unless <xref linkend="cdonopen"/> option is turned off,
	    this command also changes current node
	    to the new document.
	  </para>
	  <example>
	    <code>$scratch/&gt; <userinput>$t1 := create root</userinput>
	      $t1&gt; <userinput>ls $t1</userinput>
	      &lt;?xml version="1.0" encoding="utf-8"?&gt;
	      &lt;root/&gt;

	      $t1&gt; <userinput>$t2 := create "root id='r1'"</userinput>
	      $t2&gt; <userinput>ls $t2</userinput>
	      &lt;?xml version="1.0" encoding="utf-8"?&gt;
	      &lt;root id="r1"/&gt;

	      $t2&gt; <userinput>create "&lt;root id='r0'&gt;Just a &lt;b&gt;test&lt;/b&gt;&lt;/root&gt;"</userinput>
	      /&gt; <userinput>ls /</userinput>
	      &lt;?xml version="1.0" encoding="utf-8"?&gt;
	      &lt;root id='r0'&gt;Just a &lt;b&gt;test&lt;/b&gt;&lt;/root&gt;
	    </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="open_command" arguments=""/>
	  <ruleref ref="clone_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="save_command" type="command" name="save" inline="yes">
      <command minargs="0" maxargs="1" func="save_doc">
	<param name="format" short="F" type="string" argument="exp"/>
	<param name="xinclude" short="x"/>
	<param name="file" short="f" type="string" argument="filename"/>
	<param name="pipe" short="p" type="string" argument="exp"/>
	<param name="subtree" short="S"/>
	<param name="print" short="r"/>
	<param name="string" short="s"/>
	<param name="indent" short="i"/>
	<param name="no-indent" short="I"/>
	<param name="skip-dtd" short="d"/>
	<param name="no-skip-dtd" short="D"/>
	<param name="skip-xmldecl" short="x"/>
	<param name="no-skip-xmldecl" short="X"/>
	<param name="skip-empty-tags" short="t"/>
	<param name="no-skip-empty-tags" short="T"/>
	<param name="backup" short="b"/>
	<param name="backups" short="B"/>
	<param name="encoding" short="e" type="string" argument="enc_string"/>
      </command>
      <documentation sections="Documents">
	<usage>save [--format|:F html|xml] [--xinclude|:x] 
	  [--file|:f <xref linkend="filename"/> | 
           --pipe|:p <xref linkend="filename"/> | 
           --string|:s |
           --print|:r ]
          [--subtree|:S]
          [--indent|:i | --no-indent|:I]
	  [--skip-dtd|:d | --no-skip-dtd|:D]
	  [--skip-empty-tags|:t | --no-skip-empty-tags|:T]
	  [--skip-xmldecl|:x]
          [--encoding|:e <xref linkend="enc_string"/>] 
	  <xref linkend="document"/>
	</usage>
	<shortdesc>save a document as XML or HTML</shortdesc>
	<description>
	  <para>
	    This takes a given <xref linkend="document" />,
	    serializes it to XML or HTML and
	    either saves the result
	    to its original file or another file (default),
	    pipes it to an external command,
	    prints it on standard output, or
	    simply returns it. Without arguments
	    it simply saves current document
	    to its original file.
	  </para>
	  <para>
	    <literal>--file|:f</literal> option
	    may be used to specify an output file-name.
	    By default, the original document's file-name
	    is used.
	  </para>
	  <para>
	    <literal>--pipe|:p</literal> option
	    specifies, that the output should be
	    piped to an external command
	    specified as the option's argument.
	  </para>
	  <para>
	    <literal>--print|:r</literal> option
	    specifies, that the output should 
	    be printed on standard output.</para>
	  <para>
	    <literal>--string|:s</literal>
	    option specifies, that the output
	    should be returned by the command
	    as a string. In this case, the result is
	    always in UTF8, regardless on which
	    encoding is specified in the document
	    or using <literal>--encoding</literal> option.
	  </para>
	  <para>The above four options are mutually exclusive.</para>
	  <para>
	    <literal>--format</literal> option may be used
	    to specify the output format. It's argument
	    should be either <literal>xml</literal>,
	    <literal>html</literal> or an expression
	    evaluating to one of these. If not specified,
	    XML output is assumed.
	    Note, that a document should be saved as HTML only if it
	    actually is a HTML document, otherwise the result would be 
	    an invalid XML instance. Note also, that the optional
	    encoding parameter only forces character conversion; it is
	    up to the user to declare the document encoding in the
	    appropriate HTML &lt;META&gt; tag, if needed.
	  </para>
	  <para>
	    <literal>--xinclude</literal>
	    automatically implies XML format and
	    can be used to force &XSH; to save all already expanded
	    XInclude sections back to their original files while
	    replacing them with &lt;xi:include&gt; tags in the main
	    XML file. Moreover, all material included within
	    &lt;include&gt; elements from the
	    <ulink url="http://www.w3.org/2001/XInclude">http://www.w3.org/2001/XInclude</ulink>
	    namespace is saved to separate files too according to the
	    <literal>href</literal> attribute, leaving only empty
	    &lt;include&gt; element in the root file. This feature may
	    be used to split the document to a new set of XInclude fragments.
	  </para>
	  <para>
	    If the <literal>--subtree</literal> (<literal>:S</literal>)
	    flag is used, only the subtree of the
	    specified node is saved instead of the complete document
	    (this flag cannot be used
	    with <literal>--html</literal> format).
          </para>
	  <para>
	    <literal>--indent</literal> (<literal>:i</literal>)
	    and 
	    <literal>--no-indent</literal> (<literal>:I</literal>)
	    may be used to enforce/suppress
	    indentation, overriding current global setting
	    of <xref linkend="indent"/>.
	  </para>
	  <para>
	    <literal>--skip-dtd</literal> (<literal>:d</literal>)
	    and 
	    <literal>--no-skip-dtd</literal> (<literal>:D</literal>)
	    may be used to enforce/suppress
	    skipping DTD declaration and internal subset
	    on output, overriding current global setting
	    of <xref linkend="skip_dtd"/>.
	  </para>
	  <para>
	    <literal>--empty-tags</literal> (<literal>:t</literal>)
	    and 
	    <literal>--no-empty-tags</literal> (<literal>:T</literal>)
	    may be used to override current global setting
	    of <xref linkend="empty_tags"/>.
	    <literal>--no-empty-tags</literal> instructs &XSH;
	    to serialize elements with no child nodes
	    as start-tag/end-tag pair
	    <literal>&lt;element&gt;&lt;/element&gt;</literal>
	    instead of using a short empty-tag form
	    <literal>&lt;element/&gt;</literal>.
	  </para>
	  <para>
	    <literal>--skip-xmldecl</literal> (<literal>:x</literal>)
	    instructs &XSH; to omit the XML declaration
	    from the saved document. Note however, that XML declaration
	    is obligatory for XML documents. It usually looks like
	    <literal>&lt;?xml version="1.0" ...?&gt;</literal>.
	  </para>
	  <para>
	    <literal>--backup</literal> (<literal>:b</literal>)
	    and 
	    <literal>--no-backup</literal> (<literal>:B</literal>)
	    can be used to enforce/suppress
	    creation of a backup file if target file
	    already exists. Using these options
	    overrides current global setting of <xref linkend="backups"/>.
	  </para>	  
	  <para>
	    <literal>--encoding</literal>
	     followed by a <xref linkend="enc_string" />
	    instructs &XSH; to save the document in the specified
	    encoding.  In case of XML output, the &lt;?xml?&gt;
	    declaration is automatically changed accordingly.
	  </para>
	  <example>
	    <title>Use save to preview current HTML document in Lynx</title>
	    <code>save --format html --pipe 'lynx -stdin'</code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="open_command" arguments=""/>
	  <ruleref ref="close_command" arguments=""/>
	  <ruleref ref="print_enc_command" arguments=""/>
	  <ruleref ref="files_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>    
    <rule id="set_dtd_command" type="command" name="set-dtd" inline="yes">
      <aliases>
	<alias name="set_dtd"/>
      </aliases>
      <command maxargs="1" func="set_dtd">
	<param name="internal"/>
	<param name="name" short="n" type="string" argument="exp"/>
	<param name="system" short="s" type="string" argument="exp"/>
	<param name="public" short="p" type="public" argument="exp"/>
      </command>
      <documentation sections="Manipulation">
	<usage>set-dtd [--internal] [--name|:n <xref linkend="exp"/>] 
	  [--public|:p <xref linkend="exp"/>] 
	  [--system|:s <xref linkend="exp"/>] 
	  [<xref linkend="document"/>]</usage>
	<shortdesc>set document's DTD declaration</shortdesc>
	<description>
	  <para>
	    Set external (default) or internal DTD for a given document.  If
	    no <xref linkend="document"/> is given, the current
	    document is used. At least one of <literal>--public</literal>
	    and <literal>--system</literal> options should be used
	    to specify the PUBLIC and SYSTEM identifiers of the DTD.
	    If <literal>--name</literal> parameter is not provided, 
	    name of the document root element is used as DTD name.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="list_dtd_command" arguments=""/>
	  <ruleref ref="validate_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="list_dtd_command" type="command" name="dtd" inline="yes">
      <command maxargs="1" func="list_dtd"/><documentation sections="Information">
	<usage>dtd [<xref linkend="document"/>]</usage>
	<shortdesc>show document's DTD</shortdesc>
	<description>
	  <para>
	    Print external or internal DTD for a given document. 
	    If used without arguments prints DTD of the current document.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="set_dtd_command" arguments=""/>
	  <ruleref ref="validate_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="set_enc_command" type="command" name="set-enc" inline="yes">
      <command minargs="1" maxargs="2" func="set_doc_enc"/>
      <documentation sections="Manipulation">
	<usage>set-enc <xref linkend="enc_string"/> [<xref linkend="document"/>]</usage>
	<shortdesc>set document's charset (encoding)</shortdesc>
	<description>
	  <para>
	    Changes character encoding of a given document. 
	    If no <xref linkend="document"/>
	    is given, the command applies to the
	    current document. This has two effects:
	    changing the XMLDecl encoding declaration 
	    in the document prolog to display the new
	    encoding and making all future <xref linkend="save_command"/> operations
	    on the document default to the given charset.
	  </para>
	  <example>
	    <code>xsh&gt; <userinput>ls</userinput>
&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
&lt;foo&gt;...&lt;/foo&gt;
xsh&gt; <userinput>set-enc "utf-8"</userinput>
xsh&gt; <userinput>ls</userinput>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;foo&gt;...&lt;/foo&gt;
xsh&gt; <userinput>save</userinput> # saves the file in UTF-8 encoding
</code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="print_enc_command" arguments=""/>
	  <ruleref ref="doc_info_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="set_standalone_command" type="command" name="set-standalone" inline="yes">
      <command minargs="1" maxargs="2" func="set_doc_standalone"/>
      <documentation sections="Manipulation">
	<usage>set-standalone <xref linkend="exp"/> [<xref linkend="document"/>]</usage>
	<shortdesc>set document's standalone flag</shortdesc>
	<description>
	  <para>
	    Changes the value of <literal>standalone</literal> declaration
            in the XMLDecl prolog of a document. The <xref linkend="exp"/> should evaluate to either 1 or 0 
	    or <literal>'yes'</literal> or <literal>'no'</literal>.
	    The result of applying the command on other values is not specified.
	    If no <xref linkend="document"/> is given, 
	    the command applies to the current document. 
	  </para>
	</description>
	<see-also>
	  <ruleref ref="doc_info_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="print_enc_command" type="command" name="enc" inline="yes">
      <command maxargs="1" func="print_enc"/><documentation sections="Information">
	<usage>enc [<xref linkend="document"/>]</usage>
	<shortdesc>show document's original character encoding</shortdesc>
	<description>
	  <para>
	    Print the original document encoding string.
	    If no <xref linkend="document"/> is given, the current document is
	    used.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="set_enc_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="validate_command" type="command" name="validate" inline="yes">
      <command maxargs="1" func="validate_doc">
	<param name="yesno" short="q"/>
	<param name="dtd" short="D"/>
	<param name="relaxng" short="R"/>
	<param name="schema" short="S"/>
	<param name="file" short="f" type="string" argument="filename"/>
	<param name="string" short="s" type="exp" argument="exp"/>
	<param name="public" short="p" type="exp" argument="exp"/>
	<param name="doc" short="d" type="exp" argument="document"/>
      </command>
        <documentation sections="Information">
	<usage>validate [--yesno|:q] [<xref linkend="document"/>]</usage>
        <usage>validate [--yesno|:q] [--dtd|:D | --relaxng|:R | --schema|:S] --file|:f <xref linkend="filename"/>] [<xref
        linkend="document"/>]</usage>
        <usage>validate [--yesno|:q] [--dtd|:D | --relaxng|:R | --schema|:S] --string|:s <xref linkend="exp"/>] [<xref
        linkend="document"/>]</usage>
        <usage>validate [--yesno|:q] [--dtd|:D | --relaxng|:R | --schema|:S] --doc|:d <xref linkend="document"/>] [<xref linkend="document"/>]</usage>
	<usage>validate [--yesno|:q] [--dtd|:d] --public|:p <xref linkend="exp"/> [--file|:f <xref linkend="exp"/>] [<xref linkend="document"/>]</usage>
	<shortdesc>validate a document against a DTD, RelaxNG, or XSD schemas</shortdesc>
	<description>
	  <para>
	    This command validates the current document or
	    a document specified in the argument against a DTD,
	    RelaxNG or XSD schema.
	    If <literal>--yesno</literal> or <literal>:q</literal> is specified, only prints
	    <literal>yes</literal> and returns 1 if the document validates or
	    <literal>no</literal> and returns 0 if it does
	    not. Without <literal>--yesno</literal>, it throws an
	    exception with a complete validation error message if
	    the document doesn't validate.
	  </para>
	  <para><literal>--dtd</literal> or <literal>:D</literal> forces DTD validation
	  (default).</para>
	  <para><literal>--relaxng</literal> or <literal>:R</literal> forces RelaxNG
	  validation. Only XML RelaxNG grammars are supported.</para>
	  <para><literal>--schema</literal> or <literal>:S</literal> forces W3C XML Schema 
	    validation (XSD). Support for schema validation may still
	    be incomplete (see <ulink
	      url="http://xmlsoft.org">libxml2 home page</ulink>
	    for more details).</para>
	  <para>
	    A DTD subset can be specified by its PUBLIC identifier (with
	    <literal>--public</literal>), by its SYSTEM identifier
	    (with <literal>--file</literal>), or as a string (with
	    <literal>--string</literal>).  If none of these options is
	    used, validation is performed against the internal or
	    external DTD subset of the document being validated.
	  </para>
	  <para>
	    RelaxNG grammars and XML Schemas can either be
	    specified either as a filename or url (with
	    <literal>--file</literal>), 
	    as a string containing (with <literal>--string</literal>), 
	    or as a document currently open in &XSH; (with
	    <literal>--doc</literal>).  
	  </para>
	  <example>
	    <code>$mydoc := open "test.xml"</code>
	    <code># in all examples below, mydoc can be omitted</code>
	    <code>validate --yesno $mydoc; # validate against the document's DOCTYPE</code>
	    <code>validate --public "-//OASIS//DTD DocBook XML V4.1.2//EN" $mydoc</code>
	    <code>validate --file "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" $mydoc</code>
	  </example>
	  <example>
	    <code>validate --relaxng --file "test.rng" $mydoc</code>
	    <code>validate --relaxng --string $relaxschema $mydoc</code>
	    <code>$rng := open "test.rng"</code>
	    <code>validate --relaxng --doc $rng $mydoc</code>
	  </example>
	  <example>
	    <code>validate --schema --file "test.xsd" $mydoc</code>
	    <code>validate --schema --string $xsdschema $mydoc</code>
	    <code>$xsd := open "test.xsd"</code>
	    <code>validate --schema --doc $xsd $mydoc</code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="list_dtd_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="exit_command" type="command" name="exit" inline="yes">
      <aliases>
	<alias name="quit"/>
      </aliases>
      <command maxargs="1" func="quit"/><documentation sections="Flow">
	<usage>exit [<xref linkend="exp"/>]</usage>
	<shortdesc>exit &XSH; shell</shortdesc>
	<description>
	  <para>
	    Exit xsh, optionally with an exit-code
	    resulting from evaluation of a given <xref linkend="exp"/>.
	  </para>
	  <para>
	    WARNING: No files are saved on exit.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="process_xinclude_command" type="command" name="process-xinclude" inline="yes">
      <aliases>
	<alias name="process_xinclude"/>
	<alias name="process-xincludes"/>
	<alias name="process_xincludes"/>
	<alias name="xinclude"/>
	<alias name="xincludes"/>
	<alias name="load_xincludes"/>
	<alias name="load-xincludes"/>
	<alias name="load_xinclude"/>
	<alias name="load-xinclude"/>
      </aliases>
      <command maxargs="1" func="process_xinclude"/><documentation sections="Manipulation Documents">
	<usage>process-xinclude [<xref linkend="document"/>]</usage>
	<shortdesc>load and insert XInclude sections</shortdesc>
	<description>
	  <para>
	    Replace any xinclude tags in a given <xref linkend="document"/>
	    with the corresponding content. See
	    <ulink
	      url="http://www.w3.org/TR/xinclude/">http://www.w3.org/TR/xinclude/</ulink>
	    to find out more about XInclude technology.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="parser_expands_xinclude" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="chxpath_command" type="command" name="cd" inline="yes">
      <aliases>
	<alias name="chxpath"/>
      </aliases>
      <command maxargs="1" func="set_local_xpath"/>
      <documentation sections="Navigation">
	<usage>cd [<xref linkend="exp"/>]</usage>
	<shortdesc>change current context node</shortdesc>
	<description>
	  <para>
	    Evaluate given <xref linkend="exp"/>
	    to a node-list and 
	    change current context node to
	    the first node in it.
          </para>
	</description>
      </documentation>
    </rule>
    <rule id="pwd_command" type="command" name="pwd" inline="yes">
      <command maxargs="0" func="print_pwd">
	<param name="id" short="i"/>
      </command>
      <documentation sections="Navigation Information">
	<usage>pwd [--id|:i]</usage>
	<shortdesc>show current context node location (as a canonical XPath)</shortdesc>
	<description>
	  <para>Print XPath leading to the current context node 
	    (equivalent to <literal>locate .</literal>).
	  </para>
	  <para>
	    If flag <literal>--id</literal> (<literal>:i</literal>) is
	    used then ID-based shortcut is allowed in the resulting
	    location path. That means that if the current node or some of its
	    ancestors has an ID attribute (either
	    <literal>xml:id</literal> or one specified in a DTD) then
	    the corresponding segment of the canonical location path
	    is replaced by the <literal>id()</literal> function
	    which jumps directly to an element based on its ID.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="locate_command" arguments=""/>
	  <ruleref ref="path_function" arguments=""/>
	</see-also>
      </documentation>
    </rule>    
    <rule id="locate_command" type="command" name="locate" inline="yes">
      <command maxargs="1" func="locate">
	<param name="id" short="i"/>
      </command>
      <documentation sections="Navigation Information">
	<usage>locate [--id|:i] <xref linkend="xpath"/></usage>
	<shortdesc>show a given node location (as a canonical XPath)</shortdesc>
	<description>
	  <para>Print canonical XPaths leading to nodes matched by
	    a given <xref linkend="xpath"/>.</para>
	  <para>
	    If flag <literal>--id</literal> (<literal>:i</literal>) is
	    used then ID-based shortcuts are allowed in the resulting
	    location paths. That means that if the node or some of its
	    ancestors has an ID attribute (either
	    <literal>xml:id</literal> or one specified in a DTD) then
	    the corresponding segment of the canonical location path
	    is replaced by the <literal>id()</literal> function
	    which jumps directly to an element based on its ID.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="pwd_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>    
    <rule id="xupdate_command" type="command" name="xupdate" inline="yes">
      <command minargs="1" maxargs="2" func="xupdate"/><documentation sections="Manipulation">
	<usage>xupdate <xref linkend="document"/> [<xref linkend="document"/>]</usage>
	<shortdesc>apply XUpdate commands on a document</shortdesc>
	<description>
	  <para>Modify the current document or the document specified
	    by the second <xref linkend="document"/> argument according to
	    XUpdate commands of the first <xref linkend="document"/>
	    argument. 
	    XUpdate, or more specifically the XML Update Language, aims to
	    be a language for updating XML documents.
	  </para>
	  <para>
	    XUpdate language is described in XUpdate Working Draft at
            <ulink url="http://xmldb-org.sourceforge.net/xupdate/xupdate-wd.html">http://xmldb-org.sourceforge.net/xupdate/xupdate-wd.html</ulink>.	    	    
	  </para>
	  <para>XUpdate output can be generated for example by
            Python xmldiff utility from
	    <ulink url="http://www.logilab.org/projects/xmldiff/">http://www.logilab.org/projects/xmldiff/</ulink>.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="verbose" type="command" name="verbose" inline="yes">
      <command maxargs="0" func="set_quiet" extraargs="0"/><documentation sections="Configuration">
	<usage>verbose</usage>
	<shortdesc>make &XSH; print many messages</shortdesc>
	<description>
	  <para>Turn on verbose messages (default).</para>
	  <para>This is equivalent to setting
	    <literal>$QUIET</literal> variable to 0.</para>
	</description>
	<see-also>
	  <ruleref ref="quiet" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="test_mode" type="command" name="test-mode" inline="yes">
      <aliases>
	<alias name="test_mode"/>
      </aliases>
      <production>
	<selfref sep="yes"/>
	<action>[<lineinfo/>,"test-mode"]</action>
      </production>
      <documentation sections="Flow Configuration">
	<usage>test-mode</usage>
	<shortdesc>do not execute any command, only check the syntax</shortdesc>
	<description>
	  <para>
	    Switch into a mode in which no commands are actually
	    executed and only command syntax is checked.
	  </para>
	  <para>This is equivalent to setting
	    <literal>$TEST_MODE</literal> variable to 1.</para>
	</description>
	<see-also>
	  <ruleref ref="run_mode" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="run_mode" type="command" name="run-mode" inline="yes">
      <aliases>
	<alias name="run_mode"/>
      </aliases>
      <production>
	<selfref sep="yes"/>
	<action>[<lineinfo/>,"run-mode"]</action>
      </production>
      <documentation sections="Flow Configuration">
	<usage>run-mode</usage>
	<shortdesc>switch into normal execution mode (quit <xref linkend="test_mode"/>)</shortdesc>
	<description>
	  <para>
	    Switch from the <xref linkend="test_mode"/> back
	    to the normal execution mode.
	  </para>
	  <para>This is equivalent to setting
	    <literal>$TEST_MODE</literal> variable to 0.</para>
	</description>
	<see-also>
	  <ruleref ref="test_mode" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="debug" type="command" name="debug" inline="yes">
      <command maxargs="0" func="set_debug" extraargs="1"/><documentation sections="Configuration">
	<usage>debug</usage>
	<shortdesc>display many annoying debugging messages</shortdesc>
	<description>
	  <para>Turn on debugging messages.</para>
	  <para>This is equivalent to setting
	    <literal>$DEBUG</literal> variable to 1.</para>
	</description>
	<see-also>
	  <ruleref ref="nodebug" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="nodebug" type="command" name="nodebug" inline="yes">
      <command maxargs="0" func="set_debug" extraargs="0"/><documentation sections="Configuration">
	<usage>nodebug</usage>
	<shortdesc>turn off debugging messages</shortdesc>
	<description>
	  <para>Turn off debugging messages.</para>
	  <para>This is equivalent to setting
	    <literal>$DEBUG</literal> variable to 0.</para>
	</description>
	<see-also>
	  <ruleref ref="debug" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="version" type="command" name="version" inline="yes">
      <command maxargs="0" func="print_version" extraargs="0"/><documentation sections="Information">
	<usage>version</usage>
	<shortdesc>show version information</shortdesc>
	<description>
	  <para>
	    Prints program version plus version numbers of the most
	    important libraries used.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="validation" type="command" name="validation" inline="yes">
      <command minargs="1" maxargs="1" func="set_validation"/><documentation sections="Configuration">
	<usage>validation <xref linkend="exp"/></usage>
	<shortdesc>turn on/off validation in XML parser</shortdesc>
	<description>
	  <para>
	    Turn on validation during the parse process if the
	    <xref linkend="exp"/> is non-zero or off otherwise.
	    Defaults to off.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$VALIDATION</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="recovering" type="command" name="recovering" inline="yes">
      <command minargs="1" maxargs="1" func="set_recovering"/><documentation sections="Configuration">
	<usage>recovering <xref linkend="exp"/></usage>
	<shortdesc>turn on/off parser's ability to fix broken XML</shortdesc>
	<description>
	  <para>
	    If the <xref linkend="exp"/> evaluates to non-zero value,
	    turn on the recovering parser mode on; turn it off otherwise.
	    Defaults to off.</para>
	  <para>Note, that the in the recovering mode,
            validation is not performed by the parser even if
	    the validation flag is on.
	  </para>
	  <para>The recover mode helps to efficiently recover
	  documents that are almost well-formed. This for example
	  includes documents without a close tag for the document
	  element (or any other element inside the document).</para>
	  <para>This command is equivalent to setting the
	    <literal>$RECOVERING</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="parser_expands_entities" type="command" name="parser-expands-entities" inline="yes">
      <aliases>
	<alias name="parser_expands_entities"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_expand_entities"/><documentation sections="Configuration">
	<usage>parser-expands-entities <xref linkend="exp"/></usage>
	<shortdesc>turn on/off parser's tendency to expand entities</shortdesc>
	<description>
	  <para>
	    If the
	    <xref linkend="exp"/> is non-zero
	    enable the entity expansion during the parse process; disable it otherwise.
	    If entity expansion is disabled, any external entity references in parsed
	    documents are preserved as references. By default, entity expansion
	    is enabled.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$PARSER_EXPANDS_ENTITIES</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="keep_blanks" type="command" name="keep-blanks" inline="yes">
      <aliases>
	<alias name="keep_blanks"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_keep_blanks"/><documentation sections="Configuration">
	<usage>keep-blanks <xref linkend="exp"/></usage>
	<shortdesc>turn on/off ignorable whitespace preservation</shortdesc>
	<description>
	  <para>
	    Allows you to turn on/off preserving the parser's default
	    behavior of preserving all whitespace in the document.
	    Setting this option to 0, instructs the XML parser
	    to ignore whitespace occurring between adjacent element
	    nodes, so that no extra text nodes are created for it.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$KEEP_BLANKS</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="pedantic_parser" type="command" name="pedantic-parser" inline="yes">
      <aliases>
	<alias name="pedantic_parser"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_pedantic_parser"/><documentation sections="Configuration">
	<usage>pedantic-parser <xref linkend="exp"/></usage>
	<shortdesc>make the parser more pedantic</shortdesc>
	<description>
	  <para>
	    If you wish, you can make the XML parser little more pedantic by passing
	    a non-zero <xref linkend="exp" /> to this command.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$PEDANTIC_PARSER</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="complete_attributes" type="command" name="parser-completes-attributes" inline="yes">
      <aliases>
	<alias name="complete_attributes"/>
	<alias name="complete-attributes"/>
	<alias name="parser_completes_attributes"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_complete_attributes"/><documentation sections="Configuration">
	<usage>parser-completes-attributes <xref linkend="exp"/></usage>
	<shortdesc>turn on/off parser's ability to fill default attribute values</shortdesc>
	<description>
	  <para>
	    If the expression is non-zero, the command makes XML parser
	    add missing attributes with default values as specified in 
	    a DTD. By default, this option is enabled.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$PARSER_COMPLETES_ATTRIBUTES</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="indent" type="command" name="indent" inline="yes">
      <command minargs="1" maxargs="1" func="set_indent"/><documentation sections="Configuration">
	<usage>indent <xref linkend="exp"/></usage>
	<shortdesc>turn on/off pretty-printing</shortdesc>
	<description>
	  <para>If the value of <xref linkend="exp"/> is 1,
	    saved and listed XML will be formatted
	    using some (hopefully) ignorable whitespace. 
	    If the value is 2 (or
	    higher), &XSH; will act as in case of 1, plus it will add a
	    leading and a trailing linebreak to each text node.
	  </para>
	  <para>Note, that since the underlying C library
	    (libxml2) uses a hard-coded indentation of 2 space
	    characters per indentation level, the amount of
	    whitespace used for indentation can not be
	    altered at runtime.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$INDENT</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="empty_tags" type="command" name="empty-tags" inline="yes">
      <aliases>
	<alias name="empty_tags"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_empty_tags"/><documentation sections="Configuration">
	<usage>empty-tags <xref linkend="exp"/></usage>
	<shortdesc>turn on/off serialization of empty tags</shortdesc>
	<description>
	  <para>If the value of <xref linkend="exp"/> is 1
	    (non-zero), empty tags are serialized as a
	    start-tag/end-tag pair
	    (<literal>&lt;foo&gt;&lt;/foo&gt;</literal>).  This option
	    affects both <xref linkend="list_command"/> and <xref linkend="save_command"/> and possibly other
	    commands. Otherwise, they are compacted into a short-tag
	    form (<literal>&lt;foo/&gt;</literal>). Default value is
	    <literal>0</literal>.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$EMPTY_TAGS</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="skip_dtd" type="command" name="skip-dtd" inline="yes">
      <aliases>
	<alias name="skip_dtd"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_skip_dtd"/><documentation sections="Configuration">
	<usage>skip-dtd <xref linkend="exp"/></usage>
	<shortdesc>turn on/off serialization of DTD DOCTYPE declaration</shortdesc>
	<description>
	  <para>If the value of <xref linkend="exp"/> is 1 (non-zero),
	    DTD DOCTYPE declaration is omitted from any further serializations
	    of XML documents (including <xref linkend="list_command"/>
	    and <xref linkend="save_command"/>). Default value is
	    <literal>0</literal>.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$SKIP_DTD</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="parser_expands_xinclude" type="command" name="parser-expands-xinclude" inline="yes">
      <aliases>
	<alias name="parser_expands_xinclude"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_expand_xinclude"/><documentation sections="Configuration">
	<usage>parser-expands-xinclude <xref linkend="exp"/></usage>
	<shortdesc>turn on/off transparent XInclude insertion by parser</shortdesc>
	<description>
	  <para>
	    If the <xref linkend="exp"/> is non-zero, the parser is
	    allowed to expand XInclude tags immediately while parsing the
	    document.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$PARSER_EXPANDS_XINCLUDE</literal> variable.</para>
	</description>
	<see-also>
	  <ruleref ref="process_xinclude_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="load_ext_dtd" type="command" name="load-ext-dtd" inline="yes">
      <aliases>
	<alias name="load_ext_dtd"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_load_ext_dtd"/><documentation sections="Configuration">
	<usage>load-ext-dtd <xref linkend="exp"/></usage>
	<shortdesc>turn on/off external DTD fetching</shortdesc>
	<description>
	  <para>
	    Non-zero <xref linkend="exp"/> instructs 
	    the XML parser to load external DTD
	    subsets declared in XML documents. 
	    This option is enabled by default.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$LOAD_EXT_DTD</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="encoding" type="command" name="encoding" inline="yes">
      <command minargs="1" maxargs="1" func="set_encoding"/><documentation sections="Configuration">
	<usage>encoding <xref linkend="enc_string"/></usage>
	<shortdesc>choose output charset</shortdesc>
	<description>
	  <para>Set the default character encoding used
	    for standard (e.g. terminal) output. This doesn't influence
	    the encoding used for saving XML documents.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$ENCODING</literal> variable.</para>
	</description>
	<see-also>
	  <ruleref ref="query_encoding"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="query_encoding" type="command" name="query-encoding" inline="yes">
      <aliases>
	<alias name="query_encoding"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_qencoding"/><documentation sections="Configuration">
	<usage>query-encoding <xref linkend="enc_string"/></usage>
	<shortdesc>declare the charset of &XSH; source files and terminal input</shortdesc>
	<description>
	  <para>Set the default query character encoding, i.e.
	    encoding used when taking input from &XSH; prompt or standard input.</para>
	  <para>This command is equivalent to setting the
	    <literal>$QUERY_ENCODING</literal> variable.</para>
	</description>
	<see-also>
	  <ruleref ref="encoding"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="quiet" type="command" name="quiet" inline="yes">
      <command maxargs="0" func="set_quiet" extraargs="1"/><documentation sections="Configuration">
	<usage>quiet</usage>
	<shortdesc>turn off many &XSH; messages</shortdesc>
	<description>
	  <para>Turn off verbose messages.</para>
	  <para>This command is equivalent to setting the
	    <literal>$QUIET</literal> variable.</para>
	</description>
	<see-also>
	  <ruleref ref="verbose" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="cdonopen" type="command" name="switch-to-new-documents" inline="yes">
      <aliases>
	<alias name="switch_to_new_documents"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_cdonopen"/><documentation sections="Configuration Documents">
	<usage>switch-to-new-documents <xref linkend="exp"/></usage>
	<shortdesc>set on/off changing current document to newly
	  open/created files</shortdesc>
	<description>
	  <para>If non-zero, &XSH; changes
	    current node to the document node of a newly open/created
	    files every time a new document is opened or created with
	    <xref linkend="open_command"/> or <xref linkend="create_command"/>.
	    Default value for this option is 1. 
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$SWITCH_TO_NEW_DOCUMENTS</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="backups" type="command" name="backups" inline="yes">
      <command maxargs="0" func="set_backups" extraargs="1"/><documentation sections="Configuration Documents">
	<usage>backups</usage>
	<shortdesc>turn on backup file creation</shortdesc>
	<description>
	  <para>Enable creating backup files on save (default).</para>
	  <para>This command is equivalent to setting the
	    <literal>$BACKUPS</literal> variable to 1.</para>
	</description>
	<see-also>
	  <ruleref ref="nobackups" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="nobackups" type="command" name="nobackups" inline="yes">
      <command maxargs="0" func="set_backups" extraargs="0"/><documentation sections="Configuration Documents">
	<usage>nobackups</usage>
	<shortdesc>turn off backup file creation</shortdesc>
	<description>
	  <para>Disable creating backup files on save.</para>
	  <para>This command is equivalent to setting the
	    <literal>$BACKUPS</literal> variable to 0.</para>
	</description>
	<see-also>
	  <ruleref ref="nobackups" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="fold_command" type="command" name="fold" inline="yes">
      <command minargs="0" maxargs="1" func="mark_fold">
	<param name="depth" short="d" type="exp" argument="exp"/>
      </command><documentation sections="Navigation">
	<usage>fold [--depth|:d <xref linkend="exp"/>] [<xref linkend="exp"/>]</usage>
	<shortdesc>mark elements to be folded by list
	command</shortdesc>
	<description>
	  <para>
	    This feature is still EXPERIMENTAL and
	    may change in the future! 
	    Fold command may be used to
	    mark elements with a
	    <literal>xsh:fold</literal> attribute from the
	    <literal>http://xsh.sourceforge.net/xsh/</literal> namespace. 
	    When
	    listing the DOM tree using 
	    <literal><xref linkend="list_command"/> --fold <xref linkend="xpath"/></literal>, 
	    elements marked in this
	    way are folded to a given depth (default is 0 = fold immediately).
	  </para>
	  <para>
	    The option <literal>--depth</literal> (<literal>:d</literal>)
	    may be used to specify the depth at which
	    subtrees of given elements are to be folded.
	  </para>
	  <para>
	    If called without arguments,
	    the command applies to the current element,
	    otherwise the <xref linkend="exp"/> is evaluated to the node-list
	    and folding is applied to all elements within this node-list.
	  </para>
	  <example>
	    <code>xsh&gt; <userinput>fold --depth 1 //chapter</userinput>
	      xsh&gt; <userinput>ls --fold  //chapter[1]</userinput>
	      &lt;chapter id="intro" xsh:fold="1"&gt;
	      <tab count="1"/>&lt;title&gt;...&lt;/title&gt;
	      <tab count="1"/>&lt;para&gt;...&lt;/para&gt;
	      <tab count="1"/>&lt;para&gt;...&lt;/para&gt;
	      &lt;/chapter&gt;
	    </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="unfold_command" arguments=""/>
	  <ruleref ref="list_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="unfold_command" type="command" name="unfold" inline="yes">
      <command minargs="1" maxargs="1" func="mark_unfold"/><documentation sections="Navigation">
	<usage>unfold <xref linkend="exp"/></usage>
	<shortdesc>unfold elements folded with fold command</shortdesc>
	<description>
	  <para>
	    This feature is still EXPERIMENTAL! 
	  </para>
	  <para>Unfold command removes
	    <literal>xsh:fold</literal> attributes from all given elements.
	    Such attributes are usually created by previous
	    usage of <xref linkend="fold_command"/>.  Be aware, that
	    <literal>xmlns:xsh</literal> namespace declaration may
	    still be present in the document even when all elements
	    are unfolded.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="fold_command" arguments=""/>
	  <ruleref ref="list_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="redo_command" type="command" name="redo" inline="yes">
      <command maxargs="1" func="loop_redo"/><documentation sections="Flow">
	<usage>redo [<xref linkend="exp"/>]</usage>
	<shortdesc>restart the innermost enclosing loop block</shortdesc>
	<description>
	  <para>
	    <literal>redo</literal> restarts a loop block without evaluating
	    the conditional again. The optional <xref linkend="exp"/> argument
	    may evaluate to a positive integer number that indicates which
	    level of the nested loops should be restarted. If omitted, it
	    defaults to 1, i.e. the innermost loop.
	  </para>
	  <para>
	    Using this command outside a loop causes an immediate
	    run-time error.
	  </para>
	  <example>
	    <title>Restart a higher level loop from an inner one</title>
	    <code>while ($i&lt;100) { 
	      <tab count="1"/># ...
	      <tab count="1"/>foreach //para {
	      <tab count="1"/><tab count="1"/># some code
	      <tab count="1"/><tab count="1"/>if $param { 
	      <tab count="1"/><tab count="1"/><tab count="1"/>redo; # redo foreach loop
	      <tab count="1"/><tab count="1"/>} else {
	      <tab count="1"/><tab count="1"/><tab count="1"/>redo 2; # redo while loop
	      <tab count="1"/><tab count="1"/>}
	      <tab count="1"/>}
	      }
	    </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="foreach" arguments=""/>
	  <ruleref ref="while" arguments=""/>
	  <ruleref ref="iterate" arguments=""/>
	  <ruleref ref="next_command" arguments=""/>
	  <ruleref ref="last_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="next_command" type="command" name="next" inline="yes">
      <command maxargs="1" func="loop_next"/><documentation sections="Flow">
	<usage>next [<xref linkend="exp"/>]</usage>
	<shortdesc>start the next iteration of an enclosing
	loop</shortdesc>
	<description>
	  <para>
	    <literal>next</literal> is like the continue statement in C; it starts the
	    next iteration of an enclosing loop. 
	    The command may be used with an optional argument evaluating
	    to a positive integer number indicating which
	    level of the nested loops should be restarted.
	    If the argument is omitted, it defaults to 1, i.e. the innermost loop.
	  </para>
	  <para>
	    Using this command outside a loop causes an
	    immediate run-time error.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="foreach" arguments=""/>
	  <ruleref ref="while" arguments=""/>
	  <ruleref ref="iterate" arguments=""/>
	  <ruleref ref="redo_command" arguments=""/>
	  <ruleref ref="last_command" arguments=""/>
	  <ruleref ref="prev_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="prev_command" type="command" name="prev" inline="yes">
      <command maxargs="1" func="loop_prev"/><documentation sections="Flow">
	<usage>prev [<xref linkend="exp"/>]</usage>
	<shortdesc>restart an iteration on a previous node</shortdesc>
	<description>
	  <para>
	    This command is only allowed inside an
	    <literal>iterate</literal> loop. It returns the iteration
	    one step back, to the previous node on the iterated axis.
	    The optional <xref linkend="exp"/> argument may be
	    used to indicate to which level of nested loops the
	    command applies to (default is 1).
	  </para>
	</description>
	<see-also>
	  <ruleref ref="iterate" arguments=""/>
	  <ruleref ref="redo_command" arguments=""/>
	  <ruleref ref="last_command" arguments=""/>
	  <ruleref ref="next_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="last_command" type="command" name="last" inline="yes">
      <command maxargs="1" func="loop_last"/><documentation sections="Flow">
	<usage>last [<xref linkend="exp"/>]</usage>
	<shortdesc>immediately exit an enclosing loop</shortdesc>
	<description>
	  <para>
	    The <literal>last</literal> command is like the break
	    statement in C (as used in loops); it immediately exits an
	    enclosing loop. The optional <xref linkend="exp"/>
	    argument may evaluate to a positive integer number that
	    indicates which level of the nested loops to quit. If this
	    argument is omitted, it defaults to 1, i.e. the innermost
	    loop.
	  </para>
	  <para>
	    Using this command outside a loop causes an
	    immediate run-time error.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="foreach" arguments=""/>
	  <ruleref ref="while" arguments=""/>
	  <ruleref ref="iterate" arguments=""/>
	  <ruleref ref="next_command" arguments=""/>
	  <ruleref ref="last_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="return_command" type="command" name="return" inline="yes">
      <command maxargs="1" func="call_return"/><documentation sections="Flow">
	<usage>return [<xref linkend="exp"/>]</usage>
	<shortdesc>return from a subroutine</shortdesc>
	<description>
	  <para>
	    This command immediately stops the execution of a
	    procedure it occurs in and returns the execution to the
	    place of the script from which the subroutine was called.
	    Optional argument may be used as a return value for the
	    subroutine call.
	  </para>
	  <para>
	    Using this command outside a subroutine causes an
	    immediate run-time error.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="def" arguments=""/>
	  <ruleref ref="call_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="throw_command" type="command" name="throw" inline="yes">
      <command minargs="1" maxargs="1" func="throw_exception"/><documentation sections="Flow">
	<usage>throw <xref linkend="exp"/></usage>
	<shortdesc>throw an exception</shortdesc>
	<description>
	  <para>
	    This command throws and exception containing error message
	    given by the obligatory <xref linkend="exp"/>
	    argument. If the exception is not handled 
	    by some surrounding <xref linkend="try_catch"/> block,
	    the execution is stopped immediately and the error
	    message is printed.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="try_catch" arguments=""/>
	</see-also>
      </documentation>
    </rule>

    <rule id="catalog_command" type="command" name="catalog" inline="yes">
      <command minargs="1" maxargs="1" func="load_catalog"/><documentation sections="Documents">
	<usage>catalog <xref linkend="filename"/></usage>
	<shortdesc>use a catalog file during all parsing processes</shortdesc>
	<description>
	  <para>
	    Make use of a given XML file as a catalog during all parsing
	    processes. Using a catalog may significantly speed up
	    parsing processes if many external resources are loaded
	    into the parsed documents (such as DTDs or XIncludes).
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="xpaxis" inline="no">
      <production>
	<regexp>[-a-z]+::</regexp>
      </production>
    </rule>
    <rule id="xpnodetest" inline="no">
      <production>
	<regexp>node\(\)|text\(\)|comment\(\)|processing-instruction\(\s*(?:"[^"]*"\s*|'[^'*]'\s*)?\)|[^\(\[\/\"\'\&amp;\;\s]+</regexp>
      </production>
    </rule>
    <rule id="xplocationstep" inline="no">
      <production>
	<ruleref ref="xpaxis" rep="?" arguments=""/>
	<ruleref ref="xpnodetest" arguments=""/>
	<action>[ (@{$item[1]} ? $item[1][0] : 'child::'),$item[3] ]</action>
      </production>
    </rule>
    <rule id="xpstep" inline="no">
      <production>
	<ruleref ref="xplocationstep" arguments=""/>
	<directive type="skip">""</directive>
	<ruleref ref="xpfilter" rep="?" arguments=""/>
	<action>[ @{$item[1]}, @{$item[3]}]</action>
      </production>
    </rule>
    <rule id="iterate" type="command" name="iterate" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<ruleref ref="xpstep" arguments=""/>
	<ruleref ref="block" arguments=""/>
	<action>[<lineinfo/>,'iterate',$item[4],@{$item[3]}]</action>
      </production>
      <documentation sections="Flow">
	<usage>iterate <xref linkend="xpath"/> <xref linkend="block"/></usage>
	<shortdesc>iterate a block over current subtree</shortdesc>
	<description>
	  <para>
	    Iterate works very much like a <xref
	      linkend="foreach" /> loop with the
	    same <xref linkend="xpath"/> expression, except that it
	    evaluates the <xref linkend="block"/> as soon as a new node
	    matching a given <xref linkend="xpath"/> is found. As a
	    limitation, an <xref linkend="xpath"/> expression
	    used with <literal>iterate</literal> may consist of one XPath
	    step only, i.e. it may not contain an XPath step separator
	    <literal>/</literal>.
	  </para>
	  <para>
	    A possible benefit of using <literal>iterate</literal> instead of
	    <xref linkend="foreach" /> is some efficiency when
	    iterating over huge node-sets. Since
	    <literal>iterate</literal> doesn't compute
	    the resulting node-set in advance, it
	    doesn't have to 1) allocate extra memory for it
	    and 2) (more importantly) doesn't have to sort
	    the node-list in the document order (which
	    tends to be slow on large node-sets, unless
	    <xref linkend="index_command"/> is used). On the other
	    hand, <literal>iterate</literal> suffers from a considerable
	    speed penalty since it isn't implemented in C (unlike
	    libxml2's XPath engine).
	  </para>
	  <para>
	    Author's experience shows that, unless <xref linkend="index_command"/>
	    is used, <literal>iterate</literal> beats
	    <xref linkend="foreach"/> in speed on large
	    node-lists (&gt;=1500 nodes, but your milage may vary) while
	    <xref linkend="foreach"/> wins on smaller node-lists.
	  </para>
	  <para>The following two examples give equivalent results.
	    However, the one using <literal>iterate</literal> 
	    may be faster if the number of nodes being counted 
	    is huge and document order isn't indexed.</para>
	  <example>
	    <title>Count inhabitants of the kingdom of Rohan in productive age</title>
	    <code>cd rohan/inhabitants;</code>
	    <code>iterate child::*[@age&gt;=18 and @age&lt;60] { perl $productive++ };</code>
	    <code>echo "$productive inhabitants in productive age";</code>
	  </example>
	  <example>
	    <title>Using XPath</title>
	    <code>$productive=count(rohan/inhabitants/*[@age&gt;=18 and @age&lt;60]);</code>
	    <code>echo "$productive inhabitants in productive age";</code>
	  </example>
	  <para>
	    Hint: use e.g. <literal>| time cut</literal> pipe-line
	    redirection to benchmark a &XSH; command on a UNIX system.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="foreach" arguments=""/>
	  <ruleref ref="index_command" arguments=""/>
	  <ruleref ref="next_command" arguments=""/>
	  <ruleref ref="prev_command" arguments=""/>
	  <ruleref ref="last_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="registerns_command" type="command" name="register-namespace" inline="yes">
      <aliases>
	<alias name="regns"/>
      </aliases>
      <command minargs="2" maxargs="2" func="register_ns"/>
      <documentation sections="Namespaces Configuration">
	<usage>register-namespace <xref linkend="exp"/> <xref linkend="exp"/></usage>
	<shortdesc>register namespace prefix to use XPath expressions</shortdesc>
	<description>
	  <para>
             Registers the first argument
             as a prefix for the namespace given in the second argument.
             The prefix can later be used in XPath expressions.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="unregisterns_command" type="command" name="unregister-namespace" inline="yes">
      <aliases>
	<alias name="unregns"/>
      </aliases>
      <command minargs="1" maxargs="1" func="unregister_ns"/>
      <documentation sections="Namespaces Configuration">
	<usage>unregister-namespace <xref linkend="exp"/></usage>
	<shortdesc>unregister namespace prefix</shortdesc>
	<description>
	  <para>
	    Unregisters given namespace prefix previously registered
	    using <xref linkend="registerns_command"/>.  The prefix
	    can no longer be used in XPath expressions unless declared
	    within the current scope of the queried document.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="registerns_xhtml_command" type="command" name="register-xhtml-namespace" inline="yes">
      <aliases>
	<alias name="regns-xhtml"/>
      </aliases>
      <command minargs="1" maxargs="1" func="register_xhtml_ns"/>
      <documentation sections="Namespaces Configuration">
	<usage>register-xhtml-namespace <xref linkend="exp"/></usage>
	<shortdesc>register a prefix for the XHTML namespace</shortdesc>
	<description>
	  <para>
             Registers a prefix for the XHTML namespace
	    <literal>http://www.w3.org/1999/xhtml</literal>.
             The prefix can later be used in XPath expressions.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="registerns_xsh_command" type="command" name="register-xsh-namespace" inline="yes">
      <aliases>
	<alias name="regns-xsh"/>
      </aliases>
      <command minargs="1" maxargs="1" func="register_xsh_ns"/>
      <documentation sections="Namespaces Configuration">
	<usage>register-xsh-namespace <xref linkend="exp"/></usage>
	<shortdesc>register a prefix for the &XSH; namespace</shortdesc>
	<description>
	  <para>
	    Registers a new prefix for the &XSH; namespace <literal>http://xsh.sourceforge.net/xsh/</literal>.  The prefix
	    can later be used in XPath expressions.  Note, that &XSH;
	    namespace is by default registered with the prefix
	    <literal>xsh</literal>. This command is thus, in
	    general, useful only when some document uses
	    <literal>xsh</literal> prefix for a different namespace
	    or if you want a shorter prefix.
	  </para>
	</description>
      </documentation>
    </rule>

    <rule id="registerfunc_command" type="command" name="register-function" inline="yes">
      <aliases>
	<alias name="function"/>
	<alias name="regfunc"/>
      </aliases>
      <command minargs="2" maxargs="2" func="register_func"/><documentation sections="Navigation Configuration">
	<usage>register-function <xref linkend="exp"/> <xref linkend="perl_code"/></usage>
	<shortdesc>define XPath extension function (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>
	    EXPERIMENTAL! 
	  </para>
	  <para>Registers a given perl code as a new XPath
	    extension function under a name provided in the first
	    argument. XML::LibXML DOM
	    API as well as all Perl functions
	    pre-defined in the XML::XSH2::Map namespace
	    may be used in the perl code for object processing. If
	    the name contains a colon, then the first part before the
	    colon must be a registered namespace prefix 
	    (see <xref linkend="registerns_command"/>) and the function is
	    registered within the corresponding namespace.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="unregisterfunc_command" type="command" name="unregister-function" inline="yes">
      <aliases>
	<alias name="unregfunc"/>
      </aliases>
      <command minargs="1" maxargs="1" func="unregister_func"/><documentation sections="Navigation Configuration">
	<usage>unregister-function <xref linkend="exp"/></usage>
	<shortdesc>undefine extension function (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>
	    EXPERIMENTAL!  Unregister XPath extension function of a
	    given name previously registered using <xref linkend="registerfunc_command"/>.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="stream_select" inline="no">
      <production>
	<regexp>select\s</regexp>
	<ruleref ref="xpath" arguments=""/>
	<ruleref ref="block" arguments=""/>
        <action>[$item[2],$item[3]]</action>
      </production>
    </rule>
    <rule id="stream_process_command" type="command" name="stream" inline="yes">
      <production>
        <selfref sep="yes"/>
	<directive type="commit"/>
	<paramlist>
	  <param name="input-file" short="f" type="string" argument="filename"/>
	  <param name="input-pipe" short="p" type="string" argument="filename"/>
	  <param name="input-string" short="s" type="exp" argument="exp"/>
	  <param name="output-file" short="F" type="string"
	    argument="filename"/>
	  <param name="output-encoding" short="E" type="string" argument="enc_string"/>
	  <param name="output-pipe" short="P" type="string" argument="filename"/>
	  <param name="output-string" short="S" type="varname" argument="exp"/>
          <param name="no-output" short="N"/>
	</paramlist>
        <ruleref ref="stream_select" rep="s" arguments=""/>
	<action>[<lineinfo/>,'stream_process',$item[3],$item[4]]</action>
      </production>
      <documentation sections="Flow Documents">
	<usage>stream 
         [ --input-file|:f <xref linkend="filename"/> |
	   --input-pipe|:p <xref linkend="filename"/> |
           --input-string|:s <xref linkend="exp"/>]
	 [ --output-file|:F <xref linkend="filename"/> |
           --output-pipe|:P <xref linkend="filename"/> |
           --output-string|:S <xref linkend="varname"/> |
           --no-output|:N ]
           select <xref linkend="xpath"/> <xref linkend="block"/>
         [ select <xref linkend="xpath"/> <xref linkend="block"/> ... ]
                   </usage>
	<shortdesc>process selected elements from an XML stream (EXPERIMENTAL)</shortdesc>
	<description>
	  <para>
	    EXPERIMENTAL!  This command provides a memory efficient
	    (though slower) way to process selected parts of an XML
	    document with &XSH;. A streaming XML parser (SAX parser) is
	    used to parse the input. The parser has two states which
	    will be referred to as A and B below. The initial state of
	    the parser is A.</para> <para>In the state A, only a
	    limited vertical portion of the DOM tree is built. All XML
	    data coming from the input stream other than start-tags
	    are immediately copied to the output stream.  If a new
	    start-tag of an element arrives, a new node is created in
	    the tree. All siblings of the newly created node are
	    removed. Thus, in the state A, there is exactly one node
	    on every level of the tree. After a node is added to the
	    tree, all the <xref linkend="xpath"/> expressions
	    following the <literal>select</literal> keyword
	    are
	    checked. If none matches, the parser remains in state A
	    and copies the start-tag to the output stream. Otherwise,
	    the first expression that matches is remembered and the
	    parser changes its state to B.
	  </para>
	  <para>
	    In state B the parser builds a complete DOM subtree of the
	    element that was last added to the tree before the parser
	    changed its state from A to B. No data are sent to the
	    output at this stage. When the subtree is complete
	    (i.e. the corresponding end-tag for its topmost element is
	    encountered), the <xref linkend="block"/> of instructions
	    following the <xref linkend="xpath"/> expression that
	    matched is invoked with the root element of the subtree as
	    the current context node. The commands in <xref linkend="block"/> are allowed to transform the whole
	    element subtree or even to replace it with a different DOM
	    subtree or subtrees. They must, however, leave intact 
	    all ancestor nodes of the subtree. 
            Failing to do so can result in an error or
	    unpredictable results.
	  </para>
	  <para>
	    After the subtree processing <xref linkend="block"/>
	    returns, all subtrees that now appear in the DOM tree in
	    the place of the original subtree are serialized to the
	    output stream. After that, they are deleted and the parser
	    returns to state A.
	  </para>
	  <para>
	    Note that this type of processing highly limits the amount
	    of information the selecting XPath expressions can use. The first
	    notable fact is, that elements can not be selected by their
	    content. The only information present in the tree at the
	    time of the XPath evaluation is the element's name and
	    attributes plus the same information for all its
	    ancestors (there is no information at all about its possible
	    child nodes nor of the node's position
	    within the list of its siblings).
	  </para>
	  <para>The input parameters below are mutually exclusive.
	  If non is given, standard input is processed.</para>
	  <para><literal>--input-file</literal> or <literal>:f</literal>
	    instructs the processor to stream from a given file.</para>
	  <para><literal>--input-pipe</literal> or <literal>:p</literal>
	    instructs the processor to stream the output of a given a command.</para>
	  <para><literal>--input-string</literal> or <literal>:s</literal>
	    instructs the processor to use the result of a given
	    expression as the input to be processed.
	  </para>
	  <para>The output parameters below are mutually exclusive.
	    If none is given, standard output is used.
	  </para>
	  <para><literal>--output-file</literal> or <literal>:F</literal>
	    instructs the processor to save the output
	    to a given file.</para>
	  <para><literal>--output-pipe</literal> or <literal>:P</literal>
	    instructs the processor to pipe the output
	    to a given command.
	  </para>
	  <para><literal>--output-string</literal> or <literal>:S</literal>
	    followed by a variable name instructs the processor to 
	    store the result in the given variable.
	  </para>
	  <para><literal>--no-output</literal> or <literal>:N</literal>
            instructs the processor to throw the result away.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="namespaces_command" type="command" name="namespaces" inline="yes">
      <command maxargs="1" func="list_namespaces">
	<param name="registered" short="r"/>
      </command>
      <documentation sections="Namespaces Information">
	<usage>namespaces [--registered|:r] [<xref linkend="exp"/>]</usage>
	<shortdesc>List namespaces available in a context of
	  a given nodes</shortdesc>
	<description>
	  <para>
	    For each node in a given node-list lists
	    all namespaces that are valid the scope of the node.
	    Namespaces are listed in the form of
	    <literal>xmlns:prefix="uri"</literal> declarations,
	    preceded by a canonical xpath of the corresponding node
	    on a separate line.
	  </para>
	  <para>
	    If <literal>--registered</literal> or <literal>:r</literal>
	    flag is used, list also namespaces registered with the
	    <xref linkend="registerns_command"/> command
	    in XSH syntax.
	  </para>
	  <para>
	    If called without the <literal>--registered</literal> flag and
	    no <xref linkend="xpath"/> is given, lists namespaces
	    in the scope of the current node.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="xpath_completion_command" type="command" name="xpath-completion" inline="yes">
      <aliases>
	<alias name="xpath_completion"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_xpath_completion"/><documentation sections="Configuration">
	<usage>xpath-completion <xref linkend="exp"/></usage>
	<shortdesc>turn on/off TAB completion for xpath expressions in
	the interactive mode</shortdesc>
	<description>
	  <para>
	    If the
	    <xref linkend="exp"/> is non-zero,
	    enable the TAB completion for <xref linkend="xpath"/>
	    expansions in the interactive shell mode, disable it
	    otherwise. Defaults to on.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$XPATH_COMPLETION</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="xpath_axis_completion_command" type="command" name="xpath-axis-completion" inline="yes">
      <aliases>
	<alias name="xpath_axis_completion"/>
      </aliases>
      <command minargs="1" maxargs="1" func="set_xpath_axis_completion"/><documentation sections="Configuration">
	<usage>xpath-axis-completion <xref linkend="exp"/></usage>
	<shortdesc>sets TAB completion for axes in xpath expressions in
	the interactive mode</shortdesc>
	<description>
	  <para>
	    The following values are allowed:
	    <literal>always</literal>, <literal>never</literal>,
	    <literal>when-empty</literal>. Note, that all other values
	    (including 1) work as <literal>never</literal>!
	  </para>
	  <para>
	    If the <xref linkend="exp"/> evaluates 
	    to <literal>always</literal>, TAB completion for
	    XPath expressions always includes axis names.
	  </para>
	  <para>
	    If the <xref linkend="exp"/> evaluates to
	    <literal>when-empty</literal>, the TAB completion list for
	    XPath expressions includes axis names only if no element name
	    matches the completion.
	  </para>
	  <para>
	    If the <xref linkend="exp"/> evaluates to
	    <literal>never</literal>, the TAB completion list for
	    XPath expressions never includes axis names.
	  </para>
	  <para>
	    The default value for this option is
	    <literal>always</literal>.
	  </para>
	  <para>This command is equivalent to setting the
	    <literal>$XPATH_AXIS_COMPLETION</literal> variable.</para>
	</description>
      </documentation>
    </rule>
    <rule id="doc_info_command" type="command" name="doc-info" inline="yes">
      <aliases>
	<alias name="doc_info"/>
      </aliases>
      <command maxargs="1" func="doc_info"/><documentation sections="Information">
	<usage>doc-info [<xref linkend="document"/>]</usage>
	<shortdesc>displays various information about a document</shortdesc>
	<description>
	  <para>
	    In the present implementation, this command displays
	    information provided in the <literal>&lt;?xml
	    ...?&gt;</literal> declaration of a document:
	    <literal>version, encoding, standalone</literal>, 
	    plus information about
	    level of <literal>gzip</literal> compression of the
	    original XML file and
	    the original XML file URI.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="set_enc_command" arguments=""/>
	  <ruleref ref="set_standalone_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="xpath_extensions_command" type="command" name="xpath-extensions" inline="yes">
      <aliases>
	<alias name="xpath_extensions"/>
      </aliases>
      <command maxargs="1" func="xpath_extensions"/><documentation sections="Configuration">
	<usage>xpath-extensions [<xref linkend="exp"/>]</usage>
	<shortdesc>map predefined &XSH; XPath extension functions to
	  no or other namespace
	</shortdesc>
	<description>
	  <para>
	    <literal>xpath-extensions</literal>
	    remaps all extra
	    XPath extension functions provided by &XSH;
	    (which by default belong to the namespace
	    <literal>http://xsh.sourceforge.net/xsh/</literal>)
	    to a new namespace given by <xref linkend="exp"/>.
	    If the argument is omitted, the functions
	    are re-registered without any namespace,
	    so that they may be called without a
	    namespace prefix, just by their function
	    names. This quite convenient.
	  </para>
	  <example>
	    <code>xpath-extensions;
ls grep(//word,"^.*tion$");</code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="set_enc_command" arguments=""/>
	  <ruleref ref="set_standalone_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="lineno_command" type="command" name="lineno" inline="yes">
      <command maxargs="1" func="print_lineno"/><documentation sections="Information">
	<usage>lineno [<xref linkend="exp"/>]</usage>
	<shortdesc>print line-numbers corresponding to matching nodes</shortdesc>
	<description>
	  <para>
	    <literal>lineno</literal>
	    command prints line numbers of
	    all nodes in a given node-list. Note however, that
	    <literal>libxml2</literal>
	    only stores line number information for element nodes.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="locate_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="ignore_use_command" name="use" inline="yes">
      <production>
	<selfref sep="yes"/>
	<directive type="commit"/>
	<regexp>XML::XSH2::(?:Inline|Compile)</regexp>
	<action>1</action>
      </production>
    </rule>
    <rule id="edit_string_command" type="command" name="edit-string" inline="yes">
      <command minargs="1" maxargs="1" func="edit" extraargs="1">
	<param name="editor" short="E" type="string" argument="exp"/>
	<param name="encoding" short="e" type="string" argument="enc_string"/>
	<param name="allow-empty" short="0"/>
      </command>
      <documentation sections="Manipulation">
	<usage>edit-string [--editor|:E <xref linkend="filename"/>] 
	  [--encoding|:e <xref linkend="enc_string"/>]
	  [--allow-empty|:0] <xref linkend="exp"/></usage>
	<shortdesc>Edit a string or variable in a text editor.</shortdesc>
	<description>
	  <para>
	    Evaluating given <xref linkend="exp"/> to a string,
	    save it in a temporary file,
	    open the file an external editor as a plain text,
	    and when the editor exits,
	    read and return the result. The <literal>--editor</literal>
	    (<literal>:E</literal>) parameter can be used
	    to provide an editor command, whereas
	    <literal>--encoding</literal> (<literal>:e</literal>)
	    can be used to specify character encoding used for
	    communication with the editor. If the result
	    is empty, the interactive &XSH; shell asks user for
	    confirmation before returning the result in order
	    to prevent data loss due to some unexpected error.
	    To suppress this feature, use <literal>--allow-empty</literal>
	    or <literal>:0</literal> flag.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="edit_command" type="command" name="edit" inline="yes">
      <command maxargs="1" func="edit">
	<param name="editor" short="E" type="string" argument="exp"/>
	<param name="all" short="A"/>
	<param name="noindent" short="n"/>
	<param name="recover" short="r"/>
	<param name="keep-blanks" short="k"/>
	<param name="allow-empty" short="0"/>
	<param name="no-comment" short="q"/>
	<param name="encoding" short="e" type="string" argument="enc_string"/>
      </command>
      <documentation sections="Manipulation">
	<usage>edit [--editor|:E <xref linkend="filename"/>]
	  [--all|:A] [--noindent|:n] [--recover|:r] [--keep-blanks|:k]
	  [--allow-empty|:0] [--no-coment|:q] [--encoding|:e <xref
	    linkend="enc_string"/>] <xref linkend="exp"/>
	</usage>
	<shortdesc>Edit parts of a XML document in a text editor.</shortdesc>
	<description>
	  <para>This command may be used to interactively edit parts of a XML
	    document directly in your favorite editor.
	  </para>
	  <para>
	    A given <xref linkend="exp" /> is evaluated to a node-list and the
	    first the first resulting node is opened
	    in an external editor as a XML fragment. 
	    When the editor exits, the (possibly modified) fragment
	    is parsed and returned to the original document. Unless
	    <literal>--no-comment</literal> (<literal>:q</literal>) flag is
	    used, the XML fragment is preceded with a XML comment specifying
	    canonical XPath of the node being edited.
	  </para>
	  <para>
	    The command returns a node-list consisting of nodes
	    that resulted from parsing the individual edits.
	  </para>
	  <para>
	    <literal>--editor</literal> or <literal>:E</literal>
	    option may be used to specify external editor command.
	    If not specified, environment variables
	    <literal>EDITOR</literal> and <literal>VISUAL</literal>
	    are tried first, then <literal>vi</literal> editor
	    is used as a fallback.
	  </para>
	  <para>
	    If <literal>--all</literal> or <literal>:A</literal>
	    flag is present, all nodes from the node-list
	    are opened in the editor, one at a time.
	  </para>
	  <para>
	    If <literal>--recover</literal> or <literal>:r</literal>
	    is specified, the parser tries to recover from possible 
	    syntax errors when parsing the resulting XML.
	  </para>
	  <para>
	    <literal>--keep-blanks</literal> or <literal>:b</literal>
	    option may be used to force the parser to
	    include ignorable white space.
	  </para>
	  <para>If the result saved
	    by the editor is empty, the interactive
	    &XSH; shell asks user to confirm this was correct.
	    This confirmation can be suppressed using
	    <literal>--allow-empty</literal> or
	    <literal>:0</literal> (zero) options.
	  </para>
	  <para>
	    The <literal>--encoding</literal> or <literal>:e</literal>
	    parameter can be used to specify character encoding to
	    use when communicating with the external editor.
	  </para>
	  <example>
	    <title>Edit all chapter elements (one by one) with emacs</title>
	    <code>edit --editor 'emacs -nw' --encoding iso-8859-1 --all //chapter</code>
	  </example>
	</description>
      </documentation>
    </rule>
    <!-- ================== FUNCTIONS ====================== -->
    <rule id="doc_function" type="function" name="xsh:doc" inline="no">
      <documentation>
	<usage>node-set xsh:doc(node-set)</usage>
	<description>
	  <para>
	    Returns a node-set consisting of the owner document nodes
	    of all nodes in the given node-set.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="document_uri_function" type="function" name="xsh:document-uri" inline="no">
      <documentation>
	<usage>string xsh:document-uri(node-set?)</usage>
	<description>
	  <para>Returns URI of the document containing
	    the first node in the given node-set.
	    If called without arguments, or if the node-set is 
	    empty, returns filename of the document containing the current node.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="filename_function" type="function" name="xsh:filename" inline="no">
      <documentation>
	<usage>string xsh:filename(node-set?)</usage>
	<description>
	  <para>Same as xsh:document-uri();</para>
	</description>
      </documentation>
    </rule>
    <rule id="base_uri_function" type="function" name="xsh:base-uri" inline="no">
      <documentation>
	<usage>string xsh:base-uri(node-set?)</usage>
	<description>
	  <para>Returns base URI of the first node in the node-set (or
	  the current node).  The function should work on both XML and
	  HTML documents even if base mechanisms for these are
	  completely different. It returns the base as defined in RFC
	  2396 sections "5.1.1. Base URI within Document Content" and
	  "5.1.2. Base URI from the Encapsulating Entity". However it
	  does not return the document base (5.1.3), use
	  document-uri() for this.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="resolve_uri_function" type="function" name="xsh:resolve-uri" inline="no">
      <documentation>
	<usage>string xsh:resolve-uri(string, string?)</usage>
	<description>
	  <para>
	    This function takes one or two arguments: a relative URI and an optional base URI.
	    If the first argument is a relative URI reference, 
	    this function resolves it against either the 
	    given base URI, if given (which is assumed to be an absolute URI)
	    or, if base URI not given, against the URI of the current working directory.
	    If the first argument is an absolute URI reference, it is returned unchanged. 
	  </para>
	  <para>
	    If the first argument is the zero-length string, returns 
	    the base URI if given and the URI of the current working directory otherwise.
	  </para>
	  <para>
	    Note: Resolving a URI does not dereference it (download
	    the referenced content); it is merely a syntactic
	    operation on two character strings.
	  </para>
	</description>
      </documentation>
    </rule>

    <rule id="lineno_function" type="function" name="xsh:lineno" inline="no">
      <documentation>
	<usage>node-set xsh:lineno(node-set)</usage>
	<description>
	  <para>Returns line number of the occurrence of
	    the first node in the given node-set in its original XML
	    document (if available).
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="var_function" type="function" name="xsh:var" inline="no">
      <documentation>
	<usage>node-set xsh:var(string NAME)</usage>
	<description>
	  <para>
	    Returns a node-set consisting of nodes stored in a &XSH; node-list
	    variable named <literal>NAME</literal>.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="matches_function" type="function" name="xsh:matches" inline="no">
      <documentation>
	<usage>boolean xsh:matches(string STR,string PATTERN)</usage>
	<description>
	  <para>
	    Returns <literal>true</literal> if <literal>STR</literal>
	    matches the regular expression <literal>PATTERN</literal>.
	    Otherwise returns <literal>false</literal>.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="match_function" type="function" name="xsh:match" inline="no">
      <documentation>
	<usage>node-set xsh:match(string STR,string PATTERN,string OPTIONS)</usage>
	<description>
	  <para>
	    Searches a given string for a pattern match
	    specified by a regular expression <literal>PATTERN</literal>
	    and returns a node-set consisting of
	    <literal>&lt;xsh:string&gt;</literal>
	    elements containing portions of the string matched
	    by the pattern subexpressions enclosed in parentheses.
	    The OPTIONS string may contain the following flags:
	    <literal>c</literal> - do not reset search position on a failed match when /g is in effect;
	    <literal>g</literal> - match globally, i.e. find all occurrences;
	    <literal>i</literal> - do case insensitive search;
	    <literal>m</literal> - treat string as multiple lines 
	    (change "^" and "$" from matching the start or end of the string to matching the start or end
	    of any line anywhere within the string)
	    <literal>o</literal> - compile pattern only once;
	    <literal>s</literal> - treat string as single line (change "." to match any character whatsoever, even a newline, which normally it would not match);
	    <literal>x</literal> - extend your pattern's legibility by permitting whitespace and comments.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="grep_function" type="function" name="xsh:grep" inline="no">
      <documentation>
	<usage>node-set xsh:grep(node-set NODES, string PATTERN)</usage>
	<description>
	  <para>
	    Returns a node set consisting of those nodes of
	    <literal>NODES</literal> whose content 
	    (as returned by the built-in XPath 
	    function <literal>string()</literal>)
	    matches the regular expression <literal>PATTERN</literal>.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="substr_function" type="function" name="xsh:substr" inline="no">
      <documentation>
	<usage>string xsh:substr(string STR,float OFFSET,[float LENGTH])</usage>
	<description>
	  <para>
	    Extracts a substring out of <literal>STR</literal> 
	    and returns it. First character is at offset 0.</para>
	  <para>
	    If <literal>OFFSET</literal> is negative, starts
	    that far from the end of the string. </para>
	  <para>
	    If <literal>LENGTH</literal> is
	    omitted, returns everything to the end of the
	    string.  If <literal>LENGTH</literal> is negative,
	    leaves that many characters off the end of the string.</para>
	  <para>
	    If <literal>OFFSET</literal> and
	    <literal>LENGTH</literal> specify a substring that is
	    partly outside the string, only the part within
	    the string is returned.  If the substring is
	    beyond either end of the string, substr() returns
	    empty string and produces a warning.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="reverse_function" type="function" name="xsh:reverse" inline="no">
      <documentation>
	<usage>string xsh:reverse(string STR)</usage>
	<description>
	  <para>
	    Returns a string value same as <literal>STR</literal>
	    but with all characters in the opposite order.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="lc_function" type="function" name="xsh:lc" inline="no">
      <documentation>
	<usage>string xsh:lc(string STR)</usage>
	<description>
	  <para>
	    Returns a lowercased version of <literal>STR</literal>.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="uc_function" type="function" name="xsh:uc" inline="no">
      <documentation>
	<usage>string xsh:uc(string STR)</usage>
	<description>
	  <para>
	    Returns a uppercased version of <literal>STR</literal>.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="lcfirst_function" type="function" name="xsh:lcfirst" inline="no">
      <documentation>
	<usage>string xsh:lcfirst(string STR)</usage>
	<description>
	  <para>
	    Returns the value of <literal>STR</literal>
	    with the first character lowercased.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="ucfirst_function" type="function" name="xsh:ucfirst" inline="no">
      <documentation>
	<usage>string xsh:ucfirst(string STR)</usage>
	<description>
	  <para>
	    Returns the value of <literal>STR</literal>
	    with the first character uppercased.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="same_function" type="function" name="xsh:same" inline="no">
      <documentation>
	<usage>bool xsh:same(node-set N1, node-set N2)</usage>
	<description>
	  <para>
	    Returns <literal>true</literal> if the given node sets
	    both contain the same node
	    (in XPath, this can also be expressed as
	    <literal>count(N1|N2)+count(N1)+count(N2)=3</literal>).
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="max_function" type="function" name="xsh:max" inline="no">
      <documentation>
	<usage>float xsh:max(object EXPRESSION, ...)</usage>
	<description>
	  <para>
	    Returns the maximum of numeric values
	    computed from given <literal>EXPRESSION</literal>(s).
	    If <literal>EXPRESSION</literal> evaluates to a node-set,
	    string values of individual nodes are used.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="min_function" type="function" name="xsh:min" inline="no">
      <documentation>
	<usage>float xsh:min(object EXPRESSION, ...)</usage>
	<description>
	  <para>
	    Returns the minimum of numeric values
	    computed from given <literal>EXPRESSION</literal>(s).
	    If <literal>EXPRESSION</literal> evaluates to a node-set,
	    string values of individual nodes are used.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="strmax_function" type="function" name="xsh:strmax" inline="no">
      <documentation>
	<usage>string xsh:strmax(object EXPRESSION, ...)</usage>
	<description>
	  <para>
	    Returns a string value computed as the maximum
	    (in lexicographical order)
	    of all string values computed from given 
	    <literal>EXPRESSION</literal>(s).
	    If <literal>EXPRESSION</literal> evaluates to a node-set,
	    string values of individual nodes are used.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="strmin_function" type="function" name="xsh:strmin" inline="no">
      <documentation>
	<usage>string xsh:strmin(object EXPRESSION, ...)</usage>
	<description>
	  <para>
	    Returns a string value computed as the minimum
	    (in lexicographical order)
	    of all string values computed from given 
	    <literal>EXPRESSION</literal>(s).
	    If <literal>EXPRESSION</literal> evaluates to a node-set,
	    string values of individual nodes are used.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="sum_function" type="function" name="xsh:sum" inline="no">
      <documentation>
	<usage>float xsh:sum(object EXPRESSION, ...)</usage>
	<description>
	  <para>
	    Returns the sum of numerical value
	    computed from given 
	    <literal>EXPRESSION</literal>(s).
	    If <literal>EXPRESSION</literal> evaluates to a node-set,
	    string values of individual nodes are used.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="join_function" type="function" name="xsh:join" inline="no">
      <documentation>
	<usage>string xsh:join(string DELIM, object EXPRESSION,...)</usage>
	<description>
	  <para>
	    Joins the separate string values computed from 
	    <literal>EXPRESSION</literal>(s) into a single
	    string with fields separated by the 
	    value of <literal>DELIM</literal>,
	    and returns that new string.
	    If <literal>EXPRESSION</literal> evaluates to a node-set,
	    joins string values of individual nodes.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="subst_function" type="function" name="xsh:subst" inline="no">
      <documentation>
	<usage>string xsh:subst(string STR,string REGEXP,string
	REPLACEMENT, [string OPTIONS])</usage>
	<description>
	  <para>
	    Acts in the very same way as perl substitution operation
	    <literal>STRING =~ s/REGEXP/REPLACEMENT/OPTIONS</literal>,
	    returning the resulting string.
	    Searches a string for a pattern, and if found,
	    replaces that pattern with the replacement text.	    
	    If the <literal>REPLACEMENT</literal> string
	    contains a <literal>$</literal>  that looks like a variable,
	    the variable will be interpolated
	    into the </para>
	  <para><literal>REPLACEMENT</literal> at run-time.
	    Options are:
	    </para>
	  <para>
	    <literal>e</literal> - evaluate <literal>REPLACEMENT</literal> 
	    as a Perl expression,</para>
	  <para>
	    <literal>g</literal> - replace globally, i.e., all occurrences,</para>
	  <para>
	    <literal>i</literal> - do case-insensitive pattern matching,</para>
	  <para>
	    <literal>m</literal> - treat string as multiple lines,
	    that is, change <literal>^</literal>
	    and <literal>$</literal> from matching the start or end 
	    of the string to matching the start or end of any line anywhere
	    within the string,</para>
	  <para>
	    <literal>s</literal> - treat string as single line,
	    that is, change <literal>.</literal>
	    to match any character whatsoever, even a newline, which
	    normally it would not match,</para>
	  <para>
	    <literal>x</literal> - use extended regular expressions.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="sprintf_function" type="function" name="xsh:sprintf" inline="no">
      <documentation>
	<usage>string xsh:sprintf(string FORMAT,object EXPRESSION,...)</usage>
	<description>
	  <para>
	    Returns a string formatted by the usual <literal>printf</literal>
	    conventions of the C library function <literal>sprintf</literal>
	    and <literal>sprintf</literal> Perl function.</para>
	  <para>
	    See C documentation for an explanation of the
	    general principles and Perl documentation
	    for a list of supported formatting conversions.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="serialize_function" type="function" name="xsh:serialize" inline="no">
      <documentation>
	<usage>string xsh:serialize(node-set N,...)</usage>
	<description>
	  <para>
	    Serializes nodes of given node-set(s)
	    into XML strings and returns concatenation of
	    those strings.
	  </para>	
	</description>
      </documentation>
    </rule>
    <rule id="parse_function" type="function" name="xsh:parse" inline="no">
      <documentation>
	<usage>node-set xsh:parse(string XML-STRING)</usage>
	<description>
	  <para>
	    This function runs XML parser on <literal>XML-STRING</literal>
	    and returns a node-set consisting
	    of the top-level nodes of the resulting document node.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="current_function" type="function" name="xsh:current" inline="no">
      <documentation>
	<usage>node-set xsh:current()</usage>
	<description>
	  <para>
	    This function (very similar to XSLT <literal>current()</literal>
	    extension function) returns a node-set having the
	    current node as its only
	    member.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="path_function" type="function" name="xsh:path" inline="no">
      <documentation>
	<usage>string xsh:path(node-set NODE)</usage>
	<description>
	  <para>
	    This function returns a string containing
	    canonical XPath leading
	    to <literal>NODE</literal>.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="pwd_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="if_function" type="function" name="xsh:if" inline="no">
      <documentation>
	<usage>object xsh:if(object CONDITION, object YES, object NO)</usage>
	<description>
	  <para>
	    This function returns the <literal>YES</literal> object
	    if <literal>CONDITION</literal> is an non-empty
	    node-set or a string, boolean or integer 
	    evaluating to non-zero boolean. Otherwise the
	    <literal>NO</literal> object is returned.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_attribute_function" type="function" name="xsh:new-attribute" inline="no">
      <documentation>
	<usage>node-set xsh:new-attribute(string NAME1,string
	VALUE1,[string NAME2, string VALUE2, ...])</usage>
	<description>
	  <para>
	    Return a node-set consisting
	    of newly created attribute nodes
	    with given names and respective values.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_element_function" type="function" name="xsh:new-element" inline="no">
      <documentation>
	<usage>node-set xsh:new-element(string NAME,[string ATTR1-NAME1,
	string ATTR-VALUE1, ...])</usage>
	<description>
	  <para>
	    Create a new element node with given
	    <literal>NAME</literal> and optionally attributes with
	    given names and values and return a node-set containing
	    the new node as its only member.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_element_ns_function" type="function" name="xsh:new-element-ns" inline="no">
      <documentation>
	<usage>node-set xsh:new-element-ns(string NAME,string NS,[string ATTR1-NAME1,
	string ATTR-VALUE1, ...])</usage>
	<description>
	  <para>
	    Create a new element node with given <literal>NAME</literal> and
	    namespace-uri <literal>NS</literal> and optionally attributes with given
	    names and values and return a node-set
	    containing the new node as its only member.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_text_function" type="function" name="xsh:new-text" inline="no">
      <documentation>
	<usage>node-set xsh:new-text(string DATA)</usage>
	<description>
	  <para>
	    Create a new text node containing given
	    <literal>DATA</literal> and return a node-set containing
	    the new node as its only member.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_comment_function" type="function" name="xsh:new-comment" inline="no">
      <documentation>
	<usage>node-set xsh:new-comment(string DATA)</usage>
	<description>
	  <para>
	    Create a new comment node containing given
	    <literal>DATA</literal> and return a node-set containing
	    the new node as its only member.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_pi_function" type="function" name="xsh:new-pi" inline="no">
      <documentation>
	<usage>node-set xsh:new-pi(string NAME, [string DATA])</usage>
	<description>
	  <para>
	    Create a new processing instruction node node with given
	    <literal>NAME</literal> and (optionally) given
	    <literal>DATA</literal> and return a node-set containing
	    the new node as its only member.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_cdata_function" type="function" name="xsh:new-cdata" inline="no">
      <documentation>
	<usage>node-set xsh:new-cdata(string DATA)</usage>
	<description>
	  <para>
	    Create a new cdata section node node filled with
	    given <literal>DATA</literal> and return a node-set
	    containing the new node as its only member.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="new_chunk_function" type="function" name="xsh:new-chunk" inline="no">
      <documentation>
	<usage>node-set xsh:new-chunk(string XML)</usage>
	<description>
	  <para>
	    This is just an alias for <xref linkend="parse_function"/>.  It parses given piece of XML
	    and returns a node-set consisting of the top-level element
	    within the parsed tree.
	  </para>
	</description>
      </documentation>
    </rule>    
    <rule id="map_function" type="function" name="xsh:map" inline="no">
      <documentation>
	<usage>node-set xsh:map(node-set NODE, string XPATH)</usage>
	<description>
	  <para>
	    This function is very similar to EXSLT
	    <literal>dynamic:map</literal> function.  The description
	    below is almost literally taken from the <ulink url="http://www.exslt.org/dyn/functions/map/index.html">EXSLT
	    specification</ulink>.
	  </para>
	  <para>
	    The <literal>xsh:map</literal> function evaluates the 
	    expression passed as the second argument for each of 
	    the nodes passed as the first argument, and returns a 
	    node-set of those values. 
	  </para>
	  <para>
	    The expressions are evaluated relative to the nodes 
	    passed as the first argument. In other words, the value 
	    for each node is calculated by evaluating the XPath 
	    expression with all context information being the same as 
	    that for the call to the <literal>xsh:map</literal>
	    function itself, except for the following: 
	  </para>
	  <para>
	    1) the context node is the node whose value is being
	    calculated, 2) the context position is the position of the
	    node within the node set passed as the first argument to
	    the <literal>xsh:map</literal> function, arranged in
	    document order, and 3) the context size is the number of
	    nodes passed as the first argument to the dyn:map function.
	  </para>
	  <para>
	    If the expression string passed as the second argument is
	    an invalid XPath expression (including an empty string),
	    this function returns an empty node set.
	  </para>
	  <para>
	    If <literal>XPATH</literal> evaluates as a node set, the
	    <literal>xsh:map</literal> function returns the union of
	    the node sets returned by evaluating the expression for
	    each of the nodes in the first argument. Note that this
	    may mean that the node set resulting from the call to the
	    <literal>xsh:map</literal> function contains a different
	    number of nodes from the number in the node set passed as
	    the first argument to the function.
	  </para>
	  <para>
	    If <literal>XPATH</literal> evaluates as a number, the
	    <literal>xsh:map</literal> function returns a node set
	    containing one <literal>xsh:number</literal> element
	    (namespace
	    <literal>http://xsh.sourceforge.net/xsh/</literal>) for
	    each node in the node set passed as the first argument to
	    the dyn:map function, in document order. The string value
	    of each <literal>xsh:number</literal> element is the same
	    as the result of converting the number resulting from
	    evaluating the expression to a string as with the number
	    function, with the exception that Infinity results in an
	    <literal>xsh:number</literal> holding the highest number
	    the implementation can store, and -Infinity results in an
	    <literal>xsh:number</literal> holding the lowest number
	    the implementation can store.
	  </para>
	  <para>
	    If <literal>XPATH</literal> evaluates as a boolean, the
	    <literal>xsh:map</literal> function returns a node set
	    containing one <literal>xsh:boolean</literal> element
	    (namespace
	    <literal>http://xsh.sourceforge.net/xsh/</literal>) for
	    each node in the node set passed as the first argument to
	    the <literal>xsh:map</literal> function, in document
	    order. The string value of each
	    <literal>xsh:boolean</literal> element is
	    <literal>true</literal> if the expression evaluates as
	    true for the node, and is empty if the expression evaluates as
	    false.
	  </para>
	  <para>
	    Otherwise, the <literal>xsh:map</literal> function returns
	    a node set containing one <literal>xsh:string</literal>
	    element (namespace
	    <literal>http://xsh.sourceforge.net/xsh/</literal>) for
	    each node in the node set passed as the first argument to
	    the <literal>xsh:map</literal> function, in document
	    order. The string value of each
	    <literal>xsh:string</literal> element is the same as the
	    result of converting the result of evaluating the
	    expression for the relevant node to a string as with the
	    string function.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="evaluate_function" arguments=""/>
	</see-also>
      </documentation>
    </rule>
    <rule id="evaluate_function" type="function" name="xsh:evaluate" inline="no">
      <documentation>
	<usage>node-set xsh:evaluate(string XPATH)</usage>
	<description>
	  <para>
	    This function is very similar to EXSLT
	    <literal>dynamic:evaluate</literal> function.  The description
	    below is almost literally taken from the <ulink url="http://www.exslt.org/dyn/functions/map/index.html">EXSLT
	    specification</ulink>.
	  </para>
	  <para>
	    The <literal>xsh:evaluate</literal> function evaluates a string as an XPath expression
	    and returns the resulting value, which might be a boolean, number,
	    string, node set, result tree fragment or external object. The sole
	    argument is the string to be evaluated. 
	  </para>
	  <para>
	    The string is always evaluated exactly as if it had been literally
	    included in place of the call to the <literal>xsh:evaluate</literal> function.
	  </para>
	  <para>
	    In other words, the context information used when evaluating the
	    XPath expression passed as the argument to the <literal>xsh:evaluate</literal>
	    function is exactly the same as the context information used when
	    evaluating the <literal>xsh:evaluate</literal> function. This context information
	    includes: 
	  </para>
	  <enumerate>
	    <listitem>
	      <para>
		the context node, such that paths are evaluated relative to the
		context node at the point where the <literal>xsh:evaluate</literal> function is
		called
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		the context position, such that the expression can contain
		calls to the position function
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		the context size, such that the expression can contain calls to
		the last function
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		variable bindings, such that the expression can contain
		variable references
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		function library, such that the expression can contain calls to
		extension functions
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		namespace declarations, such that paths can contain prefixes
		the current node, such that the expression can contain calls to
		the current function
	      </para>
	    </listitem>
	  </enumerate>
	  <para>
	    If the expression string passed as the second argument is an
	    invalid XPath expression (including an empty string), this function
	    returns an empty node set. 
	  </para>
	  <para>
	    You should only use this function if the expression must be
	    constructed dynamically - otherwise it is much more efficient to
	    use the expression literally. For expressions that simply give an
	    element or attribute's name (to select a child element or
	    attribute), it is more efficient to use an expression 
	    in the style: 
	  </para>
	  <code>*[name() = $expression]</code>	      
	</description>
	<see-also>
	  <ruleref ref="map_function" arguments=""/>
	</see-also>
      </documentation>
    </rule>

    <rule id="split_function" type="function" name="xsh:split" inline="no">
      <documentation>
	<usage>node-set xsh:split(string PATTERN, string STRING)</usage>
	<description>
	  <para>
	    This function provides direct access to the very powerful
	    Perl function <literal>split</literal>. It splits
	    <literal>STRING</literal> to a list of
	    fields. <literal>PATTERN</literal> is a regular expression
	    specifying strings delimiting individual fields of
	    <literal>STRING</literal>. If <literal>PATTERN</literal>
	    is empty, <literal>STRING</literal> is split to individual
	    characters. If the regular expression in
	    <literal>PATTERN</literal> is enclosed in brackets, then
	    strings matching <literal>PATTERN</literal> are also
	    included in the resulting list.
	  </para>
	  <para>
	    The function returns a node-set consisting of
	    newly created <literal>&lt;xsh:string&gt;</literal>
	    elements containing individual strings of the resulting
	    list as their only text child nodes.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="times_function" type="function" name="xsh:times" inline="no">
      <documentation>
	<usage>node-set xsh:times(string STRING, float COUNT)</usage>
	<description>
	  <para>
	    This function returns a string
	    resulting from concatenation of <literal>COUNT</literal>
	    copies of <literal>STRING</literal>.
	    <literal>COUNT</literal> must be a non-negative integer value.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="id2_function" type="function" name="xsh:id2" inline="no">
      <documentation>
	<usage>node-set xsh:id2(node-set DOC, string IDs)</usage>
	<description>
	  <para>
	    This function is like XPath built-in <literal>id(IDs)</literal>
            function, except that it operates on the document
            specified in the first argument. It returns a node-set
            consisting of nodes that belong to the document DOC
            and whose ID belongs to the list of space separated
            IDs specified in the second argument.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="lookup_function" type="function" name="xsh:lookup" inline="no">
      <documentation>
	<usage>node-set xsh:lookup(string VARNAME, string KEY)</usage>
	<description>
	  <para>
	    This function is similar to XSLT <literal>key()</literal>
	    function. It returns a node-set
	    stored in a hash VARNAME under the key KEY.
	    The VARNAME must be a name of a lexical or global
	    XSH variable containing a Perl hash reference.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="hash_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="document_function" type="function" name="xsh:document" inline="no">
      <documentation>
	<usage>node-set xsh:document(string URL)</usage>
	<description>
	  <para>
	    Looks up among the currently open document the one whose
	    filename is same as the given URL and returns the
	    corresponding document node.  If no document's filename
	    matches exactly the given URL, then several heuristic
	    matches are tried: if the URI is a relative filename, it
	    is tilde-expanded and resolved (using the current working
	    directory as a base) and the lookup is restarted with the
	    absolute filename; finally, a lookup identifying filenames
	    with URLs of the file:// protocol is attempted.  If the
	    lookup fails completely, an empty node set is returned.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="hash_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="documents_function" type="function" name="xsh:documents" inline="no">
      <documentation>
	<usage>node-set xsh:documents()</usage>
	<description>
	  <para>
	    Returns a node-set consisting of the document
	    nodes of all currently open documents.
	  </para>
	</description>
	<see-also>
	  <ruleref ref="hash_command"/>
	</see-also>
      </documentation>
    </rule>
    <rule id="span_function" type="function" name="xsh:span" inline="no">
      <documentation>
	<usage>node-set xsh:span(node-set START,node-set END)</usage>
	<description>
	  <para>
	    Returns a node-set which forms a span of sibling nodes
	    starting at START node and ending at END node (only the first node
	    of each of the nodesets is used). It is an error if the START
	    node and END node are not siblings.
	  </para>
	</description>
      </documentation>
    </rule>
    <rule id="context_function" type="function" name="xsh:context" inline="no">
      <documentation>
	<usage>node-set xsh:context(node-set NODE, float BEFORE, float AFTER)</usage>
	<description>
	  <para>
	    Returns a node-set of sibling nodes surrounding NODE. The
	    span consists of (up to) BEFORE-many nodes immediately
	    preceding NODE, the NODE itself, and (up to) AFTER-many
	    nodes immediately following NODE.  If the AFTER is not
	    given, AFTER is set equal to BEFORE.
	  </para>
	</description>
      </documentation>
    </rule>

    <!-- CALL COMMAND SHOULD BE LAST ! -->
    <rule id="call_command" type="command" name="call" inline="no">
      <command minargs="1" func="call_command"/>
      <documentation sections="Flow">
	<usage>call <xref linkend="exp"/> [<xref linkend="exp"/> ...]</usage>
	<shortdesc>indirect call to a user-defined routine (macro)</shortdesc>
	<description>
	  <para>
	    Call a subroutine whose name is computed by evaluating
	    the first argument <xref linkend="exp"/>. All other
	    expressions are evaluated too and the results are passed
	    to the subroutine as arguments.
	  </para>
	  <para>
	    This command should only be used if the name of the subroutine
	    isn't known at the compile time. Otherwise it is recommended
	    to use a direct subroutine call of the form:
	  </para>
	  <code>subroutine-name [argument1 argument2 ...]</code>
	  <example>
	    <code>def a $arg { echo "A says" $arg }
	      def b $arg { echo "B says" $arg }
	      a "hallo!";  # call subroutine a
              b "hallo!";  # call subroutine b
	      call { chr(ord("a")+rand(2)) } "surprise!"; # call a or b randomly 
	    </code>
	  </example>
	</description>
	<see-also>
	  <ruleref ref="def" arguments=""/>
	  <ruleref ref="return_command" arguments=""/>
	</see-also>
      </documentation>
    </rule>
  </rules>  
</recdescent-xml>
<!-- Keep this comment at the end of the file
Local variables:
mode: xml
sgml-omittag:nil
sgml-shorttag:nil
sgml-namecase-general:nil
sgml-general-insert-case:lower
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-exposed-tags:nil
sgml-local-catalogs:("/usr/lib/sgml-tools/dtd/catalog /home/pajas/lib/sgml/iso-entities-8879.1986/iso-entities.cat /home/pajas/share/sgml/dtd/docbook/3.1/docbook.cat /home/pajas/share/sgml/stylesheets/docbook/catalog /home/pajas/share/sgml/entities/iso-entities-8879.1986/iso-entities.cat /home/pajas/share/sgml/dtd/jade/dsssl.cat /home/pajas/share/sgml/stylesheets/sgmltools/sgmltools.cat /home/pajas/share/sgml/dtd/sgmltools/catalog")
sgml-local-ecat-files:nil
End:
-->