{"id":20288600,"url":"https://github.com/rrthomas/ruth","last_synced_at":"2025-06-22T18:09:56.701Z","repository":{"id":40666163,"uuid":"379665512","full_name":"rrthomas/ruth","owner":"rrthomas","description":"Simple XML templating system","archived":false,"fork":false,"pushed_at":"2024-08-27T17:17:13.000Z","size":15232,"stargazers_count":4,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-21T22:35:22.278Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"XQuery","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rrthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"rrthomas","tidelift":"npm/@sc3d/ruth","custom":"https://rrt.sc3d.org"}},"created_at":"2021-06-23T16:26:57.000Z","updated_at":"2024-08-27T17:17:17.000Z","dependencies_parsed_at":"2024-02-08T12:26:24.791Z","dependency_job_id":"588daf5e-0470-48c5-b232-51b1d1fce0f4","html_url":"https://github.com/rrthomas/ruth","commit_stats":{"total_commits":668,"total_committers":2,"mean_commits":334.0,"dds":0.4356287425149701,"last_synced_commit":"738b4483acdb1aae2474429224c2c7c3194fbc4c"},"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"purl":"pkg:github/rrthomas/ruth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrthomas%2Fruth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrthomas%2Fruth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrthomas%2Fruth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrthomas%2Fruth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rrthomas","download_url":"https://codeload.github.com/rrthomas/ruth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rrthomas%2Fruth/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261338998,"owners_count":23143900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T14:48:23.853Z","updated_at":"2025-06-22T18:09:51.688Z","avatar_url":"https://github.com/rrthomas.png","language":"XQuery","funding_links":["https://github.com/sponsors/rrthomas","https://tidelift.com/funding/github/npm/@sc3d/ruth","https://rrt.sc3d.org"],"categories":[],"sub_categories":[],"readme":"# Ruth\n\n![logo](logo/ruth-small.png) _logo by Silvia Polverini_\n\n© 2002–2024 Reuben Thomas \u003crrt@sc3d.org\u003e  \n\u003chttps://github.com/rrthomas/ruth\u003e\n\nRuth is a simple [XQuery]-based XML templating system. Ruth reads a file or\ndirectory into an XML document; XML files become subdocuments. It then\nproduces a copy of the original file or directory, executing embedded XQuery\nqueries against the constructed XML document. Custom XQuery functions and\nexternal programs can be used.\n\n[XQuery]: https://www.w3.org/TR/xquery/\n\nRuth is free software, licensed under the GNU GPL version 3 (or, at your\noption, any later version), and written in TypeScript.\n\nRuth uses [fontoxpath] as its XQuery implementation. fontoxpath implements a\nsubset of [XQuery 3.1](https://www.w3.org/TR/xquery-31/).\n\n[fontoxpath]: https://www.npmjs.com/package/fontoxpath\n\nSee the [Cookbook](Cookbook.md) for examples.\n\nPlease send questions, comments, and bug reports to the maintainer, or\nreport them on the project’s web page (see above for addresses).\n\n## Installation\n\nInstall Ruth with npm (part of [Node](https://nodejs.org)):\n\n```\n$ npm install -g @sc3d/ruth\n```\n\n## API documentation\n\nRuth is mostly used via the `ruth` command, not least because of a\nlimitation of fontoxpath, which cannot easily be run more than once in the\nsame process. Nonetheless, Ruth provides some APIs which are documented in\n[docs/index.html](https://rrthomas.github.io/ruth/).\n\n## Invocation\n\n```\nruth [-h] [--path PATH] [--ext .EXT] [--version]\n           INPUT-PATH OUTPUT-DIRECTORY\n\nA simple templating system.\n\npositional arguments:\n  INPUT-PATH        desired directory list to build\n  OUTPUT-DIRECTORY  output directory\n\noptional arguments:\n  -h, --help        show this help message and exit\n  --path PATH       relative path to build [default: input directory]\n  --ext .EXT        treat files with extension .EXT as XML\n  --version         show program's version number and exit\n\nThe INPUT-PATH is a ':'-separated list of directories; the directories\nare merged, with the contents of each directory taking precedence over any\ndirectories to its right.\n```\n\n## Operation \u003ca name=\"operation\"\u003e\u003c/a\u003e\n\nRuth starts by combining the list of directories given as its _input path_.\nIf the same file or directory exists in more than one of the directories on\nthe input path, the left-most takes precedence. The result is called the\n“input tree”, and all paths are relative to it.\n\nThe input tree is read into an XML document in the ‘dirtree’ language, a\nsimple XML language for representing directory trees. Each element is either\na `directory` or a `file`. A `directory` contains further `directory` and\n`file` elements, while a `file` contains arbitrary XML, or character data\n(if the file in question is not XML). Each `directory` and `file` node has\ntwo attributes: `name`, which is the file or directory name, and `path`,\nwhich is the full file system path of the original file or directory,\nincluding its name. See `dirtree.dtd` for more information.\n\nRuth then creates the output directory if it does not already exist.\n\nNext, Ruth traverses the input tree, or the subtree given by the `--path`\nargument, if any, in breadth-first order.\n\nFor each file, Ruth looks at its name, and:\n\n- If the name contains the suffix `.ruth`, optionally followed by decimal\n  digits, the file is added to the list of files to process. The decimal\n  digits are the phase number, which defaults to zero. The files are\n  processed in phase order: any phase 0 files first, then phase 1, and so\n  on.\n- If the name contains the suffix `.in`, the file is skipped. (It may\n  be used by macros in other files.)\n- Otherwise, the file is added to the list of files to process in phase 0.\n\nThe list of files to process is then processed, in order. For each file:\n\n- If the name contains the suffix `.ruth`, the file’s contents is expanded\n  (see below), and if the name does not contain the suffix `.in` the result\n  is then written to a file of the same name, but with the `.ruth` suffix\n  removed, in the corresponding place in the output directory. The working\n  XML document is also updated with the result.\n- Otherwise, the file is copied verbatim to the corresponding place in the\n  output directory.\n\nThe special suffixes need not end the file name; they can be used as infixes\nbefore the file type suffix.\n\n### Template expansion\n\nRuth expands a template file as follows by executing it as an XQuery\nexpression.\n\nThe use of XQuery is beyond the scope of this manual; see the\n[XQuery specification][XQuery] and [fontoxpath documentation][fontoxpath]\nfor more details.\n\nRuth provides the following built-in custom functions:\n\n- `ruth:eval($query as xs:string) as node()*`: evaluates the XQuery\n  expression `$query`, and returns the first matching node, or, if there is\n  none, raises an error.\n- `ruth:map($query as xs:string, $transformQuery as xs:string, $nodes as node()*) as node()*`:\n  evaluates the XQuery expression `$query` on a copy of `$nodes`, then for\n  each node in the result set, replaces it by the value of the XQuery\n  expression `$transformQuery` applied to it. Returns the updated copy of\n  `$nodes`.\n- `ruth:real-path($relPath as xs:string) as xs:string` returns the file\n  system path of the file given by `$relPath`, a path relative to the\n  current file. If `$relPath` does not correspond to a file, an error is\n  raised. This function cannot be used for directories, because a directory\n  in the input path may represent more than one file system path.\n\nRuth also supplies a version of the\n[FunctX](http://www.xqueryfunctions.com/) function library, without the\nfunctions that fontoxpath does not support.\n\nRuth also loads other XQuery functions from `lib/ruth.xq`. See that file for\ndocumentation.\n\nSee the [website example](Cookbook.md#website-example) in the Cookbook for a\nworked example of using Ruth to template a website.\n\n### Running other programs\n\nAn executable file in the input is turned into a pair of XQuery functions in\nthe `ruth` namespace. Any `.in` suffix is stripped out. So for example,\n`foo.in` becomes a function `ruth:foo()`. The functions have the following\nsignature:\n\n```\nruth:foo($args as xs:string*) as xs:string\nruth:foo($args as xs:string*, $input as xs:string) as xs:string\n```\n\nThe sequence `$args` is passed to the program as its command-line arguments.\nThe string `$input` is fed to the program’s standard input.\n\n## Development\n\nCheck out the git repository and download dependencies with:\n\n```\ngit clone https://github.com/rrthomas/ruth\nnpm install\n```\n\nTo run the tests:\n\n```\nnpm test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frrthomas%2Fruth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frrthomas%2Fruth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frrthomas%2Fruth/lists"}