Simple XML templating system
npm install @sc3d/ruth!logo _logo by Silvia Polverini_
© 2002–2022 Reuben Thomas
Ruth is a simple [XQuery]-based XML templating system, based on the plain
text-oriented [Nancy]. Ruth reads a file or directory into an XML document;
XML files become subdocuments. It then produces a copy of the original file
or directory, executing embedded XQuery queries against the constructed XML
document. Custom XQuery functions and external programs can be used.
[XQuery]: https://www.w3.org/TR/xquery/
[Nancy]: https://github.com/rrthomas/nancy
Ruth is free software, licensed under the GNU GPL version 3 (or, at your
option, any later version), and written in TypeScript.
Ruth uses [fontoxpath] as its XQuery implementation. fontoxpath implements a
subset of XQuery 3.1.
[fontoxpath]: https://www.npmjs.com/package/fontoxpath
See the Cookbook for examples.
Please send questions, comments, and bug reports to the maintainer, or
report them on the project’s web page (see above for addresses).
Install Ruth with npm (part of Node):
```
$ npm install -g @sc3d/ruth
Ruth is mostly used via the ruth command, not least because of a
limitation of fontoxpath, which cannot easily be run more than once in the
same process. Nonetheless, Ruth provides some APIs which are documented in
docs/index.html.
``
{/bin/sh,-c,./bin/run.js --help | sed -e 's/usage: run.js/ruth/' -e 's/^ //g'}
Ruth starts by combining the list of directories given as its _input path_.
If the same file or directory exists in more than one of the directories on
the input path, the left-most takes precedence. The result is called the
“input tree”, and all paths are relative to it.
Ruth then creates the output directory if it does not already exist.
Next, Ruth traverses the input tree, or the subtree given by the --path
argument, if any, in breadth-first order.
For each file, Ruth looks at its name, and:
- If the name contains the suffix .ruth, optionally followed by decimal.in
digits, the file is added to the list of files to process. The decimal
digits are the phase number, which defaults to zero. The files are
processed in phase order: any phase 0 files first, then phase 1, and so
on.
- If the name contains the suffix , the file is skipped. (It may
be used by macros in other files.)
- Otherwise, the file is added to the list of files to process in phase 0.
The list of files to process is then processed, in order. For each file:
- If the name contains the suffix .ruth, the file’s contents is expanded.in
(see below), and if the name does not contain the suffix the result.ruth
is then written to a file of the same name, but with the suffix
removed, in the corresponding place in the output directory. The working
XML document is also updated with the result.
- Otherwise, the file is copied verbatim to the corresponding place in the
output directory.
The special suffixes need not end the file name; they can be used as infixes
before the file type suffix.
Ruth expands a template file as follows by executing it as an XQuery
expression.
The use of XQuery is beyond the scope of this manual; see the
[XQuery specification][XQuery] and [fontoxpath documentation][fontoxpath]
for more details.
Ruth provides some built-in global variables:
- $ruth:root: the INPUT-PATH argument.$ruth_path
- : the relative path from $ruth:root to the file currently$ruth_element
being expanded.
- : the element in Ruth's working XML document corresponding
to the file currently being expanded.
Ruth provides the following built-in custom functions:
- ruth:eval($query as xs:string) as node()*: evaluates the XQuery$query
expression , and returns the first matching node, or, if there isruth:real-path($relPath as xs:string) as xs:string
none, raises an error.
- returns the file$relPath
system path of the file given by . If $relPath does not
correspond to a file, an error is raised. Note in particular that a
directory does not necessarily correspond to a single file system path.
Ruth also supplies a version of the
FunctX function library, without the
functions that fontoxpath does not support.
Ruth also loads other XQuery functions from lib/ruth.xq. See that file for
documentation.
See the website example in the Cookbook for a
worked example of using Ruth to template a website.
An executable file in the input is turned into a pair of XQuery functions in
the ruth namespace. Any .in suffix is stripped out. So for example,foo.in becomes a function ruth:foo(). The functions have the following
signature:
``
ruth:foo($args as xs:string*) as xs:string
ruth:foo($args as xs:string*, $input as xs:string) as xs:string
The sequence $args is passed to the program as its command-line arguments.$input
The string is fed to the program's standard input.
Check out the git repository and download dependencies with:
``
git clone https://github.com/rrthomas/ruth
npm install
To run the tests:
```
npm test