From 00e975f32f8147fbbe379b524a52195686885271 Mon Sep 17 00:00:00 2001 From: Vallentin Date: Thu, 15 Nov 2018 14:31:28 +0100 Subject: [PATCH 1/3] Resolves #71 --- mistletoe/block_token.py | 18 ++++++++++++++++++ mistletoe/span_token.py | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/mistletoe/block_token.py b/mistletoe/block_token.py index 7eeb3f1f..8f255442 100644 --- a/mistletoe/block_token.py +++ b/mistletoe/block_token.py @@ -121,6 +121,8 @@ class BlockToken(object): """ def __init__(self, lines, tokenize_func): self.children = tokenize_func(lines) + for child in self.children: + child.parent = self def __contains__(self, text): return any(text in child for child in self.children) @@ -148,6 +150,8 @@ def __init__(self, lines): _root_node = self span_token._root_node = self self.children = tokenize(lines) + for child in self.children: + child.parent = self span_token._root_node = None _root_node = None @@ -211,6 +215,8 @@ class Quote(BlockToken): def __init__(self, parse_buffer): # span-level tokenizing happens here. self.children = tokenizer.make_tokens(parse_buffer) + for child in self.children: + child.parent = self @staticmethod def start(line): @@ -362,6 +368,8 @@ class BlockCode(BlockToken): def __init__(self, lines): self.language = '' self.children = (span_token.RawText(''.join(lines).strip('\n')+'\n'),) + for child in self.children: + child.parent = self @staticmethod def start(line): @@ -410,6 +418,8 @@ def __init__(self, match): lines, open_info = match self.language = span_token.EscapeSequence.strip(open_info[2]) self.children = (span_token.RawText(''.join(lines)),) + for child in self.children: + child.parent = self @classmethod def start(cls, line): @@ -451,6 +461,8 @@ class List(BlockToken): pattern = re.compile(r' {0,3}(?:\d{0,9}[.)]|[+\-*])(?:[ \t]*$|[ \t]+)') def __init__(self, matches): self.children = [ListItem(*match) for match in matches] + for child in self.children: + child.parent = self self.loose = any(item.loose for item in self.children) leader = self.children[0].leader self.start = None @@ -497,6 +509,8 @@ def __init__(self, parse_buffer, prepend, leader): self.leader = leader self.prepend = prepend self.children = tokenizer.make_tokens(parse_buffer) + for child in self.children: + child.parent = self self.loose = parse_buffer.loose @staticmethod @@ -622,6 +636,8 @@ def __init__(self, lines): else: self.column_align = [None] self.children = [TableRow(line) for line in lines] + for child in self.children: + child.parent = self @staticmethod def split_delimiter(delimiter): @@ -675,6 +691,8 @@ def __init__(self, line, row_align=None): cells = filter(None, line.strip().split('|')) self.children = [TableCell(cell.strip(), align) for cell, align in zip_longest(cells, self.row_align)] + for child in self.children: + child.parent = self class TableCell(BlockToken): diff --git a/mistletoe/span_token.py b/mistletoe/span_token.py index a5b33c24..42d7419d 100644 --- a/mistletoe/span_token.py +++ b/mistletoe/span_token.py @@ -115,6 +115,8 @@ class InlineCode(SpanToken): def __init__(self, match): content = match.group(self.parse_group) self.children = (RawText(' '.join(re.split('[ \n]+', content.strip()))),) + for child in self.children: + child.parent = self @classmethod def find(cls, string): @@ -169,6 +171,8 @@ class AutoLink(SpanToken): def __init__(self, match): content = match.group(self.parse_group) self.children = (RawText(content),) + for child in self.children: + child.parent = self self.target = content self.mailto = '@' in self.target and 'mailto' not in self.target.casefold() @@ -186,6 +190,8 @@ class EscapeSequence(SpanToken): def __init__(self, match): self.children = (RawText(match.group(self.parse_group)),) + for child in self.children: + child.parent = self @classmethod def strip(cls, string): From dd2d2aa95e9177133d88206a31dcff0a574b6ad0 Mon Sep 17 00:00:00 2001 From: Vallentin Date: Thu, 15 Nov 2018 15:17:03 +0100 Subject: [PATCH 2/3] Added missing cases --- mistletoe/block_token.py | 1 + mistletoe/span_tokenizer.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/mistletoe/block_token.py b/mistletoe/block_token.py index 8f255442..11f0735b 100644 --- a/mistletoe/block_token.py +++ b/mistletoe/block_token.py @@ -633,6 +633,7 @@ def __init__(self, lines): for column in self.split_delimiter(lines[1])] self.header = TableRow(lines[0], self.column_align) self.children = [TableRow(line, self.column_align) for line in lines[2:]] + self.header.parent = self else: self.column_align = [None] self.children = [TableRow(line) for line in lines] diff --git a/mistletoe/span_tokenizer.py b/mistletoe/span_tokenizer.py index 71dc9efe..b9699959 100644 --- a/mistletoe/span_tokenizer.py +++ b/mistletoe/span_tokenizer.py @@ -100,6 +100,8 @@ def make(self): children = make_tokens(self.children, self.parse_start, self.parse_end, self.string, self.fallback_token) token = self.cls(self.match) token.children = children + for child in token.children: + child.parent = token return token def __lt__(self, other): From b13d7387f382922d1fa14be49039f8dc210a6a14 Mon Sep 17 00:00:00 2001 From: Vallentin Date: Thu, 15 Nov 2018 15:17:17 +0100 Subject: [PATCH 3/3] Updated test cases --- mistletoe/ast_renderer.py | 2 ++ test/test_ast_renderer.py | 27 ++++++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/mistletoe/ast_renderer.py b/mistletoe/ast_renderer.py index c09cc7f6..7f6a7c7c 100644 --- a/mistletoe/ast_renderer.py +++ b/mistletoe/ast_renderer.py @@ -38,4 +38,6 @@ def get_ast(token): node['header'] = get_ast(node['header']) if 'children' in node: node['children'] = [get_ast(child) for child in node['children']] + if 'parent' in node: + node['parent'] = node['parent'].__class__.__name__ return node diff --git a/test/test_ast_renderer.py b/test/test_ast_renderer.py index f9bd549e..d781787e 100644 --- a/test/test_ast_renderer.py +++ b/test/test_ast_renderer.py @@ -13,21 +13,27 @@ def test(self): 'level': 1, 'children': [{ 'type': 'RawText', - 'content': 'heading 1' - }] + 'content': 'heading 1', + 'parent': 'Heading' + }], + 'parent': 'Document' }, { 'type': 'Paragraph', 'children': [{ 'type': 'RawText', - 'content': 'hello' + 'content': 'hello', + 'parent': 'Paragraph' }, { 'type': 'LineBreak', 'soft': True, - 'content': '' + 'content': '', + 'parent': 'Paragraph' }, { 'type': 'RawText', - 'content': 'world' - }] + 'content': 'world', + 'parent': 'Paragraph' + }], + 'parent': 'Document' }]} self.assertEqual(output, target) @@ -46,9 +52,12 @@ def test_footnotes(self): 'title': '', 'children': [{ 'type': 'RawText', - 'content': 'bar' - }] - }] + 'content': 'bar', + 'parent': 'Link' + }], + 'parent': 'Paragraph' + }], + 'parent': 'Document' }]} output = ast_renderer.get_ast(d) self.assertEqual(output, target)