Almost exactly two years ago (glurk!), I wrote a little item about XSLT match patterns and gave a clue to how I implement them. A pattern like
chapter/parais equivalent to an XPath expression like
boolean(self::para/parent::chapter)That's how Arabica actually implements it, rewriting the match pattern as an XPath expression during compilation.
This works in every case, except those involving positional matches,
chapter/parafor instance. In the simple case above, the rewriting is actually quite simple. You can push each step, here
para, onto a LIFO stack and then pull them off again adding the extra bit of wrapping as you go. For positional matches, the rewriting is a little more involved. A match like
chapter/para[last()]needs to be rewritten as something along the lines of
self::para[. = parent::*/para[last()]]/parent::chapteralthough you could probably simplify it to
self::para[. = parent::chapter/para[last()]]
Arabica::XSLT doesn't do this rewriting at the moment, which is, I feel, the largest single hole in it. I'm aiming to have a go at in the next few days. If I can crack it relatively quickly, maybe by this time next year I'll be looking for a new project :)
Positional matches must by the way, at least as far as I can see, be evaluated in this way (even if the underlying implementation is different). This is why matches like this can be quite expensive in terms of runtime, and are generally discouraged.