2. Examples

Example 4.1. Using sequence and choice

  <command name="addListItem">
    <macro undoable="true">
      <choice>
        <sequence>
          <command name="selectNode" 
                   parameter="ancestor[implicitElement] ul ol" />
          <command name="selectNode" parameter="child" />
          <command name="insertNode" parameter="sameElementAfter" />
        </sequence>

        <sequence>
          <choice>
            <sequence>
              <command name="selectNode" 
                       parameter="ancestorOrSelf[implicitElement] dt" />
              <!-- Assumes that a dt is followed by a dd. -->
              <command name="selectNode" parameter="nextSibling" />
            </sequence>
            <command name="selectNode" 
                     parameter="ancestorOrSelf[implicitElement] dd" />
          </choice>
          <command name="insert" parameter="after dt" />
          <command name="insert" parameter="after dd" />
          <command name="selectNode" parameter="previousSibling" />
        </sequence>
      </choice>
    </macro>
  </command>

In example 1, the macro command addListItem, which is used to add a li to a ul or ol or to add a dt/dd pair to a dl, can be described as follows:

  • Select ancestor ul or ol and then

    • Select previously select child which is always a li when the document is valid.

      (The selectNode command selects all the ancestors one after the other until it reaches the searched ancestor. This is equivalent to interactively typing Ctrl-Up until the desired ancestor is selected.)

    • AND insert element of same type (a new li) after selected element (a li).

  • OR select

    • next sibling of ancestor dt (assumes that a dt is always followed by a dd);

    • OR ancestor dd.

    Then

    • Insert a dt after the selected element (a dd).

    • AND insert a dd after the selected element (the newly inserted dt).

    • AND select previous sibling (the newly inserted dt) of selected element (the newly inserted dd).


Example 4.2. Macro-variables

  <command name="convertToLink">
    <macro undoable="true" repeatable="true" label="Convert to &lt;a&gt;">
      <sequence>
        <command name="convert" parameter="a" />
        <command name="putAttribute" parameter="%0 %1" />
      </sequence>
    </macro>
  </command>

  <binding>
    <keyPressed code="ESCAPE" />
    <charTyped char="t" />
    <command name="convertToLink" parameter="name XXX" />
  </binding>

  <binding>
    <keyPressed code="ESCAPE" />
    <charTyped char="l" />
    <command name="convertToLink" parameter="href ???" />
  </binding>

In example 2, macro-command convertToLink must be passed two arguments which specify which type of XHTML a element is to be created: is it target or is it a link? These arguments are referenced in the parameter of the putAttribute command using variables %0 and %1.


Example 4.3. The "%_" macro-variable

  <command name="insertCommandOutput">
    <macro>
      <sequence>
        <command name="run" />
        <command name="insertString" parameter="%_" />
      </sequence>
    </macro>
  </command>

In example 3, the output of the external program executed by the run command is referenced in the parameter of the insertString command using the %_ variable. (The run command having no parameter will prompt the user to specify which external program is to be executed.)


Example 4.4. Using the fail construct

  <command name="publish">
    <macro>
      <sequence>
        <pass>
          <match context="/*[1]" pattern="html" />
          <fail><command name="XXE.save" /></fail>
        </pass>
        <command name="doPublish" />
      </sequence>
    </macro>
  </command>

Execute command doPublish if current document has an html root element and if this document does not need to be saved.


Example 4.5. Using the XPath-based constructs match and set

  <command name="moveListItemUp">
    <macro undoable="true">
      <sequence>
        <command name="selectNode" 
          parameter="ancestorOrSelf[implicitElement] listitem callout step" />
        <match context="$selected" pattern="*[position() &gt; 1]" />
        <set variable="anchor" context="$selected" 
             expression="./preceding-sibling::*[1]" />
        <command name="cut" />
        <set variable="selected" expression="$anchor" />
        <command name="paste" parameter="before" />
      </sequence>
    </macro>
  </command>

Move a list item up in the list. That is, the preceding sibling of the explicitly or implicitly selected list item becomes its following sibling.


Example 4.6. A contextual drop

  <binding>
    <appEvent name="drop" />
    <command name="xhtml.fileDrop" parameter="%{value}" />
  </binding>

  <command name="xhtml.fileDrop">
    <macro>
      <choice>
        <sequence>
          <match context="$clickedElement" pattern="a[@href]" />
          <set variable="selected" expression="$clickedElement" />
          <get expression="relativize-uri('%0')" />
          <command name="putAttribute" parameter="href '%_'" />
        </sequence>

        <command name="XXE.open" parameter="%0" />
      </choice>
    </macro>
  </command>

When a string is dropped on an XHTML <a href="..."> element, this string is assigned to the href attribute (after considering this string as an URL and trying to make it relative to the base URL of the a element). When a string is dropped on any other element, XXE default action is used instead: consider the string as the URL or filename of a document to be opened.