Text Transform
This translates the XML text primitives into HTML. The XML structure is one that is used throught this site and on other sites that I have
built. It is not necessary to know it, rather the code below is just for illustration.
text2xhtml.rxsl
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//
// Text to XHTML Transforms
//
// Author:
// Name : Hugh Field-Richards
// Email : hsfr@hsfr.org.uk
//
// Copyright 2025 Hugh Field-Richards.
//
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//
// This is the main XML to XHTML for the Paloose WEB site. It is written
// in Rexsel, a simplified and compact version of the XSLT language
// that is written in XML. The Rexsel code is translated at buils time
// from within a Ant script.
stylesheet {
version “1.0”
xmlns "page" "http://www.hsfr.org.uk/Schema/Page"
xmlns "graphic" "http://www.hsfr.org.uk/Schema/Graphic"
xmlns "list" "http://www.hsfr.org.uk/Schema/List"
xmlns "link" "http://www.hsfr.org.uk/Schema/Link"
xmlns "t" "http://www.hsfr.org.uk/Schema/Text"
xmlns "news" "http://www.hsfr.org.uk/Schema/News"
xmlns "email" "http://www.hsfr.org.uk/Schema/Email"
xmlns "form" "http://www.hsfr.org.uk/Schema/Form"
xmlns "table" "http://www.hsfr.org.uk/Schema/Table"
output {
encoding "UTF-8”
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//
// Paragraphs
match using "t:p" scope "inline-text" {
element "p" {
attribute "class" "normalPara"
apply-templates scope "inline-text"
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// News Text
match using "news:text" scope "inline-text" {
apply-templates scope "inline-text"
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Verbatim Text
match using "t:verbatim" scope "inline-text" {
element "div" {
attribute "class" "verbatimTable"
if "@title" {
element "div" {
attribute "class" "verbatimTitle"
value "@title"
}
}
element "div" {
attribute "class" "verbatimCode"
apply-templates scope "inline-text"
}
}
}
// Added Verbatim Text
match using "t:addition" scope "inline-text" {
element "span" {
attribute "class" "addition"
value "."
}
}
// Deleted Verbatim Text
match using "t:deletion" scope "inline-text" {
element "span" {
attribute "class" "deletion"
value "."
}
}
// Command Line Entry in Verbatim Text
match using "t:cmd" scope "inline-text" {
element "span" {
attribute "class" "commandEntry"
apply-templates scope "inline-text"
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Inline Code Text
match using "t:code" scope "inline-text" {
choose {
when "@type = 'dir'" {
element "span" {
attribute "class" "code-dir"
apply-templates scope "inline-text"
}
}
when "@type = 'var'" {
element "span" {
attribute "class" "code-var"
apply-templates scope "inline-text"
}
}
when "@type = 'tag'" {
element "span" {
attribute "class" "code-dir"
text "<"
apply-templates scope "inline-text"
text ">"
}
}
otherwise {
apply-templates scope "inline-text"
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Foreign Words Text
match using "t:foreignWord" scope "inline-text" {
element "span" {
attribute "class" "foreignWord"
apply-templates scope "inline-text"
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Headings
//
// Note that there will always be an id here generated from
// previous stages of the pipe.
match using "t:heading" scope "inline-text" {
element "div" {
attribute "class" {
text "heading-"
value "@level"
}
if "@id" {
element "a" {
attribute "name" {
value "@id"
}
}
}
apply-templates scope "inline-text"
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Inserted new line break
match using "t:newline" scope "inline-text" {
element "br" { }
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
match using "t:quote" scope "inline-text" {
choose {
when "@type = 'para'" {
element "div" {
attribute "class" "paraQuote"
text "\""
apply-templates scope "inline-text"
text "\""
}
element "div" {
attribute "class" "whoQuote"
choose {
when "@ref" {
element "a" {
attribute "href" {
value "@ref"
}
attribute "target" {
value "'quote'"
}
value "@who"
}
}
otherwise {
value "@who"
}
}
}
}
otherwise {
element "span" {
attribute "class" "charQuote"
apply-templates scope "inline-text"
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
match using "list:list" scope "inline-text" {
choose {
when "@type = 'ordered' or @type = 'numbered'" {
element "ol" {
apply-templates scope "inline-text"
}
}
when "@type = 'unordered'" {
element "ul" {
apply-templates scope "inline-text"
}
}
}
}
match using "list:item" scope "inline-text" {
element "li" {
attribute "class" "listItem"
apply-templates scope "inline-text"
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
match using "link:link" scope "inline-text" {
variable ref "@ref"
choose {
when "@type = 'uri'" {
element "a" {
attribute "href" {
value "$ref"
}
attribute "id" {
variable idString {
call common.substring-after-last {
with string "substring-after(@ref, '/')"
with delimiter "'/'"
}
}
value "substring-before($idString, '.')"
}
if "@target" {
attribute "target" {
value "@target"
}
}
if "@target = 'pop'" {
attribute "onclick" {
text "window.open('value \"$ref\"',"
value "$ref"
text "','width=500,height=600,top=200,left=200,resize=yes,scrollbars=yes');"
text "return false;"
}
}
choose {
when "." {
apply-templates scope "inline-text"
}
otherwise {
value "$ref"
}
}
}
}
when "@type = 'email'" {
element "a" {
attribute "href" {
text "mailto:"
value "$ref"
}
choose {
when "not(. = ‘’)" {
apply-templates scope "inline-text"
}
otherwise {
value "$ref"
}
}
}
}
when "@type = 'anchor'" {
element "a" {
attribute "name" {
value "@ref"
}
apply-templates scope "inline-text"
}
}
otherwise {
element "a" {
attribute "href" {
text "\#"
value "@ref"
}
apply-templates scope "inline-text"
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Typical XML In
// ==========================================================================
// <t:group img="keyboard.png" alt="keyboard" pos="right" >
// <t:p>...}
// }
// ==========================================================================
match using "t:group" scope "inline-text" {
element "div" {
attribute "id" {
value "@id"
}
choose {
when "@img" {
call outputGraphic {
with pos "@pos"
with ref "@img"
with alt "@alt"
}
apply-templates scope "inline-text"
element "br" {
attribute "clear" "all"
}
}
otherwise {
apply-templates scope "inline-text"
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
match using "graphic:graphic" scope "inline-text" {
element "div" {
attribute "class" "imgBox"
attribute "align" "center"
element "img" {
attribute "class" "imgBox"
attribute "src" {
value "@ref"
}
attribute "id" {
value "@id"
}
attribute "width" {
value "@width"
}
attribute "alt" {
choose {
when "string-length(.) > 0" {
value "."
}
otherwise {
value "@label"
}
}
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
proc outputGraphic {
parameter width // optional graphic width
parameter height // optional graphic height
parameter ref
parameter pos
parameter alt
parameter name
element "img" {
attribute "border" "0"
attribute "src" {
value "$ref"
}
if "$name" {
attribute "alt" {
value "$name"
}
}
if "$pos" {
attribute "align" {
value "$pos"
}
}
if "$alt" {
attribute "alt" {
value "$alt"
}
}
if "$width" {
attribute "width" {
value "$width"
}
}
if "$height" {
attribute "height" {
value "$height"
}
}
choose {
when "$pos = 'right'" {
attribute "id" {
value "'rightFlowGraphic'"
}
}
when "$pos = 'left'" {
attribute "id" {
value "'leftFlowGraphic'"
}
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Emphasized text.
//
// The span class is the degree prefixed to the "Emph" string. So
//
// <t:emph degree="weak">text</t:emph>
//
// would get translated to
//
// <span class="weakEmph">text</span>
match using "t:emph" scope "inline-text" {
choose {
when "@degree" {
element "span" {
attribute "class" {
value "concat(@degree, 'Emph')"
}
apply-templates scope "inline-text"
}
}
otherwise {
element "span" {
attribute "class" {
value "'normalEmph'"
}
apply-templates scope "inline-text"
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// Table text.
match using "table:table" scope "inline-text" {
element "div" {
attribute "class" "plainTable"
element "table" {
if "@id" {
attribute "id" {
value "@id"
}
}
if "@type" {
attribute "class" {
value "@type"
}
}
apply-templates scope "table-row"
}
}
}
match using "table:header" scope "table-row" {
element "tr" {
if "@id" {
attribute "id" {
value "@id"
}
}
apply-templates scope "table-header-column"
}
}
match using "table:row" scope "table-row" {
element "tr" {
if "@id" {
attribute "id" {
value "@id"
}
}
apply-templates scope "table-column"
}
}
match using "table:column" scope "table-header-column" {
element "th" {
if "@id" {
attribute "id" {
value "@id"
}
}
apply-templates scope "inline-text"
}
}
match using "table:column" scope "table-column" {
element "td" {
if "@id" {
attribute "id" {
value "@id"
}
}
apply-templates scope "inline-text"
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
//
// This needs expanding as necesary
match using "t:note" scope "inline-text" {
choose {
when "name(//t:note/parent::*) = 't:p'" {
choose {
when "@type = 'warning'" {
element "i" {
apply-templates scope "inline-text"
}
}
}
}
otherwise {
choose {
when "@type = 'warning'" {
element "div" {
attribute "class" "warningTitle"
text "Warning"
}
element "div" {
attribute "class" "warningNote"
apply-templates scope "inline-text"
}
}
when "@type = 'note'" {
element "div" {
attribute "class" "noteTitle"
text "Note"
}
element "div" {
attribute "class" "noteNote"
apply-templates scope "inline-text"
}
}
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
match using "form:form" scope "inline-text" {
element "form" {
attribute "method" "post"
attribute "action" {
value "normalize-space(form:start/@url)"
}
element "div" {
attribute "class" "normalPara"
foreach "form:field" {
call outputField
}
}
element "input" {
attribute "type" "submit"
attribute "value" {
value "form:start"
}
}
}
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// Output individual fields of the form
proc outputField {
value "."
text ": "
element "input" {
attribute "name" "@name"
attribute "type" "@type"
}
element "br" { }
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// Ignore all index markers
match using "t:index" scope "inline-text" {
}
// -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//
// Soak up any remaining elements not processed by the above
match using "node() | @*" priority "-1" scope "inline-text" {
copy {
apply-templates using "@*"
apply-templates
}
}
}
Copyright 2024 Hugh Field-Richards. All Rights Reserved.