Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to produce an initial at the first line of a paragraph without enlargin the line-height?

I want an initial at the first line of a paragraph and a text-indent for all the other paragraphs. I'm using the following code:

<xsl:template match="paragraph">
    <xsl:choose>
        <!-- no text-indent, first letter bigger -->
        <xsl:when test="fn:position() = 1">
            <fo:block font-size="10pt" font-height="12pt">
                <fo:inline font-size="18pt"><xsl:value-of 
                  select="substring(.,1,1)"/></fo:inline>
                <xsl:value-of select="substring(.,2)"/>
            </fo:block>
        </xsl:when>
        <xsl:otherwise>
            <!-- text-indent --> 
            <fo:block line-height="12pt"  
                text-indent="10pt">
                <xsl:value-of select="."/></fo:block>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

This works, but the line-height of the first line is enlarged and there is to much space between the lines. enter image description here

line-height-attributes or <fo:initial-property-set> don't work. Thanks a lot.

Edit: I'm using fop

Edit: FOP doesn't support <fo:float> or <fo:initial-property-set>. I tried another code using <fo:list>:

        <xsl:when test="fn:position() = 1">
            <fo:block font-family="Times" font-size="10pt" line-height="12pt"> 
                <fo:list-block>
                    <fo:list-item>
                        <fo:list-item-label>
                            <fo:block font-size="18pt"><xsl:value-of select="substring(.,1,1)"/></fo:block>
                        </fo:list-item-label>
                        <fo:list-item-body>
                            <fo:block><xsl:value-of select="substring(.,2)"/></fo:block>
                        </fo:list-item-body>
                    </fo:list-item>
                </fo:list-block>
            </fo:block>
        </xsl:when>

The result looks like this:

enter image description here

So i used figure space &#8199; in the value-of select pattern of the <fo:list-item-body>:

        <xsl:when test="fn:position() = 1">
            <fo:block font-family="Times" font-size="10pt" line-height="12pt"> 
                <fo:list-block>
                    <fo:list-item>
                        <fo:list-item-label>
                            <fo:block font-size="18pt"><xsl:value-of select="substring(.,1,1)"/></fo:block>
                        </fo:list-item-label>
                        <fo:list-item-body>
                            <fo:block><xsl:value-of select="('&#8199;', '&#8199;', substring(.,2))"/></fo:block>
                        </fo:list-item-body>
                    </fo:list-item>
                </fo:list-block>
            </fo:block>
        </xsl:when> 

This isn't just dowdy, it also doesn't work really good:

enter image description here

enter image description here

Does anyone have a solution?

like image 645
FelHa Avatar asked Oct 21 '22 15:10

FelHa


1 Answers

This xsl snippet, minimally revised from the first one in the question, produces the desired result using Apache FOP:

<xsl:template match="paragraph">
    <xsl:choose>
        <!-- no text-indent, first letter bigger -->
        <xsl:when test="not(preceding-sibling::paragraph)">
            <fo:block line-height="12pt" 
                line-stacking-strategy="font-height">
                <fo:inline font-size="18pt"><xsl:value-of 
                  select="substring(.,1,1)"/></fo:inline>
                <xsl:value-of select="substring(.,2)"/>
            </fo:block>
        </xsl:when>
        <xsl:otherwise>
            <!-- text-indent --> 
            <fo:block line-height="12pt"  
                text-indent="10pt">
                <xsl:value-of select="."/></fo:block>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

Important points:

  • all fo:blocks are given the same line-height
  • the first one has line-stacking-strategy="font-height", so the formatter builds the lines using the nominal-requested-line-rectangle, regardless of the dimensions of inline children
  • testing the condition position() = 1, as done in the question, is a bit risky if the input file is indented (as child #1 could be a text node made only of whitespace, and the "first" paragraph element would be child #2), so I check not(preceding-sibling::paragraph) instead
  • the initial letter of the first paragraph overflows the resulting line area; some space-before can be set on the fo:block to avoid this, if needed
like image 109
lfurini Avatar answered Nov 01 '22 12:11

lfurini