File: Synopsis/Formatters/HTML/DirectoryLayout.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 import ASG
 11from Synopsis.Formatters import TOC
 12from Synopsis.Formatters import quote_name, open_file, copy_file
 13from Tags import *
 14import os, sys
 15
 16
 17class DirectoryLayout (TOC.Linker):
 18    """DirectoryLayout defines how the generated html files are organized.
 19    The default implementation uses a flat layout with all files being part
 20    of a single directory."""
 21
 22    def init(self, processor):
 23
 24        self.processor = processor
 25        self.base = self.processor.output
 26        if not os.path.exists(self.base):
 27            if processor.verbose: print "Warning: Output directory does not exist. Creating."
 28            try:
 29                os.makedirs(self.base, 0755)
 30            except EnvironmentError, reason:
 31                print "ERROR: Creating directory:",reason
 32                sys.exit(2)
 33        elif not os.path.isdir(self.base):
 34            print "ERROR: Output must be a directory."
 35            sys.exit(1)
 36
 37        if os.path.isfile(processor.stylesheet):
 38            self.copy_file(processor.stylesheet, 'style.css')
 39        else:
 40            print "ERROR: stylesheet %s doesn't exist"%processor.stylesheet
 41            sys.exit(1)
 42        self.copy_file(os.path.join(config.datadir, 'logo-small.png'),
 43                       'synopsis.png')
 44
 45
 46    def copy_file(self, src, dest):
 47        """Copy src to dest, if dest doesn't exist yet or is outdated."""
 48
 49        copy_file(src, os.path.join(self.base, dest))
 50
 51    def scope(self, scope = None):
 52        """Return the filename of a scoped name (class or module).
 53        The default implementation is to join the names with '-' and append
 54        ".html". Additionally, special characters are quoted."""
 55
 56        if not scope: return self.special('global')
 57        return quote_name('.'.join(scope)) + '.html'
 58
 59    def _strip(self, filename):
 60
 61        if filename.endswith('/'): filename = filename[:-1]
 62        if filename.startswith('/'): filename = filename[1:]
 63        return filename
 64
 65    def file_index(self, filename):
 66        """Return the filename for the index of an input file.
 67        Default implementation is to join the path with '.', prepend '_file.'
 68        and append '.html' """
 69
 70        filename = self._strip(filename)
 71        return '_file.%s.html'%filename.replace(os.sep, '.')
 72
 73    def file_source(self, filename):
 74        """Return the filename for the source of an input file.
 75        Default implementation is to join the path with '.', prepend '_source.'
 76        and append '.html' """
 77
 78        file = self._strip(filename)
 79        return '_source.'+file.replace(os.sep, '.')+'.html'
 80
 81    def file_details(self, filename):
 82        """Return the filename for the details of an input file.
 83        Default implementation is to join the path with '.', prepend
 84        '_file_detail.' and append '.html' """
 85
 86        return '_file_detail.'+self._strip(filename).replace(os.sep, '.')+'.html'
 87
 88    def index(self):
 89        """Return the name of the main index file. Default is index.html"""
 90
 91        return 'index.html'
 92
 93    def special(self, name):
 94        """Return the name of a special file (tree, etc). Default is
 95        _name.html"""
 96
 97        return '_%s.html'%name
 98
 99    def scoped_special(self, name, scope, ext='.html'):
100        """Return the name of a special type of scope file. Default is to join
101        the scope with '.' and prepend '.'+name"""
102
103        return "_%s%s%s"%(name, quote_name('.'.join(scope)), ext)
104
105    def xref(self, page):
106        """Return the name of the xref file for the given page"""
107
108        return '_xref%d.html'%page
109
110    def module_tree(self):
111        """Return the name of the module tree index. Default is
112        _modules.html"""
113
114        return '_modules.html'
115
116    def module_index(self, scope):
117        """Return the name of the index of the given module. Default is to
118        join the name with '.', prepend '_module' and append '.html' """
119
120        return quote_name('_module' + '.'.join(scope)) + '.html'
121
122    def link(self, decl):
123        """Create a link to the named declaration. This method may have to
124        deal with the directory layout."""
125
126        if (isinstance(decl, ASG.Scope) or
127            # If this is a forward-declared class template with known specializations,
128            # we want to treat it like an ASG.Class, as far as formatting is concerned.
129            (isinstance(decl, ASG.Forward) and decl.specializations)):
130            # This is a class or module, so it has its own file
131            return self.scope(decl.name)
132        # Assume parent scope is class or module, and this is a <A> name in it
133        filename = self.scope(decl.name[:-1])
134        fragment = quote_as_id(decl.name[-1])
135        return filename + '#' + fragment
136
137class NestedDirectoryLayout(DirectoryLayout):
138    """Organizes files in a directory tree."""
139
140    def scope(self, scope = None):
141
142        if not scope: return 'Scopes/global.html'
143        else: return quote_name('Scopes/' + '/'.join(scope)) + '.html'
144
145    def file_index(self, filename):
146
147        return 'File/%s.html'%self._strip(filename)
148
149    def file_source(self, filename):
150
151        return 'Source/%s.html'%self._strip(filename)
152
153    def file_details(self, filename):
154
155        return 'FileDetails/%s.html'%self._strip(filename)
156
157    def special(self, name):
158
159        return name + '.html'
160
161    def scoped_special(self, name, scope, ext='.html'):
162
163        return quote_name(name + '/' + '/'.join(scope)) + ext
164
165    def xref(self, page):
166
167        return 'XRef/xref%d.html'%page
168
169    def module_tree(self):
170
171        return 'Modules.html'
172
173    def module_index(self, scope):
174
175        if not len(scope):
176            return 'Modules/global.html'
177        else:
178            return quote_name('Modules/' + '/'.join(scope)) + '.html'
179