File: htmlhelp2.py

package info (click to toggle)
c-munipack 2.1.39-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 55,888 kB
  • sloc: ansic: 200,762; cpp: 106,129; lex: 9,035; yacc: 4,916; sh: 4,074; fortran: 2,613; xml: 2,105; python: 1,182; makefile: 546; perl: 104
file content (136 lines) | stat: -rw-r--r-- 5,268 bytes parent folder | download | duplicates (2)
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")