A writer here pointed out a problem with keeps and breaks and images. I'm not sure if
this is the renderer (XEP) making a decision that I don't agree with or with the
markup that the xsls produce. I've come up with a couple of templates that help our
case, but I think the problem is more genreral. Here's what we noticed. Given:
<para>
Blah blah.
<informalfigure float="0">
<mediaobject>
<imageobject><imagedata fileref="../image.gif"/>
</imageobject>
</mediaobject>
</informalfigure>
</para>
<para>
More text
</para>
The xsls give us something like this (I've simplified it for readablity):
<fo:block>
Blah blah.
<fo:block>
<fo:external-graphic
src="url(./image.gif)"
content-width="auto"
content-height="auto"/>
</fo:block>
</fo:block>
<fo:block>
More text
</fo:block>
XEP does this with the fo (Hope my ascii art doesn't get munged):
|-----------| |-----------|
|Blah blah | ||---------||
| | ||image.gif||
| | || ||
| | || ||
| | || ||
| | ||---------||
| | |More Text |
|-----------| |-----------|
This is what we'd like:
|-----------| |-----------|
|Blah blah | |More Text |
||---------|| | |
||image.gif|| | |
|| || | |
|| || | |
|| || | |
||---------|| | |
|-----------| |-----------|
The only thing that really seems to work is this:
<fo:block>
Blah blah.
</fo:block><!-- closing the para and adding a keep-with-previous and a
keep-together to the next block. XEP requires the keep together or it won't respect
the keep-with-previous -->
<fo:block keep-with-previous.within-column="always"
keep-together.within-column="always"
<fo:external-graphic
src="url(./image.gif)"
content-width="auto"
content-height="auto"/>
</fo:block>
I'm thinking it's a more general problem with any block level element inside a para.
For example if you had <para>Text <itemizedlist>..., you'd want the itemizedlist kept
with the previous text.
Below is the fix that seems to work for figures and screenshots. It seems a little
ugly to me--I can only imagine what it will look like if I tried to make it handle all
the block level things that can appear in a para (also, in its present form it
requires xsl version="1.1"). Is there a more elegant/easier way to do this?
David
<xsl:template match="para[informalfigure or figure or screenshot]">
<fo:block xsl:use-attribute-sets="normal.para.spacing">
<xsl:call-template name="anchor"/>
<xsl:call-template name="para.figure">
<xsl:with-param name="current.nodeset">
<xsl:copy-of select="./* | ./text() | ./processing-instruction() |
./comment()"/>
</xsl:with-param>
</xsl:call-template>
</fo:block>
</xsl:template>
<xsl:template name="para.figure">
<xsl:param name="current.nodeset"/>
<xsl:variable name="before.figure">
<xsl:for-each select="node()">
<xsl:if test="
not(self::informalfigure) and
not(self::figure) and
not(self::screenshot) and
not(preceding-sibling::informalfigure) and
not(preceding-sibling::figure) and
not(preceding-sibling::screenshot)">
<xsl:copy-of select="current()"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="rest">
<xsl:for-each select="$current.nodeset/node()">
<xsl:if test="preceding-sibling::informalfigure or
preceding-sibling::figure or preceding-sibling::screenshot">
<xsl:copy-of select="current()"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<fo:block><!-- before.figure -->
<xsl:apply-templates select="$before.figure/node()"/>
</fo:block>
<xsl:if test="
$current.nodeset/informalfigure or
$current.nodeset/figure or
$current.nodeset/screenshot">
<fo:block
keep-with-previous.within-column="always"
keep-together.within-column="always"
xsl:use-attribute-sets="normal.para.spacing">
<xsl:apply-templates select="$current.nodeset/informalfigure[
not(preceding-sibling::figure) and
not(preceding-sibling::informalfigure) and
not(preceding-sibling::screenshot)]"/>
<xsl:apply-templates select="$current.nodeset/figure[
not(preceding-sibling::figure) and
not(preceding-sibling::informalfigure) and
not(preceding-sibling::screenshot)]"/>
<xsl:apply-templates select="$current.nodeset/screenshot[
not(preceding-sibling::figure) and
not(preceding-sibling::informalfigure) and
not(preceding-sibling::screenshot)]"/>
</fo:block>
</xsl:if>
<xsl:if test="normalize-space($rest) != ''">
<xsl:call-template name="para.figure">
<xsl:with-param name="current.nodeset" select="$rest"/>
</xsl:call-template>
</xsl:if>
</xsl:template>