bare-script 3.8.16__tar.gz → 3.8.18__tar.gz
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-3.8.16/src/bare_script.egg-info → bare_script-3.8.18}/PKG-INFO +1 -1
- {bare_script-3.8.16 → bare_script-3.8.18}/setup.cfg +1 -1
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/args.bare +5 -3
- bare_script-3.8.18/src/bare_script/include/elementModel.bare +178 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/markdownUp.bare +1 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/qrcode.bare +173 -115
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/schemaDoc.bare +0 -1
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/library.py +31 -2
- {bare_script-3.8.16 → bare_script-3.8.18/src/bare_script.egg-info}/PKG-INFO +1 -1
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script.egg-info/SOURCES.txt +1 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/LICENSE +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/README.md +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/pyproject.toml +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/__init__.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/__main__.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/bare.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/baredoc.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/data.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/__init__.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/baredoc.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/dataLineChart.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/dataTable.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/diff.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/forms.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/pager.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/unittest.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/include/unittestMock.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/model.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/options.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/parser.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/runtime.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script/value.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script.egg-info/dependency_links.txt +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script.egg-info/entry_points.txt +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script.egg-info/requires.txt +0 -0
- {bare_script-3.8.16 → bare_script-3.8.18}/src/bare_script.egg-info/top_level.txt +0 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# Licensed under the MIT License
|
|
2
2
|
# https://github.com/craigahobbs/bare-script/blob/main/LICENSE
|
|
3
3
|
|
|
4
|
-
include <dataTable.bare>
|
|
5
|
-
|
|
6
4
|
|
|
7
5
|
# The URL arguments model
|
|
8
6
|
argsTypes = schemaParse( \
|
|
@@ -183,7 +181,7 @@ endfunction
|
|
|
183
181
|
# $doc: Generate the [arguments model's](model.html#var.vName='ArgsArguments') help content
|
|
184
182
|
# $arg arguments: The [arguments model](model.html#var.vName='ArgsArguments')
|
|
185
183
|
# $return: The array of help Markdown line strings
|
|
186
|
-
function argsHelp(arguments):
|
|
184
|
+
async function argsHelp(arguments):
|
|
187
185
|
# Create the help data
|
|
188
186
|
helpData = []
|
|
189
187
|
anyDefault = false
|
|
@@ -210,6 +208,10 @@ function argsHelp(arguments):
|
|
|
210
208
|
anyDescription = anyDescription || (description != null)
|
|
211
209
|
endfor
|
|
212
210
|
|
|
211
|
+
# Dynamically include dataTable.bare
|
|
212
|
+
include <dataTable.bare>
|
|
213
|
+
dataTableMarkdown = systemGlobalGet('dataTableMarkdown')
|
|
214
|
+
|
|
213
215
|
# Render the help table
|
|
214
216
|
helpFields = ['Variable', 'Type']
|
|
215
217
|
if anyDefault:
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/bare-script/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# $function: elementModelValidate
|
|
6
|
+
# $group: elementModel.bare
|
|
7
|
+
# $doc: Validate an element model
|
|
8
|
+
# $arg elements: The element model.
|
|
9
|
+
# $arg elements: An element model is either null, an element object, or an array of any of these.
|
|
10
|
+
# $return: The element model if valid, null otherwise
|
|
11
|
+
function elementModelValidate(elements):
|
|
12
|
+
# Null?
|
|
13
|
+
if elements == null:
|
|
14
|
+
return elements
|
|
15
|
+
endif
|
|
16
|
+
|
|
17
|
+
# Array?
|
|
18
|
+
if systemType(elements) == 'array':
|
|
19
|
+
for subElements in elements:
|
|
20
|
+
if subElements != null && elementModelValidate(subElements) == null:
|
|
21
|
+
return null
|
|
22
|
+
endif
|
|
23
|
+
endfor
|
|
24
|
+
return elements
|
|
25
|
+
endif
|
|
26
|
+
|
|
27
|
+
# Non-object?
|
|
28
|
+
if systemType(elements) != 'object':
|
|
29
|
+
return null
|
|
30
|
+
endif
|
|
31
|
+
|
|
32
|
+
# Check for element tag members and unknown members
|
|
33
|
+
tagMembers = []
|
|
34
|
+
unknownMembers = []
|
|
35
|
+
for elementMember in objectKeys(elements):
|
|
36
|
+
if elementMember == 'html' || elementMember == 'svg' || elementMember == 'text':
|
|
37
|
+
arrayPush(tagMembers, elementMember)
|
|
38
|
+
endif
|
|
39
|
+
if elementMember != 'html' && elementMember != 'svg' && elementMember != 'text' && \
|
|
40
|
+
elementMember != 'attr' && elementMember != 'elem' && elementMember != 'callback':
|
|
41
|
+
arrayPush(unknownMembers, elementMember)
|
|
42
|
+
endif
|
|
43
|
+
endfor
|
|
44
|
+
if arrayLength(tagMembers) != 1:
|
|
45
|
+
return null
|
|
46
|
+
endif
|
|
47
|
+
if arrayLength(unknownMembers) != 0:
|
|
48
|
+
return null
|
|
49
|
+
endif
|
|
50
|
+
|
|
51
|
+
# Validate the tag
|
|
52
|
+
tagMember = arrayGet(tagMembers, 0)
|
|
53
|
+
tag = objectGet(elements, tagMember)
|
|
54
|
+
if tagMember != 'text' && (systemType(tag) != 'string' || stringLength(tag) == 0):
|
|
55
|
+
return null
|
|
56
|
+
endif
|
|
57
|
+
|
|
58
|
+
# Validate attributes
|
|
59
|
+
attr = objectGet(elements, 'attr')
|
|
60
|
+
if objectHas(elements, 'attr') && tagMember == 'text':
|
|
61
|
+
return null
|
|
62
|
+
endif
|
|
63
|
+
if attr != null:
|
|
64
|
+
if systemType(attr) != 'object':
|
|
65
|
+
return null
|
|
66
|
+
endif
|
|
67
|
+
endif
|
|
68
|
+
|
|
69
|
+
# Validate child elements
|
|
70
|
+
elem = objectGet(elements, 'elem')
|
|
71
|
+
if objectHas(elements, 'elem') && tagMember == 'text':
|
|
72
|
+
return null
|
|
73
|
+
endif
|
|
74
|
+
if elem != null:
|
|
75
|
+
if elementModelValidate(elem) == null:
|
|
76
|
+
return null
|
|
77
|
+
endif
|
|
78
|
+
endif
|
|
79
|
+
|
|
80
|
+
# Validate creation callback
|
|
81
|
+
callback = objectGet(elements, 'callback')
|
|
82
|
+
if callback != null && systemType(callback) != 'function':
|
|
83
|
+
return null
|
|
84
|
+
endif
|
|
85
|
+
|
|
86
|
+
return elements
|
|
87
|
+
endfunction
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# $function: elementModelToString
|
|
91
|
+
# $group: elementModel.bare
|
|
92
|
+
# $doc: Render an element model to an HTML or SVG string
|
|
93
|
+
# $arg elements: The element model.
|
|
94
|
+
# $arg elements: An element model is either null, an element object, or an array of any of these.
|
|
95
|
+
# $arg indent: Optional (default is null). The indentation string or number of spaces
|
|
96
|
+
# $return: The HTML or SVG string
|
|
97
|
+
function elementModelToString(elements, indent):
|
|
98
|
+
# Compute the indent string
|
|
99
|
+
indentStr = ''
|
|
100
|
+
if systemType(indent) == 'string':
|
|
101
|
+
indentStr = indent
|
|
102
|
+
elif systemType(indent) == 'number':
|
|
103
|
+
indentStr = stringRepeat(' ', mathMax(0, indent))
|
|
104
|
+
endif
|
|
105
|
+
|
|
106
|
+
# Render the element model as an HTML/SVG string
|
|
107
|
+
elementStr = elementModelToStringHelper(elements, indentStr, 0)
|
|
108
|
+
if stringStartsWith(elementStr, '<html'):
|
|
109
|
+
elementStr = '<!DOCTYPE html>' + stringFromCharCode(10) + elementStr
|
|
110
|
+
endif
|
|
111
|
+
return elementStr
|
|
112
|
+
endfunction
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# Helper function to render elements to string
|
|
116
|
+
function elementModelToStringHelper(elements, indentStr, level):
|
|
117
|
+
# Null?
|
|
118
|
+
if elements == null:
|
|
119
|
+
return ''
|
|
120
|
+
endif
|
|
121
|
+
|
|
122
|
+
# Array?
|
|
123
|
+
if systemType(elements) == 'array':
|
|
124
|
+
results = []
|
|
125
|
+
for element in elements:
|
|
126
|
+
arrayPush(results, elementModelToStringHelper(element, indentStr, level))
|
|
127
|
+
endfor
|
|
128
|
+
return arrayJoin(results, '')
|
|
129
|
+
endif
|
|
130
|
+
|
|
131
|
+
# Text node
|
|
132
|
+
indentPrefix = stringRepeat(indentStr, level)
|
|
133
|
+
newline = if(indentStr, stringFromCharCode(10), '')
|
|
134
|
+
if objectHas(elements, 'text'):
|
|
135
|
+
text = stringNew(objectGet(elements, 'text'))
|
|
136
|
+
text = stringReplace(text, '&', '&')
|
|
137
|
+
text = stringReplace(text, '<', '<')
|
|
138
|
+
text = stringReplace(text, '>', '>')
|
|
139
|
+
text = stringReplace(text, '"', '"')
|
|
140
|
+
text = stringReplace(text, "'", ''')
|
|
141
|
+
return indentPrefix + text + newline
|
|
142
|
+
endif
|
|
143
|
+
|
|
144
|
+
# Attributes
|
|
145
|
+
tag = stringLower(objectGet(elements, 'html') || objectGet(elements, 'svg'))
|
|
146
|
+
attrStr = ''
|
|
147
|
+
attr = objectGet(elements, 'attr')
|
|
148
|
+
if tag == 'svg':
|
|
149
|
+
if attr == null:
|
|
150
|
+
attr = {}
|
|
151
|
+
endif
|
|
152
|
+
objectSet(attr, 'xmlns', 'http://www.w3.org/2000/svg')
|
|
153
|
+
endif
|
|
154
|
+
if attr != null:
|
|
155
|
+
attrNames = arraySort(objectKeys(attr))
|
|
156
|
+
for attrName in attrNames:
|
|
157
|
+
value = objectGet(attr, attrName)
|
|
158
|
+
if value != null:
|
|
159
|
+
attrStr = attrStr + ' ' + attrName + '="' + stringReplace(stringReplace(stringNew(value), '&', '&'), '"', '"') + '"'
|
|
160
|
+
endif
|
|
161
|
+
endfor
|
|
162
|
+
endif
|
|
163
|
+
|
|
164
|
+
# HTML void element?
|
|
165
|
+
isVoid = arrayIndexOf(elementModelVoidTags, tag) != -1
|
|
166
|
+
if isVoid:
|
|
167
|
+
return indentPrefix + '<' + tag + attrStr + ' />' + newline
|
|
168
|
+
endif
|
|
169
|
+
|
|
170
|
+
# Render the element
|
|
171
|
+
elem = objectGet(elements, 'elem')
|
|
172
|
+
childrenStr = if(elem != null, elementModelToStringHelper(elem, indentStr, level + 1), '')
|
|
173
|
+
return indentPrefix + '<' + tag + attrStr + '>' + newline + childrenStr + indentPrefix + '</' + tag + '>' + newline
|
|
174
|
+
endfunction
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# Void elements (simplified list)
|
|
178
|
+
elementModelVoidTags = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']
|
|
@@ -595,6 +595,7 @@ endfunction
|
|
|
595
595
|
# $group: markdownUp.bare: window
|
|
596
596
|
# $doc: Write text to the clipboard
|
|
597
597
|
# $arg text: The text to write
|
|
598
|
+
# $arg type: The clipboard content type (default is "text/plain")
|
|
598
599
|
function windowClipboardWrite(text):
|
|
599
600
|
return objectSet(markdownUpState, 'windowClipboard', text)
|
|
600
601
|
endfunction
|
|
@@ -32,12 +32,9 @@ function qrcodeDraw(message, x, y, size, level):
|
|
|
32
32
|
while ixCol < qrcodeSize:
|
|
33
33
|
pixelValue = arrayGet(arrayGet(matrix, ixRow), ixCol)
|
|
34
34
|
if pixelValue:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
pixelSizeRound, \
|
|
39
|
-
pixelSizeRound \
|
|
40
|
-
)
|
|
35
|
+
pixelLeft = mathRound(borderSize + x + ixCol * pixelSize, precision)
|
|
36
|
+
pixelTop = mathRound(borderSize + y + ixRow * pixelSize, precision)
|
|
37
|
+
drawPathRect(pixelLeft, pixelTop, pixelSizeRound, pixelSizeRound)
|
|
41
38
|
endif
|
|
42
39
|
ixCol = ixCol + 1
|
|
43
40
|
endwhile
|
|
@@ -46,6 +43,69 @@ function qrcodeDraw(message, x, y, size, level):
|
|
|
46
43
|
endfunction
|
|
47
44
|
|
|
48
45
|
|
|
46
|
+
# $function: qrcodeElements
|
|
47
|
+
# $group: qrcode.bare
|
|
48
|
+
# $doc: Generate the element model for a QR code
|
|
49
|
+
# $arg message: The QR code message or the QR code matrix
|
|
50
|
+
# $arg size: The size of the QR code, in pixels
|
|
51
|
+
# $arg level: Optional (default is 'low'). The error correction level: 'low', 'medium', 'quartile', or 'high'.
|
|
52
|
+
# $return: The QR code SVG [element model](https://github.com/craigahobbs/element-model#readme)
|
|
53
|
+
function qrcodeElements(message, size, level):
|
|
54
|
+
# Get the QR code pixel matrix
|
|
55
|
+
matrix = if(systemType(message) == 'string', qrcodeMatrix(message, level), message)
|
|
56
|
+
qrcodeSize = arrayLength(matrix)
|
|
57
|
+
|
|
58
|
+
# Compute the black pixel paths
|
|
59
|
+
# Note: The standard recommendation is a 4-module quiet zone on all sides.
|
|
60
|
+
cellPaths = []
|
|
61
|
+
ixRow = 0
|
|
62
|
+
pixelSize = size / (qrcodeSize + 8)
|
|
63
|
+
borderSize = pixelSize * 4
|
|
64
|
+
precision = 6
|
|
65
|
+
while ixRow < qrcodeSize:
|
|
66
|
+
ixCol = 0
|
|
67
|
+
while ixCol < qrcodeSize:
|
|
68
|
+
pixelValue = arrayGet(arrayGet(matrix, ixRow), ixCol)
|
|
69
|
+
if pixelValue:
|
|
70
|
+
pixelLeft = borderSize + ixCol * pixelSize
|
|
71
|
+
pixelTop = borderSize + ixRow * pixelSize
|
|
72
|
+
arrayPush(cellPaths, arrayJoin([ \
|
|
73
|
+
'M', numberToFixed(pixelLeft, precision), numberToFixed(pixelTop, precision), \
|
|
74
|
+
'H', numberToFixed(pixelLeft + pixelSize, precision), \
|
|
75
|
+
'V', numberToFixed(pixelTop + pixelSize, precision), \
|
|
76
|
+
'H', numberToFixed(pixelLeft, precision), \
|
|
77
|
+
'Z' \
|
|
78
|
+
], ' '))
|
|
79
|
+
endif
|
|
80
|
+
ixCol = ixCol + 1
|
|
81
|
+
endwhile
|
|
82
|
+
ixRow = ixRow + 1
|
|
83
|
+
endwhile
|
|
84
|
+
|
|
85
|
+
# Create the QR code SVG element model
|
|
86
|
+
return { \
|
|
87
|
+
'svg': 'svg', \
|
|
88
|
+
'attr': {'width': size, 'height': size}, \
|
|
89
|
+
'elem': [ \
|
|
90
|
+
{ \
|
|
91
|
+
'svg': 'rect', \
|
|
92
|
+
'attr': { \
|
|
93
|
+
'x': '0', 'y': '0', 'width': size, 'height': size, \
|
|
94
|
+
'fill': 'white', 'stroke': 'none', 'stroke-width': '0', 'stroke-dasharray': 'none' \
|
|
95
|
+
} \
|
|
96
|
+
}, \
|
|
97
|
+
{ \
|
|
98
|
+
'svg': 'path', \
|
|
99
|
+
'attr': { \
|
|
100
|
+
'fill': 'black', 'stroke': 'none', 'stroke-width': '0', 'stroke-dasharray': 'none', \
|
|
101
|
+
'd': arrayJoin(cellPaths, ' ') \
|
|
102
|
+
} \
|
|
103
|
+
} \
|
|
104
|
+
] \
|
|
105
|
+
}
|
|
106
|
+
endfunction
|
|
107
|
+
|
|
108
|
+
|
|
49
109
|
# $function: qrcodeMatrix
|
|
50
110
|
# $group: qrcode.bare
|
|
51
111
|
# $doc: Generate a QR code pixel matrix
|
|
@@ -55,90 +115,92 @@ endfunction
|
|
|
55
115
|
function qrcodeMatrix(message, level):
|
|
56
116
|
level = if(level != null, level, 'low')
|
|
57
117
|
|
|
58
|
-
# Find the QR code model
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# Create the pixel matrix
|
|
66
|
-
matrix = []
|
|
67
|
-
ixRow = 0
|
|
68
|
-
while ixRow < size:
|
|
69
|
-
arrayPush(matrix, arrayNewSize(size, null))
|
|
70
|
-
ixRow = ixRow + 1
|
|
71
|
-
endwhile
|
|
72
|
-
|
|
73
|
-
# Position squares
|
|
74
|
-
qrcodeMatrixPositionSquare(matrix, 3, 3)
|
|
75
|
-
qrcodeMatrixPositionSquare(matrix, 3, size - 4)
|
|
76
|
-
qrcodeMatrixPositionSquare(matrix, size - 4, 3)
|
|
77
|
-
|
|
78
|
-
# Alignment patterns
|
|
79
|
-
if alignmentPatterns:
|
|
80
|
-
ixLast = arrayLength(alignmentPatterns) - 1
|
|
81
|
-
for alignX, ixX in alignmentPatterns:
|
|
82
|
-
for alignY, ixY in alignmentPatterns:
|
|
83
|
-
if !(ixX == 0 && ixY == 0) && !(ixX == 0 && ixY == ixLast) && !(ixX == ixLast && ixY == 0):
|
|
84
|
-
qrcodeMatrixAlignmentPattern(matrix, alignX, alignY)
|
|
85
|
-
endif
|
|
86
|
-
endfor
|
|
87
|
-
endfor
|
|
118
|
+
# Find the QR code model that fits the message bits (mode, version, message, terminator)
|
|
119
|
+
qrcode = null
|
|
120
|
+
for qrcodeFind in qrcodeVersions:
|
|
121
|
+
messageBits = qrcodeMessageBits(qrcodeFind, level, message)
|
|
122
|
+
if messageBits != null:
|
|
123
|
+
qrcode = qrcodeFind
|
|
124
|
+
break
|
|
88
125
|
endif
|
|
126
|
+
endfor
|
|
127
|
+
if qrcode == null:
|
|
128
|
+
systemLogDebug('qrcode.bare: qrcodeMatrix - Message too long (' + stringLength(message) + ')')
|
|
129
|
+
return null
|
|
130
|
+
endif
|
|
131
|
+
size = objectGet(qrcode, 'size')
|
|
132
|
+
alignmentPatterns = objectGet(qrcode, 'alignmentPatterns')
|
|
133
|
+
totalCodewords = objectGet(objectGet(qrcode, level), 'totalCodewords')
|
|
89
134
|
|
|
90
|
-
|
|
91
|
-
|
|
135
|
+
# Create the pixel matrix
|
|
136
|
+
matrix = []
|
|
137
|
+
ixRow = 0
|
|
138
|
+
while ixRow < size:
|
|
139
|
+
arrayPush(matrix, arrayNewSize(size, null))
|
|
140
|
+
ixRow = ixRow + 1
|
|
141
|
+
endwhile
|
|
142
|
+
|
|
143
|
+
# Position squares
|
|
144
|
+
qrcodeMatrixPositionSquare(matrix, 3, 3)
|
|
145
|
+
qrcodeMatrixPositionSquare(matrix, 3, size - 4)
|
|
146
|
+
qrcodeMatrixPositionSquare(matrix, size - 4, 3)
|
|
147
|
+
|
|
148
|
+
# Alignment patterns
|
|
149
|
+
if alignmentPatterns:
|
|
150
|
+
ixLast = arrayLength(alignmentPatterns) - 1
|
|
151
|
+
for alignX, ixAX in alignmentPatterns:
|
|
152
|
+
for alignY, ixAY in alignmentPatterns:
|
|
153
|
+
if !(ixAX == 0 && ixAY == 0) && !(ixAX == 0 && ixAY == ixLast) && !(ixAX == ixLast && ixAY == 0):
|
|
154
|
+
qrcodeMatrixAlignmentPattern(matrix, alignX, alignY)
|
|
155
|
+
endif
|
|
156
|
+
endfor
|
|
157
|
+
endfor
|
|
158
|
+
endif
|
|
92
159
|
|
|
93
|
-
|
|
94
|
-
|
|
160
|
+
# Timing strips
|
|
161
|
+
qrcodeMatrixTimingStrips(matrix)
|
|
95
162
|
|
|
96
|
-
|
|
97
|
-
|
|
163
|
+
# Format strips - use mask 0 as placeholder bits for qrcodeDataPixels
|
|
164
|
+
qrcodeMatrixFormatStrips(matrix, level, 0)
|
|
98
165
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if messageBits != null:
|
|
102
|
-
# Compute the data pixels
|
|
103
|
-
dataPixels = qrcodeDataPixels(matrix)
|
|
166
|
+
# Version blocks
|
|
167
|
+
qrcodeMatrixVersionBlocks(matrix, qrcode)
|
|
104
168
|
|
|
105
|
-
|
|
106
|
-
|
|
169
|
+
# Compute the data pixels
|
|
170
|
+
dataPixels = qrcodeDataPixels(matrix)
|
|
107
171
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if remainderLength > 0:
|
|
111
|
-
arrayExtend(dataBits, arrayNewSize(remainderLength, 0))
|
|
112
|
-
endif
|
|
172
|
+
# Compute the data bits
|
|
173
|
+
dataBits = qrcodeDataBits(qrcode, level, message)
|
|
113
174
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# Set full data bits with mask
|
|
120
|
-
maskMatrix = jsonParse(jsonStringify(matrix))
|
|
121
|
-
qrcodeMatrixPixels(maskMatrix, dataPixels, dataBits, mask)
|
|
122
|
-
|
|
123
|
-
# Set the format strips bits
|
|
124
|
-
qrcodeMatrixFormatStrips(maskMatrix, level, mask)
|
|
125
|
-
|
|
126
|
-
# Compute the mask's penalty
|
|
127
|
-
maskPenalty = qrcodeMatrixPenalty(maskMatrix)
|
|
128
|
-
if bestPenalty == null || maskPenalty < bestPenalty:
|
|
129
|
-
bestMatrix = maskMatrix
|
|
130
|
-
bestPenalty = maskPenalty
|
|
131
|
-
endif
|
|
132
|
-
mask = mask + 1
|
|
133
|
-
endwhile
|
|
175
|
+
# Add the data remainder bits
|
|
176
|
+
remainderLength = arrayLength(dataPixels) - totalCodewords * 8
|
|
177
|
+
if remainderLength > 0:
|
|
178
|
+
arrayExtend(dataBits, arrayNewSize(remainderLength, 0))
|
|
179
|
+
endif
|
|
134
180
|
|
|
135
|
-
|
|
181
|
+
# Compute the penalty for each mask
|
|
182
|
+
bestMatrix = null
|
|
183
|
+
bestPenalty = null
|
|
184
|
+
mask = 0
|
|
185
|
+
while mask < 8:
|
|
186
|
+
# Set full data bits with mask
|
|
187
|
+
maskMatrix = jsonParse(jsonStringify(matrix))
|
|
188
|
+
qrcodeMatrixPixels(maskMatrix, dataPixels, dataBits, mask)
|
|
189
|
+
|
|
190
|
+
# Set the format strips bits
|
|
191
|
+
qrcodeMatrixFormatStrips(maskMatrix, level, mask)
|
|
192
|
+
|
|
193
|
+
# Compute the mask's penalty
|
|
194
|
+
maskPenalty = qrcodeMatrixPenalty(maskMatrix)
|
|
195
|
+
if bestPenalty == null || maskPenalty < bestPenalty:
|
|
196
|
+
bestMatrix = maskMatrix
|
|
197
|
+
bestPenalty = maskPenalty
|
|
136
198
|
endif
|
|
137
|
-
endfor
|
|
138
199
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
200
|
+
mask = mask + 1
|
|
201
|
+
endwhile
|
|
202
|
+
|
|
203
|
+
return bestMatrix
|
|
142
204
|
endfunction
|
|
143
205
|
|
|
144
206
|
|
|
@@ -190,12 +252,13 @@ endfunction
|
|
|
190
252
|
|
|
191
253
|
# Set the format strips pixels
|
|
192
254
|
function qrcodeMatrixFormatStrips(matrix, level, mask):
|
|
193
|
-
# The "dark pixel"
|
|
194
255
|
size = arrayLength(matrix)
|
|
256
|
+
|
|
257
|
+
# The "dark pixel"
|
|
195
258
|
arraySet(arrayGet(matrix, size - 8), 8, 1)
|
|
196
259
|
|
|
197
260
|
# Set the format strip bits
|
|
198
|
-
formatStripBits = objectGet(objectGet(
|
|
261
|
+
formatStripBits = objectGet(objectGet(qrcodeMatrixFormatStripsBitsTable, level), stringNew(mask))
|
|
199
262
|
pixelsTopLeft = [ \
|
|
200
263
|
[0, 8], [1, 8], [2, 8], [3, 8], [4, 8], [5, 8], [7, 8], [8, 8], \
|
|
201
264
|
[8, 7], [8, 5], [8, 4], [8, 3], [8, 2], [8, 1], [8, 0] \
|
|
@@ -210,7 +273,7 @@ endfunction
|
|
|
210
273
|
|
|
211
274
|
|
|
212
275
|
# Format strip bits lookup table
|
|
213
|
-
|
|
276
|
+
qrcodeMatrixFormatStripsBitsTable = { \
|
|
214
277
|
'low': { \
|
|
215
278
|
'0': [1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0], \
|
|
216
279
|
'1': [1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1], \
|
|
@@ -257,7 +320,7 @@ qrcodeMatrixFormatStripsBitsLookup = { \
|
|
|
257
320
|
# Set the version blocks pixels
|
|
258
321
|
function qrcodeMatrixVersionBlocks(matrix, qrcode):
|
|
259
322
|
version = objectGet(qrcode, 'version')
|
|
260
|
-
versionBits = objectGet(
|
|
323
|
+
versionBits = objectGet(qrcodeMatrixVersionBitsTable, stringNew(version))
|
|
261
324
|
if versionBits:
|
|
262
325
|
size = arrayLength(matrix)
|
|
263
326
|
bottomLeftPixels = [ \
|
|
@@ -277,7 +340,7 @@ endfunction
|
|
|
277
340
|
|
|
278
341
|
|
|
279
342
|
# Version bits lookup table
|
|
280
|
-
|
|
343
|
+
qrcodeMatrixVersionBitsTable = { \
|
|
281
344
|
'7': [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0], \
|
|
282
345
|
'10': [0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1], \
|
|
283
346
|
'15': [0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0] \
|
|
@@ -438,8 +501,7 @@ endfunction
|
|
|
438
501
|
# Get the terminated message bits (mode, size, message, terminator)
|
|
439
502
|
function qrcodeMessageBits(qrcode, level, message):
|
|
440
503
|
version = objectGet(qrcode, 'version')
|
|
441
|
-
|
|
442
|
-
totalMessageCodewords = objectGet(ecLevel, 'totalMessageCodewords')
|
|
504
|
+
totalMessageCodewords = objectGet(objectGet(qrcode, level), 'totalMessageCodewords')
|
|
443
505
|
|
|
444
506
|
# Determine the message mode
|
|
445
507
|
# Note: Kanji and ECI modes not supported
|
|
@@ -573,60 +635,54 @@ function qrcodeMatrixPenalty(matrix):
|
|
|
573
635
|
size = arrayLength(matrix)
|
|
574
636
|
penalty = 0
|
|
575
637
|
|
|
576
|
-
#
|
|
577
|
-
stringRowsAndColumns = []
|
|
638
|
+
# Compute row penalties
|
|
578
639
|
for row in matrix:
|
|
579
|
-
|
|
640
|
+
stringRow = arrayJoin(row, '')
|
|
641
|
+
|
|
642
|
+
# Penalty 1: Five or more same-colored modules in a row
|
|
643
|
+
for runMatch in regexMatchAll(qrcodeMatrixPenaltyRunRegex, stringRow):
|
|
644
|
+
penalty = penalty + 3 + (stringLength(objectGet(objectGet(runMatch, 'groups'), '0')) - 5)
|
|
645
|
+
endfor
|
|
646
|
+
|
|
647
|
+
# Penalty 3: Finder-like patterns (1011101 with 4 white modules on either side)
|
|
648
|
+
penalty = penalty + 40 * arrayLength(regexMatchAll(qrcodeMatrixPenaltyPatternRegex, stringRow))
|
|
580
649
|
endfor
|
|
581
650
|
|
|
582
|
-
#
|
|
583
|
-
twoByCount = 0
|
|
584
|
-
twoBySize = size - 1
|
|
651
|
+
# Compute column penalties - also count dark modules
|
|
585
652
|
darkCount = 0
|
|
653
|
+
twoBySize = size - 1
|
|
586
654
|
ix = 0
|
|
587
655
|
while ix < size:
|
|
588
656
|
column = []
|
|
589
657
|
iy = 0
|
|
590
658
|
while iy < size:
|
|
591
659
|
row = arrayGet(matrix, iy)
|
|
592
|
-
row2 = if(ix < twoBySize && iy < twoBySize, arrayGet(matrix, iy + 1))
|
|
593
660
|
bit = arrayGet(row, ix)
|
|
594
|
-
|
|
595
|
-
# Add the column bit
|
|
596
661
|
arrayPush(column, bit)
|
|
597
662
|
|
|
598
|
-
#
|
|
663
|
+
# Penalty 2: 2x2 blocks of same color
|
|
664
|
+
row2 = if(ix < twoBySize && iy < twoBySize, arrayGet(matrix, iy + 1))
|
|
599
665
|
if row2 && bit == arrayGet(row, ix + 1) && bit == arrayGet(row2, ix) && bit == arrayGet(row2, ix + 1):
|
|
600
|
-
|
|
666
|
+
penalty = penalty + 3
|
|
601
667
|
endif
|
|
602
668
|
|
|
603
669
|
# Count "dark" pixels
|
|
604
|
-
|
|
605
|
-
darkCount = darkCount + 1
|
|
606
|
-
endif
|
|
670
|
+
darkCount = darkCount + bit
|
|
607
671
|
|
|
608
672
|
iy = iy + 1
|
|
609
673
|
endwhile
|
|
674
|
+
stringColumn = arrayJoin(column, '')
|
|
610
675
|
|
|
611
|
-
#
|
|
612
|
-
|
|
613
|
-
ix = ix + 1
|
|
614
|
-
endwhile
|
|
615
|
-
|
|
616
|
-
# Penalty 1: Five or more same-colored modules in a row/column
|
|
617
|
-
for stringRow in stringRowsAndColumns:
|
|
618
|
-
for runMatch in regexMatchAll(qrcodeMatrixPenaltyRunRegex, stringRow):
|
|
676
|
+
# Penalty 1: Five or more same-colored modules in a column
|
|
677
|
+
for runMatch in regexMatchAll(qrcodeMatrixPenaltyRunRegex, stringColumn):
|
|
619
678
|
penalty = penalty + 3 + (stringLength(objectGet(objectGet(runMatch, 'groups'), '0')) - 5)
|
|
620
679
|
endfor
|
|
621
|
-
endfor
|
|
622
680
|
|
|
623
|
-
|
|
624
|
-
|
|
681
|
+
# Penalty 3: Finder-like patterns (1011101 with 4 white modules on either side)
|
|
682
|
+
penalty = penalty + 40 * arrayLength(regexMatchAll(qrcodeMatrixPenaltyPatternRegex, stringColumn))
|
|
625
683
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
penalty = penalty + 40 * arrayLength(regexMatchAll(qrcodeMatrixPenaltyPatternRegex, stringRow))
|
|
629
|
-
endfor
|
|
684
|
+
ix = ix + 1
|
|
685
|
+
endwhile
|
|
630
686
|
|
|
631
687
|
# Penalty 4: Proportion of dark modules
|
|
632
688
|
darkPercent = (darkCount * 100) / (size * size)
|
|
@@ -675,9 +731,11 @@ function qrcodeRSEncode(bytesIn, numCodewords):
|
|
|
675
731
|
|
|
676
732
|
# XOR with existing value (subtraction in GF(2^8))
|
|
677
733
|
arraySet(bytesOut, i + j, oldVal ^ product)
|
|
734
|
+
|
|
678
735
|
j = j + 1
|
|
679
736
|
endwhile
|
|
680
737
|
endif
|
|
738
|
+
|
|
681
739
|
i = i + 1
|
|
682
740
|
endwhile
|
|
683
741
|
|
|
@@ -954,6 +954,14 @@ _MATH_COS_ARGS = value_args_model([
|
|
|
954
954
|
])
|
|
955
955
|
|
|
956
956
|
|
|
957
|
+
# $function: mathE
|
|
958
|
+
# $group: math
|
|
959
|
+
# $doc: Return Euler's number
|
|
960
|
+
# $return: Euler's number
|
|
961
|
+
def _math_e(unused_args, unused_options):
|
|
962
|
+
return math.e
|
|
963
|
+
|
|
964
|
+
|
|
957
965
|
# $function: mathFloor
|
|
958
966
|
# $group: math
|
|
959
967
|
# $doc: Compute the floor of a number (round down to the next lowest integer)
|
|
@@ -1596,6 +1604,25 @@ _SCHEMA_VALIDATE_TYPE_MODEL_ARGS = value_args_model([
|
|
|
1596
1604
|
#
|
|
1597
1605
|
|
|
1598
1606
|
|
|
1607
|
+
# $function: stringCharAt
|
|
1608
|
+
# $group: string
|
|
1609
|
+
# $doc: Get a string index's character code
|
|
1610
|
+
# $arg string: The string
|
|
1611
|
+
# $arg index: The character index
|
|
1612
|
+
# $return: The character code
|
|
1613
|
+
def _string_char_at(args, unused_options):
|
|
1614
|
+
string, index = value_args_validate(_STRING_CHAR_AT_ARGS, args)
|
|
1615
|
+
if index >= len(string):
|
|
1616
|
+
raise ValueArgsError('index', index)
|
|
1617
|
+
|
|
1618
|
+
return string[int(index)]
|
|
1619
|
+
|
|
1620
|
+
_STRING_CHAR_AT_ARGS = value_args_model([
|
|
1621
|
+
{'name': 'string', 'type': 'string'},
|
|
1622
|
+
{'name': 'index', 'type': 'number', 'integer': True, 'gte': 0}
|
|
1623
|
+
])
|
|
1624
|
+
|
|
1625
|
+
|
|
1599
1626
|
# $function: stringCharCodeAt
|
|
1600
1627
|
# $group: string
|
|
1601
1628
|
# $doc: Get a string index's character code
|
|
@@ -1681,7 +1708,7 @@ def _string_from_char_code(char_codes, unused_options):
|
|
|
1681
1708
|
# $return: The first index of the search string; -1 if not found.
|
|
1682
1709
|
def _string_index_of(args, unused_options):
|
|
1683
1710
|
string, search, index = value_args_validate(_STRING_INDEX_OF_ARGS, args, -1)
|
|
1684
|
-
if index
|
|
1711
|
+
if index > len(string):
|
|
1685
1712
|
raise ValueArgsError('index', index, -1)
|
|
1686
1713
|
|
|
1687
1714
|
return string.find(search, int(index))
|
|
@@ -1703,7 +1730,7 @@ _STRING_INDEX_OF_ARGS = value_args_model([
|
|
|
1703
1730
|
def _string_last_index_of(args, unused_options):
|
|
1704
1731
|
string, search, index = value_args_validate(_STRING_LAST_INDEX_OF_ARGS, args, -1)
|
|
1705
1732
|
index = index if index is not None else len(string) - 1
|
|
1706
|
-
if index
|
|
1733
|
+
if index > len(string):
|
|
1707
1734
|
raise ValueArgsError('index', index, -1)
|
|
1708
1735
|
|
|
1709
1736
|
return string.rfind(search, 0, int(index) + len(search))
|
|
@@ -2216,6 +2243,7 @@ SCRIPT_FUNCTIONS = {
|
|
|
2216
2243
|
'mathAtan2': _math_atan2,
|
|
2217
2244
|
'mathCeil': _math_ceil,
|
|
2218
2245
|
'mathCos': _math_cos,
|
|
2246
|
+
'mathE': _math_e,
|
|
2219
2247
|
'mathFloor': _math_floor,
|
|
2220
2248
|
'mathLn': _math_ln,
|
|
2221
2249
|
'mathLog': _math_log,
|
|
@@ -2251,6 +2279,7 @@ SCRIPT_FUNCTIONS = {
|
|
|
2251
2279
|
'schemaTypeModel': _schema_type_model,
|
|
2252
2280
|
'schemaValidate': _schema_validate,
|
|
2253
2281
|
'schemaValidateTypeModel': _schema_validate_type_model,
|
|
2282
|
+
'stringCharAt': _string_char_at,
|
|
2254
2283
|
'stringCharCodeAt': _string_char_code_at,
|
|
2255
2284
|
'stringDecode': _string_decode,
|
|
2256
2285
|
'stringEncode': _string_encode,
|
|
@@ -25,6 +25,7 @@ src/bare_script/include/baredoc.bare
|
|
|
25
25
|
src/bare_script/include/dataLineChart.bare
|
|
26
26
|
src/bare_script/include/dataTable.bare
|
|
27
27
|
src/bare_script/include/diff.bare
|
|
28
|
+
src/bare_script/include/elementModel.bare
|
|
28
29
|
src/bare_script/include/forms.bare
|
|
29
30
|
src/bare_script/include/markdownUp.bare
|
|
30
31
|
src/bare_script/include/pager.bare
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|