Skip to content

Commit

Permalink
Make #UDGARRAY accept attribute address range specs in square brackets
Browse files Browse the repository at this point in the history
  • Loading branch information
skoolkid committed Jan 11, 2025
1 parent 24170b6 commit ca9589b
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 32 deletions.
10 changes: 5 additions & 5 deletions skoolkit/skoolmacro.py
Original file line number Diff line number Diff line change
Expand Up @@ -1569,11 +1569,11 @@ def _get_udgs(text, index, pvals, start, snapshot, fields):
if not has_masks:
pvals[7] = 0 # Set mask=0

if text[end:end + 2].startswith(('(@', '@')):
if text[end] == '(':
end, attr_specs = parse_brackets(text, end)
if text[end:end + 1].startswith(('[', '@')):
if text[end] == '[':
end, attr_specs = parse_brackets(text, end, opening='[', closing=']')
attr_addresses = []
for attr_spec in attr_specs[1:].split(';'):
for attr_spec in attr_specs.split(';'):
addresses = parse_address_range(attr_spec, 0, width, fields)[1]
if addresses is None:
raise MacroParsingError(f'Expected attribute address range specification: #UDGARRAY{text[start:end]}')
Expand All @@ -1597,7 +1597,7 @@ def _get_udgs(text, index, pvals, start, snapshot, fields):
return end, [udg_array]

def parse_udgarray(text, index, snapshot=None, req_fname=True, fields=None):
# #UDGARRAYwidth[,attr,scale,step,inc,flip,rotate,mask,tindex,alpha](UDGS)[@ATTRS][{x,y,width,height}](fname)
# #UDGARRAYwidth[,attr,scale,step,inc,flip,rotate,mask,tindex,alpha](UDGS)[[ATTRS]][{x,y,width,height}](fname)
names = ('width', 'attr', 'scale', 'step', 'inc', 'flip', 'rotate', 'mask', 'tindex', 'alpha')
defaults = (56, 2, 1, 0, 0, 0, 1, 0, -1)
end, crop_rect, fname, frame, alt, values = parse_image_macro(text, index, defaults, names, '', fields, _get_udgs, (index, snapshot, fields))
Expand Down
9 changes: 5 additions & 4 deletions sphinx/source/skool-macros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2468,7 +2468,7 @@ The integer parameters, mask specification and cropping specification of the
In HTML mode, the ``#UDGARRAY`` macro expands to an ``<img>`` element for the
image of an array of UDGs (8x8 blocks of pixels). ::

#UDGARRAYwidth[,attr,scale,step,inc,flip,rotate,mask,tindex,alpha](SPEC1[;SPEC2;...])[(@ATTRS1[;ATTRS2;...])][{CROP}](fname)
#UDGARRAYwidth[,attr,scale,step,inc,flip,rotate,mask,tindex,alpha](SPEC1;SPEC2;...)[[ATTRS1;ATTRS2;...]][{CROP}](fname)

* ``width`` is the width of the image (in UDGs)
* ``attr`` is the default attribute byte of each UDG (default: 56)
Expand Down Expand Up @@ -2566,14 +2566,15 @@ specification and cropping specification of the ``#UDGARRAY`` macro may contain
See also :ref:`UDGS`.

.. note::
Omitting the parentheses around the UDG specifications and around the
attribute address range specifications is deprecated since version 9.5.
Omitting the parentheses around the UDG specifications, and using the ``@``
notation instead of square brackets around the attribute address range
specifications are both deprecated since version 9.5.

+---------+-------------------------------------------------------------------+
| Version | Changes |
+=========+===================================================================+
| 9.5 | The attribute address range specifications may be enclosed in |
| | parentheses |
| | square brackets |
+---------+-------------------------------------------------------------------+
| 8.6 | The UDG specifications may be enclosed in parentheses |
+---------+-------------------------------------------------------------------+
Expand Down
10 changes: 5 additions & 5 deletions tests/macrotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2958,9 +2958,9 @@ def test_macro_udgarray_invalid(self):
self._test_invalid_image_macro(writer, '#UDGARRAY1;0:,2(foo)', 'Expected mask address range specification: #UDGARRAY1;0:', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1(0:,2)(foo)', 'Expected mask address range specification: #UDGARRAY1(0:', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0@(foo)', 'Expected attribute address range specification: #UDGARRAY1;0@', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0(@)(foo)', 'Expected attribute address range specification: #UDGARRAY1;0(@)', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0[@](foo)', 'Expected attribute address range specification: #UDGARRAY1;0[@]', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0@1;(foo)', 'Expected attribute address range specification: #UDGARRAY1;0@1;', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0(@1;)(foo)', 'Expected attribute address range specification: #UDGARRAY1;0(@1;)', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0[1;](foo)', 'Expected attribute address range specification: #UDGARRAY1;0[1;]', prefix)

self._test_invalid_image_macro(writer, '#UDGARRAY1;0', 'Missing filename: #UDGARRAY1;0', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0()', 'Missing filename: #UDGARRAY1;0()', prefix)
Expand All @@ -2976,7 +2976,7 @@ def test_macro_udgarray_invalid(self):
self._test_invalid_image_macro(writer, '#UDGARRAY1;32768xJ', "Invalid multiplier in address range specification: 32768xJ", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0x2:8xK', "Invalid multiplier in address range specification: 8xK", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0x2@2xn', "Invalid multiplier in address range specification: 2xn", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0x2(@2xn)', "Invalid multiplier in address range specification: 2xn", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0x2[2xn]', "Invalid multiplier in address range specification: 2xn", prefix)

self._test_invalid_image_macro(writer, '#UDGARRAY1;0{0,0,23,14(foo)', 'No closing brace on cropping specification: {0,0,23,14(foo)', prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0(foo', 'No closing bracket: (foo', prefix)
Expand All @@ -2989,7 +2989,7 @@ def test_macro_udgarray_invalid(self):
self._test_invalid_image_macro(writer, '#UDGARRAY1;0:0x({nae})(udg)', "Unrecognised field 'nae': {nae}", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0:0,({nada})(udg)', "Unrecognised field 'nada': {nada}", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0@({nix})(udg)', "Unrecognised field 'nix': {nix}", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0(@({nix}))(udg)', "Unrecognised field 'nix': {nix}", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0[({nix})](udg)', "Unrecognised field 'nix': {nix}", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0{{nyet}}(udg)', "Unrecognised field 'nyet': {nyet}", prefix)

self._test_invalid_image_macro(writer, '#UDGARRAY({foo);0(udg)', "Invalid format string: {foo", prefix)
Expand All @@ -2998,7 +2998,7 @@ def test_macro_udgarray_invalid(self):
self._test_invalid_image_macro(writer, '#UDGARRAY1;0:({qux)(udg)', "Invalid format string: {qux", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0:0,({xyzzy)(udg)', "Invalid format string: {xyzzy", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0@({bish)(udg)', "Invalid format string: {bish", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0(@({bish))(udg)', "Invalid format string: {bish", prefix)
self._test_invalid_image_macro(writer, '#UDGARRAY1;0[({bish)](udg)', "Invalid format string: {bish", prefix)

def test_macro_udgarray_frames_invalid(self):
writer = self._get_writer(snapshot=[0] * 8)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_skoolasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -882,9 +882,9 @@ def test_macro_udgarray(self):
self._test_udgarray_macro(writer, '#UDGARRAY2', '(256*128)x(3+1),(4*(32+32),2**2,8/8)', '(baz)')
self._test_udgarray_macro(writer, '#UDGARRAY2', '0-8-8:(2**(2+2)),((8+8)*8)', '(baz*qux)')
self._test_udgarray_macro(writer, '#UDGARRAY2', '0;1', '@2;3(attr_addrs)')
self._test_udgarray_macro(writer, '#UDGARRAY2', '0;1', '(@2;3)(attr_addrs)')
self._test_udgarray_macro(writer, '#UDGARRAY2', '0;1', '[2;3](attr_addrs)')
self._test_udgarray_macro(writer, '#UDGARRAY({w})', '({a}),(,{s}):({m}),({s});({a})-({a}+16)-16x({s}):({m})x2', '@({aa})x3{height={h}}(img)')
self._test_udgarray_macro(writer, '#UDGARRAY({w})', '({a}),(,{s}):({m}),({s});({a})-({a}+16)-16x({s}):({m})x2', '(@({aa})x3){height={h}}(img)')
self._test_udgarray_macro(writer, '#UDGARRAY({w})', '({a}),(,{s}):({m}),({s});({a})-({a}+16)-16x({s}):({m})x2', '[({aa})x3]{height={h}}(img)')
self._test_udgarray_macro(writer, '#UDGARRAY2', nest_macros('({})-({})-({})-({})x({})', 32768, 32785, 1, 16, 1), '(thing)')
self._test_udgarray_macro(writer, '#UDGARRAY1', nest_macros('32768-32785-1-16:({})-({})-({})-({})x({})', 32800, 32817, 1, 16, 1), '(thing)')
self._test_udgarray_macro(writer, '#UDGARRAY1', nest_macros('32768,({}):32776,({})', 5, 2), '(thing)')
Expand Down
34 changes: 18 additions & 16 deletions tests/test_skoolhtml.py
Original file line number Diff line number Diff line change
Expand Up @@ -4662,10 +4662,10 @@ def test_macro_udgarray_with_attribute_addresses(self):
fname = 'attr_addrs'
attrs = [1, 2, 3, 4]
snapshot[32:32 + len(attrs)] = attrs
attr_specs = '@32;33;34-35'
attr_specs = '32;33;34-35'
exp_image_path = '{}/{}.png'.format(UDGDIR, fname)
exp_udgs = [[Udg(a, [0] * 8) for a in attrs]]
for attrs in (attr_specs, f'({attr_specs})'):
for attrs in (f'@{attr_specs}', f'[{attr_specs}]'):
macro = f'#UDGARRAY4;0-24-8{attrs}({fname})'
self._test_image_macro(snapshot, macro, exp_image_path, exp_udgs)

Expand All @@ -4675,8 +4675,8 @@ def test_macro_udgarray_with_attribute_address_using_multiplier(self):
snapshot[32] = 4
exp_image_path = '{}/{}.png'.format(UDGDIR, fname)
exp_udgs = [[Udg(4, [0] * 8)]] * 3
attr_specs = '@32x3'
for attrs in (attr_specs, f'({attr_specs})'):
attr_specs = '32x3'
for attrs in (f'@{attr_specs}', f'[{attr_specs}]'):
macro = f'#UDGARRAY1;0;8;16{attrs}({fname})'
self._test_image_macro(snapshot, macro, exp_image_path, exp_udgs)

Expand All @@ -4686,10 +4686,10 @@ def test_macro_udgarray_with_attribute_addresses_using_step(self):
attrs = [12, 13, 14]
step = 2
snapshot[32:32 + step * len(attrs):step] = attrs
attr_specs = f'@32-36-{step}'
attr_specs = f'32-36-{step}'
exp_image_path = '{}/{}.png'.format(UDGDIR, fname)
exp_udgs = [[Udg(a, [0] * 8) for a in attrs]]
for attrs in (attr_specs, f'({attr_specs})'):
for attrs in (f'@{attr_specs}', f'[{attr_specs}]'):
macro = f'#UDGARRAY3;0;8;16{attrs}({fname})'
self._test_image_macro(snapshot, macro, exp_image_path, exp_udgs)

Expand All @@ -4699,10 +4699,10 @@ def test_macro_udgarray_with_attribute_addresses_using_horizontal_and_vertical_s
attrs = [15, 16, 17, 18]
snapshot[32:34] = attrs[:2]
snapshot[36:38] = attrs[2:]
attr_specs = '@32-37-1-4'
attr_specs = '32-37-1-4'
exp_image_path = '{}/{}.png'.format(UDGDIR, fname)
exp_udgs = [[Udg(a, [0] * 8) for a in attrs[:2]], [Udg(a, [0] * 8) for a in attrs[2:]]]
for attrs in (attr_specs, f'({attr_specs})'):
for attrs in (f'@{attr_specs}', f'[{attr_specs}]'):
macro = f'#UDGARRAY2;0-24-8{attrs}({fname})'
self._test_image_macro(snapshot, macro, exp_image_path, exp_udgs)

Expand All @@ -4711,10 +4711,10 @@ def test_macro_udgarray_with_attribute_address_range_too_long(self):
fname = 'attr_addrs_long'
attrs = [19, 20, 21]
snapshot[32:32 + len(attrs)] = attrs
attr_specs = '@32-36'
attr_specs = '32-36'
exp_image_path = '{}/{}.png'.format(UDGDIR, fname)
exp_udgs = [[Udg(a, [0] * 8) for a in attrs]]
for attrs in (attr_specs, f'({attr_specs})'):
for attrs in (f'@{attr_specs}', f'[{attr_specs}]'):
macro = f'#UDGARRAY3;0;8;16{attrs}({fname})'
self._test_image_macro(snapshot, macro, exp_image_path, exp_udgs)

Expand All @@ -4723,10 +4723,10 @@ def test_macro_udgarray_with_attribute_address_range_too_short(self):
fname = 'attr_addrs_short'
attrs = [22, 23]
snapshot[32:32 + len(attrs)] = attrs
attr_specs = '@32-33'
attr_specs = '32-33'
exp_image_path = '{}/{}.png'.format(UDGDIR, fname)
exp_udgs = [[Udg(a, [0] * 8) for a in attrs] + [Udg(56, [0] * 8)]]
for attrs in (attr_specs, f'({attr_specs})'):
for attrs in (f'@{attr_specs}', f'[{attr_specs}]'):
macro = f'#UDGARRAY3;0;8;16{attrs}({fname})'
self._test_image_macro(snapshot, macro, exp_image_path, exp_udgs)

Expand All @@ -4743,10 +4743,12 @@ def test_macro_udgarray_with_replacement_fields(self):
'#UDGARRAY({w})'
)
udg_specs = '({a}),(,{s}):({m}),({s});({a})-({a}+16)-16x({s}):({m})x2'
suffix = '@({aa})x3{height={h}}(img)'
exp_image_path = '{}/img.png'.format(UDGDIR)
exp_udgs = [[udg] * 3]
self._test_udgarray_macro(snapshot, prefix, udg_specs, suffix, exp_image_path, exp_udgs, scale=2, mask=1, height=15)
attr_specs = '({aa})x3'
for attrs in (f'@{attr_specs}', f'[{attr_specs}]'):
suffix = attrs + '{height={h}}(img)'
exp_image_path = '{}/img.png'.format(UDGDIR)
exp_udgs = [[udg] * 3]
self._test_udgarray_macro(snapshot, prefix, udg_specs, suffix, exp_image_path, exp_udgs, scale=2, mask=1, height=15)

def test_macro_udgarray_with_short_udg_specs(self):
snapshot = [0] * 24
Expand Down

0 comments on commit ca9589b

Please sign in to comment.