bare-script 3.8.16__tar.gz → 3.8.17__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.17}/PKG-INFO +1 -1
- {bare_script-3.8.16 → bare_script-3.8.17}/setup.cfg +1 -1
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/args.bare +5 -3
- bare_script-3.8.17/src/bare_script/include/elementModel.bare +178 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/qrcode.bare +173 -115
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/schemaDoc.bare +0 -1
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/library.py +22 -2
- {bare_script-3.8.16 → bare_script-3.8.17/src/bare_script.egg-info}/PKG-INFO +1 -1
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script.egg-info/SOURCES.txt +1 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/LICENSE +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/README.md +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/pyproject.toml +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/__init__.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/__main__.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/bare.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/baredoc.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/data.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/__init__.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/baredoc.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/dataLineChart.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/dataTable.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/diff.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/forms.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/markdownUp.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/pager.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/unittest.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/include/unittestMock.bare +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/model.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/options.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/parser.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/runtime.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script/value.py +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script.egg-info/dependency_links.txt +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script.egg-info/entry_points.txt +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/src/bare_script.egg-info/requires.txt +0 -0
- {bare_script-3.8.16 → bare_script-3.8.17}/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']
|
|
@@ -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
|
|
|
@@ -1596,6 +1596,25 @@ _SCHEMA_VALIDATE_TYPE_MODEL_ARGS = value_args_model([
|
|
|
1596
1596
|
#
|
|
1597
1597
|
|
|
1598
1598
|
|
|
1599
|
+
# $function: stringCharAt
|
|
1600
|
+
# $group: string
|
|
1601
|
+
# $doc: Get a string index's character code
|
|
1602
|
+
# $arg string: The string
|
|
1603
|
+
# $arg index: The character index
|
|
1604
|
+
# $return: The character code
|
|
1605
|
+
def _string_char_at(args, unused_options):
|
|
1606
|
+
string, index = value_args_validate(_STRING_CHAR_AT_ARGS, args)
|
|
1607
|
+
if index >= len(string):
|
|
1608
|
+
raise ValueArgsError('index', index)
|
|
1609
|
+
|
|
1610
|
+
return string[int(index)]
|
|
1611
|
+
|
|
1612
|
+
_STRING_CHAR_AT_ARGS = value_args_model([
|
|
1613
|
+
{'name': 'string', 'type': 'string'},
|
|
1614
|
+
{'name': 'index', 'type': 'number', 'integer': True, 'gte': 0}
|
|
1615
|
+
])
|
|
1616
|
+
|
|
1617
|
+
|
|
1599
1618
|
# $function: stringCharCodeAt
|
|
1600
1619
|
# $group: string
|
|
1601
1620
|
# $doc: Get a string index's character code
|
|
@@ -1681,7 +1700,7 @@ def _string_from_char_code(char_codes, unused_options):
|
|
|
1681
1700
|
# $return: The first index of the search string; -1 if not found.
|
|
1682
1701
|
def _string_index_of(args, unused_options):
|
|
1683
1702
|
string, search, index = value_args_validate(_STRING_INDEX_OF_ARGS, args, -1)
|
|
1684
|
-
if index
|
|
1703
|
+
if index > len(string):
|
|
1685
1704
|
raise ValueArgsError('index', index, -1)
|
|
1686
1705
|
|
|
1687
1706
|
return string.find(search, int(index))
|
|
@@ -1703,7 +1722,7 @@ _STRING_INDEX_OF_ARGS = value_args_model([
|
|
|
1703
1722
|
def _string_last_index_of(args, unused_options):
|
|
1704
1723
|
string, search, index = value_args_validate(_STRING_LAST_INDEX_OF_ARGS, args, -1)
|
|
1705
1724
|
index = index if index is not None else len(string) - 1
|
|
1706
|
-
if index
|
|
1725
|
+
if index > len(string):
|
|
1707
1726
|
raise ValueArgsError('index', index, -1)
|
|
1708
1727
|
|
|
1709
1728
|
return string.rfind(search, 0, int(index) + len(search))
|
|
@@ -2251,6 +2270,7 @@ SCRIPT_FUNCTIONS = {
|
|
|
2251
2270
|
'schemaTypeModel': _schema_type_model,
|
|
2252
2271
|
'schemaValidate': _schema_validate,
|
|
2253
2272
|
'schemaValidateTypeModel': _schema_validate_type_model,
|
|
2273
|
+
'stringCharAt': _string_char_at,
|
|
2254
2274
|
'stringCharCodeAt': _string_char_code_at,
|
|
2255
2275
|
'stringDecode': _string_decode,
|
|
2256
2276
|
'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
|
|
File without changes
|