I hope that I've really understood what you want to do.

I have tested the following macro (with DocBook) and it seems to be safe
and to work fine.

---
  <command name="test">
    <macro>
      <sequence>
        <command name="selectNode" parameter="previousSibling section"/>
        <set variable="anchor" expression="$selected" />
        <command name="selectNode" parameter="nextSibling section" />
        <command name="cut" />
        <set variable="selected" expression="$anchor/*[last()]" />
        <command name="paste" parameter="after"/>
      </sequence>
    </macro>
  </command>

  <binding>
    <keyPressed code="F3" />
    <command name="test" />
  </binding>
---

Note that the section to be moved must be explicitly selected for this
macro to work.

Bill Fenner wrote:
> 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.)

Reply via email to