如何在不扩大行高的情况下在段落的第一行生成一个首字母?

时间:2014-02-01 17:40:50

标签: xslt pdf xsl-fo apache-fop

我希望段落的第一行有一个首字母,所有其他段落的文本缩进。我正在使用以下代码:

<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>

这样可行,但第一行的行高增大,行之间有很大的空间。 enter image description here

line-height-attributes或<fo:initial-property-set>不起作用。 非常感谢。

编辑:我正在使用fop

修改:FOP不支持<fo:float><fo:initial-property-set>。我使用<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>

结果如下:

enter image description here

所以我在&#8199;的选择模式的值中使用了数字空间<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> 

这不仅仅是邋,,它也不是很好用:

enter image description here

enter image description here

有没有人有解决方案?

1 个答案:

答案 0 :(得分:3)

这个xsl片段,从问题中的第一个最小修订版,使用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>

重点:

  • 所有fo:块都被赋予相同的 line-height
  • 第一个 line-stacking-strategy =“font-height”,因此格式化程序使用nominal-requested-line-rectangle构建行,而不管内联子项的维数
  • 测试条件 position()= 1 ,如问题中所做的那样,如果输入文件是缩进的,则有点冒险(因为子#1可能是仅由空格组成的文本节点,并且“第一个”元素将是孩子#2),所以我检查 not(preceding-sibling :: paragraph)而不是
  • 第一段的首字母溢出了生成的行区域;可以在fo:block上设置一些 space-before 以避免这种情况,如果需要的话