1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
# -*- coding: utf-8 -*-
"""
htmlhelp2
~~~~~~~~~
Build HTML help support files with [ALIAS] and [MAP] sections
Note: Replaces original HTMLHelp builder!
:copyright: Copyright 2012 David Motl
:license: GNU GPL v.2
$Id: htmlhelp2.py,v 1.1 2015/07/06 08:19:57 dmotl Exp $
"""
import os
import subprocess
from sphinx.builders.htmlhelp import HTMLHelpBuilder
from sphinx.errors import ExtensionError
from sphinx.util import logging
from sphinx.util.console import bold, darkgreen # type: ignore
from sphinx.errors import SphinxError
class HTMLHelpCompilerFailed(SphinxError):
category = 'HTML Help compiler failed'
class HTMLHelpExtBuilder(HTMLHelpBuilder):
name = 'htmlhelp'
def init(self):
HTMLHelpBuilder.init(self)
epilog = ''
def build_map(self, filename):
""" Parse ctxhelp.h and make a dictionary which maps topics -> (num_id, label) """
mmap = {}
f = open(filename, "r")
try:
for line in f:
x = line.split(None, 3)
if len(x)==4 and x[0]=='#define' and x[2].isnumeric():
""" Get topic name """
start = x[3].find("/*");
if (start>=0):
end = x[3].find("*/", start+2);
if (end>=0):
topic = x[3][start+3:end].strip();
if len(topic)>0:
mmap[topic] = (int(x[2]), x[1], None)
finally:
f.close()
return mmap
def update_hhp(self, outdir, outname, topics):
f = self.open_file(outdir, outname+'.hhp', 'a')
try:
f.write('\n[ALIAS]\n')
for topic in iter(topics):
val = topics[topic]
if val[1] and val[2]:
f.write(val[1] + ' = ' + val[2] + '\n')
else:
logger = logging.getLogger(__name__)
logger.warn("Missing topic: %s" % val[1])
f.write('\n')
f.write('[MAP]\n')
for topic in iter(topics):
val = topics[topic]
if val[1] and val[2]:
f.write('#define ' + val[1] + ' ' + str(val[0]) + '\n')
finally:
f.close()
def get_outdated_docs(self):
if self.config.ctxhelp_file:
mapfile = os.path.join(self.srcdir, self.config.ctxhelp_file)
try:
mapmtime = os.path.getmtime(mapfile)
except Exception:
raise ExtensionError('File not found: %s' % mapfile)
for docname in self.env.found_docs:
targetname = self.get_outfilename(docname)
try:
targetmtime = os.path.getmtime(targetname)
except Exception:
targetmtime = 0
if mapmtime > targetmtime:
return self.env.found_docs
return HTMLHelpBuilder.get_outdated_docs(self)
def update_project(self, outdir, outname):
if self.config.ctxhelp_file:
# Read map list of tuples (id, symbol, label)
logger = logging.getLogger(__name__)
logger.info(bold('updating project file...'), nonl=True)
mmap = self.build_map(os.path.join(self.srcdir, self.config.ctxhelp_file))
if mmap:
# Resolve links
for obj in self.env.domains['std'].get_objects():
label = obj[0]
if obj[2]=='label' and (label in mmap):
val = mmap[label]
mmap[label] = (val[0], val[1], obj[3] + self.out_suffix)
# Update project file
self.update_hhp(outdir, outname, mmap)
else:
logger.warn("No topics found in %s" % self.config.ctxhelp_file)
logger.info('done')
def compile_chm(self, outdir, outname):
# Read map list of tuples (id, symbol, label)
logger = logging.getLogger(__name__)
logger.info(bold('building chm file...'), nonl=True)
args = [ 'hhc', os.path.join(outdir, outname+'.hhp') ]
try:
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = p.communicate()[0]
if p.returncode != 1:
raise HTMLHelpCompilerFailed(output)
except OSError:
raise AppleHelpIndexerFailed(__('Command not found: %s') % args[0])
logger.info('done')
def handle_finish(self):
HTMLHelpBuilder.handle_finish(self)
self.update_project(self.outdir, self.config.htmlhelp_basename)
self.compile_chm(self.outdir, self.config.htmlhelp_basename)
def setup(app):
# Replace original HTML Help builder
app.add_builder(HTMLHelpExtBuilder, override=True)
app.add_config_value("ctxhelp_file", "include/ctxhelp.h", "env")
|