当前位置:首页 > 开发 > 开源软件 > 正文

利用JavaDoc制作windows的CHM文档

发表于: 2012-03-12   作者:cutesunshineriver   来源:转载   浏览:
摘要: 使用了开源的一个ruby脚本来利用JavaDoc制作windows的CHM文档。 输出文件编码的时候一定记得选择中文,例如file.puts "Language=0x804 Chinese"。 def createProjectFile(prjname, basedir) packages = scanPackageTree(basedir)
使用了开源的一个ruby脚本来利用JavaDoc制作windows的CHM文档。

输出文件编码的时候一定记得选择中文,例如file.puts "Language=0x804 Chinese"。
def createProjectFile(prjname, basedir)
    
    packages = scanPackageTree(basedir)

    createContentsFile(prjname+'.hhc', basedir, packages)
    createIndexFile(prjname+'.hhk', basedir, packages)
    
    assetsexplise = /^$/
    title = getIndexTitle(basedir)
    
    file = open(prjname+'.hhp', 'w')
    file.puts "[OPTIONS]"
    file.puts "Compatibility=1.1 or later"
    file.puts "Compiled file=#{prjname}.chm"
    file.puts "Contents file=#{prjname}.hhc"
    file.puts "Default Window=default"
    file.puts "Display compile progress=Yes"
    file.puts "Default topic=#{basedir}/overview-summary.html"
    file.puts "Full-text search=Yes"
    file.puts "Index file=#{prjname}.hhk"
    # file.puts "Language=0x411 Japanese"
    file.puts "Language=0x409 English (U.S.)"
	# file.puts "Language=0x804 Chinese"
    file.puts "Title=#{title}"
    file.puts ""
    file.puts "[WINDOWS]"
    file.puts "default=\"#{title}\",\"#{prjname}.hhc\",\"#{prjname}.hhk\",\"#{basedir}/overview-summary.html\",\"#{basedir}/overview-summary.html\",,,,,0x2520,,0x384e,,,,,,,,0"
    file.puts ""
    file.puts ""
    file.puts "[FILES]"
    collectAssets(basedir, assetsexplise).each() do |path|
        file.puts(path)
    end
    file.puts ""
    file.close()
end

def getIndexTitle(basedir)
    title = ""
    open(basedir + '/index.html', 'r') do |fh|
        fh.read() =~ /\<title\>\n*(.+?)\n*\<\/title\>/i
        title = $1
    end
    return title
end

def collectAssets(assetsdir, assetsexplise)
    assets = []
    Dir.foreach(assetsdir) do |asset|
        assetpath = assetsdir + '/' + asset
        if File.stat(assetpath).ftype == 'file' then
            assets.push(assetpath) unless assetsexplise =~ assetpath
        elsif File.stat(assetpath).ftype == 'directory' and asset[0,1] != '.' then
            assets.concat(collectAssets(assetpath, assetsexplise))
        end
    end
    return assets
end

HEADER = '<HTML><HEAD><meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1"><!-- Sitemap 1.0 --></HEAD><BODY><OBJECT type="text/site properties"></OBJECT>'
FOOTER = '</BODY></HTML>'

def createContentsFile(filename, basedir, packages)
    
    file = open(filename, 'w')
    file.puts HEADER
    
    file.puts "[list]"
    file.puts "\t" + '<LI> <OBJECT type="text/sitemap">'
    file.puts "\t" * 2 + '<param name="Name" value="Overview">'
    file.puts "\t" * 2 + '<param name="Local" value="' + basedir + '/overview-summary.html">'
    file.puts "\t" * 2 + '<param name="ImageNumber" value="21">'
    file.puts "\t" * 2 + '</OBJECT>'
    
    packages.each() do |pkg|
        file.puts "\t" + formatTopicItem(pkg['name'], basedir+'/'+pkg['file'])
        file.puts "\t" * 1 + "[list]"
        pkg['classes'].each() do |cls|
            file.puts "\t" * 2 + formatTopicItem(cls['name'], basedir+'/'+cls['file'])
            file.puts "\t" * 2 + "[list]"
            cls['details'].each() do |det|
                file.puts "\t" * 3 + formatTopicItem(det, basedir+'/'+cls['file']+'#'+det)
            end
            file.puts "\t" * 2 + "[/list]"
        end
        file.puts "\t" * 1 + "[/list]"
    end
    file.puts "[/list]"
    
    file.puts FOOTER
    file.close()
end

def createIndexFile(filename, basedir, packages)
    
    file = open(filename, 'w')
    file.puts HEADER
    
    indexes = {}
    packages.each() do |pkg|
        addKeywordToIndex(indexes, pkg['name'], pkg['name'], basedir+'/'+pkg['file'])
        pkg['classes'].each() do |cls|
            addKeywordToIndex(indexes, cls['name'], pkg['name']+'.'+cls['name'], basedir+'/'+cls['file'])
            cls['details'].each() do |det|
                addKeywordToIndex(indexes, det, pkg['name']+'.'+cls['name']+'.'+det, basedir+'/'+cls['file']+'#'+det)
            end
        end
    end
    
    file.puts "[list]"
    indexes.keys.sort.each() do |keyword|
        file.puts "\t" + formatIndexItem(keyword, indexes[keyword])
    end
    file.puts "[/list]"
    
    file.puts FOOTER
    file.close()
end

def addKeywordToIndex(indexes, keyword, detail, file)
    if indexes[keyword] == nil then indexes[keyword] = {} end
    indexes[keyword][detail] = file
end


def scanPackageTree(basedir)
    packagelist = []
    rxpkg = /\<A\s+HREF\=\"([\w\d\-\/]+?)\/package\-frame\.html\"\s+target\=\"packageFrame\"\>([\w\d\.]+)\<\/A\>/i
    rxcls = /\<A\s+HREF\=\"([^\.][\w\d\-\.]+?)\"(\s+title\=\".+\")?\s+target\=\"classFrame\"\>(\<I\>)?([\w\d\.]+)(\<\/I\>)?\<\/A\>/i
    
    IO.foreach(basedir + "/overview-frame.html") do | line |
        if (line =~ rxpkg) != nil then
            pkgdir = $1
            pkgname = $2
            print "#{pkgname}\n"
            classes = []
            IO.foreach(basedir + '/' + pkgdir + '/package-frame.html') do | line |
                if (line =~ rxcls) != nil then
                    classfile = $1
                    classname = $4
                    print "#{pkgname}.#{classname}\n"
                    details = scanClassDocument(basedir+'/'+pkgdir+'/'+classfile)
                    classes.push({'name'=>classname, 'file'=>pkgdir+'/'+classfile, 'details'=>details})
                end
            end
            pkgfile = pkgdir + '/package-summary.html'
            packagelist.push({'name'=>pkgname, 'file'=>pkgfile, 'classes'=>classes})
        end
    end
    return packagelist
end

def scanClassDocument(file)
    scanstarts = false
    anchors = []
    IO.foreach(file) do |line|
        if (line =~ /\<A\s+NAME\=\"([^\"]+)\"\>/i) != nil then
            aname = $1
            if (aname =~ /\w+_detail$/i) != nil then
                scanstarts = true
            elsif (aname =~ /^navbar_\w+/i) != nil then
                scanstarts = false
            else
                if scanstarts then
                    anchors.push(aname)
                end
            end
        end
    end
    return anchors
end

def formatTopicItem(name, href)
    out = '<LI><OBJECT type="text/sitemap">'
    out += sprintf('<param name="Name" value="%s">', name)
    if href != nil then
        out += sprintf('<param name="Local" value="%s">', href)
    end
    out += "</OBJECT>"
    return out
end

def formatIndexItem(name, details)
    out = '<LI><OBJECT type="text/sitemap">'
    out += sprintf('<param name="Name" value="%s">', name)
    details.keys.each() do |det|
        out += sprintf('<param name="Name" value="%s">', det)
        out += sprintf('<param name="Local" value="%s">', details[det])
    end
    out += "</OBJECT>"
    return out
end

createProjectFile(ARGV[0], ARGV[1])


将JavaDoc的根目录拷贝到ruby脚本所在的目录下,这样会避免相对路径的问题,脚本里面处理得不好。安装好ruby环境( 因为兼容性的问题,推荐使用ruby1.8)之后,执行命令ruby createhhp.rb <help-file-basename> <javadoc-dir>,会在当前目录下生产hhc(目录)、hhk(索引)、hhp(项目)这三个文件。

记得去微软的官方站下载HTML Help Workshop。用HTML Help Workshop打开hhp文件就可以编译出正确的CHM文档。

利用JavaDoc制作windows的CHM文档

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号