Conditional Processing

Shaun McCance <shaunm at gnome.org>
Mon Jan 16 14:24:30 EST 2012

I think I messed up on conditional processing. Luckily, it's
still an early draft, and we can change it completely if we
want to. Here's the stubby draft:

http://projectmallard.org/if/1.0/

The crux of conditional processing is the test attribute. In
the current incarnation, the test attribute takes any XPath
expression, and we define two extra XPath functions, if:env
and if:supports, to pass some info along.

Problems:

1) To implement this in XSLT, you have to use the non-standard
dyn:evaluate function. That's not a huge problem, and I don't
have real qualms about using EXSLT functions with wide uptake.

2) Except dyn:evaluate resolves namespace prefixes according
to the XSLT transform, not the Mallard document. So if I've
implemented if:env using the prefix "if" (which I have), you
can't refer to it using the prefix "foo", even if "foo" is
bound to the same namespace in your document.

3) It's really hard to do "maybe" values. Sometimes you can
do all your conditional processing at transform time. ("Am I
converting to HTML?") But with HTML increasingly capable of
handling document logic, it's really useful to pass some of
those conditions through. ("Am I being read on a handheld
device?")

Alternate proposal: Make the test attribute a comma-separated
list of space-separated lists of tokens and token negations.
What huh? Examples:

<p if:test="platform:linux target:html">
Only displayed if the platform is linux AND the target is html.

<p if:test="platform:linux,platform:mac">
Only displayed if the platform is linux OR the platform is mac.

<p if:test="!target:mobile">
Only displayed if the target is NOT a mobile device.

Basically, you're checking if tokens are defined. This is an
explicit-include system, unlike some other languages, which
use an explicit-exclude system.

* Use a space-separated list of tokens to check that every one
  of the tokens is defined.
* Provide multiple token lists separated by commas to check that
  at least one of the token lists is true.
* Negate any token by prefixing it with an exclamation point.

This is, I think, sufficiently expressive to handle anything
you're likely to want to do. There's no grouping to override
precedence, but you can rewrite any expression into this form,
if verbosely. Doing a simple OR-AND-NOT means you don't have
to write a real parser and expression normalizer. You can do
simple string splits, and the processing is simple, even with
"maybe" values.

The tokens are just strings, but with recommendations on how
to construct them to keep some consistency. I have a general
outline of those recommendations, which I'll spare you for now.
It's sufficient to know you can check for the same things you
could check for with if:env and if:supports. What you can't
do is check your position in the current document, which you
could with XPath. (I could give theoretical examples of where
this could possibly be useful, but nothing real-world.)

So, thoughts on completely changing conditionals?

--
Shaun