The following macro swaps the character before the caret with the character after the caret. It is useful if, like everybody, you are a bit dyslexic.
<command name="transposeChars">
<macro undoable="true" label="Transpose Characters">
<sequence>
<test expression="not($selected) and not($mark) and
$dotOffset > 0 and
$dotOffset < string-length($dot)"/>
<command name="selectTo" parameter="previousChar" />
<command name="cut" />
<command name="moveDotTo" parameter="nextChar" />
<command name="paste" parameter="into" />
</sequence>
</macro>
</command>The above macro uses basic commands selectTo, moveDotTo, cut and paste, but also XPath-based construct test.
As a pseudo-command of a macro, test can be executed only if its expression attribute evaluated as a boolean in the context specified by its context attribute returns true.
This construct like pass, fail and match, is only a test. When test is actually executed, it does nothing at all.
Test is used in the above macro to ensure that the macro can be executed only if:
There is no node selection: not($selected).
There is no text selection: not($mark).
The caret is not before first character of a textual node: $dotOffset > 0.
The caret is not after last character of a textual node: $dotOffset < string-length($dot).
Like selected and implicitElement seen in previous examples, mark, dot and dotOffset are predefined variables mapped to the selection in XXE.