Skip to content
This repository has been archived by the owner on Aug 17, 2023. It is now read-only.

Commit

Permalink
Use attribute value of True for boolean attributes, False and None sh…
Browse files Browse the repository at this point in the history
…ould remove attribute
  • Loading branch information
rowanseymour committed Mar 13, 2017
1 parent 078717c commit aad56c4
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 15 deletions.
20 changes: 12 additions & 8 deletions hamlpy/parser/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# non-word characters that we allow in attribute keys (in HTML style attribute dicts)
ATTRIBUTE_KEY_EXTRA_CHARS = {':', '-', '$', '?', '[', ']'}

ATTRIBUTE_VALUE_KEYWORDS = {'none': None, 'true': True, 'false': False}


def read_attribute_value(stream, options):
"""
Expand All @@ -29,13 +31,15 @@ def read_attribute_value(stream, options):

elif ch.isdigit():
value = read_number(stream)
elif stream.text[stream.ptr:stream.ptr+4].lower() == 'none':
stream.ptr += 4
value = None
elif ch.isalnum():
value = '{{ %s }}' % read_word(stream)
else:
raise ParseException("Unexpected \"%s\"." % ch, stream)
raw_value = read_word(stream)

if raw_value.lower() in ATTRIBUTE_VALUE_KEYWORDS:
value = ATTRIBUTE_VALUE_KEYWORDS[raw_value.lower()]
elif raw_value:
value = '{{ %s }}' % raw_value
else:
raise ParseException("Unexpected \"%s\"." % ch, stream)

return value

Expand Down Expand Up @@ -146,7 +150,7 @@ def read_ruby_attribute(stream, options):
else:
value = read_attribute_value(stream, options)
else:
value = None
value = True

return key, value

Expand Down Expand Up @@ -180,7 +184,7 @@ def read_html_attribute(stream, options):
else:
value = read_attribute_value(stream, options)
else:
value = None
value = True

return key, value

Expand Down
4 changes: 2 additions & 2 deletions hamlpy/parser/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ def attr_wrap(val):
rendered = []

for name, value in self.attributes.items():
if name in ('id', 'class'):
if name in ('id', 'class') or value in (None, False):
continue

if value is None:
if value is True:
rendered.append("%s" % name) # boolean attribute
else:
value = self._escape_attribute_quotes(value, attr_wrapper)
Expand Down
8 changes: 4 additions & 4 deletions hamlpy/test/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ def test_read_ruby_style_attribute_dict(self):
# boolean attributes
assert dict(self._parse(
"{disabled, class:'test', data-number : 123,\n foo:\"bar\"}"
)) == {'disabled': None, 'class': 'test', 'data-number': '123', 'foo': 'bar'}
)) == {'disabled': True, 'class': 'test', 'data-number': '123', 'foo': 'bar'}

assert dict(self._parse(
"{class:'test', data-number : 123,\n foo:\"bar\", \t disabled}"
)) == {'disabled': None, 'class': 'test', 'data-number': '123', 'foo': 'bar'}
)) == {'disabled': True, 'class': 'test', 'data-number': '123', 'foo': 'bar'}

# attribute name has colon
assert dict(self._parse("{'xml:lang': 'en'}")) == {'xml:lang': 'en'}
Expand Down Expand Up @@ -132,11 +132,11 @@ def test_read_html_style_attribute_dict(self):
# boolean attributes
assert dict(self._parse(
"(disabled class='test' data-number = 123\n foo=\"bar\")"
)) == {'disabled': None, 'class': 'test', 'data-number': '123', 'foo': 'bar'}
)) == {'disabled': True, 'class': 'test', 'data-number': '123', 'foo': 'bar'}

assert dict(self._parse(
"(class='test' data-number = 123\n foo=\"bar\" \t disabled)"
)) == {'disabled': None, 'class': 'test', 'data-number': '123', 'foo': 'bar'}
)) == {'disabled': True, 'class': 'test', 'data-number': '123', 'foo': 'bar'}

# attribute name has colon
assert dict(self._parse('(xml:lang="en")')) == {'xml:lang': 'en'}
Expand Down
1 change: 1 addition & 0 deletions hamlpy/test/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def test_boolean_attributes(self):
self._test("%input{a: 'b', required, b: 'c'}", "<input a='b' required b='c'>")
self._test("%input{a: 'b', required}", "<input a='b' required>")
self._test("%input{checked, required, visible}", "<input checked required visible>")
self._test("%input(checked=true)", "<input checked>")

def test_attribute_values_as_tuples_and_lists(self):
# id attribute as tuple
Expand Down
2 changes: 1 addition & 1 deletion hamlpy/test/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_read_element(self):
self.assertEqual(element.tag, 'input')
self.assertEqual(element.id, None)
self.assertEqual(element.classes, [])
self.assertEqual(dict(element.attributes), {'required': None})
self.assertEqual(dict(element.attributes), {'required': True})
self.assertEqual(element.nuke_outer_whitespace, False)
self.assertEqual(element.nuke_inner_whitespace, False)
self.assertEqual(element.self_close, True) # input is implicitly self-closing
Expand Down

0 comments on commit aad56c4

Please sign in to comment.