[rfc-i] Section structure, was: RFC editing tools
Nico Williams
nico at cryptonector.com
Fri Dec 7 13:11:17 PST 2012
FYI, the XSLT 2.0 idiom I developed for <hN> style -> nested <section>
style is roughly as follows (taken from lyx2rfc, a bit simplified):
<xsl:template match="*[matches(name(), '^h[2-9]') and
ends-with(@class, 'section') and
not(matches(normalize-space(string-join(text(), '')), '^(Normative
|Informative |)References$'))]">
<xsl:element name="section">
<!-- N is the integer in hN -->
<xsl:variable name="N" select="substring-after(name(), 'h')
cast as xs:integer"/>
<xsl:variable name="thisHN" select="name()"/>
<!-- We refer to this <hN> in various XPath contexts below where
current() will no longer be this <h2>, so we need to save it -->
<xsl:variable name="cur_sect" select="current()"/>
<xsl:attribute name="title"
select="normalize-space(string-join(text(), ''))"/>
<!-- Make sure there's an anchor -->
<xsl:variable name="id"
select="a[not(starts-with(@id, 'magicparlabel-'))]/@id"/>
<xsl:attribute name="anchor"
select="if (string-length($id) > 0) then $id else generate-id()"/>
<!-- Handle the contents of just this section. Ask for all
siblings of this <hN> where the nodes we're looking for are
NOT hN, and their preceding <hN> is this one. -->
<xsl:apply-templates
select="(following-sibling::*[not(matches(name(), '^h[2-9]')) and
(preceding-sibling::*[matches(name(),
'^h[2-9]')])[last()] is $cur_sect])"/>
<!-- Handle sub-sections of this section. Ask for all sibling
h3 (and h4) nodes of this h2 where their preceding h2 is
this one. -->
<xsl:apply-templates
select="following-sibling::*[matches(name(), '^h[2-9]') and
(preceding-sibling::*[name() = $thisHN])[last()] is
$cur_sect and
(substring-after(name(), 'h') cast as xs:integer = ($N + 1))]"/>
</xsl:element>
</xsl:template>
The key expressions are:
<xsl:apply-templates
select="(following-sibling::*[not(matches(name(), '^h[2-9]')) and
(preceding-sibling::*[matches(name(),
'^h[2-9]')])[last()] is $cur_sect])"/>
(to get the contents of *this* section) and:
<xsl:apply-templates
select="following-sibling::*[matches(name(), '^h[2-9]') and
(preceding-sibling::*[name() = $thisHN])[last()] is
$cur_sect and
(substring-after(name(), 'h') cast as xs:integer = ($N + 1))]"/>
(to get the sub-sections following this section's content).
The key XPath 2.0 feature used here is sequences, as seen in the
sub-expression "(preceding-sibling::*[...])[last()]", where I'm
getting an <hN>'s preceding parent <hN> and then check that it's the
same the current <hN> so as to select that child.
Nico
--
More information about the rfc-interest
mailing list