Ken: I had forgotten about your PSMI. I'm coming back to FO after a long
absence.
Cheers,
E.
--
Eliot Kimber
http://contrext.com
On 4/18/18, 4:01 PM, "G. Ken Holman
g(_dot_)ken(_dot_)holman(_at_)gmail(_dot_)com"
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
There are a number of users of my Page Sequence
Master Interleave (PSMI) code for the rotated tables:
https://cranesoftwrights.github.io/resources/psmi/index.htm
Perhaps this has some ideas you can exploit.
. . . . . . Ken
At 2018-04-18 20:36 +0000, Eliot Kimber ekimber(_at_)contrext(_dot_)com
wrote:
>I definitely owe Gerrit the beverage of his
>choice. I was able to make this code work with my details.
>
>While it's not obvious (at least not to me--I
>still need to take some time to fully appreciate
>how it works) it's definitely much more elegant
>than the recursive approach I was thinking of.
>
>I will probably also need to use this technique
>to handle the challenge of changing page
>sequences to render long rotated tables or foldout pages.
>
>When generating FO it's much eaiser logically to
>emit page sequence start markers and then come
>back and allocate things to page sequences than
>it is to try to work out the page sequence
>mapping when there's not a simple mapping from
>top-level elements to page sequences.
>
>Cheers,
>
>Eliot
>--
>Eliot Kimber
>http://contrext.com
>
>On 4/18/18, 2:00 PM, "Imsieke, Gerrit, le-tex
>gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de"
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
>
> Hold my beer.
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> xmlns:xs="http://www.w3.org/2001/XMLSchema"
> xmlns:fo="http://www.w3.org/1999/XSL/Format"
> exclude-result-prefixes="xs"
> version="2.0">
>
> <xsl:output indent="yes"/>
>
> <xsl:template match="node() | @*" mode="#default split">
> <xsl:copy>
> <xsl:apply-templates select="@* | node()" mode="#current"/>
> </xsl:copy>
> </xsl:template>
>
> <xsl:template match="fo:block[empty(ancestor::fo:block)]"
> mode="#default">
> <xsl:variable name="block-root" as="element(fo:block)"
select="."/>
> <xsl:for-each-group select="descendant::node()[empty(node())]"
> group-starting-with="two-column-start">
> <xsl:for-each-group select="current-group()"
> group-ending-with="two-column-end">
> <xsl:apply-templates select="$block-root" mode="split">
> <xsl:with-param name="restricted-to" as="node()*"
> select="current-group()/ancestor-or-self::node()"
> tunnel="yes"/>
> <xsl:with-param name="two-col-start" as="xs:boolean"
> tunnel="yes"
> select="exists(self::two-column-start)"/>
> </xsl:apply-templates>
> </xsl:for-each-group>
> </xsl:for-each-group>
> </xsl:template>
>
> <xsl:template match="node()" mode="split" priority="1">
> <xsl:param name="restricted-to" tunnel="yes" as="node()+"/>
> <xsl:if test="exists(. intersect $restricted-to)">
> <xsl:next-match/>
> </xsl:if>
> </xsl:template>
>
> <xsl:template
> match="fo:block[empty(ancestor::fo:block)]" mode="split">
> <xsl:param name="restricted-to" tunnel="yes" as="node()*"/>
> <xsl:param name="two-col-start" tunnel="yes" as="xs:boolean"/>
> <xsl:copy>
> <xsl:apply-templates select="@*" mode="#current"/>
> <xsl:if test="$two-col-start">
> <xsl:attribute name="span" select="'none'"/>
> </xsl:if>
> <xsl:apply-templates mode="#current"/>
> </xsl:copy>
> </xsl:template>
>
> <xsl:template match="two-column-start | two-column-end"
mode="split"/>
>
> </xsl:stylesheet>
>
>
> On 18/04/2018 20:23, Eliot Kimber ekimber(_at_)contrext(_dot_)com
wrote:
> > Gerrit,
> >
> > I don't immediately see how the code in
> the referenced message works but it's simple enough to try in my context.
> >
> > In my case the number of switches is
> small relative to the total content, so it will
> only be applied occasionally and infrequently.
> >
> > Cheers,
> >
> > E.
> >
> > --
> > Eliot Kimber
> > http://contrext.com
> >
> > On 4/18/18, 1:15 PM, "Imsieke, Gerrit,
> le-tex gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de"
> <xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
> >
> > Hi Eliot,
> >
> > I think this can be tackled with
> what I call "upward projection", see
> > for ex. https://markmail.org/message/kmq2g4fidmw6cofz
> >
> > You'd identify all leaf elements and
> group them (maybe a combination of
> > group-starting-with="two-colum-start" and
> > group-ending-with="two-colum-end" is in order here).
> >
> > Then for each group you transform
> the top-level block in a certain mode,
> > with a tunneled parameter. The
> tunneled parameter contains the current
> > group and its ancestors.
> >
> > In the template that matches any
> element in this mode, you check whether
> > the tunneled parameter contains the current element. If so, the
> > next-match identity template will
> apply, if not, nothing will be written
> > to the result.
> >
> > There's a special template in this mode that matches the
> > two-column-start element. It will
> create <fo:block span="none"> and then
> > go on processing the children.
> >
> > I'm not 100% sure whether this
> works, but I have an intercontinental
> > flight ahead of me. It will give me
> some time to create working code,
> > unless you're faster implementing
> the suggested solution (or a better one).
> >
> > I guess that the solution scales
> with the number of splitting points
> > times the number of leaves, so
> performance may deteriorate for large
> > documents with frequently changing column spans.
> >
> > Gerrit
> >
> > On 18/04/2018 19:45, Eliot Kimber
ekimber(_at_)contrext(_dot_)com wrote:
> > > Using XSLT 2 with Saxon.
> > >
> > > In the context of generating
> XSL-FO markup where there tree of fo:block
> elements can be quite deep, I need to break the
> blocks into a sequence of top-level blocks that
> specify @span based on the presence of markers
> anywhere in the heirarchy. This is to support
> FOP's strict implementation of the FO spec,
> which only allows specifying column spans on direct children of fo:flow.
> > >
> > > In my processing I'm emitting
> marker elements to signal the starts and ends
> of areas that need to change the column spanning, e.g.:
> > >
> > > <fo:block span="all">
> > > <fo:block>
> > > <fo:block>
> > > <fo:block>
> > > <two-column-start/>
> > > </fo:block>
> > > ...
> > > <two-column-end/>
> > > </fo:block>
> > > <fo:block>...
> > > </fo:block>
> > > </fo:block>
> > >
> > > Where the result needs to be:
> > >
> > > <fo:block span="all">
> > > <!-- Stuff before two-column start -->
> > > </fo:block>
> > > <fo:block span="none">
> > > <!-- Stuff up to <two-column-end/> marker -->
> > > </fo:block>
> > > <fo:block span="all">
> > > <!-- Stuff after <two-column-end> marker -->
> > > </fo:block>
> > >
> > > There must be a general pattern
> for solving this kind of transformation pattern
> but I'm not seeing it or not remembering it.
> > >
> > > I can think of a recursive
> algorithm to do it but is there a simpler or
> more efficient approach? Conceptually it's a
> for-each-group problem but the structure of the
> content doesn't see to lend itself to grouping.
> > >
> > > Thanks,
> > >
> > > Eliot
> > > --
> > > Eliot Kimber
> > > http://contrext.com
> > >
> > >
> > >
--
Contact info, blog, articles, etc. http://www.CraneSoftwrights.com/s/ |
Check our site for free XML, XSLT, XSL-FO and UBL developer resources |
Streaming hands-on XSLT/XPath 2 training class @ US$45 (5 hours free) |
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--