Re: Adapt Saxon-CE event model to XSL-FO?

On Thu, April 18, 2013 3:02 pm, Dave Pawson wrote:
...
>>> On 17 April 2013 13:54, Tony Graham <tgraham@mentea.net> wrote:
...
>>>> <xsl:template match="BlockArea[key('fig', @id, $src-doc)]"
>>>>               mode="ppl:overflow">
>>>>   <xsl:result-document href="#{@id}/area:external-graphic"
>>>>                        method="replace-content">
>>>>     <xsl:copy>
>>>>       <xsl:apply-templates select="@*"/>
>>>>       <xsl:attribute name="width"
>>>>                      select="ppl:scale(area:external-graphic/@width,
>>>>                                        0.8)"/>
>>>>       <xsl:apply-templates/>
>>>>     </xsl:copy>
>>>>   </xsl:result-document>
>>>> </xsl:template>
...

> Issues (possible, if I guess right).
> One event per match? Hundreds of match strings?

XSLT 2.0 allows multiple tokens in xsl:template/@mode and multiple
alternatives in xsl:template/@match, so there's scope for templates that
are usable in multiple contexts.

> Many matches?
>   How to optimise, I imagined something like 'overflow' being   a single
> event?
>   Content overflowing some area.
>   Suggesting, for my dreamed up example,
>   xsl:choose
>     when event='blockOverflow'
>       now I have a limited number of options
>               reduce font
>               truncate
>               report error
>
> That sort of logic to make it a brain full?

Quite possibly, but it's the sort of thing that people have been saying
since February that they wanted.

>> If this takes off, I would also expect more appearances of @role [1] and
>> @id [2] in FO documents just so it's easier to write event handler
>> @match
>> attributes.
>
> So do you see the @match being to source document attributes?
>   ... I was thinking of 'matching' (wrong word) on formatter events?

@match would contain XPaths that would be matched against contexts in
either the FO tree or the area tree.  The formatter events would be
represented by @mode tokens.

The original source XML document(s) might or might not be available, I
don't know.

>> The question of which event handler to 'fire' if there are multiple
>> applicable event handlers with the same template priority would have to
>> be
>> decided (ideally by experience after trying it out rather than by
>> deciding
>> in email now), but my current expectation is that the XSL formatter/XSLT
>> processor combination would start with the lowest level area applicable
>> to
>> the event (e.g., the lowest level fo:block in a fo:block-container that
>> overflows) and, in effect, look up the 'ancestor' axis of the areas
>> until
>> there's an applicable event handle defined.  I have no firm opinion on
>> whether it should first look only in the FO tree or only in the area
>> tree
>> or alternate between the two at each level.
>
> That starts to make sense... (Dreaming now)
> a list, can't be fitted into area X
>    Any match on a para within a list item
>    any match on a list item
>     any match on a list
>     Any match on a block containing a list.
>
> ...Then, If I have problems with three lists, and I don't like the way
> that the
> engine is handling it, I can iterate and isolate the 'problem' by
> matching on @id values?
>  Is that where you are going Tony?

Pretty much.

>> You could also postulate a more callback-like approach where you specify
>> the event handler name(s) in the value of a new FO property, or
>> postulate
>> a new property to specify whether to look in the FO tree or area tree
>> for
>> event handlers in the event of an event.
>
> Methinks we are looking at this quite differently...
> How might this pan out please Tony?

I don't know, it's just something that I thought of mid-email.

If you went the callback route, it could be something like:

<fo:block ppl:callback="name-of-a-template">
   ...
</fo:block>

or even:

<fo:block ppl:callback="ppl:overflow my-overflow template ppl:intrusion
my-intrusion-template">
   ...
</fo:block>

but both alternatives seem like more work to write and to maintain than
letting the formatter work things out as in the original proposal.

>> What happens when, e.g., multiple cells in a table row would each cause
>> the table row to split and there's an event type and event handlers
>> defined for that sort of event is anybody's guess at this point.
>    Does your 'ripple up the source tree ' model work here?
>    As with the list above?
>>
>>> Thinks. Is it possible to categorise 'events' and provide options?

The type of the event becomes the mode name.

...
>>>  E.g. an overflow event, could I be 'pushed' into using a choose
>>> with only a number of options?
>>
>> As described, you get to write XSLT.  What that does is up to you.
>>
>>>     Blow up | report error
>>
>> <xsl:message terminate="yes">
>>
>>>     Reduce the item to fit (somehow)
>>
>> Rewrite properties in the FO tree, and when the event handler finishes
>> running, the XSL formatter gets to reformat the modified FOs and then
>> adjust the rest of the formatted document based on how the areas
>> changed.
>
> I'm less happy with this? IMHO, the formatter should know it can only do
> one or two things (small number any way). I was thinking of reducing
> options initially, so the user chooses (xsl:choose) one from n.

It seems to me that the formatter should be able to deal with the same
range of valid FOs after the event handler finishes as it can deal with if
that FO was the initial input.

Users may well restrict themselves to a limited range of responses to any
one event, even if only to avoid the 'brain full' situation alluded to
earlier, and if it gets to the point of someone wrapping a GUI around FO
processing with feedback then the GUI will probably limit people's choices
anyway, but restricting the changes to only what we can think of in
advance could limit the utility of the whole idea.

The ripple effect of changes to any one FO should in most cases only
ripple as far as the current block, the current page, or the end of the
current page sequence.

> The user poking into the area tree seems a corner case for you/Arved who
> thoroughly understand the innards?

There's a valid, general purpose use case in the requirements document:
summing values within a page.  Much simpler to do

  sum(ancestor::area:PageArea//area:BlockArea[@role="sum-me"])

in an area tree event handler than to do gymnastics from the FO tree to
first find the areas that you want to update.

>> So another part of event handling by the XSL formatter is determining
>> which event to handle first, since you don't want to first handle an
>> overflow on the last page if the next event handler to run is for an
>> overflow on the first page and that event handler changes the areas such
>> that the overflow on the last page no longer occurs anyway.
>
> Yikes. Good point. First page to last, bottom to top?
> Something like that?

Probably, though I'm not sure if you mean bottom of the tree or bottom of
the page.

>>>    wrap onto the next block/line?
>>
>> Rewrite the applicable FOs in the FO tree or rewrite the area tree, it
>> would be up to you.
> I'd run a mile! That's what I pay the formatter to do <grin/>

Another reason to not restrict the changes that an event handler can make
to the FO tree.

>>>    truncate / trim the fo?
>>
>> Rewrite the applicable FOs.
>
> If you said that again as change property X in the up/down direction
> I might be happier with that? Is that the sort of thing you mean?

Change as much or as little as you need to do to get the best result.

I expect that common practice would coalesce around some common
techniques, and few people are going to go for random font size, margins,
and line height on every block, so people will probably mostly show
restraint so the pages can still look their best.

>> As with Saxon-CE [3], xsl:result-document would be used to address parts
>> of the existing document to modify.  I don't know how an area tree event
>> handler would select to modify the FO tree, and vice-versa, but it could
>> be as simple as inventing two bogus 'x-fo' and 'x-area' URL schemes.
>>
>>>>   <xsl:result-document href="x-area:#{@id}/area:external-graphic"
>>>>                        method="ppl:replace-content">
>>
>>> so that the formatter is still in control of formatting, the user is
>>> selecting
>>> from sensible options?
>>
>> You would hope so, but it would probably also present opportunities for
>> event handlers, or sequences of event handlers, to go into endless loops
>> making and unmaking the same adjustments.
>
> Hence I'd like the user to choose, the formatter to decide if it can or
> not?

It would be good if a formatter could stop if it finds itself in an
endless loop, just as your XSLT processors do now, but I don't think
anyone could legislate against, or a processor recognise in advance, all
the ways that it's possible to make an endless loop.

Regards,


Tony.

Received on Friday, 19 April 2013 13:17:25 UTC