I'm writing a macro that is similar to incrSectionLevel, but instead
of wrapping the current section in a new blank section, tries to
attach this section to its previous sibling's last child (e.g., if we
had
1.
1.1.
1.2.
2. *
and use this command, incrSectionLevel would result in
1.
1.1.
1.2.
2.
2.1. *
and my command would result in
1.
1.1.
1.2.
1.3. *
)

I use <set> and xpath to pick the element after which I want to insert
the section.  This could be one of two things:

a. If the preceding-sibling section has section children, then it's
the last section child.
b. If not, it's the last element of the previous section.

My current way of picking between these is:

        <set variable="anchor" context="$selected"
expression="preceding-sibling::section[position()=1]//section[position()=last()]"/>
        <choice>
          <sequence>
            <test expression="not($anchor)"/>
            <set variable="anchor" context="$selected"
expression="preceding-sibling::section[position()=1]/*[position()=last()]"/>
          </sequence>
          <test expression="1"/>
        </choice>
        <!-- fail if this got no result -->
        <test expression="$anchor"/>

However, I don't feel like this is a good use of <choice> - I am
simulating my thinking process ("if that didn't work, then try this")
but I suspect there's a better way to implement this.

Here is the whole macro.

  <command name="xml2rfc.increaseSectionLevel">
    <macro undoable="true" trace="true">
      <sequence>
        <!-- Call "currentsection" either me (if I'm a section) or my
              first ancestor section.
             That's the first ./ancestor-or-self bit.
             Permission to run: currentsection has a preceding sibling
              section.
             Noop prevention: that section's last child is not me.
             -->
        <test 
expression="$implicitElement/ancestor-or-self::section[position()=1]/preceding-sibling::section[position()=1]
and 
not($implicitElement/ancestor-or-self::section[position()=1]/preceding-sibling::section[position()=1]//section[position()=last()]
= $implicitElement/ancestor-or-self::section[position()=1])"/>
        <!-- select the section containing the cursor -->
        <command name="selectNode"
parameter="ancestorOrSelf[implicitElement] section"/>
        <!-- find the previous sibling's last section (or content element)
             either we want //section[position()=last()] or if
             there is no section child, we want /*[position()=last()]
             I feel like this choice is a hack, to try the second pattern
             if the first one failed. -->
        <set variable="anchor" context="$selected"
expression="preceding-sibling::section[position()=1]//section[position()=last()]"/>
        <choice>
          <sequence>
            <test expression="not($anchor)"/>
            <set variable="anchor" context="$selected"
expression="preceding-sibling::section[position()=1]/*[position()=last()]"/>
          </sequence>
          <test expression="1"/>
        </choice>
        <!-- fail if this got no result -->
        <test expression="$anchor"/>
        <!-- cut it -->
        <command name="cut"/>
        <!-- select the previos sibling's last section -->
        <set variable="selected" expression="$anchor"/>
        <!-- paste it -->
        <command name="paste" parameter="after"/>
      </sequence>
    </macro>
  </command>

(Advice on simplifying that <test> would be appreciated, too, but I'm
not as worried about that.)

Thanks,
  Bill

Reply via email to