#xml #pdf #xsl-fo #apache-fop #exponent
#xml #PDF #xsl-fo #apache-fop #экспонента
Вопрос:
Я пытаюсь распечатать свои формулы с экспонентами в формате PDF, используя xml, xsl и fo для преобразования из xml в pdf и в html. В html у меня нет проблем, все показатели отображаются правильно. возможно, потому, что браузеры будут отображать все символы utf-8. но, похоже, apache fop этого не сделает.
Есть ли кто-нибудь, кто может мне помочь, дать мне совет или показать мне, как это сделать. я не думаю, что я первый человек, которому нужно печатать экспоненты в формате PDF с помощью преобразований fo. единственный способ, которым мне удалось распечатать экспоненту, — это вручную написать встроенные теги и изменить смещение базовой линии на «перемещение» символов выше, но я думаю, что это не очень хорошее решение.
Следующие файлы примеров покажут мою проблему. В xsl-файле я попробовал некоторые вещи
xml-файл:
<?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-файл с некоторыми попытками:
<?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:amp;#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:amp;#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:amp;#160;amp;#8254;amp;#179;amp;#8254;amp;#179;amp;#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:amp;#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:amp;#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>
Ответ №1:
Встроенные элементы, вероятно, являются более распространенным способом. Это, безусловно, был мой опыт.
Таким образом, мое единственное предложение для ваших встроенных тегов — использовать baseline-shift="super"
(см. https://www.w3.org/TR/xsl11/#baseline-shift ), который должен использовать базовый верхний индекс, встроенный в шрифт.
Что касается того, почему встроенные элементы, есть несколько причин:
- Если вы хотите представлять более сложные формулы, вам лучше использовать MathML, а не обычный текст. (AFAICT, FOP нуждается в JEuclid, чтобы иметь возможность отображать MathML, но AH Formatter поддерживает MathML 3 изначально.)
- Стандарт Unicode не поощряет использование символов нижнего и верхнего индексов. Из «Стандарта Unicode, версии 6.2» (старый, но под рукой), раздел 15.4, символы верхнего и нижнего индексов:
В общем, стандарт Unicode не пытается описать расположение символа выше или ниже базовой линии в типографском макете. Поэтому предпочтительным способом кодирования надстрочных букв или цифр, таких как «1 st» или «DC00 16«, является стиль или разметка в форматированном тексте.
- Вы не можете быть уверены, что каждый шрифт содержит цифры с надстрочным индексом, поэтому также безопаснее использовать разметку и стили, чем ожидать, что каждая цифра с надстрочным индексом будет отображаться правильно.