Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

205 lines (148 sloc) 5.75 KB
import re
import string
class BaseParser(object):
NO_RETURN_TYPE = 1 # e.g. void
UNKNOWN_RETURN_TYPE = 2 # e.g. add Returns section with no type
def __init__(self, preferences={}):
self.preferences = preferences
self.default_settings = {
'class_name': 'Class',
'function_name': 'Function',
'block_start': '',
'block_middle': '',
'block_end': ''
def setup_settings(self):
self.settings = {}
return self.settings
def get_settings(self):
return self.settings
def __getattr__(self, name):
if name in self.settings:
return self.settings[name]
if name in self.default_settings:
return self.default_settings[name]
return None
def is_existing_comment(self, line):
return'^\\s*\\*', line)
def parse(self, line):
out = self.parse_class(line) # (name, extends)
if out:
return self.format_class(*out)
out = self.parse_function(line) # (name, args)
if out:
return self.format_function(*out)
out = self.parse_var(line)
if out:
return self.format_var(*out)
return None
def parse_class(self, line):
return None
def parse_function(self, line):
return None
def parse_var(self, line):
return None
def escape(self, str):
return string.replace(str, '$', '\$')
def format_class(self, name, base=None, interface=None):
out = []
class_name = self.class_name
out.append("%s: %s" % (class_name, name))
out.append("${1:[%s description]}" % (self.escape(name)))
if base:
out.append("Extends: %s" % base)
if interface:
out.append("Implements: %s" % interface)
return out
def format_var(self, name, val):
out = []
out.append("Variable: %s" % self.escape(name))
if self.inline == False:
out.append("${1:[%s description]}" % (self.escape(name)))
return out
def format_function(self, name, args, return_type=None):
out = []
function_name = self.function_name
out.append("%s: %s" % (function_name, name))
# if there are arguments, add a Parameter section for each
if args:
# remove comments inside the argument list.
# args = re.sub("/\*.*?\*/", '', args)
params = []
for arg in self.parse_args(args):
description = '[type/description]'
if arg[0]:
description = arg[0]
params.append(" %s - ${1:%s}" % (self.escape(arg[1]), description))
# add extra line after parameters?
if self.preferences.get("natural_docs_spacer_between_sections"):
if return_type is None:
return_type = self.get_function_return_type(name)
if return_type is not None and return_type is not self.NO_RETURN_TYPE:
if return_type is not self.UNKNOWN_RETURN_TYPE:
out.append(" %s - ${1:return description}" % (return_type))
out.append(" ${1:return description}")
return out
def align_parameters(self, params):
columnWidth = 0
# discover the first column width
for param in params:
first = param.split(" - ")[0]
if len(first) > columnWidth:
columnWidth = len(first)
# adjust each parameter line with the new column width
newParams = []
for param in params:
(first, second) = param.split(" - ")
extra = columnWidth - len(first)
newParams.append(first + (" " * extra) + " - " + second)
return newParams
def get_function_return_type(self, name):
""" returns None for no return type. False meaning unknown, or a string """
def parse_args(self, args):
""" an array of tuples, the first being the best guess at the type, the second being the name """
out = []
for arg in re.split('\s*,\s*', args):
arg = arg.strip()
out.append((self.get_arg_type(arg), self.get_arg_name(arg)))
return out
def get_arg_type(self, arg):
return None
def get_arg_name(self, arg):
return arg
def add_extra_tags(self, out):
extraTags = self.preferences.get('natural_docs_extra_tags', [])
if (len(extraTags) > 0):
def guess_type_from_name(self, name):
name = re.sub("^[$_]", "", name)
hungarian_map = self.preferences.get('natural_docs_notation_map', [])
if len(hungarian_map):
for rule in hungarian_map:
matched = False
if 'prefix' in rule:
matched = re.match(rule['prefix'] + "[A-Z_]", name)
elif 'regex' in rule:
matched =['regex'], name)
if matched:
return self.settings[rule['type']] if rule['type'] in self.settings else rule['type']
if (re.match("(?:is|has)[A-Z_]", name)):
return self.settings['bool']
if (re.match("^(?:cb|callback|done|next|fn)$", name)):
return self.settings['function']
return False
def is_numeric(self, val):
return True
except ValueError:
return False
Jump to Line
Something went wrong with that request. Please try again.