xref: /btstack/doc/manual/markdown_create_gatt_services_and_clients.py (revision 2eaf98e75b0d017b1cf9b76badc55b9bffd2c354)
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