最新消息:20210917 已从crifan.com换到crifan.org

【已解决】Docbook中的callout图片在programlisting中不显示 -> xsltproc不支持areaspec

Docbook crifan 1959浏览 0评论

【问题】

Docbook中,已经设置了正确的callout的路径:

<xsl:param name="callout.graphics" select="1"></xsl:param>
<xsl:param name="callout.graphics.path">images/system/callouts/</xsl:param>

以及相应的代码:

<programlistingco>
    <areaspec>
        <area id="plco.cmdfunc" coords='6'/>
        <area id="plco.read_page" coords='8'/>
    </areaspec>
    <programlisting language="c">
    static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
    {
        ............
        while(1) {
            ......
            chip-&gt;cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
            ......
            ret = chip-&gt;ecc.read_page(mtd, chip, bufpoi,
            buf += bytes;
            ......
            readlen - = bytes;
            if (! readlen)
            break;
            / * For subsequent reads align to page boundary. */
            col = 0;
            / * Increment page address */
            realpage++;
            page = realpage &amp; chip-&gt;pagemask;
            ......
            }
        ......
        }

        ............
        return mtd-&gt;ecc_stats.corrected - stats.corrected ? - EUCLEAN : 0;
    }
    </programlisting>
    <calloutlist>
        <callout arearefs="plco.cmdfunc" >
            <para>要读取数据,肯定是要先发送对应的读页(read page)的命令</para>
        </callout>
        <callout arearefs="plco.read_page">
            <para>发送完命令,接着就可以去调用read_page函数读取对应的数据了</para>
        </callout>
    </calloutlist>
</programlistingco>

在输出的HTML和PDF中也已经可以显示出对应的图片了,但是却在代码部分,即programlisting中,没有显示对应的callout:代码中没有callout图片但是注脚部分有callout

现在要解决,希望代码中,也显示对应的callout图片。

【解决过程】

1.参考:programlistingco,试了代码:

<programlistingco>
    <areaspec>
        <areaset id="ex.plco.const" coords="">
          <area id="ex.plco.c1" coords='4'/>
          <area id="ex.plco.c2" coords='8'/>
        </areaset>
        <area id="ex.plco.ret" coords='12'/>
        <area id="ex.plco.dest" coords='12'/>
    </areaspec>
    
    <programlisting>
    sub do_nothing_useful {
        my($a, $b, $c);

        $a = new A;
        
        $a->does_nothing_either();

        $b = new B; 

        $c = "frog";

        return ($a, $c);
    }
    </programlisting>
    
    <calloutlist>
        <callout arearefs="ex.plco.const">
        <para>
        These are calls to the constructor <function>new</function> in the object
        classes.
        </para>
        </callout>
        <callout arearefs="ex.plco.ret">
        <para>
        This function returns a two-element list.
        </para>
        </callout>
        <callout arearefs="ex.plco.dest">
        <para>
        The <emphasis>destructor</emphasis> (<function>DESTROY</function>) for
        the object <literal>$b</literal> will be called automatically for this
        object since there can be no other references to it outside this function.
        </para>
        </callout>
    </calloutlist>
</programlistingco>

结果和最开始一样,还是代码中没有显示出callout图片。

2.去参考:HTMl的1.2. Callouts和FO的2.2. Callouts,结果试了很多其他一些参数,包括:

<xsl:param name="use.extensions" select="1"></xsl:param>
<xsl:param name="callouts.extension" select="1"></xsl:param>

<xsl:param name="callout.defaultcolumn">60</xsl:param>
<xsl:param name="callout.graphics.extension">.svg</xsl:param>

但是还是没有使得callout图片在代码中显示出来。

3.参考:

Re: [docbook-apps] callouts don’t work in various settings

去试了试:

<xsl:param name="shade.verbatim" select="0"></xsl:param>

结果还是不行。

4.也试了,参考:13. Callouts,去用如下代码:

<screen>
bash@host:~/cvs/newbiedoc$ ls -l
total 48
<co id="perm">drwxr-sr-x    2 jesse    jesse        4096 May  4 16:26 CVS<co id="cvs">
drwxr-sr-x    3 jesse    jesse        4096 Mar 29 03:29 dev
drwxr-sr-x    3 jesse    jesse        4096 Apr  8 19:31 general
drwxr-sr-x    3 jesse    jesse        4096 Apr  9 00:15 images
-rw-r--r--    1 jesse    jesse        4133 Apr 22 05:18 index.sgml
drwxr-sr-x    3 jesse    jesse        4096 Apr  2 02:25 metadoc
drwxr-sr-x    3 jesse    jesse        4096 May  4 19:33 metatools
drwxr-sr-x    3 jesse    jesse        4096 Apr  9 02:02 system
drwxr-sr-x    3 jesse    jesse        4096 Mar 29 01:24 text_editing
drwxr-sr-x    3 jesse    jesse        4096 May  4 00:17 tips
drwxr-sr-x    3 jesse    jesse        4096 Mar 29 01:24 utils
</screen>

<calloutlist>
   <callout arearefs="cvs">
      <para>
      This is the CVS directory.  CVS files are stored here.
      </para>
   </callout>

   <callout arearefs="perm">
      <para>
      These are the permissions for the CVS directory.
      </para>
   </callout>
</calloutlist>

结果也是不行。

5.最后是参考:Annotating program listings,写出如下代码:

<programlistingco>
    <programlisting language="c">
    static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
    {
        ............
        while(1) {
            ......
            chip-&gt;cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); <co id="co.cmdfunc" linkends="co.note.cmdfunc"/>
            ......
            ret = chip-&gt;ecc.read_page(mtd, chip, bufpoi, <co id="co.read_page" linkends="co.note.read_page"/>
            buf += bytes;
            ......
            readlen - = bytes;
            if (! readlen)
            break;
            / * For subsequent reads align to page boundary. */
            col = 0;
            / * Increment page address */
            realpage++;
            page = realpage &amp; chip-&gt;pagemask;
            ......
            }
        ......
        }

        ............
        return mtd-&gt;ecc_stats.corrected - stats.corrected ? - EUCLEAN : 0;
    }
    </programlisting>
    <calloutlist>
        <callout id="co.note.cmdfunc" arearefs="co.cmdfunc" >
            <para>要读取数据,肯定是要先发送对应的读页(read page)的命令</para>
        </callout>
        <callout id="co.note.read_page"  arearefs="co.read_page">
            <para>发送完命令,接着就可以去调用read_page函数读取对应的数据了</para>
        </callout>
    </calloutlist>
</programlistingco>

最后终于实现了,不仅可以在注释中,也可以在代码中显示callout图片了。

并且同时支持了,两个地方,都可以互相引用,这样鼠标就可以点击该callout图片,来回跳转了。

效果如下:代码和注释中 都有callout 且都可以互相引用了 可以点击了

【总结】

想要正常实现不仅在注释部分,也在代码中,显示callout图片,则先去设置:

<xsl:param name="callout.graphics" select="1"></xsl:param>
<xsl:param name="callout.graphics.path">images/system/callouts/</xsl:param>

然后在programlisting中添加co标签,且加上id,然后在callout中arearefs中引用该id,即可:

<programlistingco>
    <programlisting language="c">
    static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
    {
        chip-&gt;cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); <co id="co.cmdfunc" linkends="co.note.cmdfunc"/>
        ......
    }
    </programlisting>
    <calloutlist>
        <callout id="co.note.cmdfunc" arearefs="co.cmdfunc" >
            <para>要读取数据,肯定是要先发送对应的读页(read page)的命令</para>
        </callout>
    </calloutlist>
</programlistingco>

【后记 2012-05-30】

后来无意间在Annotating program listings中看到了这段说明:

You have to wrap your programlisting and calloutlist in a programlistingco element, because it supports the use of an areaspec to provide the coordinates. You also must use either Saxon or Xalan to process the files, because placing the callouts at the coordinates takes an XSLT extension function that is not available in xsltproc.

即,xsltproc不支持areaspec,所以才会出现之前遇到的,代码中用了areaspec后,无论如何设置,始终都无法用xsltproc+fop生成对应callout呢。原来是本身就不支持。

那说起来就有点变态了,既然常用的工具之一xsltproc不支持areaspec,结果在官方的programlistingco中的例子里面,却用了areaspec,却也没有加上合适的说明。

这样明显会导致我等不是足够熟悉的人,浪费大量的时间去折腾这个。

你直接给个co的用法,不就好了么。。。对于那些写例子的人,真是无语了。。。

转载请注明:在路上 » 【已解决】Docbook中的callout图片在programlisting中不显示 -> xsltproc不支持areaspec

发表我的评论
取消评论

表情

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

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
89 queries in 0.202 seconds, using 20.19MB memory