利用Html文件生成chm文件
文章目录
对个人使用HTML
网页生成CHM格式说明手册的使用经验进行简单的记录与分享。
背景
CHM
(Microsoft Compiled HTML Help)是微软公司开发的文件帮助格式,包含了由一系列的HTML
页面、目录菜单、索引和其它导航工具,在Windows
环境下可方便的打开与查阅。
由于其使用的便利性(Windows
环境下可直接打开,无须各种依赖),故相同当多的软件在Windows
环境下都提供了CHM
格式的说明手册,出于此考虑个人想将部门的部分使用软件整合为CHM
格式,在此过程中发现网络上关于此方面的资料较少,故简单记录下。
软件安装
说明
由于CHM
是微软开发的,其自家的操作系统为Windows
,故本文的操作环境也为Windows
。
点击此链接下载名为htmlhelp.exe
的文件,双击安装完毕后其目录结构类似如下
从图中可看出部分文件的日期相当老旧,事实上自从2009年起微软官方便计划不在提供新版本的CHM
1,尽管如此但并不影响CHM
的正常使用。
将安装路径添加到系统环境变量后,可采用类似如下方式验证安装是否成功
CHM生成
环境准备好之后,可以通过下述步骤实现将1个简单的HTML
文件生成CHM
文件:
1.编写一个简单的HTML
文件,假设其名称为index.html
,内容如下
<!DOCTYPE html>
<html>
<head>
<title>CHM测试</title>
<meta charset="utf-8">
<style type="text/css">
.content {
background-color: powderblue;
width:80%;
margin-left:auto;
margin-right:auto;
padding: 10px;
min-height:100px;
}
.content:hover {
background-color: #3e8e41;
color: white;
}
</style>
</head>
<body>
<p class="content">测试生成简单的<strong>CHM</strong>文件</p>
</body>
</html>
该文件的显示效果如下
2.编写一个扩展名为hhp
(全称为HTML Help Project
)的文件,文件名称不限制,内容如下
[OPTIONS]
Compatibility=1.1 or later
Compiled file=help.chm
Default topic=index.html
Display compile progress=Yes
Language=0x804 中文(简体,中国)
[FILES]
index.html
关于上述文件中的属性具体说明可参见此链接或此链接,也可查看老外写的更加详细的说明或在线文档。
3.假设前述步骤中的文件名为chm-test.hhp
,在命令行执行如下命令
hhc chm-test.hhp
若环境配置正确,则输出类似如下
4.若一切正常,则会在当前目录生成一个名为help.chm
的文件,打开后其展示效果如下,可看出其展示效果和步骤1中的HTML
页面直接展示类似
中文文件名
若想将生成的CHM
文件改为中文名称,可将前面的hhp
文件内容修改如下
[OPTIONS]
Compatibility=1.1 or later
Compiled file=帮助手册.chm
Default topic=index.html
Display compile progress=Yes
Language=0x804 中文(简体,中国)
[FILES]
index.html
执行编译命令的输出类似如下,可看出输出过程中的中文显示乱码,实际生成的CHM
文件名称也确实是乱码。
此问题一般是由编码问题造成的,需要将hhp
文件的编码从UTF-8
修改为ANSI
重新执行构建命令后可发现能正常生成中文文件
中文标题支持
如下图所示,默认情况下生成的CHM
文件标题在中文环境为帮助,在英文环境下为Help,看起来不太直观。
可通过此说明在hhp
文件中设置Title
属性来实现,根据说明可修改为如下
[OPTIONS]
Compatibility=1.1 or later
Compiled file=帮助手册.chm
Default topic=index.html
Display compile progress=Yes
Language=0x804 中文(简体,中国)
Title=简单的说明文档
[FILES]
index.html
此时如果执行构建指令,会发现CHM
文件的标题还是没有变化,网络上这方面的资料较少,经过自己的一番对比与尝试后,发现Title
属性必须与其它功能结合后才生效,如搜索功能、菜单目录等,原因暂时不明。
假设要添加搜索功能,将hhp
文件修改如下
[OPTIONS]
Compatibility=1.1 or later
Compiled file=帮助手册.chm
Default topic=index.html
Display compile progress=Yes
Language=0x804 中文(简体,中国)
Title=简单的说明文档
;支持搜索功能
Full-text search=Yes
[FILES]
index.html
重新执行构建指令,并打开生成的CHM
文件,可发现其标题已经改变。
菜单目录支持
前述的内容都是基于单个HTML
页面,实际使用中肯定会涉及多个文件,尤其是使用手册等说明类的文档,通常需要添加菜单目录来进行合适的分类与快速导航定位。
可通过在编译时提供hhc
(全称为HTML Help Contents
)文件来生成带有菜单目录的CHM
文件,相关操作步骤如下:
1.为了便于管理,将相关的文件都放到一个文件夹下,其层级结构如下所示,其中包含多个HTML
文件和图片等文件
2.建议一个如下图所示的hhp
文件,可发现其与前面的hhp
文件有一定差异,通过Contents file
文件来配置菜单目录,同时无需在FILES
下面指定具体的文件列表(因为在hhc
文件中已经包含了相关的文件)
[OPTIONS]
Compatibility=1.1 or later
Compiled file=帮助手册.chm
;此处用于设置菜单目录
Contents file=contents.hhc
Default topic=doc/ch1/index.html
Display compile progress=Yes
Language=0x804 中文(简体,中国)
Title=简单的说明文档
3.对应的contents.hhc
(文件名可任意起名)文件内容如下,可发现其本质上是HTML
文件,其中的UL
相关的嵌套代码即为最终要展示的层级结构
+点击以展开/折叠
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
<OBJECT type="text/site properties">
<param name="ImageType" value="Folder">
</OBJECT>
<UL>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="第1章节">
<param name="Local" value="doc/ch1/index.html">
<param name="ImageNumber" value="1">
</OBJECT>
<UL>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="功能1">
<param name="ImageNumber" value="0">
</OBJECT>
<UL>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="页面1">
<param name="Local" value="doc/ch1/func1/page1.html">
</OBJECT>
</LI>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="页面2">
<param name="Local" value="doc/ch1/func1/page2.html">
</OBJECT>
</LI>
</UL>
</LI>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="About">
<param name="Local" value="doc/ch1/about.html">
</OBJECT>
</LI>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="Menu">
<param name="Local" value="doc/ch1/menu.html">
</OBJECT>
</LI>
</UL>
</LI>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="第2章节">
<param name="ImageNumber" value="1">
</OBJECT>
<UL>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="功能1">
<param name="ImageNumber" value="0">
</OBJECT>
</LI>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="概览">
<param name="Local" value="doc/ch2/func1.html">
</OBJECT>
</LI>
<LI>
<OBJECT type="text/sitemap">
<param name="Name" value="具体说明">
<param name="Local" value="doc/ch2/具体说明.html">
</OBJECT>
</LI>
</UL>
</LI>
</UL>
</BODY>
</HTML>
4.构建过程如下,由于其包含的文件较多,故构建过程中输出的日志也更加详细
5.打开生成的文件,展示效果类似如下,可看出左侧出现了我们基于hhc
文件设置的菜单,且能够正常的点击切换
文件图标修改
前述的菜单目录实现的核心为<OBJECT>
对象,其中包含一个或多个<param>
对象,通过键值对的方式设置相关参数值,可选的参数如下:
参数 | 说明 |
---|---|
Name |
用于设置在菜单目录中的显示名称(即文件名和显示名称可不相同) |
Local |
该对象对应的HTML 文档,采用相对路径 设置 |
ImageNumber |
该对象在菜单目录中使用何种图标 |
其中ImageNumber
的值可以设置为从1到42
(若超过42不会报错且用默认值替代),分别对应如下图标
可通过如下代码来修改其值
<OBJECT type="text/sitemap">
<param name="Name" value="第1章节">
<param name="Local" value="doc/ch1/index.html">
<param name="ImageNumber" value="3">
</OBJECT>
基于上述说明修改前面的hhc
文件,展示效果如下
下述内容来源于此文章,个人并未做实际验证
如果
<OBJECT>
中没有ImageNumber
项时,如果hhp
文件中的ImageType
为Picture
(默认是Picture
),如果有子目录,就显示,否则显示
,如果
ImageType
为Folder
,如果有子目录,就显示,否则显示
中文搜索支持
可通过在hhp
文件中添加Full-text search
来添加搜索功能
[OPTIONS]
Compatibility=1.1 or later
Compiled file=帮助手册.chm
;此处用于设置菜单目录
Contents file=contents.hhc
Default topic=doc/ch1/index.html
Display compile progress=Yes
Language=0x804 中文(简体,中国)
Title=简单的说明文档
;支持搜索功能
Full-text search=Yes
但个人在实际使用中遇到了中文搜索的一些坑,需要将文件编码设置为ANSI
且在HTML
文件中去掉显示的文件编码才能正常支持中文搜索。
演示说明如下:
1.假设所有的HTML
文件编码均为UTF-8
且在文件源码中也通过如下代码进行显示声明
<!--设置为utf-8编码 -->
<meta charset="utf-8">
2.在生成的CHM
文件中搜索中文关键字,可看出虽然实际有内容,但检索结果为空
3.切换为英文单词搜索后,结果如下,虽然有结果,但是显示为乱码,同样无法使用
4.将对应的HTML
文件以ANSI
编码格式保存,重新生成CHM
文件,发现其中文直接显示乱码,此时进行搜索已经无意义
5.基于前述步骤,将对应HTML
文件源码中的编码类型去掉,然后重新生成CHM
文件
<!--设置为utf-8编码
<meta charset="utf-8">-->
6.对重新生成的CHM
文件进行中文检索,此时结果正常,如下图所示
从上图的搜索结果可发现其展示的检索结果为HTML
文件的title
属性值而非实际的文件名称,故建议在生成hhc
文件时,<OBJECT>
对象下的Name
属性值要和HTML
页面的title
值保持一致,避免使用上引起歧义,可通过代码脚本来达到此目的。
遗留问题
前述生成CHM
文件的操作适用于简单的HTML
文件,若HTML
文件本身内容很复杂(如基于GitBook生成),则生成的CHM
文件打开后可能会报错,原因尚未找出。