X-Git-Url: https://git.ladys.computer/LesML/blobdiff_plain/ae0c7e317f7c586a1771dc5f2764a904970da3d2..94f395fe0062092ce69390b661f8543a3fbf5b7b:/parser.xslt diff --git a/parser.xslt b/parser.xslt index f1ade04..6e0d82a 100644 --- a/parser.xslt +++ b/parser.xslt @@ -1,18 +1,20 @@ <?xml version="1.0"?> <!-- -SPDX-FileCopyrightText: 2024 Lady <https://www.ladys.computer/about/#lady> +SPDX-FileCopyrightText: 2024, 2025 Lady <https://www.ladys.computer/about/#lady> SPDX-License-Identifier: MPL-2.0 --> <!-- ⁌ 💄📝 Les·M·L ∷ parser.xslt -© 2024 Lady [@ Lady’s Computer] +© 2024–2025 Lady [@ Ladys Computer] This Source Code Form is subject to the terms of the Mozilla Public License, v 2.0. If a copy of the M·P·L was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0/>. --> <!DOCTYPE transform [ - <!ENTITY section-break '#*-.=_~·․‥…⁂⋯─━┄┅┈┉╌╍═╴╶╸╺☙❧ ・*-.=_~'> + <!ENTITY section-break "*-.=_~·․‥…⁂⋯─━┄┅┈┉╌╍═╴╶╸╺☙❧ ・*-.=_~"> + <!ENTITY sigiled-text "(string-length($text)=1 or substring($text, 2, 1)=' ')"> + <!ENTITY unsigiled-text "substring($text, 3, string-length($text)-2)"> ]> <transform xmlns="http://www.w3.org/1999/XSL/Transform" @@ -46,14 +48,32 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one </otherwise> </choose> </template> + <template name="LesML:break-and-unescape"> + <param name="source"/> + <variable name="broken-fragment"> + <call-template name="LesML:split"> + <with-param name="source" select="$source"/> + <with-param name="separator" select="'
'"/> + </call-template> + </variable> + <variable name="broken" select="exsl:node-set($broken-fragment)/node()"/> + <for-each select="$broken"> + <call-template name="LesML:unescape"> + <with-param name="source" select="string()"/> + </call-template> + <if test="position()!=count($broken)"> + <element name="html:br"/> + </if> + </for-each> + </template> <template name="LesML:unescape"> <param name="source"/> <choose> - <when test="contains($source, '<U+')"> - <variable name="after" select="substring-after($source, '<U+')"/> + <when test="contains($source, '{U+')"> + <variable name="after" select="substring-after($source, '{U+')"/> <choose> - <when test="contains($after, '>')"> - <variable name="inner" select="substring-before($after, '>')"/> + <when test="contains($after, '}')"> + <variable name="inner" select="substring-before($after, '}')"/> <variable name="components"> <call-template name="LesML:split"> <with-param name="source" select="$inner"/> @@ -61,14 +81,14 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one </call-template> </variable> <variable name="component-nodes" select="exsl:node-set($components)/node()"/> + <value-of select="substring-before($source, '{U+')"/> <choose> <when test="$component-nodes[string(.)='' or translate(., '0123456789ABCDEF', '')!='']"> - <value-of select="substring-before($source, '<U+')"/> - <text><U+</text> + <text>{U+</text> <value-of select="$inner"/> - <text>></text> + <text>}</text> <call-template name="LesML:unescape"> - <with-param name="source" select="substring-after($after, '>')"/> + <with-param name="source" select="substring-after($after, '}')"/> </call-template> </when> <otherwise> @@ -78,14 +98,14 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <text>;</text> </for-each> <call-template name="LesML:unescape"> - <with-param name="source" select="substring-after($after, '>')"/> + <with-param name="source" select="substring-after($after, '}')"/> </call-template> </otherwise> </choose> </when> <otherwise> - <value-of select="substring-before($source, '<U+')"/> - <text><U+</text> + <value-of select="substring-before($source, '{U+')"/> + <text>{U+</text> <call-template name="LesML:unescape"> <with-param name="source" select="$after"/> </call-template> @@ -103,9 +123,12 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <when test="starts-with($source, '¶')"> <choose> <when test="contains($source, ' ')"> - <attribute name="id"> - <value-of select="substring-before(substring-after($source, '¶'), ' ')"/> - </attribute> + <variable name="id" select="substring-before(substring-after($source, '¶'), ' ')"/> + <if test="$id!=''"> + <attribute name="id"> + <value-of select="$id"/> + </attribute> + </if> <value-of select="substring-after($source, ' ')"/> </when> <otherwise> @@ -129,7 +152,6 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <value-of select="$first-line"/> </if> </variable> - <variable name="noshebang" select="$lines[position()>1 or not(starts-with(., '#!lesml') or starts-with(., '##'))]"/> <variable name="params-string"> <choose> <when test="starts-with($shebang, '#!lesml@')"> @@ -141,120 +163,157 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one </choose> </variable> <variable name="params-fragment"> - <html:dl> - <if test="starts-with($shebang, '#!lesml@') and contains($shebang, '$')"> - <html:div> - <html:dt> - <text> LANG </text> - </html:dt> - <html:dd> - <value-of select="substring-before(substring-after($shebang, '#!lesml@'), '$')"/> - </html:dd> - </html:div> - </if> - <for-each select="exslstr:tokenize($params-string)"> - <choose> - <when test="contains(., '=')"> + <choose> + <when test="$shebang!=''"> + <html:dl> + <if test="starts-with($shebang, '#!lesml@') and contains($shebang, '$')"> <html:div> <html:dt> - <value-of select="substring-before(., '=')"/> + <text> LANG </text> </html:dt> <html:dd> - <value-of select="substring-after(., '=')"/> + <value-of select="substring-before(substring-after($shebang, '#!lesml@'), '$')"/> </html:dd> </html:div> - </when> - <otherwise> - <html:div> - <html:dt> - <value-of select="."/> - </html:dt> - <html:dd/> - </html:div> - </otherwise> - </choose> - </for-each> - </html:dl> + </if> + <for-each select="exslstr:tokenize($params-string)"> + <choose> + <when test="contains(., '=')"> + <html:div> + <html:dt> + <value-of select="substring-before(., '=')"/> + </html:dt> + <html:dd> + <value-of select="substring-after(., '=')"/> + </html:dd> + </html:div> + </when> + <otherwise> + <html:div> + <html:dt> + <value-of select="."/> + </html:dt> + <html:dd/> + </html:div> + </otherwise> + </choose> + </for-each> + </html:dl> + </when> + <when test="$parent-params"> + <copy-of select="$parent-params"/> + </when> + <otherwise> + <html:dl/> + </otherwise> + </choose> </variable> <variable name="params" select="exsl:node-set($params-fragment)/*"/> - <variable name="record-separators" select="$noshebang[starts-with(., '%%')]"/> - <html:article> - <for-each select="$params/html:div/html:dt[string()=' LANG ']"> - <attribute name="lang"> - <value-of select="following-sibling::html:dd"/> - </attribute> - <attribute name="xml:lang"> - <value-of select="following-sibling::html:dd"/> - </attribute> - </for-each> - <for-each select="$params/html:div/html:dt[string()='profile']"> - <attribute name="data-lesml-profile"> - <value-of select="following-sibling::html:dd"/> - </attribute> - </for-each> - <if test="count($record-separators)>1"> - <html:footer class="head"> - <for-each select="$record-separators"> - <variable name="position" select="position()"/> - <variable name="prev-separator" select="$record-separators[($position)-1]"/> - <variable name="fields" select="$noshebang[following-sibling::*[generate-id()=generate-id(current())] and (not($prev-separator) or preceding-sibling::*[generate-id()=generate-id($prev-separator)])]"/> - <if test="$fields"> - <html:dl> - <for-each select="$fields"> - <choose> - <when test="starts-with(., ' ') and $fields[generate-id()=generate-id(current()/preceding-sibling::*[1])]"/> - <otherwise> - <variable name="next" select="following-sibling::*[not(starts-with(., ' '))]"/> - <html:div> - <html:dt> - <value-of select="normalize-space(substring-before(., ':'))"/> - </html:dt> - <html:dd> - <variable name="firstline"> - <choose> - <when test="contains(., ':')"> - <value-of select="normalize-space(substring-after(., ':'))"/> - </when> - <otherwise> - <value-of select="normalize-space(.)"/> - </otherwise> - </choose> - </variable> - <choose> - <when test="substring($firstline, string-length($firstline))='\' and following-sibling::*[position()=1 and starts-with(., ' ')]"> - <value-of select="substring($firstline, 1, string-length($firstline)-1)"/> - </when> - <otherwise> - <value-of select="$firstline"/> - </otherwise> - </choose> - <for-each select="following-sibling::*[starts-with(., ' ') and not(preceding-sibling::*[generate-id()=generate-id($next)])]"> - <variable name="nextline" select="normalize-space(.)"/> + <variable name="noshebang" select="$lines[position()>1 or not(starts-with(., '#!lesml') or starts-with(., '##'))]"/> + <variable name="docsep" select="$noshebang[starts-with(., '#!lesml') or starts-with(., '##')][1]"/> + <variable name="doclines" select="$noshebang[not($docsep) or following-sibling::*[generate-id()=generate-id($docsep)]]"/> + <if test="starts-with($first-line, '##') and $first-line!='##'"> + <comment> + <value-of select="substring-after($first-line, '##')"/> + </comment> + </if> + <if test="$shebang!='' or $doclines[normalize-space()!='']"> + <variable name="record-separators" select="$doclines[starts-with(., '%%')]"/> + <element name="html:article"> + <for-each select="$params/html:div/html:dt[string()=' LANG ']"> + <attribute name="lang"> + <value-of select="following-sibling::html:dd"/> + </attribute> + <attribute name="xml:lang"> + <value-of select="following-sibling::html:dd"/> + </attribute> + </for-each> + <for-each select="$params/html:div/html:dt[string()='profile']"> + <attribute name="data-lesml-profile"> + <value-of select="following-sibling::html:dd"/> + </attribute> + </for-each> + <if test="$record-separators[preceding-sibling::*[normalize-space()!='']]"> + <element name="html:footer"> + <attribute name="class"> + <text>head</text> + </attribute> + <for-each select="$record-separators"> + <variable name="position" select="position()"/> + <variable name="prev-separator" select="$record-separators[($position)-1]"/> + <variable name="fields" select="$noshebang[following-sibling::*[generate-id()=generate-id(current())] and (not($prev-separator) or preceding-sibling::*[generate-id()=generate-id($prev-separator)])]"/> + <if test="$fields"> + <element name="html:dl"> + <for-each select="$fields"> + <choose> + <when test="starts-with(., ' ') and $fields[generate-id()=generate-id(current()/preceding-sibling::*[1])]"/> + <otherwise> + <variable name="next" select="following-sibling::*[not(starts-with(., ' '))]"/> + <element name="html:div"> + <element name="html:dt"> + <value-of select="normalize-space(substring-before(., ':'))"/> + </element> + <element name="html:dd"> + <variable name="firstline"> + <choose> + <when test="contains(., ':')"> + <value-of select="normalize-space(substring-after(., ':'))"/> + </when> + <otherwise> + <value-of select="normalize-space(.)"/> + </otherwise> + </choose> + </variable> <choose> - <when test="substring($nextline, string-length($nextline))='\' and following-sibling::*[position()=1 and starts-with(., ' ')]"> - <value-of select="substring($nextline, 1, string-length($nextline)-1)"/> + <when test="substring($firstline, string-length($firstline))='\' and following-sibling::*[position()=1 and starts-with(., ' ')]"> + <value-of select="substring($firstline, 1, string-length($firstline)-1)"/> </when> <otherwise> - <value-of select="$nextline"/> + <value-of select="$firstline"/> </otherwise> </choose> - </for-each> - </html:dd> - </html:div> - </otherwise> - </choose> - </for-each> - </html:dl> - </if> - </for-each> - </html:footer> - </if> - <html:div class="body"> - <call-template name="LesML:paragraphize"> - <with-param name="lines" select="$noshebang[not($record-separators) or preceding-sibling::*[generate-id()=generate-id($record-separators[last()])]]"/> - </call-template> - </html:div> - </html:article> + <for-each select="following-sibling::*[starts-with(., ' ') and not(preceding-sibling::*[generate-id()=generate-id($next)])]"> + <variable name="nextline" select="normalize-space(.)"/> + <choose> + <when test="substring($nextline, string-length($nextline))='\' and following-sibling::*[position()=1 and starts-with(., ' ')]"> + <value-of select="substring($nextline, 1, string-length($nextline)-1)"/> + </when> + <otherwise> + <value-of select="$nextline"/> + </otherwise> + </choose> + </for-each> + </element> + </element> + </otherwise> + </choose> + </for-each> + </element> + </if> + <if test=".!='%%'"> + <comment> + <value-of select="substring-after(., '%%')"/> + </comment> + </if> + </for-each> + </element> + </if> + <element name="html:div"> + <attribute name="class"> + <text>body</text> + </attribute> + <call-template name="LesML:paragraphize"> + <with-param name="lines" select="$doclines[not($record-separators) or preceding-sibling::*[generate-id()=generate-id($record-separators[last()])]]"/> + </call-template> + </element> + </element> + </if> + <if test="$docsep"> + <call-template name="LesML:parse"> + <with-param name="lines" select="$docsep|$lines[preceding-sibling::*[generate-id()=generate-id($docsep)]]"/> + <with-param name="parent-params" select="$params"/> + </call-template> + </if> </template> <template name="LesML:paragraphize"> <param name="lines" select="/.."/> @@ -265,188 +324,296 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <variable name="prev-last" select="$last-lines[($position)-1]"/> <variable name="linespans" select="$lines[following-sibling::*[generate-id()=generate-id(current())] and (not($prev-last) or preceding-sibling::*[generate-id()=generate-id($prev-last)]) and normalize-space()!='']|."/> <variable name="quoted" select="not($linespans[not(starts-with(., ' ') or starts-with(., '	'))])"/> + <variable name="preformatted" select="not($linespans[not(starts-with(normalize-space(), '|'))])"/> <variable name="text"> <for-each select="$linespans"> - <value-of select="normalize-space()"/> + <choose> + <when test="$preformatted"> + <value-of select="substring-after(., '|')"/> + </when> + <otherwise> + <value-of select="normalize-space()"/> + </otherwise> + </choose> <if test="position()!=count($linespans)"> - <text> </text> + <choose> + <when test="$preformatted"> + <text>
</text> + </when> + <otherwise> + <text> </text> + </otherwise> + </choose> </if> </for-each> </variable> <if test="string($text)!=''"> <variable name="par"> <choose> - <when test="starts-with($text, '⁌ ')"> - <html:h1> + <when test="$preformatted"> + <element name="html:pre"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '⁌ ')"/> + <with-param name="source" select="$text"/> + </call-template> + </element> + </when> + <when test="starts-with($text, '⁌') and &sigiled-text;"> + <element name="html:h1"> + <call-template name="LesML:id-and-contents"> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:h1> + </element> </when> - <when test="starts-with($text, '§ ')"> - <html:h2> + <when test="starts-with($text, '§') and &sigiled-text;"> + <element name="html:h2"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '§ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:h2> + </element> </when> - <when test="starts-with($text, '❦ ')"> - <html:h3> + <when test="starts-with($text, '❦') and &sigiled-text;"> + <element name="html:h3"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '❦ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:h3> + </element> </when> - <when test="starts-with($text, '✠ ')"> - <html:h4> + <when test="starts-with($text, '✠') and &sigiled-text;"> + <element name="html:h4"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '✠ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:h4> + </element> </when> - <when test="starts-with($text, '• ')"> - <html:li class="unordered" data-level="1"> - <html:p> + <when test="starts-with($text, '•') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>unordered</text> + </attribute> + <attribute name="data-level"> + <text>1</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '• ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '🔢 ')"> - <html:li class="ordered" data-level="1"> - <html:p> + <when test="starts-with($text, '🔢') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>ordered</text> + </attribute> + <attribute name="data-level"> + <text>1</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '🔢 ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '◦ ')"> - <html:li class="unordered" data-level="2"> - <html:p> + <when test="starts-with($text, '◦') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>unordered</text> + </attribute> + <attribute name="data-level"> + <text>2</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '◦ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '🔠 ')"> - <html:li class="ordered" data-level="2"> - <html:p> + <when test="starts-with($text, '🔠') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>ordered</text> + </attribute> + <attribute name="data-level"> + <text>2</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '🔠 ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '▪ ')"> - <html:li class="unordered" data-level="3"> - <html:p> + <when test="starts-with($text, '▪') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>unordered</text> + </attribute> + <attribute name="data-level"> + <text>3</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '▪ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '🔡 ')"> - <html:li class="ordered" data-level="3"> - <html:p> + <when test="starts-with($text, '🔡') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>ordered</text> + </attribute> + <attribute name="data-level"> + <text>3</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '🔡 ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '⁃ ')"> - <html:li class="unordered" data-level="4"> - <html:p> + <when test="starts-with($text, '⁃') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>unordered</text> + </attribute> + <attribute name="data-level"> + <text>4</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '⁃ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '🔣 ')"> - <html:li class="ordered" data-level="4"> - <html:p> + <when test="starts-with($text, '🔣') and &sigiled-text;"> + <element name="html:li"> + <attribute name="class"> + <text>ordered</text> + </attribute> + <attribute name="data-level"> + <text>4</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '🔣 ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:li> + </element> + </element> </when> - <when test="starts-with($text, '🛈 ')"> - <html:div role="note" class="info"> - <html:p> + <when test="starts-with($text, '🛈') and &sigiled-text;"> + <element name="html:div"> + <attribute name="role"> + <text>note</text> + </attribute> + <attribute name="class"> + <text>info</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '🛈 ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:div> + </element> + </element> </when> - <when test="starts-with($text, '⯑ ')"> - <html:div role="note" class="query"> - <html:p> + <when test="starts-with($text, '⯑') and &sigiled-text;"> + <element name="html:div"> + <attribute name="role"> + <text>note</text> + </attribute> + <attribute name="class"> + <text>query</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '⯑ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:div> + </element> + </element> </when> - <when test="starts-with($text, '⚠︎ ')"> - <html:div role="note" class="warn"> - <html:p> + <when test="starts-with($text, '⚠︎') and &sigiled-text;"> + <element name="html:div"> + <attribute name="role"> + <text>note</text> + </attribute> + <attribute name="class"> + <text>warn</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '⚠︎ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:div> + </element> + </element> </when> - <when test="starts-with($text, '※ ')"> - <html:div role="note" class="note"> - <html:p> + <when test="starts-with($text, '※') and &sigiled-text;"> + <element name="html:div"> + <attribute name="role"> + <text>note</text> + </attribute> + <attribute name="class"> + <text>note</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '※ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:div> + </element> + </element> </when> - <when test="starts-with($text, '☡ ')"> - <html:div role="note" class="caution"> - <html:p> + <when test="starts-with($text, '☡') and &sigiled-text;"> + <element name="html:div"> + <attribute name="role"> + <text>note</text> + </attribute> + <attribute name="class"> + <text>caution</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '☡ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:div> + </element> + </element> </when> - <when test="starts-with($text, '⋯ ')"> - <html:div class="continuation"> - <html:p> + <when test="starts-with($text, '⋯') and &sigiled-text;"> + <element name="html:div"> + <attribute name="class"> + <text>continuation</text> + </attribute> + <element name="html:p"> <call-template name="LesML:id-and-contents"> - <with-param name="source" select="substring-after($text, '⋯ ')"/> + <with-param name="source" select="&unsigiled-text;"/> </call-template> - </html:p> - </html:div> + </element> + </element> + </when> + <when test="starts-with($text, '#') and &sigiled-text;"> + <comment> + <value-of select="&unsigiled-text;"/> + </comment> </when> <otherwise> - <html:p> + <element name="html:p"> <call-template name="LesML:id-and-contents"> <with-param name="source" select="$text"/> </call-template> - </html:p> + </element> </otherwise> </choose> </variable> <choose> <when test="translate(string($text), '§ion-break; ', '')=''"> - <html:hr/> + <element name="html:hr"/> </when> <when test="$quoted"> - <html:blockquote> + <element name="html:blockquote"> <copy-of select="$par"/> - </html:blockquote> + </element> </when> <otherwise> <copy-of select="$par"/> @@ -474,16 +641,6 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <with-param name="lines" select="exsl:node-set($lines-fragment)/*"/> </call-template> </template> - <template match="@*|node()" mode="LesML:finalize-tree" priority="-1"> - <copy> - <apply-templates select="@*|node()" mode="LesML:finalize-tree"/> - </copy> - </template> - <template match="text()" mode="LesML:finalize-tree"> - <call-template name="LesML:unescape"> - <with-param name="source" select="string(.)"/> - </call-template> - </template> <template match="html:blockquote" mode="LesML:finalize-tree"> <if test="not(preceding-sibling::node()) or preceding-sibling::node()[position()=1 and not(self::html:blockquote)]"> <variable name="notquote" select="following-sibling::node()[not(self::html:blockquote)][1]"/> @@ -502,18 +659,18 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <value-of select="substring-after($laststarttext, '— ')"/> <copy-of select="$laststarttext/following-sibling::node()"/> </variable> - <html:figure> + <element name="html:figure"> <copy> <apply-templates select="@*|$content-nodes[position()!=last()]" mode="LesML:finalize-tree"/> </copy> - <html:figcaption> + <element name="html:figcaption"> <for-each select="$content-nodes[last()]"> <copy> <apply-templates select="@*|exsl:node-set($caption)/node()" mode="LesML:finalize-tree"/> </copy> </for-each> - </html:figcaption> - </html:figure> + </element> + </element> </when> <otherwise> <copy> @@ -576,6 +733,19 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one </apply-templates> </if> </template> + <template match="processing-instruction()[local-name()='LesML-Link-Escape']" mode="LesML:finalize-tree"> + <text>🔗</text> + </template> + <template match="text()" mode="LesML:finalize-tree"> + <call-template name="LesML:break-and-unescape"> + <with-param name="source" select="string(.)"/> + </call-template> + </template> + <template match="@*|node()" mode="LesML:finalize-tree" priority="-1"> + <copy> + <apply-templates select="@*|node()" mode="LesML:finalize-tree"/> + </copy> + </template> <template match="node()" mode="LesML:inline"> <param name="element-name"/> <param name="element-namespace" select="'http://www.w3.org/1999/xhtml'"/> @@ -585,88 +755,85 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <param name="langtag-supported" select="false()"/> <choose> <when test="self::*"> - <copy> - <copy-of select="@*"/> - <variable name="start-node" select="text()[contains(., $start-sigil)][1]"/> - <choose> - <when test="$start-node"> - <variable name="remaining"> - <value-of select="substring-after($start-node, $start-sigil)"/> - <copy-of select="$start-node/following-sibling::node()"/> - </variable> - <variable name="end-node" select="exsl:node-set($remaining)/node()[self::text() and contains(., $end-sigil)][1]"/> - <choose> - <when test="$end-node"> - <variable name="restoftext" select="substring-after($end-node, $end-sigil)"/> - <variable name="maybe-langtag"> - <if test="$langtag-supported and starts-with($restoftext, '@') and contains($restoftext, '$')"> - <value-of select="substring-before(substring-after($restoftext, '@'), '$')"/> - </if> - </variable> - <variable name="langtag"> - <if test="translate($maybe-langtag, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-', '')=''"> - <value-of select="$maybe-langtag"/> - </if> - </variable> - <variable name="rest"> - <html:div> - <choose> - <when test="string($langtag)!=''"> - <value-of select="substring-after($restoftext, '$')"/> - </when> - <otherwise> - <value-of select="$restoftext"/> - </otherwise> - </choose> - <copy-of select="$end-node/following-sibling::node()"/> - </html:div> - </variable> - <variable name="processed-rest"> - <apply-templates select="exsl:node-set($rest)/*" mode="LesML:inline"> - <with-param name="element-name" select="$element-name"/> - <with-param name="element-namespace" select="$element-namespace"/> - <with-param name="start-sigil" select="$start-sigil"/> - <with-param name="end-sigil" select="$end-sigil"/> - <with-param name="role" select="$role"/> - <with-param name="langtag-supported" select="$langtag-supported"/> - </apply-templates> - </variable> - <copy-of select="$start-node/preceding-sibling::node()"/> - <value-of select="substring-before($start-node, $start-sigil)"/> - <element name="{$element-name}" namespace="{$element-namespace}"> - <if test="string($role)!=''"> - <attribute name="role"> - <value-of select="$role"/> - </attribute> - </if> - <if test="string($langtag)!=''"> - <if test="$element-namespace='http://www.w3.org/1999/xhtml'"> - <attribute name="lang"> - <value-of select="$langtag"/> - </attribute> - </if> - <attribute name="xml:lang"> + <variable name="end-node" select="text()[contains(., $end-sigil)][1]"/> + <variable name="has-start-node" select="$end-node/preceding-sibling::text()[contains(., $start-sigil)] or string-length(substring-after($end-node, $start-sigil))>string-length(substring-after($end-node, $end-sigil))"/> + <choose> + <when test="$end-node and $has-start-node"> + <variable name="preceding"> + <copy-of select="$end-node/preceding-sibling::node()"/> + <value-of select="substring-before($end-node, $end-sigil)"/> + </variable> + <variable name="start-node" select="exsl:node-set($preceding)/text()[contains(., $start-sigil)][last()]"/> + <variable name="restoftext" select="substring-after($end-node, $end-sigil)"/> + <variable name="maybe-langtag"> + <if test="$langtag-supported and starts-with($restoftext, '@') and contains($restoftext, '$')"> + <value-of select="substring-before(substring-after($restoftext, '@'), '$')"/> + </if> + </variable> + <variable name="langtag"> + <if test="translate($maybe-langtag, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-', '')=''"> + <value-of select="$maybe-langtag"/> + </if> + </variable> + <variable name="start-tokens-fragment"> + <call-template name="LesML:split"> + <with-param name="source" select="string($start-node)"/> + <with-param name="separator" select="$start-sigil"/> + </call-template> + </variable> + <variable name="start-tokens" select="exsl:node-set($start-tokens-fragment)/*"/> + <variable name="wrapped"> + <copy> + <copy-of select="@*"/> + <copy-of select="$start-node/preceding-sibling::node()"/> + <for-each select="$start-tokens[position()!=last()]"> + <value-of select="."/> + <if test="position()!=last()"> + <value-of select="$start-sigil"/> + </if> + </for-each> + <element name="{$element-name}" namespace="{$element-namespace}"> + <if test="string($role)!=''"> + <attribute name="role"> + <value-of select="$role"/> + </attribute> + </if> + <if test="string($langtag)!=''"> + <if test="$element-namespace='http://www.w3.org/1999/xhtml'"> + <attribute name="lang"> <value-of select="$langtag"/> </attribute> </if> - <copy-of select="$end-node/preceding-sibling::node()"/> - <value-of select="substring-before($end-node, $end-sigil)"/> - </element> - <copy-of select="exsl:node-set($processed-rest)/*/node()"/> - </when> - <otherwise> - <apply-templates select="node()" mode="LesML:inline"> - <with-param name="element-name" select="$element-name"/> - <with-param name="element-namespace" select="$element-namespace"/> - <with-param name="start-sigil" select="$start-sigil"/> - <with-param name="end-sigil" select="$end-sigil"/> - <with-param name="role" select="$role"/> - <with-param name="langtag-supported" select="$langtag-supported"/> - </apply-templates> - </otherwise> - </choose> - </when> - <otherwise> + <attribute name="xml:lang"> + <value-of select="$langtag"/> + </attribute> + </if> + <value-of select="$start-tokens[last()]"/> + <copy-of select="$start-node/following-sibling::node()"/> + </element> + <choose> + <when test="string($langtag)!=''"> + <value-of select="substring-after($restoftext, '$')"/> + </when> + <otherwise> + <value-of select="$restoftext"/> + </otherwise> + </choose> + <copy-of select="$end-node/following-sibling::node()"/> + </copy> + </variable> + <apply-templates select="exsl:node-set($wrapped)/*" mode="LesML:inline"> + <with-param name="element-name" select="$element-name"/> + <with-param name="element-namespace" select="$element-namespace"/> + <with-param name="start-sigil" select="$start-sigil"/> + <with-param name="end-sigil" select="$end-sigil"/> + <with-param name="role" select="$role"/> + <with-param name="langtag-supported" select="$langtag-supported"/> + </apply-templates> + </when> + <otherwise> + <copy> + <copy-of select="@*"/> <apply-templates select="node()" mode="LesML:inline"> <with-param name="element-name" select="$element-name"/> <with-param name="element-namespace" select="$element-namespace"/> @@ -675,9 +842,9 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <with-param name="role" select="$role"/> <with-param name="langtag-supported" select="$langtag-supported"/> </apply-templates> - </otherwise> - </choose> - </copy> + </copy> + </otherwise> + </choose> </when> <otherwise> <copy-of select="."/> @@ -688,79 +855,108 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <variable name="result"> <choose> <when test="self::*"> - <copy> - <copy-of select="@*"/> - <variable name="start-node" select="text()[contains(., '{🔗')][1]"/> - <choose> - <when test="$start-node"> - <variable name="remaining"> - <value-of select="substring-after($start-node, '{🔗')"/> - <copy-of select="$start-node/following-sibling::node()"/> - </variable> - <variable name="end-node" select="exsl:node-set($remaining)/node()[self::text() and contains(., '>}') and not(preceding-sibling::*)][1]"/> - <variable name="hyperlink"> - <for-each select="$end-node/preceding-sibling::node()"> - <value-of select="."/> - </for-each> - <value-of select="substring-before($end-node, '>}')"/> - </variable> - <choose> - <when test="contains($hyperlink, '<')"> - <variable name="ltcomponents"> - <call-template name="LesML:split"> - <with-param name="source" select="$hyperlink"/> - <with-param name="separator" select="'<'"/> - </call-template> - </variable> - <variable name="ltcomponent-nodes" select="exsl:node-set($ltcomponents)/*"/> - <variable name="rest"> - <html:div> - <value-of select="substring-after($end-node, '>}')"/> - <copy-of select="$end-node/following-sibling::node()"/> - </html:div> - </variable> - <variable name="processed-rest"> - <apply-templates select="exsl:node-set($rest)/*" mode="LesML:linkify"/> - </variable> - <copy-of select="$start-node/preceding-sibling::node()"/> - <value-of select="substring-before($start-node, '{🔗')"/> - <html:a href="{$ltcomponent-nodes[last()]}"> - <choose> - <when test="count($ltcomponent-nodes)>2 or normalize-space($ltcomponent-nodes[1])!=''"> - <value-of select="$ltcomponent-nodes[1]"/> - <for-each select="$ltcomponent-nodes[position()>1 and position()!=last()]"> - <text><</text> - <value-of select="."/> - </for-each> - </when> - <otherwise> - <value-of select="$ltcomponent-nodes[last()]"/> - </otherwise> - </choose> - </html:a> - <copy-of select="exsl:node-set($processed-rest)/*/node()"/> - </when> - <otherwise> - <variable name="rest"> - <html:div> - <copy-of select="$remaining"/> - </html:div> - </variable> - <variable name="processed-rest"> - <apply-templates select="exsl:node-set($rest)/*" mode="LesML:linkify"/> - </variable> - <copy-of select="$start-node/preceding-sibling::node()"/> - <value-of select="substring-before($start-node, '{🔗')"/> - <text>{🔗</text> - <copy-of select="exsl:node-set($processed-rest)/*/node()"/> - </otherwise> - </choose> - </when> - <otherwise> + <variable name="end-node" select="text()[contains(., '>}')][1]"/> + <variable name="has-start-node" select="$end-node/preceding-sibling::text()[contains(., '{🔗') and not(following-sibling::*)] or string-length(substring-after($end-node, '{🔗'))>string-length(substring-after($end-node, '>}'))"/> + <choose> + <when test="$end-node and $has-start-node"> + <variable name="preceding"> + <copy-of select="$end-node/preceding-sibling::node()"/> + <value-of select="substring-before($end-node, '>}')"/> + </variable> + <variable name="start-node" select="exsl:node-set($preceding)/text()[contains(., '{🔗') and not(following-sibling::*)][last()]"/> + <variable name="start-tokens-fragment"> + <call-template name="LesML:split"> + <with-param name="source" select="string($start-node)"/> + <with-param name="separator" select="'{🔗'"/> + </call-template> + </variable> + <variable name="start-tokens" select="exsl:node-set($start-tokens-fragment)/*"/> + <variable name="hyperlink"> + <value-of select="$start-tokens[last()]"/> + <for-each select="$start-node/following-sibling::node()"> + <choose> + <when test="self::text()"> + <value-of select="."/> + </when> + <when test="self::processing-instruction()[local-name()='LesML-Link-Escape']"> + <text>🔗</text> + </when> + </choose> + </for-each> + </variable> + <choose> + <when test="contains($hyperlink, '<')"> + <variable name="ltcomponents-fragment"> + <call-template name="LesML:split"> + <with-param name="source" select="$hyperlink"/> + <with-param name="separator" select="'<'"/> + </call-template> + </variable> + <variable name="ltcomponents" select="exsl:node-set($ltcomponents-fragment)/*"/> + <variable name="wrapped"> + <copy> + <copy-of select="@*"/> + <copy-of select="$start-node/preceding-sibling::node()"/> + <for-each select="$start-tokens[position()!=last()]"> + <value-of select="."/> + <if test="position()!=last()"> + <text>{🔗</text> + </if> + </for-each> + <element name="html:a"> + <attribute name="href"> + <value-of select="$ltcomponents[last()]"/> + </attribute> + <choose> + <when test="count($ltcomponents)>2 or normalize-space($ltcomponents[1])!=''"> + <for-each select="$ltcomponents[position()!=last()]"> + <value-of select="."/> + <if test="position()!=last()"> + <text><</text> + </if> + </for-each> + </when> + <otherwise> + <value-of select="$ltcomponents[last()]"/> + </otherwise> + </choose> + </element> + <value-of select="substring-after($end-node, '>}')"/> + <copy-of select="$end-node/following-sibling::node()"/> + </copy> + </variable> + <apply-templates select="exsl:node-set($wrapped)/*" mode="LesML:linkify"/> + </when> + <otherwise> + <variable name="escaped"> + <copy> + <copy-of select="@*"/> + <copy-of select="$start-node/preceding-sibling::node()"/> + <for-each select="$start-tokens[position()!=last()]"> + <value-of select="."/> + <if test="position()!=last()"> + <text>{🔗</text> + </if> + </for-each> + <text>{</text> + <processing-instruction name="LesML-Link-Escape"/> + <copy-of select="$hyperlink"/> + <text>>}</text> + <value-of select="substring-after($end-node, '>}')"/> + <copy-of select="$end-node/following-sibling::node()"/> + </copy> + </variable> + <apply-templates select="exsl:node-set($escaped)/*" mode="LesML:linkify"/> + </otherwise> + </choose> + </when> + <otherwise> + <copy> + <copy-of select="@*"/> <apply-templates select="node()" mode="LesML:linkify"/> - </otherwise> - </choose> - </copy> + </copy> + </otherwise> + </choose> </when> <otherwise> <copy-of select="."/> @@ -808,24 +1004,14 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <with-param name="end-sigil" select="'⸩'"/> </apply-templates> </variable> - <apply-templates select="exsl:node-set($result)/node()" mode="LesML:important"/> - </template> - <template match="node()" mode="LesML:important"> - <variable name="result"> - <apply-templates select="." mode="LesML:inline"> - <with-param name="element-name" select="'html:strong'"/> - <with-param name="start-sigil" select="'☞'"/> - <with-param name="end-sigil" select="'☜'"/> - </apply-templates> - </variable> - <apply-templates select="exsl:node-set($result)/node()" mode="LesML:emphasized"/> + <apply-templates select="exsl:node-set($result)/node()" mode="LesML:code"/> </template> - <template match="node()" mode="LesML:emphasized"> + <template match="node()" mode="LesML:code"> <variable name="result"> <apply-templates select="." mode="LesML:inline"> - <with-param name="element-name" select="'html:em'"/> - <with-param name="start-sigil" select="'⹐'"/> - <with-param name="end-sigil" select="'⹑'"/> + <with-param name="element-name" select="'html:code'"/> + <with-param name="start-sigil" select="'`'"/> + <with-param name="end-sigil" select="'´'"/> </apply-templates> </variable> <apply-templates select="exsl:node-set($result)/node()" mode="LesML:titled"/> @@ -859,13 +1045,23 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one <with-param name="end-sigil" select="'⦄'"/> </apply-templates> </variable> - <apply-templates select="exsl:node-set($result)/node()" mode="LesML:code"/> + <apply-templates select="exsl:node-set($result)/node()" mode="LesML:important"/> </template> - <template match="node()" mode="LesML:code"> + <template match="node()" mode="LesML:important"> + <variable name="result"> + <apply-templates select="." mode="LesML:inline"> + <with-param name="element-name" select="'html:strong'"/> + <with-param name="start-sigil" select="'☞'"/> + <with-param name="end-sigil" select="'☜'"/> + </apply-templates> + </variable> + <apply-templates select="exsl:node-set($result)/node()" mode="LesML:emphasized"/> + </template> + <template match="node()" mode="LesML:emphasized"> <apply-templates select="." mode="LesML:inline"> - <with-param name="element-name" select="'html:code'"/> - <with-param name="start-sigil" select="'`'"/> - <with-param name="end-sigil" select="'´'"/> + <with-param name="element-name" select="'html:em'"/> + <with-param name="start-sigil" select="'⹐'"/> + <with-param name="end-sigil" select="'⹑'"/> </apply-templates> </template> </transform>