-
-
Notifications
You must be signed in to change notification settings - Fork 583
/
Copy pathgenerate_docs.py
158 lines (141 loc) · 5.66 KB
/
generate_docs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import os
import sys
import shutil
import zipfile
import json
import subprocess
import platform
import html
import re
from lib.doc_entities import PageType, PageGroup, PageDoc, EnumMemberDoc, EnumDoc, ParameterDoc, ReturnsDoc, FunctionDoc, ClassDoc
from lib.doc_generator import Documentation, GenerateDocumentation
def GetDictValue (dict, key):
if not key in dict:
return None
return dict[key]
def GetDocumentedDoclets (doclets):
documented = []
for doclet in doclets:
kind = doclet['kind']
if kind not in ['class', 'function', 'constant', 'member']:
continue
if 'undocumented' in doclet and doclet['undocumented'] == True:
continue
documented.append (doclet)
return documented
def GetParametersFromDoclet (doclet):
parameters = []
paramNamespaceToDoc = {}
if not 'params' in doclet:
return parameters
for param in doclet['params']:
paramName = GetDictValue (param, 'name')
paramIsOptional = 'optional' in param and param['optional'] == True
paramNameParts = paramName.split ('.')
paramTypes = None
if 'type' in param:
paramTypes = param['type']['names']
if len (paramNameParts) == 1:
paramDoc = ParameterDoc (
paramName,
paramTypes,
paramIsOptional,
GetDictValue (param, 'description')
)
parameters.append (paramDoc)
paramNamespaceToDoc[paramName] = paramDoc
else:
paramDoc = ParameterDoc (
paramNameParts[len (paramNameParts) - 1],
paramTypes,
paramIsOptional,
GetDictValue (param, 'description')
)
paramNamespace = '.'.join (paramNameParts[0:-1])
paramNamespaceToDoc[paramNamespace].AddSubParameter (paramDoc)
paramNamespaceToDoc[paramName] = paramDoc
return parameters
def GetReturnsFromDoclet (doclet):
if not 'returns' in doclet:
return None
assert (len (doclet['returns']) == 1)
returns = doclet['returns'][0]
returnType = None
if 'type' in returns:
returnType = returns['type']['names']
return ReturnsDoc (
returnType,
GetDictValue (returns, 'description')
)
def AddPageGroupsToDocumentation (documentation, pageGroups, sourcesFolder):
for pageGroup in pageGroups:
pageGroupDoc = PageGroup (pageGroup['name'])
for page in pageGroup['pages']:
pageType = PageType.External if page['url'].startswith ('http') else PageType.Internal
pageDoc = PageDoc (page['name'], page['url'], sourcesFolder, pageType)
pageGroupDoc.AddPage (pageDoc)
documentation.AddPageGroup (pageGroupDoc)
def AddEntitiesToDocumentation (documentation, doclets):
classNameToDoc = {}
enumNameToDoc = {}
for doclet in doclets:
kind = doclet['kind']
name = doclet['name']
parameters = GetParametersFromDoclet (doclet)
returns = GetReturnsFromDoclet (doclet)
description = GetDictValue (doclet, 'description')
if kind == 'class':
classDoc = ClassDoc (name, doclet['classdesc'])
constructorDoc = FunctionDoc (name, description, parameters, returns)
classDoc.SetConstructor (constructorDoc)
documentation.AddClass (classDoc)
classNameToDoc[name] = classDoc
elif kind == 'function':
if 'memberof' in doclet:
parentName = doclet['memberof']
if parentName in classNameToDoc:
classDoc = classNameToDoc[parentName]
functionDoc = FunctionDoc (name, description, parameters, returns)
classDoc.AddFunction (functionDoc)
else:
functionDoc = FunctionDoc (name, description, parameters, returns)
documentation.AddFunction (functionDoc)
elif kind == 'constant':
if 'isEnum' in doclet and doclet['isEnum'] == True:
enumDoc = EnumDoc (name, description)
documentation.AddEnum (enumDoc)
enumNameToDoc[name] = enumDoc
elif kind == 'member':
parentName = doclet['memberof']
if parentName in enumNameToDoc:
enumDoc = enumNameToDoc[parentName]
memberDoc = EnumMemberDoc (name, description)
enumDoc.AddMember (memberDoc)
def Main (argv):
toolsDir = os.path.dirname (os.path.abspath (__file__))
rootDir = os.path.dirname (toolsDir)
os.chdir (rootDir)
shell = True
if platform.system () != 'Windows':
shell = False
result = subprocess.run (['jsdoc', '-c', 'tools/jsdoc.json'], stdout = subprocess.PIPE, shell = shell)
resultJson = json.loads (result.stdout)
resultDir = os.path.join (rootDir, 'docs')
sourceDir = os.path.join (resultDir, 'source')
for fileName in os.listdir (resultDir):
filePath = os.path.join (resultDir, fileName)
if not os.path.isdir (filePath):
os.remove (filePath)
config = None
with open (os.path.join (sourceDir, 'config.json')) as configJson:
config = json.load (configJson)
documentation = Documentation ()
pageGroups = config['page_groups']
AddPageGroupsToDocumentation (documentation, pageGroups, sourceDir)
doclets = GetDocumentedDoclets (resultJson)
AddEntitiesToDocumentation (documentation, doclets)
for name in config['external_refs']:
documentation.AddEntityLink (name, config['external_refs'][name])
GenerateDocumentation (documentation, sourceDir, resultDir)
return 0
sys.exit (Main (sys.argv))