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>

Reply via email to