Synopsis - Synopsis/Formatters/HTML/Views/Source.py

File: Synopsis/Formatters/HTML/Views/Source.py

      1#
      2# Copyright (C) 2000 Stephen Davies
      3# Copyright (C) 2000 Stefan Seefeld
      4# All rights reserved.
      5# Licensed to the public under the terms of the GNU LGPL (>= 2),
      6# see the file COPYING for details.
      7#
      8
      9from Synopsis import config
     10from Synopsis.Processor import *
     11from Synopsis.QualifiedName import *
     12from Synopsis.Formatters import join_paths
     13from Synopsis.Formatters.HTML.View import View
     14from Synopsis.Formatters.HTML.Tags import *
     15from xml.dom.minidom import parse
     16import os, urllib, time
     17
     18class SXRTranslator:
     19    """Read in an sxr file, resolve references, and write it out as
     20    part of a Source view."""
     21
     22    def __init__(self, filename, language, debug):
     23
     24        try:
     25            self.sxr = parse(filename)
     26        except:
     27            if debug:
     28                print 'Error parsing', filename
     29                raise
     30            else:
     31                raise InternalError('parsing %s'%filename)
     32        if language == 'Python':
     33            self.qname = lambda name: QualifiedPythonName(str(name).split('.'))
     34        else:
     35            self.qname = lambda name: QualifiedCxxName(str(name).split('::'))
     36
     37    def link(self, linker):
     38
     39        for a in self.sxr.getElementsByTagName('a'):
     40            ref = self.qname(a.getAttribute('href'))
     41            target = linker(ref)
     42            a.setAttribute('href', target)
     43            if a.hasAttribute('type'):
     44                a.removeAttribute('type')
     45            if a.hasAttribute('from'):
     46                a.removeAttribute('from')
     47            if a.hasAttribute('continuation'):
     48                a.removeAttribute('continuation')
     49
     50    def translate(self, writer):
     51
     52        writer.write('<pre class="sxr">')
     53        lines = self.sxr.getElementsByTagName('line')
     54        lineno_template = '%%%ds' % len(`len(lines)`)
     55        for lineno, line in enumerate(lines):
     56            writer.write('<a id="line%d"></a>'%(lineno + 1))
     57            text = lineno_template % (lineno + 1)
     58            writer.write('<span class="lineno">%s</span>'%text)
     59            text = ''.join([n.toxml() for n in line.childNodes])
     60            if text:
     61                writer.write('<span class="line">%s</span>\n'%text)
     62            else:
     63                writer.write('\n')
     64        writer.write('</pre>')
     65
     66
     67class Source(View):
     68    """A module for creating a view for each file with hyperlinked source"""
     69
     70    external_url = Parameter(None, 'base url to use for external links (if None the toc will be used')
     71
     72    def register(self, frame):
     73
     74        super(Source, self).register(frame)
     75        self.icons = {}
     76        if self.processor.sxr_prefix:
     77            share = config.datadir
     78            self.icons['C'] = 'src-c.png'
     79            self.icons['C++'] = 'src-c++.png'
     80            self.icons['Python'] = 'src-py.png'
     81            for l in self.icons:
     82                src = os.path.join(share, self.icons[l])
     83                self.directory_layout.copy_file(src, self.icons[l])
     84
     85
     86    def filename(self):
     87
     88        return self.__filename
     89
     90
     91    def title(self):
     92
     93        return self.__title
     94
     95
     96    def process(self):
     97        """Creates a view for every file"""
     98
     99        self.prefix = self.processor.sxr_prefix
    100        if self.prefix is None: return
    101
    102        # Get the TOC
    103        self.__toc = self.processor.toc
    104        # create a view for each primary file
    105        for file in self.processor.ir.files.values():
    106            if file.annotations['primary']:
    107                self.process_node(file)
    108
    109
    110    def register_filenames(self):
    111        """Registers a view for every source file"""
    112
    113        if self.processor.sxr_prefix is None: return
    114
    115        for file in self.processor.ir.files.values():
    116            if file.annotations['primary']:
    117                filename = file.name
    118                filename = self.directory_layout.file_source(filename)
    119                self.processor.register_filename(filename, self, file)
    120
    121
    122    def process_node(self, file):
    123        """Creates a view for the given file"""
    124
    125        # Start view
    126        filename = file.name
    127        self.__filename = self.directory_layout.file_source(filename)
    128        self.rel_url = rel(self.filename(), '')
    129
    130        source = file.name
    131        self.__title = source
    132
    133        self.start_file()
    134        self.write_navigation_bar()
    135        self.write('File: '+element('b', self.__title))
    136
    137        sxr = join_paths(self.prefix, source + '.sxr')
    138        if os.path.exists(sxr):
    139            translator = SXRTranslator(sxr, file.annotations['language'], self.processor.debug)
    140            linker = self.external_url and self.external_ref or self.lookup_symbol
    141            translator.link(linker)
    142            translator.translate(self)
    143        self.end_file()
    144
    145
    146    def lookup_symbol(self, name):
    147
    148        e = self.__toc.lookup(name)
    149        return e and self.rel_url + e.link or ''
    150
    151
    152    def external_ref(self, name):
    153
    154        return self.external_url + urllib.quote(str(name))
    155
    156    def end_file(self):
    157        """Overrides end_file to provide synopsis logo"""
    158
    159        self.write('\n')
    160        now = time.strftime(r'%c', time.localtime(time.time()))
    161        logo = img(src=rel(self.filename(), 'synopsis.png'), alt='logo')
    162        logo = href('http://synopsis.fresco.org', logo + ' synopsis', target='_blank')
    163        logo += ' (version %s)'%config.version
    164        self.write(div('logo', 'Generated on ' + now + ' by \n<br/>\n' + logo))
    165        View.end_file(self)
    166

Generated on Thu Apr 16 16:27:13 2009 by
synopsis (version devel)