aboutsummaryrefslogtreecommitdiff
path: root/utils/python/doc_gen/md_converter.py
diff options
context:
space:
mode:
authorJakob Stendahl <jakobste@uio.no>2021-01-11 13:41:18 +0100
committerJakob Stendahl <jakobste@uio.no>2021-01-11 13:41:18 +0100
commitd17bc0fc4bb057378fadf3f9feb0de1df60d611a (patch)
treeca3069eeacb0b7379cb289d87be932956e449d9c /utils/python/doc_gen/md_converter.py
parent19d65c7b2e287223113ab916e103638c5c5003f5 (diff)
downloadhoverbit-ble-d17bc0fc4bb057378fadf3f9feb0de1df60d611a.tar.gz
hoverbit-ble-d17bc0fc4bb057378fadf3f9feb0de1df60d611a.zip
:sparkles: Add working bluetooth receiver
Diffstat (limited to 'utils/python/doc_gen/md_converter.py')
-rw-r--r--utils/python/doc_gen/md_converter.py242
1 files changed, 242 insertions, 0 deletions
diff --git a/utils/python/doc_gen/md_converter.py b/utils/python/doc_gen/md_converter.py
new file mode 100644
index 0000000..ff3a1eb
--- /dev/null
+++ b/utils/python/doc_gen/md_converter.py
@@ -0,0 +1,242 @@
+import re, json, copy
+
+class MarkdownConverter:
+
+ #constructor
+ def __init__(self, type_colour, function_name_colour, separate_defaults = True, display_defaults = False):
+ self.type_colour = type_colour
+ self.function_name_colour = function_name_colour
+ self.separate_defaults = separate_defaults
+ self.display_defaults = display_defaults
+
+ ###
+ # wraps text in a div element with a given color
+ #
+ # @param text the text to wrap
+ # @param color the desired text color
+ #
+ # @return a string representing the now wrapped text
+ ###
+ def wrap_text(self, text, color):
+ return "<div style='color:" + color + "; display:inline-block'>" + text + "</div>"
+
+ ###
+ # removes previously generated markdown from the file.
+ #
+ # @param file_lines a list of lines representing a file.
+ # @param regexp the regular expression that dictates a match.
+ ###
+ def clean(self, file_lines, regexp):
+ start = 0
+ end = 0
+
+ for line_number, line in enumerate(file_lines, 1):
+ result = re.findall(regexp,line)
+
+ if len(result) is not 0:
+ meta_data = json.loads(result[0])
+
+ keys = meta_data.keys()
+
+ #classname indicates the beginning of a meta_data section
+ if 'className' in keys:
+ start = line_number
+
+ #end indicated the end of a meta_data section
+ if 'end' in keys:
+ end = line_number - 1
+
+ return file_lines[:start] + file_lines[end:]
+
+ ###
+ # given a member function, this function derives the alternative versions
+ #
+ # @param member_func the member function that is required to be derrived
+ #
+ # @return a list of function dictionaries that contain the alternatives, based on the original
+ ###
+ def derive_functions(self, member_func):
+ member_functions_derived = []
+
+ if len(member_func['params']) is not 0:
+
+ param_index = 0
+
+ for param in member_func['params']:
+ if len(param['default']['name']) is 0:
+ param_index = param_index + 1
+ else:
+ break
+
+ bare_function = {
+ 'short_name' : member_func['short_name'],
+ 'name' : member_func['name'],
+ 'params' : [],
+ 'description' : member_func['description'],
+ 'returns' : member_func['returns'],
+ 'notes' : member_func['notes'],
+ 'examples' : member_func['examples'],
+ 'return_type' : member_func['return_type'],
+ }
+
+ for i in range(0, param_index):
+ bare_function['params'] = bare_function['params'] + [member_func['params'][i]]
+
+ member_functions_derived = member_functions_derived + [bare_function]
+
+ current = copy.copy(bare_function)
+
+ #lists retain references, so we have to copy objects to maintain separation
+ for remainder in range(param_index, len(member_func['params'])):
+ current['params'] = current['params'] + [member_func['params'][remainder]]
+ member_functions_derived = member_functions_derived + [current]
+ current = copy.copy(current)
+
+ else:
+ member_functions_derived = member_functions_derived + [member_func]
+
+ return member_functions_derived
+
+ ###
+ # given a parameter, this function generates text
+ #
+ # @param param the parameter that needs a textual translation
+ #
+ # @return a string representing the parameter
+ ###
+ def gen_param_text(self, param):
+ text = "\n> "
+
+ if param['type'] is not None:
+ text = text + " " + self.wrap_text(param['type'], self.type_colour)
+
+ text = text + " " + param['name']
+
+ if self.display_defaults:
+ if len(param['default']['name']) is not 0:
+ text = text + " `= " + param['default']['name']
+
+ if len(param['default']['value']) is not 0:
+ text = text + param['default']['value']
+
+ text = text + "`"
+
+ if 'description' in param.keys():
+ text = text +" - " + param['description']
+
+ text = text.encode('ascii','ignore')
+
+ return text
+
+ ###
+ # given a list of member functions, this function returns a list of new lines for the
+ # file currently being processed.
+ #
+ # @param class_name the name of the current class (found in the meta data)
+ # @param member_functions the list of member_functions extracted from XML
+ #
+ # @return a list containing the new lines to be inserted into the current file.
+ ###
+ def gen_member_func_doc(self, class_name, member_functions):
+
+ # this is what a member function dictionary contains.
+ # function = {
+ # 'short_name':"",
+ # 'name':"",
+ # 'return_type':"",
+ # 'params':[],
+ # 'description':[],
+ # 'returns':"",
+ # 'notes':"",
+ # 'examples':"",
+ # 'default':None
+ # }
+
+ lines = []
+
+ for index, member_func in enumerate(member_functions,0):
+
+ member_functions_derived = []
+
+ if index is 0 or member_func['short_name'] != member_functions[index - 1]['short_name']:
+ if class_name == member_func["short_name"]:
+ lines.append("##Constructor\n")
+ else:
+ lines.append("##" + member_func["short_name"]+"\n")
+
+ #we want to clearly separate our different level of functions in the DAL
+ #so we present methods with defaults as overloads.
+ if self.separate_defaults is True:
+ member_functions_derived = member_functions_derived + self.derive_functions(member_func)
+
+ for derived_func in member_functions_derived:
+ #---- short name for urls ----
+ lines.append("<br/>\n")
+
+ short_name = ""
+
+ if len(derived_func["return_type"]) is not 0:
+ short_name = "####" + self.wrap_text(derived_func["return_type"],self.type_colour) + " " +self.wrap_text(derived_func["short_name"], self.function_name_colour) + "("
+ else:
+ short_name = "####" + derived_func["short_name"] + "("
+
+ last_param = None
+
+ if len(derived_func['params']) is not 0:
+ last_param = derived_func['params'][-1]
+
+ #generate parameters for the name of this function
+ for param in derived_func['params']:
+ text = ""
+
+ if param['type'] is not None:
+ text = text + " " + self.wrap_text(param['type'], self.type_colour)
+
+ text = text + " " + param['name']
+
+ if param is not last_param:
+ short_name = short_name + text +", "
+ else:
+ short_name = short_name + text
+
+ lines.append(short_name + ")\n")
+ #-----------------------------
+
+ #---- description ----
+ if len(derived_func['description']) is not 0:
+ lines.append("#####Description\n")
+ lines.append(' '.join(derived_func['description']) + "\n")
+ #-----------------------------
+
+ #---- parameters ----
+ if len(derived_func['params']) is not 0:
+ lines.append("#####Parameters\n")
+
+ for param in derived_func['params']:
+ lines.append(self.gen_param_text(param) + "\n")
+ #-----------------------------
+
+ #---- returns ----
+ if len(derived_func['returns']) is not 0:
+ lines.append("#####Returns\n")
+ lines.append(derived_func['returns'] + "\n")
+ #-----------------------------
+
+ #---- examples ----
+ if len(derived_func['examples']) is not 0:
+ lines.append("#####Example\n")
+ lines.append("```cpp\n")
+ lines.append(derived_func['examples'])
+ lines.append("```\n")
+ #-----------------------------
+
+ #---- notes ----
+ if len(derived_func['notes']) is not 0:
+ lines.append("\n!!! note\n")
+ lines.append(" " + derived_func['notes'].replace('\n','\n '))
+ lines.append('\n\n')
+ #-----------------------------
+
+ lines.append("____\n")
+
+ return lines