bare-script 3.5.5 → 3.7.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/README.md +19 -19
- package/lib/bare.js +6 -10
- package/lib/include/args.bare +8 -8
- package/lib/include/dataTable.bare +211 -0
- package/lib/include/diff.bare +1 -1
- package/lib/include/markdownUp.bare +8 -117
- package/lib/include/pager.bare +3 -3
- package/lib/include/unittest.bare +365 -89
- package/lib/library.js +76 -0
- package/lib/model.js +70 -12
- package/lib/options.js +45 -2
- package/lib/parser.js +224 -84
- package/lib/runtime.js +87 -28
- package/lib/runtimeAsync.js +68 -49
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ function or the
|
|
|
36
36
|
[executeScriptAsync](https://craigahobbs.github.io/bare-script/module-lib_runtimeAsync.html#.executeScriptAsync)
|
|
37
37
|
function. For example:
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
``` javascript
|
|
40
40
|
import {executeScript} from 'bare-script/lib/runtime.js';
|
|
41
41
|
import {parseScript} from 'bare-script/lib/parser.js';
|
|
42
42
|
|
|
@@ -53,13 +53,13 @@ return N + ' times 2 is ' + double(N)
|
|
|
53
53
|
// Execute the script
|
|
54
54
|
const globals = {'N': 10};
|
|
55
55
|
console.log(executeScript(script, {globals}));
|
|
56
|
-
|
|
56
|
+
```
|
|
57
57
|
|
|
58
58
|
This outputs:
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
```
|
|
61
61
|
10 times 2 is 20
|
|
62
|
-
|
|
62
|
+
```
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
### The BareScript Library
|
|
@@ -73,7 +73,7 @@ of the
|
|
|
73
73
|
[arrayLength](https://craigahobbs.github.io/bare-script/library/#var.vGroup='Array'&arraylength)
|
|
74
74
|
functions.
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
``` javascript
|
|
77
77
|
import {executeScriptAsync} from 'bare-script/lib/runtimeAsync.js';
|
|
78
78
|
import {parseScript} from 'bare-script/lib/parser.js';
|
|
79
79
|
|
|
@@ -88,13 +88,13 @@ return 'The BareScript Library has ' + arrayLength(objectGet(docs, 'functions'))
|
|
|
88
88
|
|
|
89
89
|
// Execute the script
|
|
90
90
|
console.log(await executeScriptAsync(script, {'fetchFn': fetch}));
|
|
91
|
-
|
|
91
|
+
```
|
|
92
92
|
|
|
93
93
|
This outputs:
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
```
|
|
96
96
|
The BareScript Library has 105 functions
|
|
97
|
-
|
|
97
|
+
```
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
## Evaluating BareScript Expressions
|
|
@@ -115,7 +115,7 @@ a set of built-in, spreadsheet-like functions.
|
|
|
115
115
|
|
|
116
116
|
For example:
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
``` javascript
|
|
119
119
|
import {evaluateExpression} from 'bare-script/lib/runtime.js';
|
|
120
120
|
import {parseExpression} from 'bare-script/lib/parser.js';
|
|
121
121
|
|
|
@@ -125,13 +125,13 @@ const expr = parseExpression('2 * max(a, b, c)');
|
|
|
125
125
|
// Evaluate the expression
|
|
126
126
|
const variables = {'a': 1, 'b': 2, 'c': 3};
|
|
127
127
|
console.log(evaluateExpression(expr, null, variables))
|
|
128
|
-
|
|
128
|
+
```
|
|
129
129
|
|
|
130
130
|
This outputs:
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
```
|
|
133
133
|
6
|
|
134
|
-
|
|
134
|
+
```
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
## The BareScript Command-Line Interface (CLI)
|
|
@@ -139,9 +139,9 @@ This outputs:
|
|
|
139
139
|
You can run BareScript from the command line using the BareScript CLI, "bare". BareScript script
|
|
140
140
|
files use the ".bare" file extension.
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
```
|
|
143
143
|
bare script.bare
|
|
144
|
-
|
|
144
|
+
```
|
|
145
145
|
|
|
146
146
|
**Note:** In the BareScript CLI, import statements and the
|
|
147
147
|
[systemFetch](https://craigahobbs.github.io/bare-script/library/#var.vGroup='System'&systemfetch)
|
|
@@ -163,15 +163,15 @@ with functions for dynamically rendering Markdown text, drawing SVG images, etc.
|
|
|
163
163
|
|
|
164
164
|
For example:
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
~~~
|
|
167
167
|
# Markdown Application
|
|
168
168
|
|
|
169
169
|
This is a Markdown document with embedded BareScript:
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
``` markdown-script
|
|
172
172
|
markdownPrint('Hello, Markdown!')
|
|
173
|
-
~~~
|
|
174
173
|
```
|
|
174
|
+
~~~
|
|
175
175
|
|
|
176
176
|
|
|
177
177
|
## Development
|
|
@@ -179,6 +179,6 @@ markdownPrint('Hello, Markdown!')
|
|
|
179
179
|
This package is developed using [javascript-build](https://github.com/craigahobbs/javascript-build#readme).
|
|
180
180
|
It was started using [javascript-template](https://github.com/craigahobbs/javascript-template#readme) as follows:
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
```
|
|
183
183
|
template-specialize javascript-template/template/ bare-script/ -k package bare-script -k name 'Craig A. Hobbs' -k email 'craigahobbs@gmail.com' -k github 'craigahobbs' -k noapp 1
|
|
184
|
-
|
|
184
|
+
```
|
package/lib/bare.js
CHANGED
|
@@ -46,7 +46,6 @@ export async function main(options) {
|
|
|
46
46
|
|
|
47
47
|
let statusCode = 0;
|
|
48
48
|
let inlineCount = 0;
|
|
49
|
-
let errorName = null;
|
|
50
49
|
try {
|
|
51
50
|
// Evaluate the global variable expression arguments
|
|
52
51
|
const globals = {};
|
|
@@ -81,22 +80,22 @@ export async function main(options) {
|
|
|
81
80
|
}
|
|
82
81
|
} else {
|
|
83
82
|
inlineCount += 1;
|
|
84
|
-
scriptName =
|
|
83
|
+
scriptName = `<string${inlineCount > 1 ? inlineCount : ''}>`;
|
|
85
84
|
scriptSource = scriptValue;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
// Parse the script source
|
|
89
|
-
|
|
90
|
-
const script = parseScript(scriptSource);
|
|
88
|
+
const script = parseScript(scriptSource, 1, scriptName);
|
|
91
89
|
|
|
92
90
|
// Run the bare-script linter?
|
|
93
91
|
if (args.static || args.debug) {
|
|
94
92
|
const warnings = lintScript(script);
|
|
95
|
-
const warningPrefix = `BareScript: Static analysis "${scriptName}" ...`;
|
|
96
93
|
if (warnings.length === 0) {
|
|
97
|
-
options.logFn(
|
|
94
|
+
options.logFn(`BareScript: Static analysis "${scriptName}" ... OK`);
|
|
98
95
|
} else {
|
|
99
|
-
options.logFn(
|
|
96
|
+
options.logFn(
|
|
97
|
+
`BareScript: Static analysis "${scriptName}" ... ${warnings.length} warning${warnings.length > 1 ? 's' : ''}:`
|
|
98
|
+
);
|
|
100
99
|
for (const warning of warnings) {
|
|
101
100
|
options.logFn(`BareScript: ${warning}`);
|
|
102
101
|
}
|
|
@@ -141,9 +140,6 @@ export async function main(options) {
|
|
|
141
140
|
}
|
|
142
141
|
}
|
|
143
142
|
} catch ({message}) {
|
|
144
|
-
if (errorName !== null) {
|
|
145
|
-
options.logFn(`${errorName}:`);
|
|
146
|
-
}
|
|
147
143
|
options.logFn(message);
|
|
148
144
|
statusCode = 1;
|
|
149
145
|
}
|
package/lib/include/args.bare
CHANGED
|
@@ -67,7 +67,7 @@ function argsValidate(arguments):
|
|
|
67
67
|
name = objectGet(argument, 'name')
|
|
68
68
|
if objectHas(argNames, name):
|
|
69
69
|
validatedArguments = null
|
|
70
|
-
systemLogDebug('
|
|
70
|
+
systemLogDebug('args.bare: Duplicate argument "' + name + '"')
|
|
71
71
|
else:
|
|
72
72
|
objectSet(argNames, name, true)
|
|
73
73
|
endif
|
|
@@ -151,7 +151,7 @@ function argsURL(arguments, args, explicit, headerText, url):
|
|
|
151
151
|
if args != null:
|
|
152
152
|
for name in objectKeys(args):
|
|
153
153
|
if !objectHas(argNames, name):
|
|
154
|
-
systemLogDebug('
|
|
154
|
+
systemLogDebug('args.bare: Unknown argument "' + name + '"')
|
|
155
155
|
endif
|
|
156
156
|
endfor
|
|
157
157
|
endif
|
|
@@ -279,7 +279,7 @@ function argsValidateValue(value, type, global, warn):
|
|
|
279
279
|
value = !!value
|
|
280
280
|
elif valueType != 'boolean':
|
|
281
281
|
if warn != false:
|
|
282
|
-
systemLogDebug('
|
|
282
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
283
283
|
endif
|
|
284
284
|
value = null
|
|
285
285
|
endif
|
|
@@ -291,7 +291,7 @@ function argsValidateValue(value, type, global, warn):
|
|
|
291
291
|
endif
|
|
292
292
|
if valueType != 'datetime' || datetimeHour(value) != 0 || datetimeMinute(value) != 0 || datetimeSecond(value) != 0:
|
|
293
293
|
if warn != false:
|
|
294
|
-
systemLogDebug('
|
|
294
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(valueOrig) + ' for URL argument "' + global + '"')
|
|
295
295
|
endif
|
|
296
296
|
value = null
|
|
297
297
|
endif
|
|
@@ -303,21 +303,21 @@ function argsValidateValue(value, type, global, warn):
|
|
|
303
303
|
endif
|
|
304
304
|
if valueType != 'datetime':
|
|
305
305
|
if warn != false:
|
|
306
|
-
systemLogDebug('
|
|
306
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(valueOrig) + ' for URL argument "' + global + '"')
|
|
307
307
|
endif
|
|
308
308
|
value = null
|
|
309
309
|
endif
|
|
310
310
|
elif type == 'float':
|
|
311
311
|
if valueType != 'number':
|
|
312
312
|
if warn != false:
|
|
313
|
-
systemLogDebug('
|
|
313
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
314
314
|
endif
|
|
315
315
|
value = null
|
|
316
316
|
endif
|
|
317
317
|
elif type == 'int':
|
|
318
318
|
if valueType != 'number' || value != mathFloor(value):
|
|
319
319
|
if warn != false:
|
|
320
|
-
systemLogDebug('
|
|
320
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
321
321
|
endif
|
|
322
322
|
value = null
|
|
323
323
|
endif
|
|
@@ -325,7 +325,7 @@ function argsValidateValue(value, type, global, warn):
|
|
|
325
325
|
# type == 'string'
|
|
326
326
|
if valueType != 'string':
|
|
327
327
|
if warn != false:
|
|
328
|
-
systemLogDebug('
|
|
328
|
+
systemLogDebug('args.bare: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
329
329
|
endif
|
|
330
330
|
value = null
|
|
331
331
|
endif
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/markdown-up/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Include sentinel
|
|
6
|
+
if systemGlobalGet('dataTableSentinel'):
|
|
7
|
+
return
|
|
8
|
+
endif
|
|
9
|
+
dataTableSentinel = true
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# The data table model's Schema Markdown
|
|
13
|
+
dataTableTypes = schemaParse( \
|
|
14
|
+
'group "Data Table"', \
|
|
15
|
+
'', \
|
|
16
|
+
'', \
|
|
17
|
+
'# A data table model', \
|
|
18
|
+
'struct DataTable', \
|
|
19
|
+
'', \
|
|
20
|
+
" # The table's fields", \
|
|
21
|
+
' optional string[len > 0] fields', \
|
|
22
|
+
'', \
|
|
23
|
+
" # The table's category fields", \
|
|
24
|
+
' optional string[len > 0] categories', \
|
|
25
|
+
'', \
|
|
26
|
+
' # The field formatting for "categories" and "fields"', \
|
|
27
|
+
' optional DataTableFieldFormat{len > 0} formats', \
|
|
28
|
+
'', \
|
|
29
|
+
' # The numeric formatting precision (default is 2)', \
|
|
30
|
+
' optional int(>= 0) precision', \
|
|
31
|
+
'', \
|
|
32
|
+
' # The datetime format', \
|
|
33
|
+
' optional DataTableDatetimeFormat datetime', \
|
|
34
|
+
'', \
|
|
35
|
+
' # If true, trim formatted values (default is true)', \
|
|
36
|
+
' optional bool trim', \
|
|
37
|
+
'', \
|
|
38
|
+
'', \
|
|
39
|
+
'# A data table field formatting model', \
|
|
40
|
+
'struct DataTableFieldFormat', \
|
|
41
|
+
'', \
|
|
42
|
+
' # The field alignment', \
|
|
43
|
+
' optional DataTableFieldAlignment align', \
|
|
44
|
+
'', \
|
|
45
|
+
" # If true, don't wrap text", \
|
|
46
|
+
' optional bool nowrap', \
|
|
47
|
+
'', \
|
|
48
|
+
' # If true, format the field as Markdown', \
|
|
49
|
+
' optional bool markdown', \
|
|
50
|
+
'', \
|
|
51
|
+
' # The field header (default is the field name)', \
|
|
52
|
+
' optional string header', \
|
|
53
|
+
'', \
|
|
54
|
+
'', \
|
|
55
|
+
'# A field alignment', \
|
|
56
|
+
'enum DataTableFieldAlignment', \
|
|
57
|
+
' left', \
|
|
58
|
+
' right', \
|
|
59
|
+
' center', \
|
|
60
|
+
'', \
|
|
61
|
+
'', \
|
|
62
|
+
'# A datetime format', \
|
|
63
|
+
'enum DataTableDatetimeFormat', \
|
|
64
|
+
'', \
|
|
65
|
+
' # ISO datetime year format', \
|
|
66
|
+
' year', \
|
|
67
|
+
'', \
|
|
68
|
+
' # ISO datetime month format', \
|
|
69
|
+
' month', \
|
|
70
|
+
'', \
|
|
71
|
+
' # ISO datetime day format', \
|
|
72
|
+
' day' \
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# $function: dataTableMarkdown
|
|
77
|
+
# $group: dataTable.bare
|
|
78
|
+
# $doc: Create the array of Markdown table line strings
|
|
79
|
+
# $arg data: The array of row objects
|
|
80
|
+
# $arg model: The [data table model](includeModel.html#var.vName='DataTable')
|
|
81
|
+
# $return: The array of Markdown table line strings
|
|
82
|
+
function dataTableMarkdown(data, model):
|
|
83
|
+
# Validate the data
|
|
84
|
+
data = dataValidate(data)
|
|
85
|
+
if data == null:
|
|
86
|
+
return null
|
|
87
|
+
endif
|
|
88
|
+
|
|
89
|
+
# Validate the table model
|
|
90
|
+
if model != null && !schemaValidate(dataTableTypes, 'DataTable', model):
|
|
91
|
+
return null
|
|
92
|
+
endif
|
|
93
|
+
|
|
94
|
+
# Determine the table fields
|
|
95
|
+
fields = arrayNew()
|
|
96
|
+
modelFields = if(model != null, objectGet(model, 'fields'))
|
|
97
|
+
modelCategories = if(model != null, objectGet(model, 'categories'))
|
|
98
|
+
if modelFields != null || modelCategories != null:
|
|
99
|
+
if modelCategories != null:
|
|
100
|
+
arrayExtend(fields, modelCategories)
|
|
101
|
+
endif
|
|
102
|
+
if modelFields != null:
|
|
103
|
+
arrayExtend(fields, modelFields)
|
|
104
|
+
endif
|
|
105
|
+
elif arrayLength(data) > 0:
|
|
106
|
+
arrayExtend(fields, objectKeys(arrayGet(data, 0)))
|
|
107
|
+
endif
|
|
108
|
+
if !arrayLength(fields):
|
|
109
|
+
return null
|
|
110
|
+
endif
|
|
111
|
+
|
|
112
|
+
# Get precision and formatting
|
|
113
|
+
precisionDatetime = if(model != null, objectGet(model, 'datetime'))
|
|
114
|
+
precisionNumber = if(model != null, objectGet(model, 'precision', 2), 2)
|
|
115
|
+
precisionTrim = if(model != null, objectGet(model, 'trim', true), true)
|
|
116
|
+
formats = if(model != null, objectGet(model, 'formats'))
|
|
117
|
+
|
|
118
|
+
# Compute the field header widths
|
|
119
|
+
widths = objectNew()
|
|
120
|
+
for field in fields:
|
|
121
|
+
fieldWidth = stringLength(field)
|
|
122
|
+
if !objectHas(widths, field) || fieldWidth > objectGet(widths, field):
|
|
123
|
+
objectSet(widths, field, fieldWidth)
|
|
124
|
+
endif
|
|
125
|
+
endfor
|
|
126
|
+
|
|
127
|
+
# Compute the formatted field value strings and widths
|
|
128
|
+
dataFormat = arrayNew()
|
|
129
|
+
for row in data:
|
|
130
|
+
rowFormat = objectNew()
|
|
131
|
+
arrayPush(dataFormat, rowFormat)
|
|
132
|
+
for field in fields:
|
|
133
|
+
# Format the value
|
|
134
|
+
value = objectGet(row, field)
|
|
135
|
+
valueType = systemType(value)
|
|
136
|
+
if valueType == 'string':
|
|
137
|
+
valueFormat = value
|
|
138
|
+
elif valueType == 'number':
|
|
139
|
+
valueFormat = numberToFixed(value, precisionNumber, precisionTrim)
|
|
140
|
+
elif valueType == 'datetime':
|
|
141
|
+
valueFormat = datetimeISOFormat(value, precisionDatetime != null)
|
|
142
|
+
else:
|
|
143
|
+
valueFormat = stringNew(value)
|
|
144
|
+
endif
|
|
145
|
+
objectSet(rowFormat, field, valueFormat)
|
|
146
|
+
|
|
147
|
+
# Update the field width
|
|
148
|
+
valueWidth = stringLength(valueFormat)
|
|
149
|
+
if !objectHas(widths, field) || valueWidth > objectGet(widths, field):
|
|
150
|
+
objectSet(widths, field, valueWidth)
|
|
151
|
+
endif
|
|
152
|
+
endfor
|
|
153
|
+
endfor
|
|
154
|
+
|
|
155
|
+
# Compute the field header separator
|
|
156
|
+
headerSeparator = ''
|
|
157
|
+
for field in fields:
|
|
158
|
+
width = objectGet(widths, field)
|
|
159
|
+
format = if(formats != null, objectGet(formats, field))
|
|
160
|
+
align = if(format != null, objectGet(format, 'align'))
|
|
161
|
+
alignLeft = if(align == 'center', ':', '-')
|
|
162
|
+
alignRight = if(align == 'center' || align == 'right', ':', '-')
|
|
163
|
+
headerSeparator = headerSeparator + '|' + alignLeft + dataTableMarkdownField('', width, align, '-') + alignRight
|
|
164
|
+
endfor
|
|
165
|
+
headerSeparator = headerSeparator + '|'
|
|
166
|
+
|
|
167
|
+
# Compute the table header fields
|
|
168
|
+
headerFields = ''
|
|
169
|
+
for field in fields:
|
|
170
|
+
width = objectGet(widths, field)
|
|
171
|
+
format = if(formats != null, objectGet(formats, field))
|
|
172
|
+
align = if(format != null, objectGet(format, 'align'))
|
|
173
|
+
header = if(format != null, objectGet(format, 'header', field), field)
|
|
174
|
+
headerFields = headerFields + '| ' + dataTableMarkdownField(header, width, align, ' ') + ' '
|
|
175
|
+
endfor
|
|
176
|
+
headerFields = headerFields + '|'
|
|
177
|
+
|
|
178
|
+
# Output the table header
|
|
179
|
+
lines = arrayNew()
|
|
180
|
+
arrayPush(lines, headerFields)
|
|
181
|
+
arrayPush(lines, headerSeparator)
|
|
182
|
+
|
|
183
|
+
# Output each row
|
|
184
|
+
for row in dataFormat:
|
|
185
|
+
line = ''
|
|
186
|
+
for field in fields:
|
|
187
|
+
width = objectGet(widths, field)
|
|
188
|
+
format = if(formats != null, objectGet(formats, field))
|
|
189
|
+
align = if(format != null, objectGet(format, 'align'))
|
|
190
|
+
line = line + '| ' + dataTableMarkdownField(objectGet(row, field), width, align, ' ') + ' '
|
|
191
|
+
endfor
|
|
192
|
+
line = line + '|'
|
|
193
|
+
arrayPush(lines, line)
|
|
194
|
+
endfor
|
|
195
|
+
|
|
196
|
+
return lines
|
|
197
|
+
endfunction
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# Helper to generate the Markdown field text
|
|
201
|
+
function dataTableMarkdownField(value, width, align, fill):
|
|
202
|
+
spaces = width - stringLength(value)
|
|
203
|
+
if align == 'right':
|
|
204
|
+
return stringRepeat(fill, spaces) + value
|
|
205
|
+
elif align == 'center':
|
|
206
|
+
spacesLeft = mathFloor(spaces / 2)
|
|
207
|
+
spacesRight = spaces - spacesLeft
|
|
208
|
+
return stringRepeat(fill, spacesLeft) + value + stringRepeat(fill, spacesRight)
|
|
209
|
+
endif
|
|
210
|
+
return value + stringRepeat(fill, spaces)
|
|
211
|
+
endfunction
|
package/lib/include/diff.bare
CHANGED
|
@@ -99,7 +99,7 @@ function diffLines(left, right):
|
|
|
99
99
|
ixRight = ixRight + 1
|
|
100
100
|
endwhile
|
|
101
101
|
if identicalLines:
|
|
102
|
-
arrayPush(
|
|
102
|
+
arrayPush(diffs, objectNew('type', 'Identical', 'lines', identicalLines))
|
|
103
103
|
continue
|
|
104
104
|
endif
|
|
105
105
|
|
|
@@ -9,6 +9,9 @@ endif
|
|
|
9
9
|
markdownUpSentinel = true
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
include <dataTable.bare>
|
|
13
|
+
|
|
14
|
+
|
|
12
15
|
# Constants
|
|
13
16
|
markdownUpPixelsPerPoint = 4 / 3
|
|
14
17
|
markdownUpDefaultFontSizePx = 12 * markdownUpPixelsPerPoint
|
|
@@ -43,124 +46,12 @@ endfunction
|
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
function dataTable(data, model):
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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, ' ') + ' '
|
|
49
|
+
lines = dataTableMarkdown(data, model)
|
|
50
|
+
if lines:
|
|
51
|
+
for line in lines:
|
|
52
|
+
systemLog(line)
|
|
144
53
|
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
54
|
endif
|
|
163
|
-
return value + stringRepeat(fill, spaces)
|
|
164
55
|
endfunction
|
|
165
56
|
|
|
166
57
|
|
|
@@ -368,7 +259,7 @@ function markdownUp_markdownPrintHelper(lines):
|
|
|
368
259
|
for line in lines:
|
|
369
260
|
if systemType(line) == 'array':
|
|
370
261
|
markdownUp_markdownPrintHelper(line)
|
|
371
|
-
|
|
262
|
+
elif line != null:
|
|
372
263
|
systemLog(line)
|
|
373
264
|
endif
|
|
374
265
|
endfor
|
package/lib/include/pager.bare
CHANGED
|
@@ -9,7 +9,7 @@ endif
|
|
|
9
9
|
pagerSentinel = true
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
include
|
|
12
|
+
include <args.bare>
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
# The pager model
|
|
@@ -139,11 +139,11 @@ async function pagerMain(pagerModel, options):
|
|
|
139
139
|
endif
|
|
140
140
|
endfor
|
|
141
141
|
if startPageName == null:
|
|
142
|
-
systemLogDebug('
|
|
142
|
+
systemLogDebug('pager.bare: No visible and navigable pages')
|
|
143
143
|
return
|
|
144
144
|
endif
|
|
145
145
|
if optionStart && !startPageExplicit:
|
|
146
|
-
systemLogDebug('
|
|
146
|
+
systemLogDebug('pager.bare: Unknown start page "' + optionStart + '"')
|
|
147
147
|
return
|
|
148
148
|
endif
|
|
149
149
|
|