diff options
| author | rsiddharth <s@ricketyspace.net> | 2018-01-02 00:51:19 +0000 | 
|---|---|---|
| committer | rsiddharth <s@ricketyspace.net> | 2018-01-02 00:51:19 +0000 | 
| commit | 673c0ad9bbce77a121353757a93c18c808a2655e (patch) | |
| tree | 06552e72205c3667a4622b7ab6fe1e84ec44d42d | |
| parent | ad8fa809c55e2bf2a6bf2e977f6683e90ad7200d (diff) | |
md_tw.py: Add `TWBlockLexer.parse_def_footnotes`.
* md_tw.py
(TWBlockLexer.parse_def_footnotes): New method.
* tests/test_md_tw.py
(TestTWBlockLexer.test_parse_def_footnotes): New test.
* tests/data/blexer-footnotes.md: New file.
| -rw-r--r-- | md_tw.py | 42 | ||||
| -rw-r--r-- | tests/data/blexer-footnotes.md | 24 | ||||
| -rw-r--r-- | tests/test_md_tw.py | 97 | 
3 files changed, 163 insertions, 0 deletions
| @@ -159,6 +159,48 @@ class TWBlockLexer(mistune.BlockLexer):              'text': m.group(0)              }) +    def parse_def_footnotes(self, m): +        key = self._keyify(m.group(1)) +        if key in self.def_footnotes: +            # footnote is already defined +            return + +        self.def_footnotes[key] = 0 + +        text = m.group(2) +        multiline = False +        spaces = 0 +        if '\n' in text: +            multiline = True +            lines = text.split('\n') +            whitespace = None +            for line in lines[1:]: +                space = len(line) - len(line.lstrip()) +                if space and (not whitespace or space < whitespace): +                    whitespace = space +            newlines = [lines[0]] +            for line in lines[1:]: +                newlines.append(line[whitespace:]) +            text = '\n'.join(newlines) + +            if whitespace: +                spaces = whitespace + +        self.tokens.append({ +            'type': 'footnote_start', +            'key': key, +            'multiline': multiline, +            'spaces': spaces +        }) + +        self.parse(text, self.footnote_rules) + +        self.tokens.append({ +            'type': 'footnote_end', +            'key': key, +            'spaces': spaces +        }) +  class TWInlineLexer(mistune.InlineLexer):      """Text Wrap Inline level lexer for inline gramars.""" diff --git a/tests/data/blexer-footnotes.md b/tests/data/blexer-footnotes.md new file mode 100644 index 0000000..0bd38b5 --- /dev/null +++ b/tests/data/blexer-footnotes.md @@ -0,0 +1,24 @@ +This phrase has a single line footnote[^foot1]. + +[^foot1]: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + +This other phrase has a multiline footnote[^foot2]. + +[^foot2]: Vestibulum enim wisi, viverra nec, fringilla in, laoreet +    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet +    velit. + +This phrase has a blockquote in its footnote[^foot3]. + +[^foot3]: A footnote with blockquotes + +   Start of block quote in footnote: + +   > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, +   > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. +   > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. +   >  +   > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse +   > id sem consectetuer libero luctus adipiscing. + +   End of block quote in foot note. diff --git a/tests/test_md_tw.py b/tests/test_md_tw.py index 467caaf..f821f0d 100644 --- a/tests/test_md_tw.py +++ b/tests/test_md_tw.py @@ -480,6 +480,103 @@ class TestTWBlockLexer(object):              ]          self._validate(tokens, 'def_links', expected_dls) +    def test_parse_def_footnotes(self): +        tokens = self._parse('blexer-footnotes.md') + +        def process(tokens): +            token = tokens.pop(0) +            while token: +                type_ = token['type'] + +                expected_token = None +                if type_ in expected: +                    expected_token = expected[type_].pop(0) + +                validate(token, expected_token) + +                if type_ == 'footnote_end': +                    break +                else: +                    token = tokens.pop(0) + +            return tokens + +        def validate(token, expected_token=None): +            type_ = token['type'] + +            if type_ == 'footnote_start': +                assert 'multiline' in token +                assert 'spaces' in token +            elif type_ == 'footnote_end': +                assert 'spaces' in token + +            if not expected_token: +                return + +            if 'text' in token: +                assert_equal(token['text'], expected_token['text']) +            if 'spaces' in token: +                assert_equal(token['spaces'], expected_token['spaces']) + +            return + +        # test footnote 1 +        expected = { +            'footnote_start': [ +                {'multiline': False, 'spaces': 0}, +                ], +            'paragraph': [ +                {'text': 'This phrase has a single line footnote[^foot1].'}, +                {'text': 'Lorem ipsum dolor sit amet, consectetuer' +                     ' adipiscing elit.'}, +                ], +            'footnote_end': [ +                {'spaces': 0} +                ] +            } +        tokens = process(tokens) + +        # test footnote 2 +        expected = { +            'footnote_start': [ +                {'multiline': True, 'spaces': 4}, +                ], +            'paragraph': [ +                {'text': 'This other phrase has a multiline footnote[^foot2].'}, +                {'text': 'Vestibulum enim wisi, viverra nec, fringilla in, ' +                     'laoreet\nvitae, risus. Donec sit amet nisl. Aliquam ' +                'semper ipsum sit amet\nvelit.'}, +                ], +            'footnote_end': [ +                {'spaces': 4} +                ] +            } +        tokens = process(tokens) + +        # test footnote 3 +        expected = { +            'footnote_start': [ +                {'multiline': True, 'spaces': 3}, +                ], +            'paragraph': [ +                {'text': 'This phrase has a blockquote in its footnote[^foot3].'}, +                {'text': 'A footnote with blockquotes'}, +                {'text': 'Start of block quote in footnote:'}, +                {'text': 'This is a blockquote with two paragraphs. Lorem' +                     ' ipsum dolor sit amet,\nconsectetuer adipiscing elit.' +                ' Aliquam hendrerit mi posuere lectus.\nVestibulum enim wisi,' +                ' viverra nec, fringilla in, laoreet vitae, risus.'}, +                {'text': 'Donec sit amet nisl. Aliquam semper ipsum sit amet ' +                     'velit. Suspendisse\nid sem consectetuer libero luctus ' +                'adipiscing.'}, +                {'text': 'End of block quote in foot note.'}, +                ], +            'footnote_end': [ +                {'spaces': 3} +                ] +            } +        tokens = process(tokens) +      def teardown(self):          pass | 
