Changeset 1071


Ignore:
Timestamp:
Aug 15, 2012 11:03:49 AM (11 years ago)
Author:
jemian
Message:

fixes #32

Location:
specdomain/trunk/src/specdomain
Files:
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • specdomain/trunk/src/specdomain/CHANGES

    r1067 r1071  
    1111* refs #13: show a bullet list at the top of the page (alternative to separate pages for each macro file)
    1212* fixed #14: "duplicate ID warnings" resolved
     13* fixed #32: descriptive comments also for *def* definitions
    1314
    1415Version 1.0 (2012-07-16)
  • specdomain/trunk/src/specdomain/doc/conventions.rst

    r1052 r1071  
    127127--------------------
    128128
    129 .. caution::  This is not a confirmed convention yet,
    130                                 but it does not violate any SPEC rules.
     129.. caution::  This is new convention,
     130                                yet it does not violate any SPEC rules.
    131131                                It *is* awfully useful!
    132132.. Is it used to document Python code?
     
    135135that cannot contain extended comments (triple-quoted strings) themselves,
    136136such as variable declarations or *rdef* or *cdef* macro declarations.
     137(They can also be used to document one-line *def* macros!)
    137138They appear either as comments in the same line after the declaration (in-line)
    138139or as a comment-only line immediately preceding the declaration (one-liner).
     
    141142docstring.
    142143
    143 Like the summary lines in exteded docstrings, these descriptive comments are
     144Like the summary lines in extended comments, these descriptive comments are
    144145used as descriptions in summary tables, etc.
    145146
     
    155156    rdef ccdset_shutter ''
    156157
    157 .. spec:global:: TTH    #: two-theta, the scattering angle
     158Descriptive comment that documents **do_nothing()**, a *function def* declaration::
     159
     160    def do_nothing() ''      #: this macro does do anything
    158161
    159162
  • specdomain/trunk/src/specdomain/sphinxcontrib/specmacrofileparser.py

    r1027 r1071  
    8484                        )
    8585
     86arg_list_match = r'(\(' + non_greedy_filler + r'\))?'
     87
    8688spec_macro_declaration_match_re = re.compile(
    8789                        string_start
     
    9092                        + non_greedy_whitespace
    9193                        + macro_name_match                  # 2: macro_name
    92                         + non_greedy_filler_match           # 3: optional arguments
    93                         + r'\'\{?'                          # start body section
     94                        + arg_list_match                    # 3: optional arguments
     95                        + non_greedy_whitespace
     96                        + '\''                              # start body section
    9497                        + non_greedy_filler_match           # 4: body
    95                         + r'\}?\''                          # end body section
     98                        + '\''                              # end body section
     99                        + non_greedy_whitespace
    96100                        + r'(#.*?)?'                        # 5: optional comment
    97                         + string_end,
     101                        + string_end
     102                        ,
    98103                        re.IGNORECASE|re.DOTALL|re.MULTILINE)
    99    
    100 args_match = re.compile(
     104
     105
     106
     107args_match_re = re.compile(
    101108                          r'\('
    102109                        + arglist_match                     # 1:  argument list
     
    135142        self.read(macrofile)
    136143        self.parse_macro_file()
     144        self.description = ''
     145        self.clear_description = False
     146        self.found_first_global_extended_comment = False
    137147   
    138148    def read(self, macrofile):
     
    177187            has the keys: objtype, start_line, end_line, and others
    178188        """
     189        db = self._make_db()        # first, the file parsing
     190       
     191        # Build a dict with objecttype for keys and methods for values
     192        # each method handles that particular spec macro file structure
     193        handler_method = {
     194            'cdef': self.handle_other,
     195            'constant': self.handle_other,
     196            'def': self.handle_def,
     197            'descriptive comment': self.handle_descriptive_comment,
     198            'extended comment': self.handle_extended_comment,
     199            'function def': self.handle_def,
     200            'global': self.handle_other,
     201            'local': self.handle_other,
     202            'rdef': self.handle_other,
     203        }
     204        process_first_list = ('descriptive comment', )
     205       
     206        # then analyze what was found
     207        # proceed line-by-line in order
     208        # TODO: could override this rule with a sort-order option
     209        self.findings = []
     210        self.description = ''
     211        self.clear_description = False
     212        self.found_first_global_extended_comment = False
     213        for linenumber in sorted(db.keys()):
     214            # Diagnostic line for development only
     215            #print linenumber, ':', ' '.join(['<%s>' % d['objtype'] for d in db[linenumber]])
     216           
     217            # process any descriptive comment first
     218            for item in db[linenumber]:
     219                if item['objtype'] in process_first_list:
     220                    handler_method[item['objtype']](item, db)
     221            # now process the others
     222            for item in db[linenumber]:
     223                if item['objtype'] not in process_first_list:
     224                    handler_method[item['objtype']](item, db)
     225           
     226            if self.clear_description:
     227                self.description, self.clear_description = '', False
     228   
     229    def _make_db(self):
     230        """build the db dict by parsing for each type of structure"""
    179231        db = {}
    180232        # first, the file parsing
     
    190242                    db[s] = []
    191243                db[s].append(item)
    192        
    193         # then, the analysis of what was found
    194         # proceed line-by-line in order
    195         # TODO: could override this rule with an option
    196         self.findings = []
    197         description = ''
    198         clear_description = False
    199         found_first_global_extended_comment = False
    200         for linenumber in sorted(db.keys()):
    201             #print linenumber, ':', ', '.join([d['objtype'] for d in db[linenumber]])
    202            
    203             line = db[linenumber]
    204             item = line[-1]
    205             if item['objtype'] in ('def', 'function def'):
    206                 # identify all the children of this item
    207                 parent = item['name']
    208                 found_first_local_extended_comment = False
    209                 for row in xrange(item['start_line']+1, item['end_line']-1):
    210                     if row in db.keys():
    211                         for thing in db[row]:
    212                             thing['parent'] = parent
    213                             if thing['objtype'] == 'extended comment':
    214                                 if not found_first_local_extended_comment:
    215                                     # TODO: could override this rule with an option
    216                                     item['description'] = thing['text']
    217                                     found_first_local_extended_comment = False
    218                 if not item['name'].startswith('_'):
    219                     # TODO: could override this rule with an option
    220                     self.findings.append(item)
    221                 item['summary'] = self._extract_summary(item.get('description', ''))
    222            
    223             if item['objtype'] == 'extended comment':
    224                 start = item['start_line']
    225                 if item['parent'] == None:
    226                     if not found_first_global_extended_comment:
    227                         # TODO: could override this rule with an option
    228                         self.findings.append(item)
    229                         found_first_global_extended_comment = True
    230 
    231             if item['objtype'] == 'descriptive comment':
    232                 description = item['text']
    233 
    234             for item in line:
    235                 if item['objtype'] in ('local', 'global', 'constant', 'rdef', 'cdef'):
    236                     if len(description)>0:
    237                         item['description'] = description
    238                         item['summary'] = self._extract_summary(description)
    239                         clear_description = True
    240                     if not item['name'].startswith('_'):
    241                         # TODO: could override this rule with an option
    242                         self.findings.append(item)
    243            
    244             if clear_description:
    245                 description, clear_description = '', False
    246    
     244        return db
     245
     246    def handle_def(self, node, db):
     247        """document SPEC def structures"""
     248        # identify all the children of this node
     249        parent = node['name']
     250        self.found_first_local_extended_comment = False
     251        if node.get('comment') is not None:
     252            node['description'] = node.get('comment').lstrip('#:').strip()
     253        if len(self.description)>0:
     254            node['description'] = self.description
     255        for row in xrange(node['start_line']+1, node['end_line']-1):
     256            if row in db.keys():
     257                for item in db[row]:
     258                    item['parent'] = parent
     259                    if item['objtype'] == 'extended comment':
     260                        if not self.found_first_local_extended_comment:
     261                            # TODO: could override this rule with an option
     262                            node['description'] = item['text']
     263                            self.found_first_local_extended_comment = False
     264        if not node['name'].startswith('_'):
     265            # TODO: could override this rule with an option
     266            self.findings.append(node)
     267        node['summary'] = self._extract_summary(node.get('description', ''))
     268        self.clear_description = True
     269   
     270    def handle_descriptive_comment(self, node, db):
     271        """document SPEC descriptive comment structures"""
     272        self.description = node['text']
     273   
     274    def handle_extended_comment(self, node, db):
     275        """document SPEC extended comment structures"""
     276        #start = node['start_line']
     277        if node['parent'] == None:
     278            if not self.found_first_global_extended_comment:
     279                # TODO: could override this rule with an option
     280                self.findings.append(node)
     281                self.found_first_global_extended_comment = True
     282   
     283    def handle_other(self, node, db):
     284        """document SPEC cdef, constant, global, local, and rdef structures"""
     285        if len(self.description)>0:
     286            node['description'] = self.description
     287            node['summary'] = self._extract_summary(self.description)
     288            self.clear_description = True
     289        if not node['name'].startswith('_'):
     290            # TODO: could override this rule with an option
     291            self.findings.append(node)
     292   
     293#    def _handle_ignore(self, node, db):
     294#        """call this handler to ignore an identified SPEC macro file structure"""
     295#        pass
     296
    247297    def _extract_summary(self, description):
    248298        """
     
    367417            end = self.find_pos_in_line_number(mo.end(4))
    368418            args = mo.group(3)
    369             if len(args)>2:
    370                 m = args_match.search(args)
    371                 if m is not None:
    372                     objtype = 'function ' + objtype
    373                     args = m.group(1)
    374419            # TODO: What if args is multi-line?  flatten.  What if really long?
    375             items.append({
    376                             'start_line': start,
    377                             'end_line':   end,
    378                             'objtype':    objtype,
    379                             'name':       mo.group(2),
    380                             'args':       args,
    381                             'body':       mo.group(4),
    382                             'comment':    mo.group(5),
    383                             'parent':     None,
    384                           })
     420            if args is not None:
     421                if len(args)>2:
     422                    m = args_match_re.search(args)
     423                    if m is not None:
     424                        objtype = 'function ' + objtype
     425                        args = m.group(1)
     426            d = {
     427                'start_line': start,
     428                'end_line':   end,
     429                'objtype':    objtype,
     430                'name':       mo.group(2),
     431                'args':       str(args),
     432                'body':       mo.group(4),
     433                'comment':    mo.group(5),
     434                'parent':     None,
     435            }
     436            items.append(d)
    385437        return items
    386438
    387439    def list_cdef_macros(self):
    388440        """
    389         parse the internal buffer for def and rdef macro declarations
     441        parse the internal buffer for cdef macro declarations
    390442        """
    391443        # too complicated for a regular expression, just look for the initial part
Note: See TracChangeset for help on using the changeset viewer.