]> Lady’s Gitweb - LesML/commitdiff
Improve/adjust note/sectioning elements
authorLady <redacted>
Sat, 20 Sep 2025 04:51:30 +0000 (00:51 -0400)
committerLady <redacted>
Sat, 20 Sep 2025 05:25:01 +0000 (01:25 -0400)
- Notes are now `<section>`s, not `<div>`s.

- A new “abstract” section type has been added.

- Sections can now contain list items (with a level > 1).

- The `LesML:finalize-footnotes` stage has been repurposed into a more
  general `LesML:finalize` stage, in part to facilitate the above.

- Paragraph i·d¦s are now passed upwards to the containing element in
  all cases, when applied to the first paragraph in a container. To
  literally assign an i·d to the first paragraph, add an empty initial
  paragraph (just a `¶`), which will be dropped. The same is true for
  language tags.

It would be nice to be able to specify titles/labels for sections, but
there isn¦t a good mechanism for doing this as of now. The heading
sigils are probably inappropriate for this, as headings in sections are
conceptually singular and “unleveled”. There is no need for four
heading types when a section can only contain one heading and it must
always be the first paragraph.

But on the H·T·M·L side, section headings _should_ have appropriate
levels corresponding to their position in the document. So this would
need to be remediated somehow.

README.markdown
parser.xslt

index 35f5a53727f6b3adbcccf1eacb4b363010c29d9d..99ff8badb8b838699e8e8ba0928287fbd636050c 100644 (file)
@@ -60,7 +60,8 @@ The lines, minus this leading, are then re‐analysed.
 Bracketed paragraphs which end quotes are treated as captions
   (`<html:figcaption>`); otherwise, they are footers (`<html:footer>`).
 
-Non·empty paragraphs are classified as follows :⁠—
+Non·empty paragraphs (which, to be clear, may still result in empty
+  `<html:p>` elements) are classified as follows :⁠—
 
 - If the paragraph consists of only the following section‐break
     characters, plus any amount of white·space, then it is
@@ -113,9 +114,9 @@ Non·empty paragraphs are classified as follows :⁠—
 - Otherwise, the paragraph is ordinary.
 
 After this classification, each ordinary paragraph is further
-  classified by type based on its first character (which is must be
-  followed by white·space, a pilcrow, or else the only thing on the
-  line) :⁠—
+  classified by type based on its first character (which must be
+  followed by white·space or a pilcrow, or else be the only thing on
+  the line) :⁠—
 
 - If the paragraph is preformatted, it is an ordinary paragraph.
 
@@ -155,19 +156,22 @@ After this classification, each ordinary paragraph is further
     secondary, and tertiary list items which precede them.
 
 - If the paragraph begins with `※`, it is an ordinary note
-    (`<html:div role="note" class="note">`).
+    (`<html:section role="note" class="note">`).
 
 - If the paragraph begins with `☡`, it is a cautionary note
-    (`<html:div role="note" class="caution">`).
-
-- If the paragraph begins with `🛈`, it is an informative note
-    (`<html:div role="note" class="info">`).
+    (`<html:section role="note" class="caution">`).
 
 - If the paragraph begins with `⯑`, it is a questioning note
-    (`<html:div role="note" class="query">`).
+    (`<html:section role="note" class="query">`).
+
+- If the paragraph begins with `@`, it is an abstract
+    (`<html:section role="doc-abstract">`).
 
-- If the paragraph begins with `⚠︎`, it is a warning note
-    (`<html:div role="note" class="warn">`).
+- If the paragraph begins with `🛈`, it is a (informative) tip
+    (`<html:section role="doc-tip">`).
+
+- If the paragraph begins with `⚠︎`, it is a (warning) notice
+    (`<html:section role="doc-notice">`).
 
 - If the paragraph begins with `^`, it is a footnote
     (`<html:li class="ordered footnote" aria-level="1">`).
@@ -204,6 +208,17 @@ The characters following the `¶` give the identifier for the paragraph,
 This may be suffixed with a language tag beginning with `@` and
   terminated with `$`.
 
+When a paragraph produces an `<html:p>` element “wrapped in” another
+  kind of element (e·g, a blockquote, section, or list item), the
+  identifier and language of the first paragraph are applied to the
+  wrapping element.
+If the first paragraph has no other contents, it is deleted.
+To apply the identifier or language to the `<html:p>` element itself,
+  and not its wrapper, one can simply make the first paragraph empty
+  (using a literal `¶` with no other contents).
+This paragraph will be dropped, but the following paragraphs will still
+  be processed as non·initial.
+
 The remaining characters in a paragraph form its contents.
 Markup within paragraphs is delimited with·out exception by pairs of
   characters, with the following precedence :⁠—
@@ -266,10 +281,12 @@ Once the tree is built as above, it is remediated into its final form
   by the following steps :⁠—
 
 - Continuation paragraphs are joined with the preceding list items or
-    divs.
+    sections.
 
 - List items of a higher level are nested in preceding list items, when
     present.
+  List items of a level greater than 1 can also be nested in preceding
+    sections (notes, abstracts, ⁊·c…).
 
 - Successive list items of the same level and class are joined into
     a single list.
index 5164ea125b2bf4502cf582ce70970d30c4b05b3c..a304a462926119f82ce8053d5a5f895a7628bcc9 100644 (file)
@@ -13,7 +13,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
 -->
 <!DOCTYPE transform [
        <!ENTITY LesML "urn:fdc:ladys.computer:20240512:LesML">
-       <!ENTITY section-break "">
+       <!ENTITY pilcrow-atts "(local-name()='id' or local-name()='lang') and namespace-uri()='' or local-name()='lang' and namespace-uri()='http://www.w3.org/XML/1998/namespace'">
        <!ENTITY sigiled-text "(string-length($text)=1 or substring($text, 2, 1)=' ' or substring($text, 2, 1)='¶')">
        <!ENTITY unsigiled-text "concat(translate(substring($text, 2, 1), ' ', ''), substring($text, 3, string-length($text)-2))">
        <!ENTITY xhtml "http://www.w3.org/1999/xhtml">
@@ -422,7 +422,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                        <attribute name="class">
                                                <text>body</text>
                                        </attribute>
-                                       <apply-templates select="$paragraphized/node()" mode="LesML:finalize-footnotes">
+                                       <apply-templates select="$paragraphized/node()" mode="LesML:finalize">
                                                <with-param name="used-footnotes" select="$used-footnote-nodes"/>
                                        </apply-templates>
                                </element>
@@ -432,7 +432,7 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                                        <text>doc-endnotes</text>
                                                </attribute>
                                                <element name="ol" namespace="&xhtml;">
-                                                       <apply-templates select="$used-footnote-nodes" mode="LesML:finalize-footnotes">
+                                                       <apply-templates select="$used-footnote-nodes" mode="LesML:finalize">
                                                                <with-param name="used-footnotes" select="$used-footnote-nodes"/>
                                                        </apply-templates>
                                                </element>
@@ -690,13 +690,13 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                                                </element>
                                                        </element>
                                                </when>
-                                               <when test="starts-with($text, '🛈') and &sigiled-text;">
-                                                       <element name="div" namespace="&xhtml;">
+                                               <when test="starts-with($text, '') and &sigiled-text;">
+                                                       <element name="section" namespace="&xhtml;">
                                                                <attribute name="role">
                                                                        <text>note</text>
                                                                </attribute>
                                                                <attribute name="class">
-                                                                       <text>info</text>
+                                                                       <text>note</text>
                                                                </attribute>
                                                                <element name="p" namespace="&xhtml;">
                                                                        <call-template name="LesML:id-and-contents">
@@ -705,13 +705,13 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                                                </element>
                                                        </element>
                                                </when>
-                                               <when test="starts-with($text, '') and &sigiled-text;">
-                                                       <element name="div" namespace="&xhtml;">
+                                               <when test="starts-with($text, '') and &sigiled-text;">
+                                                       <element name="section" namespace="&xhtml;">
                                                                <attribute name="role">
                                                                        <text>note</text>
                                                                </attribute>
                                                                <attribute name="class">
-                                                                       <text>query</text>
+                                                                       <text>caution</text>
                                                                </attribute>
                                                                <element name="p" namespace="&xhtml;">
                                                                        <call-template name="LesML:id-and-contents">
@@ -720,13 +720,13 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                                                </element>
                                                        </element>
                                                </when>
-                                               <when test="starts-with($text, '') and &sigiled-text;">
-                                                       <element name="div" namespace="&xhtml;">
+                                               <when test="starts-with($text, '') and &sigiled-text;">
+                                                       <element name="section" namespace="&xhtml;">
                                                                <attribute name="role">
                                                                        <text>note</text>
                                                                </attribute>
                                                                <attribute name="class">
-                                                                       <text>warn</text>
+                                                                       <text>query</text>
                                                                </attribute>
                                                                <element name="p" namespace="&xhtml;">
                                                                        <call-template name="LesML:id-and-contents">
@@ -735,13 +735,10 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                                                </element>
                                                        </element>
                                                </when>
-                                               <when test="starts-with($text, '') and &sigiled-text;">
-                                                       <element name="div" namespace="&xhtml;">
+                                               <when test="starts-with($text, '@') and &sigiled-text;">
+                                                       <element name="section" namespace="&xhtml;">
                                                                <attribute name="role">
-                                                                       <text>note</text>
-                                                               </attribute>
-                                                               <attribute name="class">
-                                                                       <text>note</text>
+                                                                       <text>doc-abstract</text>
                                                                </attribute>
                                                                <element name="p" namespace="&xhtml;">
                                                                        <call-template name="LesML:id-and-contents">
@@ -750,13 +747,22 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                                                </element>
                                                        </element>
                                                </when>
-                                               <when test="starts-with($text, '') and &sigiled-text;">
-                                                       <element name="div" namespace="&xhtml;">
+                                               <when test="starts-with($text, '🛈') and &sigiled-text;">
+                                                       <element name="section" namespace="&xhtml;">
                                                                <attribute name="role">
-                                                                       <text>note</text>
+                                                                       <text>doc-tip</text>
                                                                </attribute>
-                                                               <attribute name="class">
-                                                                       <text>caution</text>
+                                                               <element name="p" namespace="&xhtml;">
+                                                                       <call-template name="LesML:id-and-contents">
+                                                                               <with-param name="source" select="&unsigiled-text;"/>
+                                                                       </call-template>
+                                                               </element>
+                                                       </element>
+                                               </when>
+                                               <when test="starts-with($text, '⚠') and &sigiled-text;">
+                                                       <element name="section" namespace="&xhtml;">
+                                                               <attribute name="role">
+                                                                       <text>doc-notice</text>
                                                                </attribute>
                                                                <element name="p" namespace="&xhtml;">
                                                                        <call-template name="LesML:id-and-contents">
@@ -840,22 +846,12 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                        </call-template>
                </element>
        </template>
-       <template match="node()" mode="LesML:finalize-attributes">
-               <variable name="notattr" select="following-sibling::node()[not(self::text() and translate(., ' &#x9;', '')='' or self::LesML:attribute)]"/>
-               <for-each select="(.|exslset:leading(following-sibling::node(), $notattr)[self::LesML:attribute])/@*">
-                       <copy-of select="."/>
-                       <if test="local-name()='lang' and namespace-uri()=''">
-                               <attribute name="xml:lang">
-                                       <value-of select="."/>
-                               </attribute>
-                       </if>
-               </for-each>
-       </template>
-       <template match="html:a[@role='doc-noteref']" mode="LesML:finalize-footnotes">
+       <template match="html:ol[processing-instruction()[local-name()='LesML-Footnote']]|processing-instruction()[local-name()='LesML-Footnote']" mode="LesML:finalize" priority="1"/>
+       <template match="html:a[@role='doc-noteref']" mode="LesML:finalize">
                <param name="used-footnotes" select="/.."/>
                <variable name="matching-note" select="$used-footnotes[concat('#', @id)=current()/@href]"/>
                <copy>
-                       <apply-templates select="@*" mode="LesML:finalize-footnotes">
+                       <apply-templates select="@*" mode="LesML:finalize">
                                <with-param name="used-footnotes" select="$used-footnotes"/>
                        </apply-templates>
                        <choose>
@@ -863,30 +859,74 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                                        <value-of select="$matching-note/@value"/>
                                </when>
                                <otherwise>
-                                       <apply-templates select="node()" mode="LesML:finalize-footnotes">
+                                       <apply-templates select="node()" mode="LesML:finalize">
                                                <with-param name="used-footnotes" select="$used-footnotes"/>
                                        </apply-templates>
                                </otherwise>
                        </choose>
                </copy>
        </template>
-       <template match="html:p[preceding-sibling::*[1]=processing-instruction()[local-name()='LesML-Footnote']]" mode="LesML:finalize-footnotes">
-               <variable name="content" select="@*[not(local-name()='@id' and namespace-uri()='')]|node()"/>
+       <template match="html:p[position()=1 and ancestor::*]" mode="LesML:finalize">
+               <param name="used-footnotes" select="/.."/>
+               <variable name="content" select="@*[not(&pilcrow-atts;)]|node()"/>
                <if test="$content">
                        <copy>
-                               <apply-templates select="$content" mode="LesML:finalize-footnotes"/>
+                               <apply-templates select="$content" mode="LesML:finalize">
+                                       <with-param name="used-footnotes" select="$used-footnotes"/>
+                               </apply-templates>
                        </copy>
                </if>
        </template>
-       <template match="html:ol[processing-instruction()[local-name()='LesML-Footnote']]|processing-instruction()[local-name()='LesML-Footnote']" mode="LesML:finalize-footnotes"/>
-       <template match="@*|node()" mode="LesML:finalize-footnotes" priority="-1">
+       <template match="html:section" mode="LesML:finalize">
                <param name="used-footnotes" select="/.."/>
+               <variable name="notinsection" select="following-sibling::node()[not(html:li/@aria-level>1)][1]"/>
                <copy>
-                       <apply-templates select="@*|node()" mode="LesML:finalize-footnotes">
+                       <apply-templates select="@*|html:p[1]/@*[&pilcrow-atts;]" mode="LesML:finalize"/>
+                       <apply-templates select="node()" mode="LesML:finalize"/>
+                       <for-each select="exslset:leading(following-sibling::node(), $notinsection)">
+                               <copy>
+                                       <apply-templates select="@*|node()" mode="LesML:finalize">
+                                               <with-param name="used-footnotes" select="$used-footnotes"/>
+                                       </apply-templates>
+                               </copy>
+                       </for-each>
+               </copy>
+       </template>
+       <template match="html:*[html:li/@aria-level>1]" mode="LesML:finalize">
+               <param name="used-footnotes" select="/.."/>
+               <if test="not(preceding-sibling::node()[not(html:li/@aria-level>1)][1]/self::html:section)">
+                       <copy>
+                               <apply-templates select="@*|node()" mode="LesML:finalize">
+                                       <with-param name="used-footnotes" select="$used-footnotes"/>
+                               </apply-templates>
+                       </copy>
+               </if>
+       </template>
+       <template match="text()" mode="LesML:finalize">
+               <call-template name="LesML:break-and-unescape">
+                       <with-param name="source" select="string()"/>
+               </call-template>
+       </template>
+       <template match="@*|node()" mode="LesML:finalize" priority="-1">
+               <param name="used-footnotes" select="/.."/>
+               <copy>
+                       <apply-templates select="@*|html:p[1]/@*[&pilcrow-atts;]" mode="LesML:finalize"/>
+                       <apply-templates select="node()" mode="LesML:finalize">
                                <with-param name="used-footnotes" select="$used-footnotes"/>
                        </apply-templates>
                </copy>
        </template>
+       <template match="node()" mode="LesML:finalize-attributes">
+               <variable name="notattr" select="following-sibling::node()[not(self::text() and translate(., ' &#x9;', '')='' or self::LesML:attribute)]"/>
+               <for-each select="(.|exslset:leading(following-sibling::node(), $notattr)[self::LesML:attribute])/@*">
+                       <copy-of select="."/>
+                       <if test="local-name()='lang' and namespace-uri()=''">
+                               <attribute name="xml:lang">
+                                       <value-of select="."/>
+                               </attribute>
+                       </if>
+               </for-each>
+       </template>
        <template match="html:li" mode="LesML:finalize-list">
                <param name="parent-level" select="0"/>
                <variable name="current-class" select="string(@class)"/>
@@ -932,14 +972,12 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                <element name="span" namespace="&xhtml;">
                        <apply-templates select="." mode="LesML:finalize-attributes"/>
                        <if test="self::text()">
-                               <call-template name="LesML:break-and-unescape">
-                                       <with-param name="source" select="string(.)"/>
-                               </call-template>
+                               <copy/>
                        </if>
                </element>
        </template>
        <template match="html:div" mode="LesML:finalize-tree">
-               <if test="not(processing-instruction()[local-name()='LesML-Continuation']) or not(preceding-sibling::node()[position()=1 and self::html:* and contains(' div li h1 h2 h3 h4 h5 h6 ', local-name())])">
+               <if test="not(processing-instruction()[local-name()='LesML-Continuation']) or not(preceding-sibling::node()[position()=1 and self::html:* and contains(' div h1 h2 h3 h4 h5 h6 li section ', local-name())])">
                        <variable name="notcontinuation" select="following-sibling::node()[not(self::html:div/processing-instruction()[local-name()='LesML-Continuation'])][1]"/>
                        <choose>
                                <when test="processing-instruction()[local-name()='LesML-Continuation'] and $notcontinuation[self::html:* and contains(' h1 h2 h3 h4 h5 h6 ', local-name())]">
@@ -1004,15 +1042,19 @@ If a copy of the M·P·L was not distributed with this file, You can obtain one
                        <apply-templates select="." mode="LesML:finalize-list"/>
                </if>
        </template>
+       <template match="html:section" mode="LesML:finalize-tree">
+               <variable name="notcontinuation" select="following-sibling::node()[not(self::html:div/processing-instruction()[local-name()='LesML-Continuation'])][1]"/>
+               <copy>
+                       <apply-templates select="@*|node()" mode="LesML:finalize-tree"/>
+                       <for-each select="exslset:leading(following-sibling::node(), $notcontinuation)">
+                               <apply-templates select="node()" mode="LesML:finalize-tree"/>
+                       </for-each>
+               </copy>
+       </template>
        <template match="processing-instruction()[local-name()='LesML-Continuation']" mode="LesML:finalize-tree"/>
        <template match="processing-instruction()[local-name()='LesML-Token-Escape']" mode="LesML:finalize-tree">
                <value-of select="."/>
        </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="." mode="LesML:finalize-attributes"/>
This page took 0.045117 seconds and 4 git commands to generate.