bare-script 3.8.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bare_script/__init__.py +37 -0
- bare_script/__main__.py +12 -0
- bare_script/bare.py +165 -0
- bare_script/baredoc.py +177 -0
- bare_script/data.py +477 -0
- bare_script/include/__init__.py +0 -0
- bare_script/include/args.bare +340 -0
- bare_script/include/baredoc.bare +313 -0
- bare_script/include/dataLineChart.bare +90 -0
- bare_script/include/dataTable.bare +204 -0
- bare_script/include/diff.bare +148 -0
- bare_script/include/forms.bare +72 -0
- bare_script/include/markdownUp.bare +662 -0
- bare_script/include/pager.bare +301 -0
- bare_script/include/unittest.bare +529 -0
- bare_script/include/unittestMock.bare +456 -0
- bare_script/library.py +2273 -0
- bare_script/model.py +547 -0
- bare_script/options.py +119 -0
- bare_script/parser.py +859 -0
- bare_script/runtime.py +471 -0
- bare_script/value.py +530 -0
- bare_script-3.8.2.dist-info/METADATA +201 -0
- bare_script-3.8.2.dist-info/RECORD +28 -0
- bare_script-3.8.2.dist-info/WHEEL +5 -0
- bare_script-3.8.2.dist-info/entry_points.txt +3 -0
- bare_script-3.8.2.dist-info/licenses/LICENSE +21 -0
- bare_script-3.8.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/bare-script/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# The URL arguments model
|
|
6
|
+
argsTypes = schemaParse( \
|
|
7
|
+
'group "<args.bare>"', \
|
|
8
|
+
'', \
|
|
9
|
+
'', \
|
|
10
|
+
'# An argument model list', \
|
|
11
|
+
'typedef ArgsArgument[len > 0] ArgsArguments', \
|
|
12
|
+
'', \
|
|
13
|
+
'', \
|
|
14
|
+
'# An argument model', \
|
|
15
|
+
'struct ArgsArgument', \
|
|
16
|
+
'', \
|
|
17
|
+
' # The argument name', \
|
|
18
|
+
' string(len > 0) name', \
|
|
19
|
+
'', \
|
|
20
|
+
' # The argument type', \
|
|
21
|
+
' optional ArgsType type', \
|
|
22
|
+
'', \
|
|
23
|
+
" # The argument's global variable name", \
|
|
24
|
+
' optional string(len > 0) global', \
|
|
25
|
+
'', \
|
|
26
|
+
' # If true, the argument is explicit.', \
|
|
27
|
+
' # An explicit argument is only included in the URL if it is in the arguments object.', \
|
|
28
|
+
' optional bool explicit', \
|
|
29
|
+
'', \
|
|
30
|
+
' # The default argument value', \
|
|
31
|
+
' optional object default', \
|
|
32
|
+
'', \
|
|
33
|
+
' # The argument description', \
|
|
34
|
+
' optional string(len > 0) description', \
|
|
35
|
+
'', \
|
|
36
|
+
'', \
|
|
37
|
+
'# An argument value type', \
|
|
38
|
+
'enum ArgsType', \
|
|
39
|
+
' bool', \
|
|
40
|
+
' date', \
|
|
41
|
+
' datetime', \
|
|
42
|
+
' float', \
|
|
43
|
+
' int', \
|
|
44
|
+
' string' \
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# $function: argsValidate
|
|
49
|
+
# $group: args.bare
|
|
50
|
+
# $doc: Validate an arguments model
|
|
51
|
+
# $arg arguments: The [arguments model](model.html#var.vName='ArgsArguments')
|
|
52
|
+
# $return: The validated [arguments model](model.html#var.vName='ArgsArguments') or null if validation fails
|
|
53
|
+
function argsValidate(arguments):
|
|
54
|
+
validatedArguments = schemaValidate(argsTypes, 'ArgsArguments', arguments)
|
|
55
|
+
|
|
56
|
+
# Check for duplicate arguments
|
|
57
|
+
if validatedArguments != null:
|
|
58
|
+
argNames = {}
|
|
59
|
+
for argument in arguments:
|
|
60
|
+
name = objectGet(argument, 'name')
|
|
61
|
+
if objectHas(argNames, name):
|
|
62
|
+
validatedArguments = null
|
|
63
|
+
systemLogDebug('args.bare: Duplicate argument "' + name + '"')
|
|
64
|
+
else:
|
|
65
|
+
objectSet(argNames, name, true)
|
|
66
|
+
endif
|
|
67
|
+
endfor
|
|
68
|
+
endif
|
|
69
|
+
|
|
70
|
+
return validatedArguments
|
|
71
|
+
endfunction
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# $function: argsParse
|
|
75
|
+
# $group: args.bare
|
|
76
|
+
# $doc: Parse an [arguments model](model.html#var.vName='ArgsArguments').
|
|
77
|
+
# $doc: Argument globals are validated and added to the arguments object using the argument name.
|
|
78
|
+
# $arg arguments: The [arguments model](model.html#var.vName='ArgsArguments')
|
|
79
|
+
# $return: The arguments object
|
|
80
|
+
function argsParse(arguments):
|
|
81
|
+
# Create the arguments object
|
|
82
|
+
args = {}
|
|
83
|
+
for argument in arguments:
|
|
84
|
+
# Get the argument value
|
|
85
|
+
global = argsGlobalName(argument)
|
|
86
|
+
value = argsValidateValue(systemGlobalGet(global), objectGet(argument, 'type'), global)
|
|
87
|
+
|
|
88
|
+
# Apply the default argument value, if any
|
|
89
|
+
if value == null:
|
|
90
|
+
value = objectGet(argument, 'default')
|
|
91
|
+
endif
|
|
92
|
+
|
|
93
|
+
# Set the argument value, if any
|
|
94
|
+
if value != null:
|
|
95
|
+
objectSet(args, objectGet(argument, 'name'), value)
|
|
96
|
+
endif
|
|
97
|
+
endfor
|
|
98
|
+
|
|
99
|
+
return args
|
|
100
|
+
endfunction
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# $function: argsURL
|
|
104
|
+
# $group: args.bare
|
|
105
|
+
# $doc: Create a MarkdownUp application URL
|
|
106
|
+
# $arg arguments: The [arguments model](model.html#var.vName='ArgsArguments')
|
|
107
|
+
# $arg args: Optional (default is null). The arguments object. Null argument values are excluded from the URL.
|
|
108
|
+
# $arg explicit: Optional (default is false). If true, arguments are only included in the URL if they are in the arguments object.
|
|
109
|
+
# $arg headerText: Optional (default is null). If non-null, the URL's header text.
|
|
110
|
+
# $arg headerText: The special "_top" header ID scrolls to the top of the page.
|
|
111
|
+
# $arg url: Optional (default is null). If non-null, the MarkdownUp URL hash parameter.
|
|
112
|
+
# $return: The MarkdownUp application URL
|
|
113
|
+
function argsURL(arguments, args, explicit, headerText, url):
|
|
114
|
+
# Get the URL variables
|
|
115
|
+
urlVars = []
|
|
116
|
+
argNames = {}
|
|
117
|
+
for argument in arguments:
|
|
118
|
+
name = objectGet(argument, 'name')
|
|
119
|
+
type = objectGet(argument, 'type')
|
|
120
|
+
global = argsGlobalName(argument)
|
|
121
|
+
default = objectGet(argument, 'default')
|
|
122
|
+
|
|
123
|
+
# Add the argument name (for unknown argument check below)
|
|
124
|
+
objectSet(argNames, name, null)
|
|
125
|
+
|
|
126
|
+
# Add the URL variable, if any
|
|
127
|
+
value = null
|
|
128
|
+
if args != null && objectHas(args, name):
|
|
129
|
+
value = argsValidateValue(objectGet(args, name), type, global)
|
|
130
|
+
elif !(explicit || objectGet(argument, 'explicit')):
|
|
131
|
+
value = argsValidateValue(systemGlobalGet(global), type, global, false)
|
|
132
|
+
endif
|
|
133
|
+
|
|
134
|
+
# Add the URL variable
|
|
135
|
+
if value != null && (default == null || !argsValuesEqual(value, default, type)):
|
|
136
|
+
arrayPush(urlVars, 'var.' + global + '=' + urlEncodeComponent(argsFormatValue(value, type)))
|
|
137
|
+
endif
|
|
138
|
+
endfor
|
|
139
|
+
|
|
140
|
+
# Sort the URL variables for general consistency
|
|
141
|
+
arraySort(urlVars)
|
|
142
|
+
|
|
143
|
+
# Check for unknown arguments
|
|
144
|
+
if args != null:
|
|
145
|
+
for name in objectKeys(args):
|
|
146
|
+
if !objectHas(argNames, name):
|
|
147
|
+
systemLogDebug('args.bare: Unknown argument "' + name + '"')
|
|
148
|
+
endif
|
|
149
|
+
endfor
|
|
150
|
+
endif
|
|
151
|
+
|
|
152
|
+
# Create the URL
|
|
153
|
+
return '#' + if(url != null, 'url=' + urlEncodeComponent(url) + '&', '') + \
|
|
154
|
+
if(arrayLength(urlVars), arrayJoin(urlVars, '&'), 'var=') + \
|
|
155
|
+
if(headerText != null, '&' + if(headerText == argsTopHeaderId, argsTopHeaderId, markdownHeaderId(headerText)), '')
|
|
156
|
+
endfunction
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# The special "top" header ID
|
|
160
|
+
argsTopHeaderId = '_top'
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# $function: argsLink
|
|
164
|
+
# $group: args.bare
|
|
165
|
+
# $doc: Create a Markdown link text to a MarkdownUp application URL
|
|
166
|
+
# $arg arguments: The [arguments model](model.html#var.vName='ArgsArguments')
|
|
167
|
+
# $arg text: The link text
|
|
168
|
+
# $arg args: Optional (default is null). The arguments object.
|
|
169
|
+
# $arg explicit: Optional (default is false). If true, arguments are only included in the URL if they are in the arguments object.
|
|
170
|
+
# $arg headerText: Optional (default is null). If non-null, the URL's header text.
|
|
171
|
+
# $arg headerText: The special "_top" header ID scrolls to the top of the page.
|
|
172
|
+
# $arg url: Optional (default is null). If non-null, the MarkdownUp URL hash parameter.
|
|
173
|
+
# $return: The Markdown link text
|
|
174
|
+
function argsLink(arguments, text, args, explicit, headerText, url):
|
|
175
|
+
return '[' + markdownEscape(text) + '](' + argsURL(arguments, args, explicit, headerText, url) + ')'
|
|
176
|
+
endfunction
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# $function: argsHelp
|
|
180
|
+
# $group: args.bare
|
|
181
|
+
# $doc: Generate the [arguments model's](model.html#var.vName='ArgsArguments') help content
|
|
182
|
+
# $doc:
|
|
183
|
+
# $doc: **NOTE:** Calling this function requires `include <dataTable.bare>`
|
|
184
|
+
# $arg arguments: The [arguments model](model.html#var.vName='ArgsArguments')
|
|
185
|
+
# $return: The array of help Markdown line strings
|
|
186
|
+
function argsHelp(arguments):
|
|
187
|
+
# Create the help data
|
|
188
|
+
helpData = []
|
|
189
|
+
anyDefault = false
|
|
190
|
+
anyExplicit = false
|
|
191
|
+
anyDescription = false
|
|
192
|
+
for argument in arguments:
|
|
193
|
+
type = objectGet(argument, 'type', 'string')
|
|
194
|
+
default = objectGet(argument, 'default')
|
|
195
|
+
explicit = objectGet(argument, 'explicit')
|
|
196
|
+
description = objectGet(argument, 'description')
|
|
197
|
+
|
|
198
|
+
# Add the help data row
|
|
199
|
+
arrayPush(helpData, { \
|
|
200
|
+
'Variable': argsGlobalName(argument), \
|
|
201
|
+
'Type': type, \
|
|
202
|
+
'Default': argsFormatValue(default, type), \
|
|
203
|
+
'Explicit': if(explicit, 'Yes', ''), \
|
|
204
|
+
'Description': if(description != null, description, '') \
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
# Update the "any" field bools
|
|
208
|
+
anyDefault = anyDefault || (default != null)
|
|
209
|
+
anyExplicit = anyExplicit || explicit
|
|
210
|
+
anyDescription = anyDescription || (description != null)
|
|
211
|
+
endfor
|
|
212
|
+
|
|
213
|
+
# Render the help table
|
|
214
|
+
helpFields = ['Variable', 'Type']
|
|
215
|
+
if anyDefault:
|
|
216
|
+
arrayPush(helpFields, 'Default')
|
|
217
|
+
endif
|
|
218
|
+
if anyExplicit:
|
|
219
|
+
arrayPush(helpFields, 'Explicit')
|
|
220
|
+
endif
|
|
221
|
+
if anyDescription:
|
|
222
|
+
arrayPush(helpFields, 'Description')
|
|
223
|
+
endif
|
|
224
|
+
return dataTableMarkdown(helpData, {'fields': helpFields})
|
|
225
|
+
endfunction
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
# Helper function to compute an argument's global name
|
|
229
|
+
function argsGlobalName(argument):
|
|
230
|
+
global = objectGet(argument, 'global')
|
|
231
|
+
if global == null:
|
|
232
|
+
name = objectGet(argument, 'name')
|
|
233
|
+
global = 'v' + stringUpper(stringSlice(name, 0, 1)) + stringSlice(name, 1)
|
|
234
|
+
endif
|
|
235
|
+
return global
|
|
236
|
+
endfunction
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# Helper function to format an argument value
|
|
240
|
+
function argsFormatValue(value, type):
|
|
241
|
+
# No value?
|
|
242
|
+
if value == null:
|
|
243
|
+
return ''
|
|
244
|
+
endif
|
|
245
|
+
|
|
246
|
+
# Return the formatted value
|
|
247
|
+
if type == 'bool':
|
|
248
|
+
return if(value, 'true', 'false')
|
|
249
|
+
elif type == 'date':
|
|
250
|
+
return "'" + datetimeISOFormat(value, true) + "'"
|
|
251
|
+
elif type == 'datetime':
|
|
252
|
+
return "'" + datetimeISOFormat(value) + "'"
|
|
253
|
+
elif type == 'float':
|
|
254
|
+
return stringNew(value)
|
|
255
|
+
elif type == 'int':
|
|
256
|
+
return stringNew(value)
|
|
257
|
+
endif
|
|
258
|
+
|
|
259
|
+
# type == 'string'
|
|
260
|
+
return "'" + value + "'"
|
|
261
|
+
endfunction
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# Helper function to validate an argument value's type
|
|
265
|
+
function argsValidateValue(value, type, global, warn):
|
|
266
|
+
# No value?
|
|
267
|
+
if value == null:
|
|
268
|
+
return null
|
|
269
|
+
endif
|
|
270
|
+
|
|
271
|
+
# Validate the value's type
|
|
272
|
+
valueType = systemType(value)
|
|
273
|
+
if type == 'bool':
|
|
274
|
+
if valueType == 'number' && (value == 0 || value == 1):
|
|
275
|
+
value = !!value
|
|
276
|
+
elif valueType != 'boolean':
|
|
277
|
+
if warn != false:
|
|
278
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
279
|
+
endif
|
|
280
|
+
value = null
|
|
281
|
+
endif
|
|
282
|
+
elif type == 'date':
|
|
283
|
+
valueOrig = value
|
|
284
|
+
if valueType == 'string':
|
|
285
|
+
value = datetimeISOParse(value)
|
|
286
|
+
valueType = systemType(value)
|
|
287
|
+
endif
|
|
288
|
+
if valueType != 'datetime' || datetimeHour(value) != 0 || datetimeMinute(value) != 0 || datetimeSecond(value) != 0:
|
|
289
|
+
if warn != false:
|
|
290
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(valueOrig) + ' for URL argument "' + global + '"')
|
|
291
|
+
endif
|
|
292
|
+
value = null
|
|
293
|
+
endif
|
|
294
|
+
elif type == 'datetime':
|
|
295
|
+
valueOrig = value
|
|
296
|
+
if valueType == 'string':
|
|
297
|
+
value = datetimeISOParse(value)
|
|
298
|
+
valueType = systemType(value)
|
|
299
|
+
endif
|
|
300
|
+
if valueType != 'datetime':
|
|
301
|
+
if warn != false:
|
|
302
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(valueOrig) + ' for URL argument "' + global + '"')
|
|
303
|
+
endif
|
|
304
|
+
value = null
|
|
305
|
+
endif
|
|
306
|
+
elif type == 'float':
|
|
307
|
+
if valueType != 'number':
|
|
308
|
+
if warn != false:
|
|
309
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
310
|
+
endif
|
|
311
|
+
value = null
|
|
312
|
+
endif
|
|
313
|
+
elif type == 'int':
|
|
314
|
+
if valueType != 'number' || value != mathFloor(value):
|
|
315
|
+
if warn != false:
|
|
316
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
317
|
+
endif
|
|
318
|
+
value = null
|
|
319
|
+
endif
|
|
320
|
+
else:
|
|
321
|
+
# type == 'string'
|
|
322
|
+
if valueType != 'string':
|
|
323
|
+
if warn != false:
|
|
324
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
325
|
+
endif
|
|
326
|
+
value = null
|
|
327
|
+
endif
|
|
328
|
+
endif
|
|
329
|
+
|
|
330
|
+
return value
|
|
331
|
+
endfunction
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
# Helper function to determine if two values are equal
|
|
335
|
+
function argsValuesEqual(value, valueOther, type):
|
|
336
|
+
if type == 'date' || type == 'datetime':
|
|
337
|
+
return (value - valueOther) == 0
|
|
338
|
+
endif
|
|
339
|
+
return value == valueOther
|
|
340
|
+
endfunction
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/bare-script/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
include <args.bare>
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# $function: baredocMain
|
|
8
|
+
# $group: baredocMain.bare
|
|
9
|
+
# $doc: The BareScript library documentation application main entry point
|
|
10
|
+
# $arg url: The library documentation JSON resource URL
|
|
11
|
+
# $arg title: The library title
|
|
12
|
+
# $arg menuLinks: Optional array of text/URL menu link tuples
|
|
13
|
+
# $arg groupURLs: Optional map of group name to group Markdown content URL ('' is index) or JSON resource URL
|
|
14
|
+
async function baredocMain(url, title, menuLinks, groupURLs):
|
|
15
|
+
# Parse arguments
|
|
16
|
+
args = argsParse(baredocArguments)
|
|
17
|
+
group = objectGet(args, 'group')
|
|
18
|
+
name = objectGet(args, 'name')
|
|
19
|
+
single = objectGet(args, 'single')
|
|
20
|
+
url = objectGet(args, 'url', url)
|
|
21
|
+
|
|
22
|
+
# Render library JSON documentation page?
|
|
23
|
+
if objectGet(args, 'doc'):
|
|
24
|
+
documentSetTitle('Library')
|
|
25
|
+
elementModelRender(schemaElements(baredocTypes, 'Library'))
|
|
26
|
+
return
|
|
27
|
+
endif
|
|
28
|
+
|
|
29
|
+
# Fetch and validate the library documentation resource
|
|
30
|
+
groups = {}
|
|
31
|
+
urls = if(systemType(url) == 'array', url, [url])
|
|
32
|
+
for libraryJSON, ixLibrary in systemFetch(urls):
|
|
33
|
+
libraryPart = if(libraryJSON != null, jsonParse(libraryJSON))
|
|
34
|
+
libraryPart = if(libraryPart != null, schemaValidate(baredocTypes, 'Library', libraryPart))
|
|
35
|
+
if libraryPart == null:
|
|
36
|
+
libraryURL = arrayGet(urls, ixLibrary)
|
|
37
|
+
markdownPrint('**Error:** Failed to fetch library documentation resource "' + markdownEscape(libraryURL) + '"')
|
|
38
|
+
return
|
|
39
|
+
endif
|
|
40
|
+
|
|
41
|
+
# Group the function documentation
|
|
42
|
+
for function_ in objectGet(libraryPart, 'functions'):
|
|
43
|
+
groupName = objectGet(function_, 'group')
|
|
44
|
+
groupFunctions = objectGet(groups, groupName)
|
|
45
|
+
if groupFunctions == null:
|
|
46
|
+
groupFunctions = []
|
|
47
|
+
objectSet(groups, groupName, groupFunctions)
|
|
48
|
+
endif
|
|
49
|
+
arrayPush(groupFunctions, function_)
|
|
50
|
+
endfor
|
|
51
|
+
endfor
|
|
52
|
+
|
|
53
|
+
# Group URLs?
|
|
54
|
+
if groupURLs != null:
|
|
55
|
+
# Fetch the group URLs, if necessary
|
|
56
|
+
if systemType(groupURLs) == 'string':
|
|
57
|
+
groupURLs = jsonParse(systemFetch(groupURLs))
|
|
58
|
+
endif
|
|
59
|
+
|
|
60
|
+
# Add an empty group for any missing group URLs
|
|
61
|
+
for groupName in objectKeys(groupURLs):
|
|
62
|
+
if groupName != '' && !objectHas(groups, groupName):
|
|
63
|
+
objectSet(groups, groupName, [])
|
|
64
|
+
endif
|
|
65
|
+
endfor
|
|
66
|
+
endif
|
|
67
|
+
|
|
68
|
+
# Sort the group functions
|
|
69
|
+
for groupName in objectKeys(groups):
|
|
70
|
+
groupFunctions = objectGet(groups, groupName)
|
|
71
|
+
arraySort(groupFunctions, baredocFunctionCompare)
|
|
72
|
+
|
|
73
|
+
# Function requested by name?
|
|
74
|
+
if name != null:
|
|
75
|
+
for function_ in groupFunctions:
|
|
76
|
+
functionName = objectGet(function_, 'name')
|
|
77
|
+
if functionName == name:
|
|
78
|
+
# Redirect to the actual URL
|
|
79
|
+
windowSetLocation( \
|
|
80
|
+
argsURL(baredocArguments, {'group': objectGet(function_, 'group'), 'name': null}, false, functionName) \
|
|
81
|
+
)
|
|
82
|
+
return
|
|
83
|
+
endif
|
|
84
|
+
endfor
|
|
85
|
+
endif
|
|
86
|
+
endfor
|
|
87
|
+
if name != null:
|
|
88
|
+
markdownPrint('', '**Error:** Unknown function "' + markdownEscape(name) + '"')
|
|
89
|
+
return
|
|
90
|
+
endif
|
|
91
|
+
|
|
92
|
+
# Render the page
|
|
93
|
+
title = if(title != null && !objectHas(args, 'url'), title, url)
|
|
94
|
+
if group != null:
|
|
95
|
+
baredocGroupPage(args, title, groupURLs, groups, group)
|
|
96
|
+
elif single:
|
|
97
|
+
baredocSinglePage(args, title, menuLinks, groupURLs, groups)
|
|
98
|
+
else:
|
|
99
|
+
baredocIndexPage(args, title, menuLinks, groupURLs, groups)
|
|
100
|
+
endif
|
|
101
|
+
endfunction
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# The BareScript library documentation application arguments
|
|
105
|
+
baredocArguments = argsValidate([ \
|
|
106
|
+
{'name': 'doc', 'type': 'bool', 'default': false}, \
|
|
107
|
+
{'name': 'group'}, \
|
|
108
|
+
{'name': 'name'}, \
|
|
109
|
+
{'name': 'publish', 'type': 'bool', 'default': false}, \
|
|
110
|
+
{'name': 'single', 'type': 'bool', 'default': false}, \
|
|
111
|
+
{'name': 'url', 'global': 'vURL'} \
|
|
112
|
+
])
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# Helper to compare library function objects by name
|
|
116
|
+
function baredocFunctionCompare(f1, f2):
|
|
117
|
+
f1Name = objectGet(f1, 'name')
|
|
118
|
+
f2Name = objectGet(f2, 'name')
|
|
119
|
+
return if(f1Name < f2Name, -1, if(f1Name == f2Name, 0, 1))
|
|
120
|
+
endfunction
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# Render a library documentation index page
|
|
124
|
+
async function baredocIndexPage(args, title, menuLinks, groupURLs, groups):
|
|
125
|
+
publish = objectGet(args, 'publish')
|
|
126
|
+
|
|
127
|
+
# Render the menu and title
|
|
128
|
+
documentSetTitle(title)
|
|
129
|
+
if menuLinks != null && arrayLength(menuLinks) > 0 && !publish:
|
|
130
|
+
menuSpacer = ' | '
|
|
131
|
+
for menuLink, ixMenuLink in menuLinks:
|
|
132
|
+
menuLinkText = arrayGet(menuLink, 0)
|
|
133
|
+
menuLinkURL = arrayGet(menuLink, 1)
|
|
134
|
+
markdownPrint(if(ixMenuLink == 0, '', menuSpacer) + '[' + markdownEscape(menuLinkText) + '](' + urlEncode(menuLinkURL) + ')')
|
|
135
|
+
endfor
|
|
136
|
+
markdownPrint('')
|
|
137
|
+
endif
|
|
138
|
+
markdownPrint('# ' + markdownEscape(title))
|
|
139
|
+
|
|
140
|
+
# Render the index Markdown, if any
|
|
141
|
+
if groupURLs != null && objectHas(groupURLs, ''):
|
|
142
|
+
rootURL = objectGet(groupURLs, '')
|
|
143
|
+
rootMarkdown = systemFetch(rootURL)
|
|
144
|
+
markdownPrint('', if(rootMarkdown != null, rootMarkdown, '**Error:** Failed to load "' + markdownEscape(rootURL) + '"'))
|
|
145
|
+
endif
|
|
146
|
+
|
|
147
|
+
# Render the single page toggle
|
|
148
|
+
if !publish:
|
|
149
|
+
markdownPrint('', argsLink(baredocArguments, 'Single Page', {'single': true}))
|
|
150
|
+
endif
|
|
151
|
+
|
|
152
|
+
# Render the library function index
|
|
153
|
+
markdownPrint('', '## Table of Contents', '')
|
|
154
|
+
for groupName in arraySort(objectKeys(groups)):
|
|
155
|
+
markdownPrint('- ' + argsLink(baredocArguments, groupName, {'group': groupName}, false, argsTopHeaderId))
|
|
156
|
+
endfor
|
|
157
|
+
endfunction
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# Render the single-page library documentation
|
|
161
|
+
async function baredocSinglePage(args, title, menuLinks, groupURLs, groups):
|
|
162
|
+
publish = objectGet(args, 'publish')
|
|
163
|
+
|
|
164
|
+
# Render the menu and title
|
|
165
|
+
documentSetTitle(title)
|
|
166
|
+
if menuLinks != null && arrayLength(menuLinks) > 0 && !publish:
|
|
167
|
+
menuSpacer = ' | '
|
|
168
|
+
for menuLink, ixMenuLink in menuLinks:
|
|
169
|
+
menuLinkText = arrayGet(menuLink, 0)
|
|
170
|
+
menuLinkURL = arrayGet(menuLink, 1)
|
|
171
|
+
markdownPrint(if(ixMenuLink == 0, '', menuSpacer) + '[' + markdownEscape(menuLinkText) + '](' + urlEncode(menuLinkURL) + ')')
|
|
172
|
+
endfor
|
|
173
|
+
markdownPrint('')
|
|
174
|
+
endif
|
|
175
|
+
markdownPrint('# ' + markdownEscape(title))
|
|
176
|
+
|
|
177
|
+
# Render the index Markdown, if any
|
|
178
|
+
if groupURLs != null && objectHas(groupURLs, ''):
|
|
179
|
+
rootURL = objectGet(groupURLs, '')
|
|
180
|
+
rootMarkdown = systemFetch(rootURL)
|
|
181
|
+
markdownPrint('', if(rootMarkdown != null, rootMarkdown, '**Error:** Failed to load "' + markdownEscape(rootURL) + '"'))
|
|
182
|
+
endif
|
|
183
|
+
|
|
184
|
+
# Render the single page toggle
|
|
185
|
+
if !publish:
|
|
186
|
+
markdownPrint('', argsLink(baredocArguments, 'Multi Page', {'single': false}))
|
|
187
|
+
endif
|
|
188
|
+
|
|
189
|
+
# The table of contents
|
|
190
|
+
markdownPrint('', '## Table of Contents', '')
|
|
191
|
+
for groupName in arraySort(objectKeys(groups)):
|
|
192
|
+
markdownPrint('- ' + argsLink(baredocArguments, groupName, null, false, groupName))
|
|
193
|
+
endfor
|
|
194
|
+
|
|
195
|
+
# Render the library function index
|
|
196
|
+
for groupName in arraySort(objectKeys(groups)):
|
|
197
|
+
markdownPrint('', '---', '')
|
|
198
|
+
baredocGroupPage(args, title, groupURLs, groups, groupName, true)
|
|
199
|
+
endfor
|
|
200
|
+
endfunction
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# Render a library documentation group page
|
|
204
|
+
async function baredocGroupPage(args, title, groupURLs, groups, groupName):
|
|
205
|
+
single = objectGet(args, 'single')
|
|
206
|
+
baseHeader = if(single, '##', '#')
|
|
207
|
+
|
|
208
|
+
if !single:
|
|
209
|
+
# Set the document title
|
|
210
|
+
documentSetTitle(title + ' - ' + groupName)
|
|
211
|
+
|
|
212
|
+
# Group exist?
|
|
213
|
+
if !objectHas(groups, groupName):
|
|
214
|
+
markdownPrint('', '**Error:** Unknown group "' + markdownEscape(groupName) + '"')
|
|
215
|
+
return
|
|
216
|
+
endif
|
|
217
|
+
endif
|
|
218
|
+
|
|
219
|
+
# Render the menu and title
|
|
220
|
+
if !single:
|
|
221
|
+
markdownPrint(argsLink(baredocArguments, 'Index', {'group': null}), '')
|
|
222
|
+
endif
|
|
223
|
+
markdownPrint(baseHeader + ' ' + markdownEscape(groupName))
|
|
224
|
+
if single:
|
|
225
|
+
markdownPrint('', argsLink(baredocArguments, 'Back to top', null, false, '_top'))
|
|
226
|
+
endif
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
# Render the group Markdown, if any
|
|
230
|
+
if groupURLs != null && objectHas(groupURLs, groupName):
|
|
231
|
+
groupURL = objectGet(groupURLs, groupName)
|
|
232
|
+
groupMarkdown = systemFetch(groupURL)
|
|
233
|
+
markdownPrint('', if(groupMarkdown != null, groupMarkdown, '**Error:** Failed to load "' + markdownEscape(groupURL) + '"'))
|
|
234
|
+
endif
|
|
235
|
+
|
|
236
|
+
# Render the group function index
|
|
237
|
+
groupFunctions = objectGet(groups, groupName)
|
|
238
|
+
if arrayLength(groupFunctions) != 0:
|
|
239
|
+
markdownPrint('', baseHeader + '# Function Index', '')
|
|
240
|
+
endif
|
|
241
|
+
for function_, ixFunction in groupFunctions:
|
|
242
|
+
functionName = objectGet(function_, 'name')
|
|
243
|
+
markdownPrint('- ' + argsLink(baredocArguments, functionName, null, false, functionName))
|
|
244
|
+
endfor
|
|
245
|
+
|
|
246
|
+
# Render the group function documentation
|
|
247
|
+
for function_ in groupFunctions:
|
|
248
|
+
# Render the function header
|
|
249
|
+
markdownPrint( \
|
|
250
|
+
'', \
|
|
251
|
+
'---', \
|
|
252
|
+
'', \
|
|
253
|
+
baseHeader + '# ' + markdownEscape(objectGet(function_, 'name')), \
|
|
254
|
+
'', \
|
|
255
|
+
objectGet(function_, 'doc') \
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
# Render the functions's argument documentation
|
|
259
|
+
markdownPrint('', baseHeader + '## Arguments')
|
|
260
|
+
arguments = objectGet(function_, 'args')
|
|
261
|
+
if arguments != null:
|
|
262
|
+
for argument in arguments:
|
|
263
|
+
markdownPrint('', '**' + markdownEscape(objectGet(argument, 'name')) + ' -**', objectGet(argument, 'doc'))
|
|
264
|
+
endfor
|
|
265
|
+
else:
|
|
266
|
+
markdownPrint('', 'None')
|
|
267
|
+
endif
|
|
268
|
+
|
|
269
|
+
# Render the function's return documentation
|
|
270
|
+
markdownPrint('', baseHeader + '## Returns')
|
|
271
|
+
returnDoc = objectGet(function_, 'return')
|
|
272
|
+
markdownPrint('', if(returnDoc != null, returnDoc, 'Nothing'))
|
|
273
|
+
endfor
|
|
274
|
+
endfunction
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# The library documentation schema
|
|
278
|
+
baredocTypes = schemaParse( \
|
|
279
|
+
'# A library documentation model', \
|
|
280
|
+
'struct Library', \
|
|
281
|
+
'', \
|
|
282
|
+
' # The library functions', \
|
|
283
|
+
' Function[len > 0] functions', \
|
|
284
|
+
'', \
|
|
285
|
+
'', \
|
|
286
|
+
'# A library function', \
|
|
287
|
+
'struct Function', \
|
|
288
|
+
'', \
|
|
289
|
+
' # The function name', \
|
|
290
|
+
' string(len > 0) name', \
|
|
291
|
+
'', \
|
|
292
|
+
' # The function group (e.g. "Math")', \
|
|
293
|
+
' string(len > 0) group', \
|
|
294
|
+
'', \
|
|
295
|
+
" # The function's documentation Markdown lines", \
|
|
296
|
+
' string[len > 0] doc', \
|
|
297
|
+
'', \
|
|
298
|
+
' # The function arguments', \
|
|
299
|
+
' optional FunctionArgument[len > 0] args', \
|
|
300
|
+
'', \
|
|
301
|
+
" # The function return's documentation Markdown lines", \
|
|
302
|
+
' optional string[len > 0] return', \
|
|
303
|
+
'', \
|
|
304
|
+
'', \
|
|
305
|
+
'# A function argument', \
|
|
306
|
+
'struct FunctionArgument', \
|
|
307
|
+
'', \
|
|
308
|
+
' # The argument name', \
|
|
309
|
+
' string(len > 0) name', \
|
|
310
|
+
'', \
|
|
311
|
+
" # The argument's documentation Markdown lines", \
|
|
312
|
+
' string[len > 0] doc' \
|
|
313
|
+
)
|