From 1a9abac07e262c82e3790c3a848216bfc89dd4df Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sat, 7 Mar 2020 04:34:44 +0000 Subject: [PATCH] Add `arguments` field for `CodeFence` --- mistletoe/base_elements.py | 3 +- mistletoe/block_tokens.py | 28 +++++++++++----- test/test_block_token.py | 4 +-- .../test_json_renderer/test_basic.yml | 33 ++++++++++--------- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/mistletoe/base_elements.py b/mistletoe/base_elements.py index ceb00ac..38a8390 100644 --- a/mistletoe/base_elements.py +++ b/mistletoe/base_elements.py @@ -16,6 +16,7 @@ def __getattr__(self, name): return None if name == "content": return "" + raise AttributeError(name) @property def name(self) -> str: @@ -71,7 +72,7 @@ def walk( if tokens is None or child.name in tokens: yield WalkItem(child, parent, current_depth) new_children.extend([(child, c) for c in child.children or []]) - if self.child == "Table" and getattr(child, "header", None) is not None: + if child.name == "Table" and getattr(child, "header", None) is not None: # table headers row new_children.append((child, child.header)) diff --git a/mistletoe/block_tokens.py b/mistletoe/block_tokens.py index 8d979dc..59fbf35 100644 --- a/mistletoe/block_tokens.py +++ b/mistletoe/block_tokens.py @@ -119,6 +119,10 @@ class FrontMatter(BlockToken): metadata={"doc": "Line position in source text (start, end)"} ) + @classmethod + def start(cls, line: str) -> bool: + return False + @classmethod def read(cls, lines): assert lines and lines[0].startswith("---") @@ -393,7 +397,7 @@ def start(line): @classmethod def read(cls, lines): - start_line = lines.lineno + 1 + start_line = lines.lineno line_buffer = [] for line in lines: if line.strip() == "": @@ -406,9 +410,7 @@ def read(cls, lines): children = (span_tokens.RawText("".join(line_buffer).strip("\n") + "\n"),) - return cls( - children=children, language="", position=(start_line, lines.lineno - 1) - ) + return cls(children=children, language="", position=(start_line, lines.lineno)) @staticmethod def strip(string): @@ -438,11 +440,14 @@ class CodeFence(BlockToken): language: str = attr.ib( default="", metadata={"doc": "The code language (for sytax highlighting)"} ) + arguments: str = attr.ib( + default="", metadata={"doc": "Any string occuring after the language"} + ) position: Tuple[int, int] = attr.ib( metadata={"doc": "Line position in source text (start, end)"} ) - pattern = re.compile(r"( {0,3})((?:`|~){3,}) *(\S*)") + pattern = re.compile(r"^( {0,3})((?:`|~){3,}) *([^`~\s]*) *([^`~]*)$") _open_info = None @classmethod @@ -450,10 +455,10 @@ def start(cls, line): match_obj = cls.pattern.match(line) if not match_obj: return False - prepend, leader, lang = match_obj.groups() + prepend, leader, lang, arguments = match_obj.groups() if leader[0] in lang or leader[0] in line[match_obj.end() :]: return False - cls._open_info = len(prepend), leader, lang + cls._open_info = len(prepend), leader, lang, arguments return True @classmethod @@ -475,10 +480,15 @@ def read(cls, lines): line_buffer.append(stripped_line) language = span_tokens.EscapeSequence.strip(cls._open_info[2]) + arg_lines = cls._open_info[3].splitlines() or [""] + arguments = span_tokens.EscapeSequence.strip(arg_lines[0]) children = (span_tokens.RawText("".join(line_buffer)),) return cls( - children=children, language=language, position=(start_line, lines.lineno) + children=children, + language=language, + arguments=arguments, + position=(start_line, lines.lineno), ) @@ -745,7 +755,7 @@ def start(line): @classmethod def read(cls, lines): - start_line = lines.lineno + start_line = lines.lineno + 1 lines.anchor() line_buffer = [next(lines)] while lines.peek() is not None and "|" in lines.peek(): diff --git a/test/test_block_token.py b/test/test_block_token.py index 27899d3..6a42d1e 100644 --- a/test/test_block_token.py +++ b/test/test_block_token.py @@ -236,7 +236,7 @@ def test_match(self): token.children calls = [ call.read(line, [None, None, None], lineno=l) - for line, l in zip(lines[:1] + lines[2:], [0, 2, 3]) + for line, l in zip(lines[:1] + lines[2:], [1, 3, 4]) ] mock.assert_has_calls(calls) @@ -250,7 +250,7 @@ def test_easy_table(self): token.children calls = [ call.read(line, [1, None], lineno=l) - for line, l in zip(lines[:1] + lines[2:], [0, 2]) + for line, l in zip(lines[:1] + lines[2:], [1, 3]) ] mock.assert_has_calls(calls) diff --git a/test/test_renderers/test_json_renderer/test_basic.yml b/test/test_renderers/test_json_renderer/test_basic.yml index ba9e711..4372155 100644 --- a/test/test_renderers/test_json_renderer/test_basic.yml +++ b/test/test_renderers/test_json_renderer/test_basic.yml @@ -110,7 +110,8 @@ children: - 21 - 21 type: LinkDefinition -- children: +- arguments: '' + children: - content: 'code = 1 ' @@ -129,8 +130,8 @@ children: type: RawText language: '' position: - - 27 - - 28 + - 26 + - 29 type: BlockCode - position: - 30 @@ -143,20 +144,20 @@ children: - content: '1' type: RawText position: - - 33 - - 33 + - 34 + - 34 type: TableCell - align: 1 children: - content: '2' type: RawText position: - - 33 - - 33 + - 34 + - 34 type: TableCell position: - - 33 - - 33 + - 34 + - 34 row_align: - null - 1 @@ -171,26 +172,26 @@ children: - content: a type: RawText position: - - 31 - - 31 + - 32 + - 32 type: TableCell - align: 1 children: - content: b type: RawText position: - - 31 - - 31 + - 32 + - 32 type: TableCell position: - - 31 - - 31 + - 32 + - 32 row_align: - null - 1 type: TableRow position: - - 31 + - 32 - 34 type: Table front_matter: