Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Formatter/HTML/doxygen.py
    1| # $Id: doxygen.py,v 1.5 2003/01/20 06:43:02 chalky Exp $
    2| #
    3| # This file is a part of Synopsis.
    4| # Copyright (C) 2000, 2001 Stephen Davies
    5| # Copyright (C) 2000, 2001 Stefan Seefeld
    6| #
    7| # Synopsis is free software; you can redistribute it and/or modify it
    8| # under the terms of the GNU General Public License as published by
    9| # the Free Software Foundation; either version 2 of the License, or
   10| # (at your option) any later version.
   11| #
   12| # This program is distributed in the hope that it will be useful,
   13| # but WITHOUT ANY WARRANTY; without even the implied warranty of
   14| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15| # General Public License for more details.
   16| #
   17| # You should have received a copy of the GNU General Public License
   18| # along with this program; if not, write to the Free Software
   19| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   20| # 02111-1307, USA.
   21| #
   22| # $Log: doxygen.py,v $
   23| # Revision 1.5  2003/01/20 06:43:02  chalky
   24| # Refactored comment processing. Added AST.CommentTag. Linker now determines
   25| # comment summary and extracts tags. Increased AST version number.
   26| #
   27| # Revision 1.4  2001/07/10 06:47:45  chalky
   28| # Doxygen stuff works again
   29| #
   30| # Revision 1.3  2001/04/06 06:27:09  chalky
   31| # Change from import * since our py parser cant handle that too well
   32| #
   33| # Revision 1.2  2001/04/05 09:57:49  chalky
   34| # Add pre and post summary div, so the [Source] link can go inside it
   35| #
   36| # Revision 1.1  2001/02/12 04:55:45  chalky
   37| # Initial commit
   38| #
   39| #
   40| 
   41| """Doxygen emulation mode classes."""
   42| 
   43| import string
   44| 
   45| from Synopsis.Core import AST
   46| from Synopsis.Formatter.HTML import ScopeSorter, core
   47| from Synopsis.Formatter.HTML.core import config
   48| from Synopsis.Formatter.HTML.Tags import *
   49| from Synopsis.Formatter.HTML import ASTFormatter, FormatStrategy
   50|         
   51| 
   52| class DOScopeSorter (ScopeSorter.ScopeSorter):
   53|     def _section_of(self, decl):
   54|         _axs_str = ('','Public ','Protected ','Private ')
   55|         _types = {'enum':'Type', 'function':'Method', 'operation':'Method',
   56|             'variable':'Attribute', 'attribute':'Attribute'
   57|         }
   58|         if _types.has_key(decl.type()): section = _types[decl.type()]
   59|         else: section = string.capitalize(decl.type())
   60|         if decl.accessibility != AST.DEFAULT:
   61|             section = _axs_str[decl.accessibility()]+section
   62|         return section
   63| 
   64|     def sort_section_names(self):
   65|         "Sort by a known order.."
   66|         _axs_str = ['Public ','Protected ','Private ']
   67|         _axs_order = _axs_str
   68|         _sec_order = ['Type', 'Method', 'Attribute']
   69|         # Split into (Section, Name) tuples
   70|         def totuple(name, axs_l=_axs_str):
   71|             for axs in axs_l:
   72|                if name[:len(axs)] == axs:
   73|                    return axs, name[len(axs):]
   74|             return '',name
   75|         names = map(totuple, self.sections())
   76|         def order(name, axs_o = _axs_order, sec_o = _sec_order):
   77|             "return a sort order for given name tuple"
   78|             o1 = (name[0] in axs_o) and axs_o.index(name[0])+1 or len(axs_o)
   79|             o2 = (name[1] in sec_o) and sec_o.index(name[1])+1 or len(sec_o)
   80|             return o1 * 1000 + o2
   81|         names.sort(lambda a, b, order=order: cmp(order(a),order(b)))
   82|         self._set_section_names(map(lambda x: string.join(x,''), names))
   83|         
   84| class DOSummaryAST (FormatStrategy.SummaryAST):
   85|     def formatEnum(self, decl):
   86|         "(enum, enum { list of enumerator names })"
   87|         ename = self.label(decl.name())
   88|         enumer = lambda enumor, ref=self.reference: ref(enumor.name())
   89|         divver = lambda text: div("enumerator", text)
   90|         commer = lambda text: text+","
   91|         name = map(enumer, decl.enumerators())
   92|         name = map(commer, name[:-1]) + name[-1:]
   93|         name = "%s {%s}"%(ename, string.join(map(divver, name)))
   94|         return "enum" + self.col_sep + name
   95| 
   96| class DOSummaryCommenter (FormatStrategy.SummaryCommenter):
   97|     """Adds summary comments to all declarations"""
   98|     def formatDeclaration(self, decl):
   99|         style = config.decl_style[decl]
  100|         more = (style != core.DeclStyle.SUMMARY) and ' '+self.reference(decl.name(), 'More...') or ''
  101|         summary = config.comments.format_summary(self.page, decl)
  102|         return span('summary', summary) + more
  103| 
  104| class DODetailAST (FormatStrategy.DetailAST):
  105|     def formatFunction(self, decl):
  106|         premod = self.formatModifiers(decl.premodifier())
  107|         type = self.formatType(decl.returnType())
  108|         name = self.label(decl.name(), decl.realname())
  109|         # Special C++ functions  TODO: maybe move to a separate AST formatter...
  110|         if decl.language() == 'C++' and len(decl.realname())>1:
  111|             if decl.realname()[-1] == decl.realname()[-2]: type = '<i>constructor</i>'
  112|             elif decl.realname()[-1] == "~"+decl.realname()[-2]: type = '<i>destructor</i>'
  113|             elif decl.realname()[-1] == "(conversion)":
  114|                name = "(%s)"%type
  115|         params = map(self.formatParameter, decl.parameters())
  116|         postmod = self.formatModifiers(decl.postmodifier())
  117|         raises = self.formatOperationExceptions(decl)
  118|         type = '%s %s'%(premod,type)
  119|         if decl.type() == "attribute": name = '%s %s %s %s'%(type, name, postmod, raises)
  120|         else:
  121|             str = '<table border=0 cellspacing=0 cellpadding=0>'\
  122|                    '<tr><td valign=top class="func">%s %s (</td>'\
  123|                    '<td class="func">%s ) %s %s</td></tr></table>'
  124|             str2 = ',</td></tr><tr><td></td><td class="func">'
  125|             params = string.join(params, str2)
  126|             name = str%(type, name, params, postmod, raises)
  127|         return self.col_sep + name
  128| 
  129| class PreDivFormatter (FormatStrategy.Default):
  130|     def formatDeclaration(self, decl):
  131|         return '<div class="preformat">'
  132| 
  133| class PostDivFormatter (FormatStrategy.Default):
  134|     def formatDeclaration(self, decl):
  135|         return '</div>'
  136| 
  137| class PreSummaryDiv (FormatStrategy.Default):
  138|     def formatDeclaration(self, decl):
  139|         return '<div class="summary">'
  140| 
  141| class PostSummaryDiv (FormatStrategy.Default):
  142|     def formatDeclaration(self, decl):
  143|         return '</div>'
  144| 
  145| 
  146| class DOSummary (ASTFormatter.Summary):
  147|     def old_init_formatters(self):
  148|         self.addFormatter( DOSummaryAST)
  149|         self.addFormatter( DOSummaryCommenter )
  150| 
  151|     def write_start(self):
  152|         str = '<table width="100%%">'
  153|         self.write(str)
  154| 
  155|     def writeSectionStart(self, heading):
  156|         str = '<tr><td colspan="2" class="heading">%s</td></tr>'
  157|         self.write(str%heading)
  158| 
  159|     def writeSectionEnd(self, heading):
  160|         str = '<tr><td colspan="2" class="gap" height=20px>&nbsp;</td></tr>'
  161|         self.write(str)
  162| 
  163|     def write_end(self):
  164|         """Closes the table entity and adds a break."""
  165|         str = '</table><br>'
  166|         self.write(str)
  167| 
  168|     def writeSectionItem_Foo(self, type, name):
  169|         """Adds a table row with one or two data elements. If type is None
  170|         then there is only one td with a colspan of 2."""
  171|         if not len(type):
  172|             str = '<tr><td colspan="2">%s</td></tr>'
  173|             self.write(str%name)
  174|         else:
  175|             str = '<tr><td valign="top" align="right">%s</td><td>%s</td></tr>'
  176|             self.write(str%(type,name))
  177| 
  178| 
  179| class DODetail (ASTFormatter.Detail):
  180|     def old_init_formatters(self):
  181|         self.addFormatter( PreDivFormatter )
  182|         self.addFormatter( DODetailAST )
  183|         self.addFormatter( PostDivFormatter )
  184|         self.addFormatter( FormatStrategy.ClassHierarchyGraph )
  185|         self.addFormatter( FormatStrategy.DetailCommenter )
  186| 
  187|     def writeSectionEnd(self, heading):
  188|         self.write('<hr>')
  189|     def writeSectionItem_Foo(self, text):
  190|         """Joins text1 and text2"""
  191|         self.write(text)