Code Duplication    Length = 172-173 lines in 2 locations

pythonx/mistune.py 1 location

@@ 504-676 (lines=173) @@
501
        )
502
503
504
class InlineLexer(object):
505
    """Inline level lexer for inline grammars."""
506
    grammar_class = InlineGrammar
507
508
    default_rules = [
509
        'escape', 'inline_html', 'autolink', 'url',
510
        'footnote', 'link', 'reflink', 'nolink',
511
        'double_emphasis', 'emphasis', 'code',
512
        'linebreak', 'strikethrough', 'text',
513
    ]
514
    inline_html_rules = [
515
        'escape', 'inline_html', 'autolink', 'url', 'link', 'reflink',
516
        'nolink', 'double_emphasis', 'emphasis', 'code',
517
        'linebreak', 'strikethrough', 'text',
518
    ]
519
520
    def __init__(self, renderer, rules=None, **kwargs):
521
        self.renderer = renderer
522
        self.links = {}
523
        self.footnotes = {}
524
        self.footnote_index = 0
525
526
        if not rules:
527
            rules = self.grammar_class()
528
529
        kwargs.update(self.renderer.options)
530
        if kwargs.get('hard_wrap'):
531
            rules.hard_wrap()
532
533
        self.rules = rules
534
535
        self._in_link = False
536
        self._in_footnote = False
537
        self._parse_inline_html = kwargs.get('parse_inline_html')
538
539
    def __call__(self, text, rules=None):
540
        return self.output(text, rules)
541
542
    def setup(self, links, footnotes):
543
        self.footnote_index = 0
544
        self.links = links or {}
545
        self.footnotes = footnotes or {}
546
547
    def output(self, text, rules=None):
548
        text = text.rstrip('\n')
549
        if not rules:
550
            rules = list(self.default_rules)
551
552
        if self._in_footnote and 'footnote' in rules:
553
            rules.remove('footnote')
554
555
        output = self.renderer.placeholder()
556
557
        def manipulate(text):
558
            for key in rules:
559
                pattern = getattr(self.rules, key)
560
                m = pattern.match(text)
561
                if not m:
562
                    continue
563
                self.line_match = m
564
                out = getattr(self, 'output_%s' % key)(m)
565
                if out is not None:
566
                    return m, out
567
            return False  # pragma: no cover
568
569
        while text:
570
            ret = manipulate(text)
571
            if ret is not False:
572
                m, out = ret
573
                output += out
574
                text = text[len(m.group(0)):]
575
                continue
576
            if text:  # pragma: no cover
577
                raise RuntimeError('Infinite loop at: %s' % text)
578
579
        return output
580
581
    def output_escape(self, m):
582
        text = m.group(1)
583
        return self.renderer.escape(text)
584
585
    def output_autolink(self, m):
586
        link = m.group(1)
587
        if m.group(2) == '@':
588
            is_email = True
589
        else:
590
            is_email = False
591
        return self.renderer.autolink(link, is_email)
592
593
    def output_url(self, m):
594
        link = m.group(1)
595
        if self._in_link:
596
            return self.renderer.text(link)
597
        return self.renderer.autolink(link, False)
598
599
    def output_inline_html(self, m):
600
        tag = m.group(1)
601
        if self._parse_inline_html and tag in _inline_tags:
602
            text = m.group(3)
603
            if tag == 'a':
604
                self._in_link = True
605
                text = self.output(text, rules=self.inline_html_rules)
606
                self._in_link = False
607
            else:
608
                text = self.output(text, rules=self.inline_html_rules)
609
            extra = m.group(2) or ''
610
            html = '<%s%s>%s</%s>' % (tag, extra, text, tag)
611
        else:
612
            html = m.group(0)
613
        return self.renderer.inline_html(html)
614
615
    def output_footnote(self, m):
616
        key = _keyify(m.group(1))
617
        if key not in self.footnotes:
618
            return None
619
        if self.footnotes[key]:
620
            return None
621
        self.footnote_index += 1
622
        self.footnotes[key] = self.footnote_index
623
        return self.renderer.footnote_ref(key, self.footnote_index)
624
625
    def output_link(self, m):
626
        return self._process_link(m, m.group(3), m.group(4))
627
628
    def output_reflink(self, m):
629
        key = _keyify(m.group(2) or m.group(1))
630
        if key not in self.links:
631
            return None
632
        ret = self.links[key]
633
        return self._process_link(m, ret['link'], ret['title'])
634
635
    def output_nolink(self, m):
636
        key = _keyify(m.group(1))
637
        if key not in self.links:
638
            return None
639
        ret = self.links[key]
640
        return self._process_link(m, ret['link'], ret['title'])
641
642
    def _process_link(self, m, link, title=None):
643
        line = m.group(0)
644
        text = m.group(1)
645
        if line[0] == '!':
646
            return self.renderer.image(link, title, text)
647
648
        self._in_link = True
649
        text = self.output(text)
650
        self._in_link = False
651
        return self.renderer.link(link, title, text)
652
653
    def output_double_emphasis(self, m):
654
        text = m.group(2) or m.group(1)
655
        text = self.output(text)
656
        return self.renderer.double_emphasis(text)
657
658
    def output_emphasis(self, m):
659
        text = m.group(2) or m.group(1)
660
        text = self.output(text)
661
        return self.renderer.emphasis(text)
662
663
    def output_code(self, m):
664
        text = m.group(2)
665
        return self.renderer.codespan(text)
666
667
    def output_linebreak(self, m):
668
        return self.renderer.linebreak()
669
670
    def output_strikethrough(self, m):
671
        text = self.output(m.group(1))
672
        return self.renderer.strikethrough(text)
673
674
    def output_text(self, m):
675
        text = m.group(0)
676
        return self.renderer.text(text)
677
678
679
class Renderer(object):

pythonx/tests/markdown_parser.py 1 location

@@ 482-653 (lines=172) @@
479
        )
480
481
482
class InlineLexer(object):
483
    """Inline level lexer for inline grammars."""
484
    grammar_class = InlineGrammar
485
486
    default_rules = [
487
        'escape', 'inline_html', 'autolink', 'url',
488
        'footnote', 'link', 'reflink', 'nolink',
489
        'double_emphasis', 'emphasis', 'code',
490
        'linebreak', 'strikethrough', 'text',
491
    ]
492
    inline_html_rules = [
493
        'escape', 'autolink', 'url', 'link', 'reflink',
494
        'nolink', 'double_emphasis', 'emphasis', 'code',
495
        'linebreak', 'strikethrough', 'text',
496
    ]
497
498
    def __init__(self, renderer, rules=None, **kwargs):
499
        self.renderer = renderer
500
        self.links = {}
501
        self.footnotes = {}
502
        self.footnote_index = 0
503
504
        if not rules:
505
            rules = self.grammar_class()
506
507
        self.rules = rules
508
509
        self._in_link = False
510
        self._in_footnote = False
511
512
        kwargs.update(self.renderer.options)
513
        self._parse_inline_html = kwargs.get('parse_inline_html')
514
515
    def __call__(self, text, rules=None):
516
        return self.output(text, rules)
517
518
    def setup(self, links, footnotes):
519
        self.footnote_index = 0
520
        self.links = links or {}
521
        self.footnotes = footnotes or {}
522
523
    def output(self, text, rules=None):
524
        text = text.rstrip('\n')
525
        if not rules:
526
            rules = list(self.default_rules)
527
528
        if self._in_footnote and 'footnote' in rules:
529
            rules.remove('footnote')
530
531
        output = self.renderer.placeholder()
532
533
        def manipulate(text):
534
            for key in rules:
535
                pattern = getattr(self.rules, key)
536
                m = pattern.match(text)
537
                if not m:
538
                    continue
539
                self.line_match = m
540
                out = getattr(self, 'output_%s' % key)(m)
541
                if out is not None:
542
                    return m, out
543
            return False  # pragma: no cover
544
545
        self.line_started = False
546
        while text:
547
            ret = manipulate(text)
548
            self.line_started = True
549
            if ret is not False:
550
                m, out = ret
551
                output += out
552
                text = text[len(m.group(0)):]
553
                continue
554
            if text:  # pragma: no cover
555
                raise RuntimeError('Infinite loop at: %s' % text)
556
557
        return output
558
559
    def output_escape(self, m):
560
        return m.group(1)
561
562
    def output_autolink(self, m):
563
        link = m.group(1)
564
        if m.group(2) == '@':
565
            is_email = True
566
        else:
567
            is_email = False
568
        return self.renderer.autolink(link, is_email)
569
570
    def output_url(self, m):
571
        link = m.group(1)
572
        if self._in_link:
573
            return self.renderer.text(link)
574
        return self.renderer.autolink(link, False)
575
576
    def output_inline_html(self, m):
577
        tag = m.group(1)
578
        if self._parse_inline_html and tag in _inline_tags:
579
            text = m.group(3)
580
            if tag == 'a':
581
                self._in_link = True
582
                text = self.output(text, rules=self.inline_html_rules)
583
                self._in_link = False
584
            else:
585
                text = self.output(text, rules=self.inline_html_rules)
586
            extra = m.group(2) or ''
587
            html = '<%s%s>%s</%s>' % (tag, extra, text, tag)
588
        else:
589
            html = m.group(0)
590
        return self.renderer.inline_html(html)
591
592
    def output_footnote(self, m):
593
        key = _keyify(m.group(1))
594
        if key not in self.footnotes:
595
            return None
596
        if self.footnotes[key]:
597
            return None
598
        self.footnote_index += 1
599
        self.footnotes[key] = self.footnote_index
600
        return self.renderer.footnote_ref(key, self.footnote_index)
601
602
    def output_link(self, m):
603
        return self._process_link(m, m.group(3), m.group(4))
604
605
    def output_reflink(self, m):
606
        key = _keyify(m.group(2) or m.group(1))
607
        if key not in self.links:
608
            return None
609
        ret = self.links[key]
610
        return self._process_link(m, ret['link'], ret['title'])
611
612
    def output_nolink(self, m):
613
        key = _keyify(m.group(1))
614
        if key not in self.links:
615
            return None
616
        ret = self.links[key]
617
        return self._process_link(m, ret['link'], ret['title'])
618
619
    def _process_link(self, m, link, title=None):
620
        line = m.group(0)
621
        text = m.group(1)
622
        if line[0] == '!':
623
            return self.renderer.image(link, title, text)
624
625
        self._in_link = True
626
        text = self.output(text)
627
        self._in_link = False
628
        return self.renderer.link(link, title, text)
629
630
    def output_double_emphasis(self, m):
631
        text = m.group(2) or m.group(1)
632
        text = self.output(text)
633
        return self.renderer.double_emphasis(text)
634
635
    def output_emphasis(self, m):
636
        text = m.group(2) or m.group(1)
637
        text = self.output(text)
638
        return self.renderer.emphasis(text)
639
640
    def output_code(self, m):
641
        text = m.group(2)
642
        return self.renderer.codespan(text)
643
644
    def output_linebreak(self, m):
645
        return self.renderer.linebreak()
646
647
    def output_strikethrough(self, m):
648
        text = self.output(m.group(1))
649
        return self.renderer.strikethrough(text)
650
651
    def output_text(self, m):
652
        text = m.group(0)
653
        return self.renderer.text(text)
654
655
656
class Renderer(object):