1#!/usr/bin/env python3 2import os, sys, getopt, re 3import subprocess 4 5class State: 6 SearchIntro = 0 7 IntroFound = 1 8 SearchAPI = 2 9 10mdfiles = { 11 # source file sufix : docu file, [white list od source files] 12 "_server.h" : ["gatt_services.md", ["hids_device.h"]], 13 "_client.h" : ["gatt_clients.md", []] 14} 15 16abrevations = { 17 "Ancs" : "ANCS", 18 "Hids" : "HIDS", 19 "Ublox": "u-blox", 20 "Spp" : "SPP", 21 "And" : "and" 22} 23 24description_template = """ 25## NAME {#sec:REFERENCE} 26 27""" 28 29description_api = """ 30 31See [NAME API](../appendix/apis/#REFERENCE). 32 33""" 34 35def isEmptyCommentLine(line): 36 return re.match('(\s*\*\s*)\n',line) 37 38def isCommentLine(line): 39 return re.match('(\s*\*\s*).*',line) 40 41def isEndOfComment(line): 42 return re.match('\s*\*/.*', line) 43 44def isNewItem(line): 45 return re.match('(\s*\*\s*\-\s*)(.*)',line) 46 47def isTextTag(line): 48 return re.match('.*(@text).*', line) 49 50def isItemizeTag(line): 51 return re.match("(\s+\*\s+)(-\s)(.*)", line) 52 53def processTextLine(line): 54 if isEmptyCommentLine(line): 55 return "\n\n" 56 57 line.rstrip() 58 59 if isTextTag(line): 60 text_line_parts = re.match(".*(@text\s*)(.*)", line) 61 return text_line_parts.group(2).lstrip() + " " 62 63 if isItemizeTag(line): 64 text_line_parts = re.match("(\s*\*\s*\-\s*)(.*)", line) 65 return "- " + text_line_parts.group(2) 66 67 if isEmptyCommentLine(line): 68 return "\n" 69 70 text_line_parts = re.match("(\s+\*\s+)(.*)", line) 71 if text_line_parts: 72 return text_line_parts.group(2) + " " 73 return "" 74 75def handle_abrevations(basename): 76 name_parts = [item.capitalize() for item in basename.split("_")] 77 for i in range(len(name_parts)): 78 try: 79 name_parts[i] = abrevations[name_parts[i]] 80 except KeyError: 81 continue 82 83 return " ".join(name_parts) 84 85 86def process_file(basename, inputfile_path, outputfile_path): 87 reference = basename.replace("_", "-") 88 name = handle_abrevations(basename) 89 90 title = description_template.replace("NAME", name).replace("REFERENCE", reference) 91 api = description_api.replace("NAME", name).replace("REFERENCE", reference) 92 93 text_block = "" 94 with open(inputfile_path, 'r') as fin: 95 state = State.SearchIntro 96 for line in fin: 97 if state == State.SearchIntro: 98 if isTextTag(line): 99 state = State.IntroFound 100 text_block = text_block + processTextLine(line) 101 continue 102 103 if state == State.IntroFound: 104 text_block = text_block + processTextLine(line) 105 106 if isEndOfComment(line): 107 state = State.SearchIntro 108 fin.close() 109 110 with open(outputfile_path, 'a+') as fout: 111 fout.write(title) 112 fout.write(text_block) 113 fout.write(api) 114 fout.close() 115 116def main(argv): 117 btstackfolder = os.path.abspath(os.path.dirname(sys.argv[0]) + '/../../') 118 inputfolder = btstackfolder + "/src/ble/gatt-service/" 119 120 markdownfolder = "docs-markdown/" 121 templatefolder = "docs-intro/" 122 123 cmd = 'markdown_create_gatt_services_and_clients.py [-r <root_btstackfolder>] [-t <templatefolder>] [-o <output_markdownfolder>]' 124 125 try: 126 opts, args = getopt.getopt(argv,"r:t:o:",["rfolder=","tfolder=","ofolder="]) 127 except getopt.GetoptError: 128 print (cmd) 129 sys.exit(2) 130 for opt, arg in opts: 131 if opt == '-h': 132 print (cmd) 133 sys.exit() 134 elif opt in ("-r", "--rfolder"): 135 btstackfolder = arg 136 elif opt in ("-t", "--tfolder"): 137 templatefolder = arg 138 elif opt in ("-o", "--ofolder"): 139 markdownfolder = arg 140 141 142 for source_filename_sufix, [outputfile, white_list] in mdfiles.items(): 143 outputfile_path = markdownfolder + outputfile 144 introfile_path = templatefolder + outputfile[:-3] + "_intro.md" 145 146 with open(outputfile_path, 'w') as fout: 147 with open(introfile_path, 'r') as fin: 148 for line in fin: 149 fout.write(line) 150 151 fin.close() 152 fout.close() 153 154 files_to_process = [] 155 for root, dirs, files in os.walk(inputfolder, topdown=True): 156 for f in files: 157 if not f.endswith(source_filename_sufix): 158 if f not in white_list: 159 continue 160 files_to_process.append(root + "/"+ f) 161 162 files_to_process.sort() 163 164 for inputfile_path in files_to_process: 165 basename = os.path.basename(inputfile_path)[:-2] 166 process_file(basename, inputfile_path, outputfile_path) 167 168 169if __name__ == "__main__": 170 main(sys.argv[1:]) 171