bare-script 3.0.15 → 3.2.0
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.
- package/lib/bare.js +47 -4
- package/lib/include/args.mds +344 -0
- package/lib/include/forms.mds +79 -0
- package/lib/include/markdownUp.bare +466 -0
- package/lib/include/pager.mds +235 -0
- package/lib/include/unittest.mds +191 -0
- package/lib/include/unittestMock.mds +462 -0
- package/lib/value.js +20 -0
- package/package.json +2 -2
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/markdown-up/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Include sentinel
|
|
6
|
+
if systemGlobalGet('markdownUpSentinel'):
|
|
7
|
+
return
|
|
8
|
+
endif
|
|
9
|
+
markdownUpSentinel = true
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Constants
|
|
13
|
+
markdownUpPixelsPerPoint = 4 / 3
|
|
14
|
+
markdownUpDefaultFontSizePx = 12 * markdownUpPixelsPerPoint
|
|
15
|
+
markdownUpFontWidthRatio = 0.6
|
|
16
|
+
markdownUpWindowHeight = 768
|
|
17
|
+
markdownUpWindowWidth = 1024
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# The simulated MarkdownUp state
|
|
21
|
+
markdownUpState = objectNew( \
|
|
22
|
+
'drawingFontSizePx', markdownUpDefaultFontSizePx, \
|
|
23
|
+
'drawingHeight', 480, \
|
|
24
|
+
'drawingWidth', 640, \
|
|
25
|
+
'localStorage', objectNew(), \
|
|
26
|
+
'sessionStorage', objectNew(), \
|
|
27
|
+
'windowClipboard', '' \
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Data functions
|
|
33
|
+
#
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
function dataLineChart(data, lineChart):
|
|
37
|
+
width = objectGet(lineChart, 'width', 640)
|
|
38
|
+
height = objectGet(lineChart, 'height', 320)
|
|
39
|
+
title = objectGet(lineChart, 'title')
|
|
40
|
+
systemLog('')
|
|
41
|
+
systemLog('<LineChart ' + width + 'x' + height + ', ' + arrayLength(data) + ' rows' + if(title, ' - ' + title, '') + '>')
|
|
42
|
+
endfunction
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
function dataTable(data, model):
|
|
46
|
+
# Validate the data
|
|
47
|
+
data = dataValidate(data)
|
|
48
|
+
if data == null:
|
|
49
|
+
return
|
|
50
|
+
endif
|
|
51
|
+
|
|
52
|
+
# Determine the table fields
|
|
53
|
+
fields = arrayNew()
|
|
54
|
+
modelFields = if(model != null, objectGet(model, 'fields'))
|
|
55
|
+
modelCategories = if(model != null, objectGet(model, 'categories'))
|
|
56
|
+
if modelFields != null || modelCategories != null:
|
|
57
|
+
arrayExtend(fields, modelCategories)
|
|
58
|
+
arrayExtend(fields, modelFields)
|
|
59
|
+
elif arrayLength(data) > 0:
|
|
60
|
+
arrayExtend(fields, objectKeys(arrayGet(data, 0)))
|
|
61
|
+
endif
|
|
62
|
+
if !arrayLength(fields):
|
|
63
|
+
return
|
|
64
|
+
endif
|
|
65
|
+
|
|
66
|
+
# Get precision and formatting
|
|
67
|
+
precisionDatetime = if(model != null, objectGet(model, 'datetime'))
|
|
68
|
+
precisionNumber = if(model != null, objectGet(model, 'precision', 2), 2)
|
|
69
|
+
precisionTrim = if(model != null, objectGet(model, 'trim', true), true)
|
|
70
|
+
formats = if(model != null, objectGet(model, 'formats'))
|
|
71
|
+
|
|
72
|
+
# Compute the field header widths
|
|
73
|
+
widths = objectNew()
|
|
74
|
+
for field in fields:
|
|
75
|
+
fieldWidth = stringLength(field)
|
|
76
|
+
if !objectHas(widths, field) || fieldWidth > objectGet(widths, field):
|
|
77
|
+
objectSet(widths, field, fieldWidth)
|
|
78
|
+
endif
|
|
79
|
+
endfor
|
|
80
|
+
|
|
81
|
+
# Compute the formatted field value strings and widths
|
|
82
|
+
dataFormat = arrayNew()
|
|
83
|
+
for row in data:
|
|
84
|
+
rowFormat = objectNew()
|
|
85
|
+
arrayPush(dataFormat, rowFormat)
|
|
86
|
+
for field in fields:
|
|
87
|
+
# Format the value
|
|
88
|
+
value = objectGet(row, field)
|
|
89
|
+
valueType = systemType(value)
|
|
90
|
+
if valueType == 'string':
|
|
91
|
+
valueFormat = value
|
|
92
|
+
elif valueType == 'number':
|
|
93
|
+
valueFormat = numberToFixed(value, precisionNumber, precisionTrim)
|
|
94
|
+
elif valueType == 'datetime':
|
|
95
|
+
valueFormat = datetimeISOFormat(value, precisionDatetime != null)
|
|
96
|
+
else:
|
|
97
|
+
valueFormat = stringNew(value)
|
|
98
|
+
endif
|
|
99
|
+
objectSet(rowFormat, field, valueFormat)
|
|
100
|
+
|
|
101
|
+
# Update the field width
|
|
102
|
+
valueWidth = stringLength(valueFormat)
|
|
103
|
+
if !objectHas(widths, field) || valueWidth > objectGet(widths, field):
|
|
104
|
+
objectSet(widths, field, valueWidth)
|
|
105
|
+
endif
|
|
106
|
+
endfor
|
|
107
|
+
endfor
|
|
108
|
+
|
|
109
|
+
# Compute the field header separator
|
|
110
|
+
headerSeparator = ''
|
|
111
|
+
for field in fields:
|
|
112
|
+
width = objectGet(widths, field)
|
|
113
|
+
format = if(formats != null, objectGet(formats, field))
|
|
114
|
+
align = if(format != null, objectGet(format, 'align'))
|
|
115
|
+
headerSeparator = headerSeparator + '+=' + markdownUpValueField('', width, align, '=') + '='
|
|
116
|
+
endfor
|
|
117
|
+
headerSeparator = headerSeparator + '+'
|
|
118
|
+
|
|
119
|
+
# Compute the table header fields
|
|
120
|
+
headerFields = ''
|
|
121
|
+
for field in fields:
|
|
122
|
+
width = objectGet(widths, field)
|
|
123
|
+
format = if(formats != null, objectGet(formats, field))
|
|
124
|
+
align = if(format != null, objectGet(format, 'align'))
|
|
125
|
+
header = if(format != null, objectGet(format, 'header', field), field)
|
|
126
|
+
headerFields = headerFields + '| ' + markdownUpValueField(header, width, align, ' ') + ' '
|
|
127
|
+
endfor
|
|
128
|
+
headerFields = headerFields + '|'
|
|
129
|
+
|
|
130
|
+
# Output the table header
|
|
131
|
+
systemLog('')
|
|
132
|
+
systemLog(headerSeparator)
|
|
133
|
+
systemLog(headerFields)
|
|
134
|
+
systemLog(headerSeparator)
|
|
135
|
+
|
|
136
|
+
# Output each row
|
|
137
|
+
for row in dataFormat:
|
|
138
|
+
line = ''
|
|
139
|
+
for field in fields:
|
|
140
|
+
width = objectGet(widths, field)
|
|
141
|
+
format = if(formats != null, objectGet(formats, field))
|
|
142
|
+
align = if(format != null, objectGet(format, 'align'))
|
|
143
|
+
line = line + '| ' + markdownUpValueField(objectGet(row, field), width, align, ' ') + ' '
|
|
144
|
+
endfor
|
|
145
|
+
line = line + '|'
|
|
146
|
+
systemLog(line)
|
|
147
|
+
endfor
|
|
148
|
+
|
|
149
|
+
# Output the table footer
|
|
150
|
+
systemLog(headerSeparator)
|
|
151
|
+
endfunction
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
function markdownUpValueField(value, width, align, fill):
|
|
155
|
+
spaces = width - stringLength(value)
|
|
156
|
+
if align == 'right':
|
|
157
|
+
return stringRepeat(fill, spaces) + value
|
|
158
|
+
elif align == 'center':
|
|
159
|
+
spacesLeft = mathFloor(spaces / 2)
|
|
160
|
+
spacesRight = spaces - spacesLeft
|
|
161
|
+
return stringRepeat(fill, spacesLeft) + value + stringRepeat(fill, spacesRight)
|
|
162
|
+
endif
|
|
163
|
+
return value + stringRepeat(fill, spaces)
|
|
164
|
+
endfunction
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
#
|
|
168
|
+
# Document functions
|
|
169
|
+
#
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
function documentFontSize():
|
|
173
|
+
return markdownUpDefaultFontSizePx
|
|
174
|
+
endfunction
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
function documentInputValue():
|
|
178
|
+
endfunction
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
function documentSetFocus():
|
|
182
|
+
endfunction
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
function documentSetReset():
|
|
186
|
+
endfunction
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
function documentSetTitle():
|
|
190
|
+
endfunction
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
function documentURL(url):
|
|
194
|
+
return url
|
|
195
|
+
endfunction
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
#
|
|
199
|
+
# Drawing functions
|
|
200
|
+
#
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
function drawArc():
|
|
204
|
+
endfunction
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
function drawCircle():
|
|
208
|
+
endfunction
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
function drawClose():
|
|
212
|
+
endfunction
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
function drawEllipse():
|
|
216
|
+
endfunction
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
function drawHLine():
|
|
220
|
+
endfunction
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
function drawHeight():
|
|
224
|
+
return objectGet(markdownUpState, 'drawingHeight')
|
|
225
|
+
endfunction
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
function drawImage():
|
|
229
|
+
endfunction
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
function drawLine():
|
|
233
|
+
endfunction
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
function drawMove():
|
|
237
|
+
endfunction
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
function drawNew(width, height):
|
|
241
|
+
objectSet(markdownUpState, 'drawingWidth', width)
|
|
242
|
+
objectSet(markdownUpState, 'drawingHeight', height)
|
|
243
|
+
systemLog('')
|
|
244
|
+
systemLog('<Drawing ' + width + 'x' + height + '>')
|
|
245
|
+
endfunction
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
function drawOnClick():
|
|
249
|
+
endfunction
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
function drawPathRect():
|
|
253
|
+
endfunction
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
function drawRect():
|
|
257
|
+
endfunction
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
function drawStyle():
|
|
261
|
+
endfunction
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
function drawText():
|
|
265
|
+
endfunction
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
function drawTextHeight(text, width):
|
|
269
|
+
if width > 0:
|
|
270
|
+
return width / (markdownUpFontWidthRatio * stringLength(text))
|
|
271
|
+
endif
|
|
272
|
+
return objectGet(markdownUpState, 'drawingFontSizePx')
|
|
273
|
+
endfunction
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
function drawTextStyle(fontSizePx):
|
|
277
|
+
objectSet(markdownUpState, 'drawingFontSizePx', if(fontSizePx != null, fontSizePx, markdownUpDefaultFontSizePx))
|
|
278
|
+
endfunction
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
function drawTextWidth(text, fontSizePx):
|
|
282
|
+
return markdownUpFontWidthRatio * fontSizePx * stringLength(text)
|
|
283
|
+
endfunction
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
function drawVLine():
|
|
287
|
+
endfunction
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
function drawWidth():
|
|
291
|
+
return objectGet(markdownUpState, 'drawingWidth')
|
|
292
|
+
endfunction
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
#
|
|
296
|
+
# Element Model functions
|
|
297
|
+
#
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
function elementModelRender():
|
|
301
|
+
endfunction
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
#
|
|
305
|
+
# Local storage functions
|
|
306
|
+
#
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
function localStorageClear():
|
|
310
|
+
objectSet(markdownUpState, 'localStorage', objectNew())
|
|
311
|
+
endfunction
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
function localStorageGet(key):
|
|
315
|
+
return objectGet(objectGet(markdownUpState, 'localStorage'), key)
|
|
316
|
+
endfunction
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
function localStorageRemove(key):
|
|
320
|
+
objectDelete(objectGet(markdownUpState, 'localStorage'), key)
|
|
321
|
+
endfunction
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
function localStorageSet(key, value):
|
|
325
|
+
objectSet(objectGet(markdownUpState, 'localStorage'), key, value)
|
|
326
|
+
endfunction
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
#
|
|
330
|
+
# Markdown functions
|
|
331
|
+
#
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
function markdownEscape(text):
|
|
335
|
+
return regexReplace(markdownUp_markdownEscapeRegex, text, '\\$1')
|
|
336
|
+
endfunction
|
|
337
|
+
|
|
338
|
+
markdownUp_markdownEscapeRegex = regexNew('([\\\\[\\]()<>"\'*_~`#=+|-])')
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
function markdownHeaderId(text):
|
|
342
|
+
result = stringLower(text)
|
|
343
|
+
result = regexReplace(markdownUp_markdownHeaderId_start, result, '')
|
|
344
|
+
result = regexReplace(markdownUp_markdownHeaderId_end, result, '')
|
|
345
|
+
result = regexReplace(markdownUp_markdownHeaderId_remove, result, '')
|
|
346
|
+
return regexReplace(markdownUp_markdownHeaderId_dash, result, '-')
|
|
347
|
+
endfunction
|
|
348
|
+
|
|
349
|
+
markdownUp_markdownHeaderId_start = regexNew('^[^a-z0-9]+')
|
|
350
|
+
markdownUp_markdownHeaderId_end = regexNew('[^a-z0-9]+$')
|
|
351
|
+
markdownUp_markdownHeaderId_remove = regexNew('[\'"]')
|
|
352
|
+
markdownUp_markdownHeaderId_dash = regexNew('[^a-z0-9]+')
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
function markdownParse():
|
|
356
|
+
endfunction
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
function markdownPrint(lines...):
|
|
360
|
+
markdownUp_markdownPrintHelper(lines)
|
|
361
|
+
endfunction
|
|
362
|
+
|
|
363
|
+
function markdownUp_markdownPrintHelper(lines):
|
|
364
|
+
for line in lines:
|
|
365
|
+
if systemType(line) == 'array':
|
|
366
|
+
markdownUp_markdownPrintHelper(line)
|
|
367
|
+
else:
|
|
368
|
+
systemLog(line)
|
|
369
|
+
endif
|
|
370
|
+
endfor
|
|
371
|
+
endfunction
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
function markdownTitle():
|
|
375
|
+
endfunction
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
#
|
|
379
|
+
# Schema functions
|
|
380
|
+
#
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
function schemaElements(types, typeName):
|
|
384
|
+
userType = objectGet(types, typeName)
|
|
385
|
+
userTypeKey = arrayGet(objectKeys(userType), 0)
|
|
386
|
+
if userTypeKey == 'struct' && objectGet(objectGet(userType, 'struct'), 'union'):
|
|
387
|
+
userTypeKey = 'union'
|
|
388
|
+
endif
|
|
389
|
+
return arrayNew( \
|
|
390
|
+
arrayNew( \
|
|
391
|
+
objectNew('html', 'h1', 'elem', objectNew('text', userTypeKey + ' ' + typeName)) \
|
|
392
|
+
) \
|
|
393
|
+
)
|
|
394
|
+
endfunction
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
#
|
|
398
|
+
# Session storage functions
|
|
399
|
+
#
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
function sessionStorageClear():
|
|
403
|
+
objectSet(markdownUpState, 'sessionStorage', objectNew())
|
|
404
|
+
endfunction
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
function sessionStorageGet(key):
|
|
408
|
+
return objectGet(objectGet(markdownUpState, 'sessionStorage'), key)
|
|
409
|
+
endfunction
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
function sessionStorageRemove(key):
|
|
413
|
+
objectDelete(objectGet(markdownUpState, 'sessionStorage'), key)
|
|
414
|
+
endfunction
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
function sessionStorageSet(key, value):
|
|
418
|
+
objectSet(objectGet(markdownUpState, 'sessionStorage'), key, value)
|
|
419
|
+
endfunction
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
#
|
|
423
|
+
# URL functions
|
|
424
|
+
#
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
function urlObjectCreate(data, contentType):
|
|
428
|
+
return 'blob:' + urlEncode(contentType) + '-' + urlEncode(if(stringLength(data) < 20, data, stringSlice(data, 0, 20)))
|
|
429
|
+
endfunction
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
#
|
|
433
|
+
# Window functions
|
|
434
|
+
#
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
function windowClipboardRead():
|
|
438
|
+
return objectGet(markdownUpState, 'windowClipboard')
|
|
439
|
+
endfunction
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
function windowClipboardWrite(text):
|
|
443
|
+
return objectSet(markdownUpState, 'windowClipboard', text)
|
|
444
|
+
endfunction
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
function windowHeight():
|
|
448
|
+
return markdownUpWindowHeight
|
|
449
|
+
endfunction
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
function windowSetLocation():
|
|
453
|
+
endfunction
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
function windowSetResize():
|
|
457
|
+
endfunction
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
function windowSetTimeout():
|
|
461
|
+
endfunction
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
function windowWidth():
|
|
465
|
+
return markdownUpWindowWidth
|
|
466
|
+
endfunction
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/markdown-up/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
include <args.mds>
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Include sentinel
|
|
8
|
+
if systemGlobalGet('pagerSentinel'):
|
|
9
|
+
return
|
|
10
|
+
endif
|
|
11
|
+
pagerSentinel = true
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# The pager model
|
|
15
|
+
pagerTypes = schemaParse( \
|
|
16
|
+
'group "Pager"', \
|
|
17
|
+
'', \
|
|
18
|
+
'', \
|
|
19
|
+
'# A pager application model', \
|
|
20
|
+
'struct Pager', \
|
|
21
|
+
'', \
|
|
22
|
+
" # The application's pages", \
|
|
23
|
+
' PagerPage[len > 0] pages', \
|
|
24
|
+
'', \
|
|
25
|
+
'', \
|
|
26
|
+
'# A page model', \
|
|
27
|
+
'struct PagerPage', \
|
|
28
|
+
'', \
|
|
29
|
+
' # The page name', \
|
|
30
|
+
' string name', \
|
|
31
|
+
'', \
|
|
32
|
+
' # If true, the page is hidden', \
|
|
33
|
+
' optional bool hidden', \
|
|
34
|
+
'', \
|
|
35
|
+
' # The page type', \
|
|
36
|
+
' PagerPageType type', \
|
|
37
|
+
'', \
|
|
38
|
+
'', \
|
|
39
|
+
'# The page type', \
|
|
40
|
+
'union PagerPageType', \
|
|
41
|
+
'', \
|
|
42
|
+
' # A function page', \
|
|
43
|
+
' PagerPageFunction function', \
|
|
44
|
+
'', \
|
|
45
|
+
' # A markdown resource page', \
|
|
46
|
+
' PagerPageMarkdown markdown', \
|
|
47
|
+
'', \
|
|
48
|
+
' # A navigation link', \
|
|
49
|
+
' PagerPageLink link', \
|
|
50
|
+
'', \
|
|
51
|
+
'', \
|
|
52
|
+
'# A page function', \
|
|
53
|
+
'struct PagerPageFunction', \
|
|
54
|
+
'', \
|
|
55
|
+
' # The page function', \
|
|
56
|
+
' object function', \
|
|
57
|
+
'', \
|
|
58
|
+
' # The page title', \
|
|
59
|
+
' optional string title', \
|
|
60
|
+
'', \
|
|
61
|
+
'', \
|
|
62
|
+
'# A Markdown resource page', \
|
|
63
|
+
'struct PagerPageMarkdown', \
|
|
64
|
+
'', \
|
|
65
|
+
' # The Markdown resource URL', \
|
|
66
|
+
' string url', \
|
|
67
|
+
'', \
|
|
68
|
+
'', \
|
|
69
|
+
'# A page link', \
|
|
70
|
+
'struct PagerPageLink', \
|
|
71
|
+
'', \
|
|
72
|
+
' # The link URL', \
|
|
73
|
+
' string url' \
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# $function: pagerValidate
|
|
78
|
+
# $group: pager.mds
|
|
79
|
+
# $doc: Validate a pager model
|
|
80
|
+
# $arg pagerModel: The [pager model](includeModel.html#var.vName='Pager')
|
|
81
|
+
# $return: The validated [pager model](includeModel.html#var.vName='Pager') or null if validation fails
|
|
82
|
+
function pagerValidate(pagerModel):
|
|
83
|
+
return schemaValidate(pagerTypes, 'Pager', pagerModel)
|
|
84
|
+
endfunction
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# $function: pagerMain
|
|
88
|
+
# $group: pager.mds
|
|
89
|
+
# $doc: The pager application main entry point
|
|
90
|
+
# $arg pagerModel: The [pager model](includeModel.html#var.vName='Pager')
|
|
91
|
+
# $arg options: The pager application options. The following options are available:
|
|
92
|
+
# $arg options: - **arguments** - The [arguments model](includeModel.html#var.vName='ArgsArguments').
|
|
93
|
+
# $arg options: Must contain a string argument named "page".
|
|
94
|
+
# $arg options: - **hideMenu** - Hide the menu links
|
|
95
|
+
# $arg options: - **hideNav** - Hide the navigation links
|
|
96
|
+
# $arg options: - **start** - The start page name
|
|
97
|
+
async function pagerMain(pagerModel, options):
|
|
98
|
+
if options == null:
|
|
99
|
+
options = objectNew()
|
|
100
|
+
endif
|
|
101
|
+
|
|
102
|
+
# Validate the pager model
|
|
103
|
+
pagerModel = pagerValidate(pagerModel)
|
|
104
|
+
if pagerModel == null:
|
|
105
|
+
return
|
|
106
|
+
endif
|
|
107
|
+
|
|
108
|
+
# Compute the visible and navigable pages
|
|
109
|
+
pages = objectGet(pagerModel, 'pages')
|
|
110
|
+
visiblePages = arrayNew()
|
|
111
|
+
navPages = arrayNew()
|
|
112
|
+
for page in pages:
|
|
113
|
+
# Visible page?
|
|
114
|
+
if !objectGet(page, 'hidden'):
|
|
115
|
+
arrayPush(visiblePages, page)
|
|
116
|
+
|
|
117
|
+
# Navigable page?
|
|
118
|
+
pageTypeKey = arrayGet(objectKeys(objectGet(page, 'type')), 0)
|
|
119
|
+
if pageTypeKey != 'link':
|
|
120
|
+
arrayPush(navPages, page)
|
|
121
|
+
endif
|
|
122
|
+
endif
|
|
123
|
+
endfor
|
|
124
|
+
|
|
125
|
+
# Parse arguments
|
|
126
|
+
startPageName = objectGet(options, 'start', if(arrayLength(navPages), objectGet(arrayGet(navPages, 0), 'name'), null))
|
|
127
|
+
if objectHas(options, 'arguments'):
|
|
128
|
+
arguments = argsValidate(objectGet(options, 'arguments'))
|
|
129
|
+
if arguments == null:
|
|
130
|
+
return
|
|
131
|
+
endif
|
|
132
|
+
else:
|
|
133
|
+
arguments = arrayNew(objectNew('name', 'page', 'default', startPageName))
|
|
134
|
+
endif
|
|
135
|
+
args = argsParse(arguments)
|
|
136
|
+
|
|
137
|
+
# Determine the current page
|
|
138
|
+
curPage = null
|
|
139
|
+
startPage = null
|
|
140
|
+
for page in pages:
|
|
141
|
+
if objectGet(page, 'name') == objectGet(args, 'page'):
|
|
142
|
+
curPage = page
|
|
143
|
+
endif
|
|
144
|
+
if objectGet(page, 'name') == startPageName:
|
|
145
|
+
startPage = page
|
|
146
|
+
endif
|
|
147
|
+
endfor
|
|
148
|
+
if startPage == null:
|
|
149
|
+
systemLogDebug('MarkdownUp - pager.mds: Unknown start page' + if(startPageName != null, '"' + startPageName + '"', ''))
|
|
150
|
+
return
|
|
151
|
+
endif
|
|
152
|
+
if curPage == null:
|
|
153
|
+
curPage = startPage
|
|
154
|
+
endif
|
|
155
|
+
|
|
156
|
+
# Determine the current page's navigable index, if any
|
|
157
|
+
ixCurPage = -1
|
|
158
|
+
for navPage, ixNavPage in navPages:
|
|
159
|
+
if objectGet(navPage, 'name') == objectGet(curPage, 'name'):
|
|
160
|
+
ixCurPage = ixNavPage
|
|
161
|
+
break
|
|
162
|
+
endif
|
|
163
|
+
endfor
|
|
164
|
+
|
|
165
|
+
# Render the menu
|
|
166
|
+
if !objectGet(options, 'hideMenu'):
|
|
167
|
+
for page, ixPage in visiblePages:
|
|
168
|
+
pageName = objectGet(page, 'name')
|
|
169
|
+
pageType = objectGet(page, 'type')
|
|
170
|
+
pageTypeKey = arrayGet(objectKeys(pageType), 0)
|
|
171
|
+
|
|
172
|
+
# Render the menu link
|
|
173
|
+
pageNameNbsp = stringReplace(pageName, ' ', ' ')
|
|
174
|
+
separator = if(ixPage != arrayLength(visiblePages) - 1, ' |', '')
|
|
175
|
+
if pageTypeKey == 'link':
|
|
176
|
+
pageLinkURL = objectGet(objectGet(pageType, 'link'), 'url')
|
|
177
|
+
markdownPrint('[' + markdownEscape(pageNameNbsp) + '](' + urlEncode(pageLinkURL) + ')' + separator)
|
|
178
|
+
elif pageName == objectGet(curPage, 'name'):
|
|
179
|
+
markdownPrint(markdownEscape(pageNameNbsp) + separator)
|
|
180
|
+
else:
|
|
181
|
+
markdownPrint(argsLink(arguments, pageNameNbsp, objectNew('page', pageName)) + separator)
|
|
182
|
+
endif
|
|
183
|
+
endfor
|
|
184
|
+
markdownPrint('')
|
|
185
|
+
endif
|
|
186
|
+
|
|
187
|
+
# Render the start/next/prev buttons
|
|
188
|
+
if !objectGet(options, 'hideNav') && arrayLength(navPages) > 1 && ixCurPage != -1:
|
|
189
|
+
if startPageName == objectGet(curPage, 'name'):
|
|
190
|
+
startPageName = null
|
|
191
|
+
endif
|
|
192
|
+
prevPageName = if(ixCurPage != -1 && ixCurPage - 1 >= 0, objectGet(arrayGet(navPages, ixCurPage - 1), 'name'), null)
|
|
193
|
+
nextPageName = if(ixCurPage != -1 && ixCurPage + 1 < arrayLength(navPages), objectGet(arrayGet(navPages, ixCurPage + 1), 'name'), null)
|
|
194
|
+
markdownPrint( \
|
|
195
|
+
'( ' + if(startPageName != null, argsLink(arguments, 'Start', objectNew('page', startPageName)), 'Start') + ' |', \
|
|
196
|
+
if(prevPageName != null, argsLink(arguments, 'Previous', objectNew('page', prevPageName)), 'Previous') + ' |', \
|
|
197
|
+
if(nextPageName != null, argsLink(arguments, 'Next', objectNew('page', nextPageName)), 'Next') + ' )', \
|
|
198
|
+
'' \
|
|
199
|
+
)
|
|
200
|
+
endif
|
|
201
|
+
|
|
202
|
+
# Function page?
|
|
203
|
+
curPageType = objectGet(curPage, 'type')
|
|
204
|
+
curPageTypeKey = arrayGet(objectKeys(curPageType), 0)
|
|
205
|
+
if curPageTypeKey == 'function':
|
|
206
|
+
# Set the title
|
|
207
|
+
title = objectGet(objectGet(curPageType, 'function'), 'title')
|
|
208
|
+
if title != null:
|
|
209
|
+
documentSetTitle(title)
|
|
210
|
+
markdownPrint('# ' + markdownEscape(title), '')
|
|
211
|
+
endif
|
|
212
|
+
|
|
213
|
+
# Call the page function
|
|
214
|
+
pageFn = objectGet(objectGet(curPageType, 'function'), 'function')
|
|
215
|
+
pageFn(args)
|
|
216
|
+
elif curPageTypeKey == 'markdown':
|
|
217
|
+
# Fetch the Markdown text
|
|
218
|
+
url = objectGet(objectGet(curPageType, 'markdown'), 'url')
|
|
219
|
+
markdownText = systemFetch(url)
|
|
220
|
+
if markdownText == null:
|
|
221
|
+
markdownPrint('**Error:** Failed to load "' + url + '"')
|
|
222
|
+
else:
|
|
223
|
+
# Compute and set the page title
|
|
224
|
+
markdownModel = markdownParse(markdownText)
|
|
225
|
+
title = markdownTitle(markdownModel)
|
|
226
|
+
if title == null:
|
|
227
|
+
title = 'No Title'
|
|
228
|
+
endif
|
|
229
|
+
documentSetTitle(title)
|
|
230
|
+
|
|
231
|
+
# Render the Markdown text
|
|
232
|
+
markdownPrint('', markdownText)
|
|
233
|
+
endif
|
|
234
|
+
endif
|
|
235
|
+
endfunction
|