-1

I try to print my formulas with exponents in pdf using xml, xsl and fo to transform from xml to pdf and to html. In html, i have no problem, all exponents are shown correctly. maybe because the browsers will show all utf-8 characters. but it seems that apache fop will not do that.

Is there someone that can help me out, give me a tip or show me the way how to do that. i don't think that i'm the first person that needs to print exponents in pdf with fo transformations. the only way i managed to print exponent was to manually write inline-tags and changed the baseline-shift to "move" the characters higher, but i think thats not a good solution.

Following example files will show my problem. In the xsl-File, i tried some things out

xml-file:

<?xml version="1.0" encoding="utf-8"?>
<demo>
    <formulas>
      <formula>0,2 µm + 3 · 10⁻⁶ · a</formula>
      <formula>0,3 µm + 4 · 10⁻³ · b</formula>
      <formula>0,4 µm + 5 · E-6 · c</formula>
      <formula>0,5 µm + 6 · E-3 · d</formula>
    </formulas>
</demo>

xsl-file with some tries:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    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"
    xmlns:own="http://www.own.com"
    >

    <xsl:template match="/demo">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="master_demo" page-width="21.0cm" page-height="29.7cm" margin-top="0.5cm" margin-bottom="0.25cm" margin-left="2.0cm" margin-right="1.0cm">
                    <fo:region-body region-name="flow_demo" margin-top="0.0cm" margin-bottom="0.85cm" />
                    <fo:region-before extent="4.5cm" />
                    <fo:region-after extent="0.5cm"/>
                </fo:simple-page-master>
            </fo:layout-master-set>

            <fo:page-sequence master-reference="master_demo">
                <fo:flow flow-name="flow_demo">
                    <fo:block-container absolute-position="fixed" top="5.0cm" margin-left="1.0cm">
                        <fo:block>
                            <fo:table>
                                <fo:table-column column-width="6.0cm"/>
                                <fo:table-column column-width="6.0cm"/>
                                <fo:table-column column-width="6.0cm"/>
                                <fo:table-body>
                                    <xsl:for-each select="formulas/formula">
                                        <fo:table-row>
                                            <fo:table-cell>
                                                <fo:block font-size="9pt" font-family="SansSerif" margin-top="0.2cm">
                                                    Test:&#160;<xsl:value-of select="own:GetFormattedFormulaPDF(.)"/>
                                                </fo:block>
                                            </fo:table-cell>
                                            <fo:table-cell>
                                                <fo:block font-size="9pt" font-family="SansSerif" margin-top="0.2cm">
                                                    Test:&#160;<xsl:copy-of select="own:GetFormattedFormulaPDF(.)"></xsl:copy-of>
                                                </fo:block>
                                            </fo:table-cell>
                                            <fo:table-cell>
                                                <fo:block font-size="9pt" font-family="SansSerif" margin-top="0.2cm">
                                                    Test:&#160;&#8254;&#179;&#8254;&#179;&#8315;
                                                </fo:block>
                                            </fo:table-cell>
                                        </fo:table-row>
                                    </xsl:for-each>
                                </fo:table-body>
                            </fo:table>

                            <fo:table margin-top="2.0cm">
                                <fo:table-column column-width="10.0cm"/>
                                <fo:table-body>
                                    <xsl:for-each select="formulas/formula">
                                        <fo:table-row>
                                            <fo:table-cell>
                                                <fo:block font-size="9pt" font-family="SansSerif" margin-top="0.2cm">
                                                    XML-Text:&#160;<xsl:value-of select="."/>
                                                </fo:block>
                                            </fo:table-cell>
                                        </fo:table-row>
                                    </xsl:for-each>
                                </fo:table-body>
                            </fo:table>

                            <fo:table margin-top="2.0cm">
                                <fo:table-column column-width="10.0cm"/>
                                <fo:table-body>
                                    <xsl:for-each select="formulas/formula">
                                        <fo:table-row>
                                            <fo:table-cell>
                                                <fo:block font-size="9pt" font-family="SansSerif" margin-top="0.2cm">
                                                    <xsl:call-template name="mu">
                                                        <xsl:with-param name="formula" select = "." />
                                                    </xsl:call-template>
                                                </fo:block>
                                            </fo:table-cell>
                                        </fo:table-row>
                                    </xsl:for-each>
                                </fo:table-body>
                            </fo:table>

                            <fo:table margin-top="2.0cm">
                                <fo:table-column column-width="10.0cm"/>
                                <fo:table-body>
                                    <xsl:for-each select="formulas/formula">
                                        <fo:table-row>
                                            <fo:table-cell>
                                                <fo:block font-size="9pt" font-family="SansSerif" margin-top="0.2cm">
                                                    Formula with fo-tags:&#160;0,9 µm + 5 · 10<fo:inline font-size="7pt" baseline-shift="40%">–4</fo:inline> · <fo:inline font-style="italic">abc</fo:inline>
                                                </fo:block>
                                            </fo:table-cell>
                                        </fo:table-row>
                                    </xsl:for-each>
                                </fo:table-body>
                            </fo:table>

                        </fo:block>
                    </fo:block-container>
                </fo:flow>
            </fo:page-sequence>

        </fo:root>
    </xsl:template>
    
    <xsl:function name="own:GetFormattedFormulaPDF" as="xs:string">
        <xsl:param name="mu" as="xs:string"></xsl:param>
        <xsl:choose>
            <xsl:when test="contains($mu, '10⁻³')">
                <xsl:variable name="E-3d">
                    10<fo:inline font-size="7pt" baseline-shift="40%">–3</fo:inline> · <fo:inline font-style="italic">d</fo:inline>
                </xsl:variable>
                <xsl:value-of select="concat(substring-before($mu, '10⁻³'),$E-3d)"/>
            </xsl:when>
            <xsl:when test="contains($mu, '10⁻⁶')">
                <xsl:variable name="E-6d">
                    10<fo:inline font-size="7pt" baseline-shift="40%">–6</fo:inline> · <fo:inline font-style="italic">d</fo:inline>
                </xsl:variable>
                <xsl:value-of select="concat(substring-before($mu, '10⁻⁶'),$E-6d)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="formel">
                    Formel direkt -> 50<fo:inline font-size="7pt" baseline-shift="40%">–12</fo:inline> · <fo:inline font-style="italic">dx</fo:inline>
                </xsl:variable>
                <xsl:value-of select="$formel"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
    
    <xsl:template name="mu">
        <xsl:param name="formula"></xsl:param>
        <xsl:choose>
            <xsl:when test="contains($formula, '10⁻³')">
                <xsl:variable name="E-3d">
                    Hier Minus 3 -> 10<fo:inline font-size="7pt" baseline-shift="40%">–3</fo:inline> · <fo:inline font-style="italic">d</fo:inline>
                </xsl:variable>
                <xsl:value-of select="concat(substring-before($formula, '10⁻³'),$E-3d)"/>
            </xsl:when>
            <xsl:when test="contains($formula, '10⁻⁶')">
                <xsl:variable name="E-6d">
                    Hier Minus 6 -> 10<fo:inline font-size="7pt" baseline-shift="40%">–6</fo:inline> · <fo:inline font-style="italic">d</fo:inline>
                </xsl:variable>
                <xsl:value-of select="concat(substring-before($formula, '10⁻⁶'),$E-6d)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="formel">
                    Formel direkt -> 50<fo:inline font-size="7pt" baseline-shift="40%">–12</fo:inline> · <fo:inline font-style="italic">dx</fo:inline>
                </xsl:variable>
                <xsl:value-of select="$formel"/>
            </xsl:otherwise>
        </xsl:choose>        
    </xsl:template>

</xsl:stylesheet>
Tom
  • 157
  • 1
  • 2
  • 8

1 Answers1

2

Inline elements is probably the more common way. It certainly has been my experience.

As such, my only suggestion for your inline tags is to use baseline-shift="super" (see https://www.w3.org/TR/xsl11/#baseline-shift), which should use a superscript baseline that is built into the font.

As to why inline elements, there's multiple reasons:

  • If you want to represent more complex formulas, you'd be better off using MathML rather than plain text. (AFAICT, FOP needs JEuclid to be able to render MathML, but AH Formatter supports MathML 3 natively.)
  • The Unicode Standard doesn't encourage use of subscript and superscript characters. From 'The Unicode Standard, Version 6.2' (old but near to hand), Section 15.4, Superscript and Subscript Symbols:

In general, the Unicode Standard does not attempt to describe the positioning of a character above or below the baseline in typographic layout. Therefore, the preferred means to encode superscripted letters or digits, such as "1st" or "DC0016", is by style or markup in rich text.

  • You can't be certain that every font has superscript numerals, so it's also safer to use markup and styles than to expect every superscript numeral to come out correctly.
Tony Graham
  • 7,306
  • 13
  • 20