# This script is intended to take an API-style class from OpenBR and output
# structured Markdown text in the OpenBR documentation format. The class details
# should then be filled in.
import sys
import re
def find_name_parent(content):
name_re = re.compile('class(.*?):')
name = name_re.search(content).group()[:-1].strip().split(' ')[-1]
parent_re = re.compile('public.*')
parent = parent_re.search(content).group().strip().split(' ')[-1]
return name, parent
def find_properties(content):
properties = []
property_re = re.compile('Q_PROPERTY\((.*?)\)')
it = property_re.finditer(content)
for prop in it:
prop_type = prop.group()[11:-1].split(' ')[0]
prop_name = prop.group()[11:-1].split(' ')[1]
properties.append((prop_name, prop_type))
return properties
def find_members(content):
members = []
member_re = re.compile('(\w+(<\w+>)*)\s(\w+);')
it = member_re.finditer(content)
for member in it:
member_type = member.group()[:-1].strip().split(' ')[0]
member_name = member.group()[:-1].strip().split(' ')[1]
members.append((member_name, member_type))
return members
def find_constructors(name, content):
constructors = []
constructor_re = re.compile('(.*)' + name + '\(\)')
it = constructor_re.finditer(content)
for constructor in it:
constructors.append(constructor.group().strip())
return constructors
def find_functions(content):
functions = []
function_re = re.compile('(.*)[^PROPERTY]\(.*\).*;')
it = function_re.finditer(content)
for func in it:
function = {}
function['Full'] = func.group()[:-1].strip() #don't include semi colon
func_split = func.group().strip().split(' ')
if func_split[0] == "static":
function['Type'] = 'static'
function['Return'] = func_split[1]
function['Name'] = func_split[2].split('(')[0]
elif func_split[0] == "virtual":
function['Type'] = 'virtual'
function['Return'] = func_split[1]
function['Name'] = func_split[2].split('(')[0]
else:
function['Type'] = 'normal'
function['Return'] = func_split[0]
function['Name'] = func_split[1].split('(')[0]
args = []
args_list = func.group()[func.group().find('(')+1:func.group().find(')')].split(',')
for arg in args_list:
arg = arg.strip()
split_idx = arg.rfind(' ')
if arg[split_idx:].strip()[0] == '*' or arg[split_idx:].strip()[0] == '&':
split_idx += 2
args.append((arg[split_idx:].strip(), arg[:split_idx].strip()))
function['Args'] = args
functions.append(function)
return functions
def parse(content):
name, parent = find_name_parent(content)
properties = find_properties(content)
members = find_members(content)
constructors = find_constructors(name, content)
functions = find_functions(content)
return name, parent, properties, members, constructors, functions
def function_builder(name, function):
markdown = ""
markdown += "### " + function["Full"] + " {: #" + name.lower() + "-function-" + function['Name'].lower() + "}\n\n"
markdown += "DOCUMENT ME\n\n"
markdown += "* **function definition:**\n\n"
markdown += "\t\t" + function['Full'] + "\n\n"
markdown += "* **parameters:**"
if len(function['Args']) == 0:
markdown += " NONE\n"
else:
markdown += "\n\n"
markdown += "\tParameter | Type | Description\n"
markdown += "\t--- | --- | ---\n"
for arg in function['Args']:
markdown += "\t" + arg[0] + " | " + arg[1] + " | DOCUMENT ME\n"
markdown += "\n"
markdown += "* **output:** (" + function['Return'] + ") DOCUMENT ME\n\n\n"
return markdown
def format_md(name, parent, properties, members, constructors, functions):
markdown = ""
markdown += "# " + name + "\n\n"
markdown += "Inherits from [" + parent + "](#" + parent.lower() + ")\n\n"
markdown += "## Properties {: #" + name.lower() + "-properties }\n\n"
if len(properties) == 0:
markdown += "NONE\n\n"
else:
markdown += "Property | Type | Description\n"
markdown += "--- | --- | ---\n"
for prop in properties:
markdown += ''
markdown += prop[0] + " | " + prop[1] + " | DOCUMENT ME\n"
markdown += "\n"
markdown += "## Members {: #" + name.lower() + "-members }\n\n"
if len(members) == 0:
markdown += "NONE\n\n"
else:
markdown += "Member | Type | Description\n"
markdown += "--- | --- | ---\n"
for member in members:
markdown += ''
markdown += member[0] + " | " + member[1] + " | DOCUMENT ME\n"
markdown += "\n"
markdown += "## Constructors {: #" + name.lower() + "-constructors }\n\n"
if len(constructors) == 0:
markdown += "NONE\n\n"
else:
markdown += "Constructor \| Destructor | Description\n"
markdown += "--- | ---\n"
for constructor in constructors:
markdown += constructor + " | DOCUMENT ME\n"
markdown += "\n"
markdown += "## Static Functions {: #" + name.lower() + "-static-functions }\n\n"
for function in functions:
if function['Type'] == 'static':
markdown += function_builder(name, function)
markdown += "## Functions {: #" + name.lower() + "-functions }\n\n"
for function in functions:
if not function['Type'] == 'static':
markdown += function_builder(name, function)
return markdown
def main():
if len(sys.argv) != 3:
print 'Inputs => class documentation'
sys.exit(1)
class_file = open(sys.argv[1], 'r')
doc_file = open(sys.argv[2], 'w+')
name, parent, properties, members, constructors, functions = parse(class_file.read())
doc_file.write(format_md(name, parent, properties, members, constructors, functions))
main()