Synopsis - Synopsis/Formatters/HTML/Markup/__init__.py

File: Synopsis/Formatters/HTML/Markup/__init__.py

      1#
      2# Copyright (C) 2006 Stefan Seefeld
      3# All rights reserved.
      4# Licensed to the public under the terms of the GNU LGPL (>= 2),
      5# see the file COPYING for details.
      6#
      7"""Markup formatters."""
      8
      9from Synopsis.Processor import Parametrized, Parameter
     10from Synopsis import ASG
     11from Synopsis.QualifiedName import *
     12from Synopsis.Formatters.HTML.Tags import escape
     13import re
     14
     15class Struct:
     16
     17    def __init__(self, summary = '', details = ''):
     18        self.summary = summary
     19        self.details = details
     20
     21
     22class Formatter(Parametrized):
     23    """Interface class that takes a 'doc' annotation and formats its
     24    text. Markup-specific subclasses should provide appropriate format methods."""
     25
     26    def init(self, processor):
     27
     28        self.processor = processor
     29
     30    def format(self, decl, view):
     31        """Format the declaration's documentation.
     32        @param view the View to use for references and determining the correct
     33        relative filename.
     34        @param decl the declaration
     35        @returns Struct containing summary / details pair.
     36        """
     37
     38        doc = decl.annotations.get('doc')
     39        text = doc and escape(doc.text) or ''
     40        m = re.match(r'(\s*[\w\W]*?\.)(\s|$)', text)
     41        summary = m and m.group(1) or ''
     42        return Struct(summary, text)
     43
     44    def lookup_symbol(self, symbol, scope):
     45        """Given a symbol and a scope, returns an URL.
     46        Various methods are tried to resolve the symbol. First the
     47        parameters are taken off, then we try to split the symbol using '.' or
     48        '::'. The params are added back, and then we try to match this scoped
     49        name against the current scope. If that fails, then we recursively try
     50        enclosing scopes.
     51        """
     52
     53        # Remove params
     54        index = symbol.find('(')
     55        if index >= 0:
     56            params = symbol[index:]
     57            symbol = symbol[:index]
     58        else:
     59            params = ''
     60        if '.' in symbol:
     61            symbol = QualifiedPythonName(symbol.split('.'))
     62        else:
     63            symbol = QualifiedCxxName(symbol.split('::'))
     64        # Add params back
     65        symbol = symbol[:-1] + (symbol[-1] + params,)
     66        # Find in all scopes
     67        while 1:
     68            entry = self._lookup_symbol_in(symbol, scope)
     69            if entry:
     70                return entry.link
     71            if len(scope) == 0: break
     72            scope = scope[:-1]
     73        # Not found
     74        return None
     75
     76
     77    def _lookup_symbol_in(self, symbol, scope):
     78
     79        paren = symbol[-1].find('(')
     80        if paren != -1:
     81            return self._find_method_entry(symbol[-1], scope + symbol[:-1])
     82        else:
     83            return self.processor.toc.lookup(scope + symbol)
     84
     85
     86    def _find_method_entry(self, name, scope):
     87
     88        try:
     89            scope = self.processor.ir.asg.types[scope]
     90        except KeyError:
     91            return None
     92        if not isinstance(scope, ASG.DeclaredTypeId):
     93            return None
     94        scope = scope.declaration
     95        if not isinstance(scope, ASG.Scope):
     96            return None
     97        # For now disregard parameters during lookup.
     98        name = name[:name.find('(')]
     99        for d in scope.declarations:
    100            if isinstance(d, ASG.Function):
    101                if d.real_name[-1] == name:
    102                    return self.processor.toc.lookup(d.name)
    103        return None
    104

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