From 44526696147c42ef51b8fcd15f44721d7ca46dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Thu, 31 Jan 2019 07:18:58 +0100 Subject: [PATCH] module documentation: add support for subcategories --- Tools/px4moduledoc/markdownout.py | 40 +++++++++++++++------ Tools/px4moduledoc/srcparser.py | 29 ++++++++++++--- Tools/px_process_module_doc.py | 2 +- src/drivers/distance_sensor/sf1xx/sf1xx.cpp | 1 + src/platforms/common/module.cpp | 5 +++ src/platforms/px4_module.h | 6 ++++ 6 files changed, 66 insertions(+), 17 deletions(-) diff --git a/Tools/px4moduledoc/markdownout.py b/Tools/px4moduledoc/markdownout.py index ce5e2b52c0..ba59f82e19 100644 --- a/Tools/px4moduledoc/markdownout.py +++ b/Tools/px4moduledoc/markdownout.py @@ -40,22 +40,40 @@ The generated files will be written to the `modules` directory. self._outputs['main'] = result - for category in sorted(module_groups): result = "# Modules Reference: %s\n" % category.capitalize() - module_list = module_groups[category] - for module in module_list: - result += "## %s\n" % module.name() - result += "Source: [%s](https://github.com/PX4/Firmware/tree/master/src/%s)\n\n" % (module.scope(), module.scope()) - doc = module.documentation() - if len(doc) > 0: - result += "%s\n" % doc - usage_string = module.usage_string() - if len(usage_string) > 0: - result += "### Usage {#%s_usage}\n```\n%s\n```\n" % (module.name(), usage_string) + subcategories = module_groups[category] + if len(subcategories) > 1: + result += 'Subcategories:\n' + for subcategory in subcategories: + if subcategory == '': + continue + subcategory_label = subcategory.replace('_', ' ').title() + subcategory_file_name = category+'_'+subcategory + result += '- [%s](modules_%s.md)\n' % (subcategory_label, subcategory_file_name) + # add a sub-page for the subcategory + result_subpage = '# Modules Reference: %s (%s)\n' % \ + (subcategory_label, category.capitalize()) + result_subpage += self._ProcessModules(subcategories[subcategory]) + self._outputs[subcategory_file_name] = result_subpage + + result += '\n' + self._ProcessModules(subcategories['']) self._outputs[category] = result + def _ProcessModules(self, module_list): + result = '' + for module in module_list: + result += "## %s\n" % module.name() + result += "Source: [%s](https://github.com/PX4/Firmware/tree/master/src/%s)\n\n" % (module.scope(), module.scope()) + doc = module.documentation() + if len(doc) > 0: + result += "%s\n" % doc + usage_string = module.usage_string() + if len(usage_string) > 0: + result += "### Usage {#%s_usage}\n```\n%s\n```\n" % (module.name(), usage_string) + return result + def Save(self, dirname): for output_name in self._outputs: output = self._outputs[output_name] diff --git a/Tools/px4moduledoc/srcparser.py b/Tools/px4moduledoc/srcparser.py index 2e227699e6..2c29645fa3 100644 --- a/Tools/px4moduledoc/srcparser.py +++ b/Tools/px4moduledoc/srcparser.py @@ -8,8 +8,11 @@ class ModuleDocumentation(object): documentation for a single module """ + # If you add categories or subcategories, they also need to be added to the + # TOC in https://github.com/PX4/Devguide/blob/master/en/SUMMARY.md valid_categories = ['driver', 'estimator', 'controller', 'system', 'communication', 'command', 'template'] + valid_subcategories = ['', 'distance_sensor'] max_line_length = 80 # wrap lines that are longer than this @@ -19,6 +22,7 @@ class ModuleDocumentation(object): """ self._name = '' self._category = '' + self._subcategory = '' self._doc_string = '' self._usage_string = '' self._first_command = True @@ -43,7 +47,6 @@ class ModuleDocumentation(object): assert(len(args) == 1) # description self._doc_string = self._get_string(args[0]) - def _handle_usage_name(self, args): assert(len(args) == 2) # executable_name, category self._name = self._get_string(args[0]) @@ -52,6 +55,10 @@ class ModuleDocumentation(object): self._usage_string = "%s [arguments...]\n" % self._name self._usage_string += " Commands:\n" + def _handle_usage_subcategory(self, args): + assert(len(args) == 1) # description + self._subcategory = self._get_string(args[0]) + def _handle_usage_name_simple(self, args): assert(len(args) == 2) # executable_name, category self._name = self._get_string(args[0]) @@ -196,6 +203,9 @@ class ModuleDocumentation(object): def category(self): return self._category + def subcategory(self): + return self._subcategory + def scope(self): return self._scope @@ -304,6 +314,9 @@ class SourceParser(object): if not module_doc.category() in ModuleDocumentation.valid_categories: raise Exception('Invalid/unknown category ' + module_doc.category() + ' for ' + scope) + if not module_doc.subcategory() in ModuleDocumentation.valid_subcategories: + raise Exception('Invalid/unknown subcategory ' + + module_doc.subcategory() + ' for ' + scope) self._do_consistency_check(contents, scope, module_doc) @@ -483,19 +496,25 @@ class SourceParser(object): def GetModuleGroups(self): """ - Returns a dictionary of all categories with a list of associated modules. + Returns a dictionary of all categories with a dictonary of subcategories + that contain a list of associated modules. """ groups = {} for module_name in self._modules: module = self._modules[module_name] + subcategory = module.subcategory() if module.category() in groups: - groups[module.category()].append(module) + if subcategory in groups[module.category()]: + groups[module.category()][subcategory].append(module) + else: + groups[module.category()][subcategory] = [module] else: - groups[module.category()]= [module] + groups[module.category()] = {subcategory: [module]} # sort by module name for category in groups: group = groups[category] - groups[category] = sorted(group, key=lambda x: x.name()) + for subcategory in group: + group[subcategory] = sorted(group[subcategory], key=lambda x: x.name()) return groups diff --git a/Tools/px_process_module_doc.py b/Tools/px_process_module_doc.py index 569dc0cad7..b09ec606c3 100755 --- a/Tools/px_process_module_doc.py +++ b/Tools/px_process_module_doc.py @@ -93,7 +93,7 @@ def main(): # Output to Markdown/HTML tables if args.markdown: - if (args.verbose): print("Creating markdown output to directory " + str(args.markdown)) + if args.verbose: print("Creating markdown output to directory " + str(args.markdown)) if not os.path.exists(args.markdown): os.makedirs(args.markdown) out = markdownout.MarkdownOutput(module_groups) diff --git a/src/drivers/distance_sensor/sf1xx/sf1xx.cpp b/src/drivers/distance_sensor/sf1xx/sf1xx.cpp index 2d5ae43446..ba67d56fae 100644 --- a/src/drivers/distance_sensor/sf1xx/sf1xx.cpp +++ b/src/drivers/distance_sensor/sf1xx/sf1xx.cpp @@ -835,6 +835,7 @@ $ sf1xx stop )DESCR_STR"); PRINT_MODULE_USAGE_NAME("sf1xx", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("distance_sensor"); PRINT_MODULE_USAGE_COMMAND_DESCR("start","Start driver"); PRINT_MODULE_USAGE_PARAM_FLAG('a', "Attempt to start driver on all I2C buses", true); PRINT_MODULE_USAGE_PARAM_INT('b', 1, 1, 2000, "Start driver on specific I2C bus", true); diff --git a/src/platforms/common/module.cpp b/src/platforms/common/module.cpp index 31e8b6c7af..319fc6b583 100644 --- a/src/platforms/common/module.cpp +++ b/src/platforms/common/module.cpp @@ -64,6 +64,11 @@ void PRINT_MODULE_USAGE_NAME(const char *executable_name, const char *category) PX4_INFO_RAW(" Commands:\n"); } +void PRINT_MODULE_USAGE_SUBCATEGORY(const char *subcategory) +{ + (void)subcategory; +} + void PRINT_MODULE_USAGE_NAME_SIMPLE(const char *executable_name, const char *category) { PX4_INFO_RAW("Usage: %s [arguments...]\n", executable_name); diff --git a/src/platforms/px4_module.h b/src/platforms/px4_module.h index c3806da110..150da68c24 100644 --- a/src/platforms/px4_module.h +++ b/src/platforms/px4_module.h @@ -472,6 +472,12 @@ __EXPORT void PRINT_MODULE_DESCRIPTION(const char *description); */ __EXPORT void PRINT_MODULE_USAGE_NAME(const char *executable_name, const char *category); +/** + * @brief Specify a subcategory. + * @param subcategory e.g. if the category is 'driver', subcategory can be 'distance_sensor' + */ +__EXPORT void PRINT_MODULE_USAGE_SUBCATEGORY(const char *subcategory); + /** * @brief Prints the name for a command without any sub-commands (@see PRINT_MODULE_USAGE_NAME()). */