bare-script 3.0.14 → 3.1.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.
@@ -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, ' ', '&nbsp;')
174
+ separator = if(ixPage != arrayLength(visiblePages) - 1, '&nbsp;|', '')
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
+ '(&nbsp;' + if(startPageName != null, argsLink(arguments, 'Start', objectNew('page', startPageName)), 'Start') + '&nbsp;|', \
196
+ if(prevPageName != null, argsLink(arguments, 'Previous', objectNew('page', prevPageName)), 'Previous') + '&nbsp;|', \
197
+ if(nextPageName != null, argsLink(arguments, 'Next', objectNew('page', nextPageName)), 'Next') + '&nbsp;)', \
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