Skip to content

Commit 7e7bb78

Browse files
committed
WIP: feat: add parent attribute (#71)
1 parent 2190c87 commit 7e7bb78

File tree

7 files changed

+41
-8
lines changed

7 files changed

+41
-8
lines changed

mistletoe/ast_renderer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def get_ast(token):
4040
node[attrname] = getattr(token, attrname)
4141
if 'header' in vars(token):
4242
node['header'] = get_ast(getattr(token, 'header'))
43-
if 'children' in vars(token):
43+
if token.children is not None:
4444
node['children'] = [get_ast(child) for child in token.children]
4545
return node
4646

mistletoe/html_renderer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def __exit__(self, *args):
4949
super().__exit__(*args)
5050

5151
def render_to_plain(self, token) -> str:
52-
if hasattr(token, 'children'):
52+
if token.children is not None:
5353
inner = [self.render_to_plain(child) for child in token.children]
5454
return ''.join(inner)
5555
return html.escape(token.content)

mistletoe/span_token.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def __init__(self, match):
7171
self.content = match.group(self.parse_group)
7272

7373
def __contains__(self, text):
74-
if hasattr(self, 'children'):
74+
if self.children is not None:
7575
return any(text in child for child in self.children)
7676
return text in self.content
7777

mistletoe/token.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def __repr__(self):
5454
self.__class__.__name__
5555
)
5656

57-
if "children" in vars(self):
57+
if self.children is not None:
5858
count = len(self.children)
5959
if count == 1:
6060
output += " with 1 child"
@@ -69,3 +69,18 @@ def __repr__(self):
6969
output += " {}={}".format(attrname, _short_repr(attrvalue))
7070
output += " at {:#x}>".format(id(self))
7171
return output
72+
73+
@property
74+
def parent(self):
75+
return getattr(self, '_parent', None)
76+
77+
@property
78+
def children(self):
79+
return getattr(self, '_children', None)
80+
81+
@children.setter
82+
def children(self, value):
83+
self._children = value
84+
if value:
85+
for child in value:
86+
child._parent = self

mistletoe/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ def traverse(source, klass=None, depth=None, include_source=False):
2020
current_depth = 0
2121
if include_source and (klass is None or isinstance(source, klass)):
2222
yield TraverseResult(source, None, current_depth)
23-
next_children = [(source, c) for c in getattr(source, 'children', [])]
23+
next_children = [(source, c) for c in source.children or []]
2424
while next_children and (depth is None or current_depth < depth):
2525
current_depth += 1
2626
new_children = []
2727
for parent, child in next_children:
2828
if klass is None or isinstance(child, klass):
2929
yield TraverseResult(child, parent, current_depth)
3030
new_children.extend(
31-
[(child, c) for c in getattr(child, 'children', [])]
31+
[(child, c) for c in child.children or []]
3232
)
3333
next_children = new_children

test/test_block_token.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,18 @@ def test_contains(self):
612612
self.assertFalse('foo' in token)
613613

614614

615+
class TestParent(unittest.TestCase):
616+
def test_parent(self):
617+
lines = ['# heading\n', '\n', 'paragraph\n']
618+
token = block_token.Document(lines)
619+
self.assertEqual(len(token.children), 2)
620+
self.assertIsNone(token.parent)
621+
for child in token.children:
622+
self.assertEqual(child.parent, token)
623+
for grandchild in child.children:
624+
self.assertEqual(grandchild.parent, child)
625+
626+
615627
class TestHtmlBlock(unittest.TestCase):
616628
def setUp(self):
617629
block_token.add_token(block_token.HtmlBlock)

test/test_span_token.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ def test_attribute(self):
151151

152152
def test_no_children(self):
153153
token = span_token.RawText('some text')
154-
with self.assertRaises(AttributeError):
155-
token.children
154+
self.assertIsNone(token.children)
156155

157156
def test_valid_html_entities(self):
158157
tokens = span_token.tokenize_inner('&nbsp; &#21512;')
@@ -189,6 +188,13 @@ def test_contains(self):
189188
self.assertFalse('foo' in token)
190189

191190

191+
class TestParent(unittest.TestCase):
192+
def test_parent(self):
193+
token, = span_token.tokenize_inner('**some text**')
194+
self.assertIsInstance(token.children[0], span_token.RawText)
195+
self.assertEqual(token.children[0].parent, token)
196+
197+
192198
class TestHtmlSpan(unittest.TestCase):
193199
def setUp(self):
194200
span_token.add_token(span_token.HtmlSpan)

0 commit comments

Comments
 (0)