最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】docbook中生成的pdf的(中文字体的)emphasis无效果,没有加粗或斜体等效果

Docbook crifan 4005浏览 0评论

【问题】

docbook的源码中包含了emphasis的部分:

    <sect2><title>什么是ISO/IEC 11172-3和ISO/IEC 13818-3</title>
        <para>由于MPEG只是ISO/IEC下面的一个组织,所以,关于MPEG音频部分的规范,也都是出自ISO/IEC之手。</para>
        <para>因此,<emphasis>ISO/IEC 11172</emphasis>和<emphasis>ISO/IEC 13818</emphasis>,其实就是<emphasis>MPEG-1</emphasis>和<emphasis>MPEG-2</emphasis>的别名。</para>
        <para>另外,由于MPEG-1和MPEG-2,每个都分好几个部分,其中,第3部分是关于音频(Audio)的。</para>
        <para>所以,<emphasis>ISO/IEC 11172-3</emphasis>和<emphasis>ISO/IEC 13818-3</emphasis>,就分别对应着<emphasis>MPEG-1的音频</emphasis>,<emphasis>MPEG-2的音频</emphasis>,也就是我们常常提到的MPEG的音频文件所对应的规范。</para>
    </sect2>

生成的HTML中,效果如下:

html中有emphasis的效果

但是生成的pdf却没效果:

pdf中没有emphasis的效果

现在想要给pdf中的emphasis添加一定的效果,比如加粗,或斜体,或设置字体颜色为蓝色/红色等。

【解决过程】

1.估计pdf输出效果的控制,会有对应的参数的,所以又去:

DocBook XSL Stylesheets: Reference Documentation

找有没有和emphasis相关的参数。

结果没有找到,只找到一个针对HTML的emphasis.propagates.style,结果试了下,对于HTML输出也没啥影响。

2.找到了这个人的解释:

Docbook PDF格式输出效果增强实例

才知道,原来pdf中emphasis没效果,是中文字体没有对应的粗体字体所导致的。

所以去试试修改字体配置。

3.试了试改成这样:

        <font metrics-url="D:\tmp\tmp_dev_root\cgwin\home\CLi\develop\docbook\config\fop\fonts\msyh.xml" kerning="yes" embed-url="C:\Windows\Fonts\msyh.ttf">
          <font-triplet name="msyh" style="normal" weight="normal"/>
          
          <!-- <font-triplet name="msyh" style="normal" weight="bold"/> -->
          <font-triplet name="msyhbd" style="normal" weight="bold"/>
          
          <font-triplet name="msyh" style="italic" weight="normal"/>
          <font-triplet name="msyh" style="italic" weight="bold"/>
        </font>

结果还是没效果。

然后才发现,好像源码中emphasis没有加上bold,所以又去加上:

    <sect2><title>什么是ISO/IEC 11172-3和ISO/IEC 13818-3</title>
        <para>由于MPEG只是ISO/IEC下面的一个组织,所以,关于MPEG音频部分的规范,也都是出自ISO/IEC之手。</para>
        <para>因此,<emphasis role="bold">ISO/IEC 11172</emphasis>和<emphasis role="bold">ISO/IEC 13818</emphasis>,其实就是<emphasis role="bold">MPEG-1</emphasis>和<emphasis role="bold">MPEG-2</emphasis>的别名。</para>
        <para>另外,由于MPEG-1和MPEG-2,每个都分好几个部分,其中,第3部分是关于音频(Audio)的。</para>
        <para>所以,<emphasis role="bold">ISO/IEC 11172-3</emphasis>和<emphasis role="bold">ISO/IEC 13818-3</emphasis>,就分别对应着<emphasis role="bold">MPEG-1的音频</emphasis>,<emphasis role="bold">MPEG-2的音频</emphasis>,也就是我们常常提到的MPEG的音频文件所对应的规范。</para>
    </sect2>

结果还是不行。

然后又发现没有注释掉原先的msyhbd的部分,又去注释掉,变成:

        <font metrics-url="D:\tmp\tmp_dev_root\cgwin\home\CLi\develop\docbook\config\fop\fonts\msyh.xml" kerning="yes" embed-url="C:\Windows\Fonts\msyh.ttf">
          <font-triplet name="msyh" style="normal" weight="normal"/>
          
          <!-- <font-triplet name="msyh" style="normal" weight="bold"/> -->
          <font-triplet name="msyhbd" style="normal" weight="bold"/>
          
          <font-triplet name="msyh" style="italic" weight="normal"/>
          <font-triplet name="msyh" style="italic" weight="bold"/>
        </font>
        
        <font metrics-url="D:\tmp\tmp_dev_root\cgwin\home\CLi\develop\docbook\config\fop\fonts\msyhbd.xml" kerning="yes" embed-url="C:\Windows\Fonts\msyhbd.ttf">
          <font-triplet name="msyhbd" style="normal" weight="normal"/>
          <!-- <font-triplet name="msyhbd" style="normal" weight="bold"/> -->
          <font-triplet name="msyhbd" style="italic" weight="normal"/>
          <font-triplet name="msyhbd" style="italic" weight="bold"/>
        </font>
      </fonts>

结果试了还是不行,并且导致我原先的标题文字从雅黑粗体msyhbd都变成了msyh的字体了。

4.后来改了源码变为:

    <sect2><title>什么是ISO/IEC 11172-3和ISO/IEC 13818-3</title>
        <para>由于MPEG只是ISO/IEC下面的一个组织,所以,关于MPEG音频部分的规范,也都是出自ISO/IEC之手。</para>
        <para>因此,<emphasis role="strong">ISO/IEC 11172</emphasis>和<emphasis role="strong">ISO/IEC 13818</emphasis>,其实就是<emphasis role="bold">MPEG-1</emphasis>和<emphasis role="bold">MPEG-2</emphasis>的别名。</para>
        <para>另外,由于MPEG-1和MPEG-2,每个都分好几个部分,其中,第3部分是关于音频(Audio)的。</para>
        <para>所以,<emphasis role="underline">ISO/IEC 11172-3</emphasis>和<emphasis role="underline">ISO/IEC 13818-3</emphasis>,就分别对应着<emphasis role="bold">MPEG-1的音频</emphasis>,<emphasis role="bold">MPEG-2的音频</emphasis>,也就是我们常常提到的MPEG的音频文件所对应的规范。</para>
    </sect2>

结果只有underline有效果,其他都没效果:

只有underline有效果

5.参考:

Publishing DocBook Documents

去给xsl中添加:

<xsl:template match="emphasis">
  <fo:inline font-style="italic">
    <xsl:apply-templates/>  
  </fo:inline>
</xsl:template>

结果还是没实现所要的效果。

6.其实上面已经找到了对应emphasis部分的显示控制,在:

inline.xsl

中:

<xsl:template match="d:emphasis">
  <xsl:variable name="depth">
    <xsl:call-template name="dot.count">
      <xsl:with-param name="string">
        <xsl:number level="multiple"/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="@role='bold' or @role='strong'">
      <xsl:call-template name="inline.boldseq"/>
    </xsl:when>
    <xsl:when test="@role='underline'">
      <fo:inline text-decoration="underline">
        <xsl:call-template name="inline.charseq"/>
      </fo:inline>
    </xsl:when>
    <xsl:when test="@role='strikethrough'">
      <fo:inline text-decoration="line-through">
        <xsl:call-template name="inline.charseq"/>
      </fo:inline>
    </xsl:when>
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$depth mod 2 = 1">
          <fo:inline font-style="normal">
            <xsl:apply-templates/>
          </fo:inline>
        </xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="inline.italicseq"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

但是对于其所调用的inline.boldseq:

<xsl:template name="inline.boldseq">
  <xsl:param name="content">
    <xsl:call-template name="simple.xlink">
      <xsl:with-param name="content">
        <xsl:apply-templates/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:param>

  <fo:inline font-weight="bold">
    <xsl:if test="@dir">
      <xsl:attribute name="direction">
        <xsl:choose>
          <xsl:when test="@dir = 'ltr' or @dir = 'lro'">ltr</xsl:when>
          <xsl:otherwise>rtl</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:if>
    <xsl:copy-of select="$content"/>
  </fo:inline>
</xsl:template>

中,却没太看懂。

大概意思好像是,用:

<fo:inline font-weight="bold">

来实现字体设置为bold。

但是结果还是没效果啊。

不知道理解是否正确,以及是否此处的bold,就是对应着字体设置,body字体为msyh的bold中的:

<font-triplet name="SimHei" style="normal" weight="bold"/>

如果是,那应该显示出黑体才对,但是这里没效果。

7.折腾了半天,

参考这里:

XSL对象格式使用指南(三)

对于fo的语法,又多了些了解。

知道各种字体属性,背景属性等的关键词有哪些了。

知道了block和inline的区别了。

后来,继续折腾,通过手动将

inline.xsl中的<xsl:template name="inline.boldseq">中的:

<fo:inline font-weight="bold">

改为:

  <fo:inline font-weight="bold"
                color="red"
                >

是可以实现对应的红色字体的效果的:

手动给emphasis添加了color为red 是有效果的

所以,这样看来,还是可以想办法,把这个设置,提取出来,单独放到我的xsl配置文件中的。

经过测试,不需要修改原始的inline.xsl,而只需要把如下配置,放到xsl配置文件docbook_crl.xsl中:

8.根据上面已经贴出的,inline.xsl中的关于emphasis的配置可以看出,其对于默认的,没有加role="strong",role="bold"等的emphasis,其格式化为italic斜体的,对应的配置为:

<xsl:template name="inline.italicseq">
  <xsl:param name="content">
    <xsl:call-template name="simple.xlink">
      <xsl:with-param name="content">
        <xsl:apply-templates/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:param>

  <fo:inline font-style="italic">
    <xsl:call-template name="anchor"/>
    <xsl:if test="@dir">
      <xsl:attribute name="direction">
        <xsl:choose>
          <xsl:when test="@dir = 'ltr' or @dir = 'lro'">ltr</xsl:when>
          <xsl:otherwise>rtl</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:if>
    <xsl:copy-of select="$content"/>
  </fo:inline>
</xsl:template>

可以看出,其通过font-style="italic"去配置的字体为斜体,但是由于此处的中文,不支持,所以还是没效果的。

即普通的,不加参数的使用emphasis:

<para>MPEG规范中规定了,每一个版本的MPEG,比如MPEG1,MPEG2等,都有三种不同的Layer,不同Layer的序号命令是以罗马数字的,所以叫做Layer I, Layer II, Layer III。其中,MPEG-1或MPEG-2的Layer III,被称为MP3,而其中最常见的是MPEG 1 的Layer III,所以,被大家所熟知的MP3,一般都指的是MPEG-1的Lay III。
    </para>
    <para>即<emphasis>MPEG-1的Layer III</emphasis>被简称为<emphasis>MP3</emphasis>。</para>
    <para>根据事物发展由简到繁的规律,我们知道,Layer III,相对Layer I和Layer II,有着更复杂的压缩算法。正是其相对复杂,用了很多算法,比如声学上的掩蔽效应(masking effect),Huffman压缩等,才使得可以实现,在尽可能保持音质的前提下,极大地减少了音频文件大小,也就是说,尽量让你听上去音频声音和音质都没啥变化,但是MP3的文件大小,相对于原先没处理的音频数据或者其他格式的,比如WAV格式等,要小很多。</para>

其也是没有斜体的特殊效果的:

普通的不加参数的emphasis是没有效果的

而参照bold的方法,去在xsl中添加对应的配置:

<xsl:template name="inline.italicseq">
  <xsl:param name="content">
    <xsl:call-template name="simple.xlink">
      <xsl:with-param name="content">
        <xsl:apply-templates/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:param>

  <!-- <fo:inline font-style="italic"> -->
  <fo:inline font-family="msyhbd">
    <xsl:call-template name="anchor"/>
    <xsl:if test="@dir">
      <xsl:attribute name="direction">
        <xsl:choose>
          <xsl:when test="@dir = 'ltr' or @dir = 'lro'">ltr</xsl:when>
          <xsl:otherwise>rtl</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:if>
    <xsl:copy-of select="$content"/>
  </fo:inline>
</xsl:template>

然后就有效果了:

普通的不加参数的emphasis也是可以的

【总结】

想要给中文字体,此处为微软的雅黑(msyh)和微软的雅黑粗体(msyhbd),添加对应的emphasis的效果,直接使用默认的配置,是不行的,因为其默认的配置为斜体,但是pdf中显示不出来,所以,可以采用当emphasis,使用别的字体显示,此处使用msyhbd,以此来间接地实现emphasis的效果。

 

方法可以简述为:

将默认的inline.xsl中关于emphasis的配置中的:

inline.italicseq中的:

<fo:inline font-style="italic">

inline.boldseq中的:

<fo:inline font-weight="bold">

都改为:

<fo:inline font-family="msyhbd">

 

具体做法如下:

在自己的xsl配置文件中,添加如下代码:

<xsl:template name="inline.italicseq">
  <xsl:param name="content">
    <xsl:call-template name="simple.xlink">
      <xsl:with-param name="content">
        <xsl:apply-templates/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:param>

  <!-- <fo:inline font-style="italic"> -->
  <fo:inline font-family="msyhbd">
    <xsl:call-template name="anchor"/>
    <xsl:if test="@dir">
      <xsl:attribute name="direction">
        <xsl:choose>
          <xsl:when test="@dir = 'ltr' or @dir = 'lro'">ltr</xsl:when>
          <xsl:otherwise>rtl</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:if>
    <xsl:copy-of select="$content"/>
  </fo:inline>
</xsl:template>


<xsl:template name="inline.boldseq">
  <xsl:param name="content">
    <xsl:call-template name="simple.xlink">
      <xsl:with-param name="content">
        <xsl:apply-templates/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:param>

  <!-- <fo:inline font-weight="bold"> -->
  <fo:inline font-family="msyhbd">
    <xsl:if test="@dir">
      <xsl:attribute name="direction">
        <xsl:choose>
          <xsl:when test="@dir = 'ltr' or @dir = 'lro'">ltr</xsl:when>
          <xsl:otherwise>rtl</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:if>
    <xsl:copy-of select="$content"/>
  </fo:inline>
</xsl:template>

就可以实现,对于emphasis的默认配置(斜体)和添加了role="strong",role="bold"等的emphasis,都使用msyhbd字体来显示。

注:上面的内容,是从docbook-xsl-ns-1.76.1\fo\inline.xsl中拷贝出来,然后把字体修改为msyhbd的。

【一点疑问】

说是中文字体没有对应的斜体,但是却看到最开始就贴出来的,HTML中,emphasis却是可以正常显示出斜体的效果的。不知道为何?有待后续搞懂原因。

【后记 2012-06-05】

后来知道了,中文字体在html中有斜体等效果,是浏览器渲染出来的,不是真正的斜体的中文字体。

另外,后来对于emphasis的效果,后来改为换个其他的颜色,这样就更加容易实现了“强调”的效果了。

即把上述的font-family="msyhbd"改为color="brown"即可。

转载请注明:在路上 » 【已解决】docbook中生成的pdf的(中文字体的)emphasis无效果,没有加粗或斜体等效果

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.177 seconds, using 22.05MB memory