Tangle Transform in Rexsel

This is the Tangle transform written in the Rexsel language (a compact version of XSLT). It is the primary source of the tangle filter transform that is currently used. If you need to write a new filter then I suggest that Rexsel is used.

tangle.rxsl
stylesheet { version "1.0" xmlns "aw" "http://www.hsfr.org.uk/Schema/AntWeave" output { method text version "1.0" encoding "UTF-8" omit-xml-declaration yes indent no } preserve-space "aw:code" // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* PARAMETERS -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* parameter rootChunk parameter startCommentString "'//'" parameter endCommentString "''" // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- CONSTANTS -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* constant NEW_LINE { text "
" } constant NON_BREAKING_SPACE { text "~" } constant SPACE { text " " } // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* TEMPLATES -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* match using "/" { foreach "//aw:chunk[(@name = '*' or @name = $rootChunk) and @type = 'code']" { variable rootName { choose { when "string-length($rootChunk) = 0" { value "'*'" } otherwise { value "$rootChunk" } } } variable firstChunkPosition "position()" call processCode { with isFirstChunk "$firstChunkPosition = 1" with chunkNode "." with name "$rootName" } } } // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // // Process a code chunk. // // - Parameters: // - isFirstChunk: (boolean) is this first chunk of code (used to inhbit first comment in XML files). // - chunkNode: (nodes) the current node chunk being processed (a list of code lines). // - string name: (string) the name of the current code chunk. // // - Returns: the raw code line to be output. proc processCode { parameter isFirstChunk parameter chunkNode parameter name foreach "$chunkNode" { if "not($isFirstChunk)" { value "concat( $startCommentString, ' File:', @file )" value "concat( ' Line:', @line )" value "concat( ' chunk:', $name )" value "concat( $endCommentString, $NEW_LINE )" } // For each of the code lines in this chunk. foreach "aw:code" { // For each of the tokens and separator elements in this line. foreach "*" { choose { when "name() = 'aw:include'" { // An include statement which defines a reference to another chunk which must be inserted here. variable chunkRef "@ref" // Recurse until all included lines are output. call processCode { // A set of nodes that are the named chunks. with chunkNode "//aw:chunk[@name = $chunkRef]" with name "$chunkRef" } } otherwise { // Ordinary text so just output it. value disable-output-escaping "." } } } value "$NEW_LINE" } } } // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* // // Soak up any remaining elements not processed by the above. match using "node() | @*" priority "-1" { } }