如何正确的编译 Zend Framework 手册的 chm 版本

或许早就应该写一下这个方法了,只是一直没有什么心情。这会休息,就随手敲打敲打吧。

由于我的环境是 windows,所以需要额外安装一些辅助软件。windows 下编译 docbook 的方法有许多种。我以前使用 java 写的一个工具,不过后来发现 cygwin 比较方便。

详细的 cygwin 以及 docbook 编译必须的包请看 hohappy 编写的指南:http://www.phpeye.com/article/view/id/55

废话不说了,现在看看如何编译chm。首先需要编译 chm 对应的 xsl。我使用sf.net 下载的 docbook-xsl-1.72.0。其中包含 /htmlhelp/htmlhelp.xsl。

进入 Zend Framework 中文手册根目录,执行下面的命令:

$ autoconf  
$ ./configure  
$ export DOCBOOK_XSL=~/docbook-xsl-1.72.0/htmlhelp/htmlhelp.xsl

$ make -e 

make -e 是用环境变量覆盖 Makefile 中的变量。

这样,就会在 zh/html/ 目录下生成所有需要的文件,以及 htmlhelp.hhp 和 toc.hhc 文件。可以用微软出品的 HTML Help Workshop 直接编译 htmlhelp.hhp 文件,生成 chm 帮助。

OK,到此已经生成了 chm 帮助,但是如果是英文手册没有问题。中文手册由于 dtd 和 xsl 的规则问题,直接使用 htmlhelp.hhp 文件编译出来的手册目录是乱码。所以还缺少关键的转码一步。我是使用自己写的一个脚本完成了这个工作:

#!/cygdrive/e/AppServ/php5/php.exe
<?php
function toUtf8($ar)
{
    foreach(
$ar as $val)
    {
        
$val intval(substr($val,2),16);
        if(
$val 0x7F)
        {        
// 0000-007F
            
$c .= chr($val);
        }
        elseif(
$val 0x800)
        { 
// 0080-0800
            
$c .= chr(0xC0 | ($val 64));
            
$c .= chr(0x80 | ($val 64));
        }
        else
        {                
// 0800-FFFF
            
$c .= chr(0xE0 | (($val 64) / 64));
            
$c .= chr(0x80 | (($val 64) % 64));
            
$c .= chr(0x80 | ($val 64));
        }
    }
    return 
$c;
}
function 
uniDecode($str$charcode="UTF-8")
{
    
$text preg_replace_callback("/%u[0-9A-Za-z]{4}/"toUtf8$str);
    return 
mb_convert_encoding($text$charcode'utf-8');
}

function cp($m)
{
    return 
iconv('UTF-8''GBK'uniDecode('%u' dechex($m[1])));        
}

function c($str)
{
    return 
preg_replace_callback('/&#([0-9]+);/''cp'$str);
}

if (isset($_GET['fileName']))
{
    
$fileName $_GET['fileName'];
}
else if(isset(
$argv[1]))
{
    
$fileName $argv[1];
}
else
{
    echo 
"Usage: In the command line: php scriptName fileName or on the web http://foobar/scriptName.php?fileName=foobar";
}

if (isset($_GET['output']))
{
    
$output $_GET['output'];
}
elseif(isset(
$argv[2]))
{
    
$output $argv[2];
}
else
{
    
$p pathinfo($fileName);
    
$output $p['basename'];
}

$file file_get_contents($fileName);
$file c($file);
file_put_contents($output$file);

这个脚本可以工作在 web 和 cli 两种模式下。大家直接看一下代码了解一下使用方法吧。比较简单的。

用处理过的 hhp 和 hhc 文件重新编译,则可以得到编码正确的中文 chm 帮助。

Join the Conversation

2 Comments

  1. 其实还有更加简单的方法的说
    $doc = new DOMDocument();
    $doc->loadHTMLFile(‘toc.hhc’);
    echo $doc->saveHTML();

    it’s ok
    不过编码要修改一下,相比较更简单:)

Leave a comment

Your email address will not be published. Required fields are marked *