def read_table_body(self, reader: LineReader,
                        aligns: List[str]) -> List[nodes.row]:
        try:
            rows = []
            while True:
                if self.parser.is_interrupted(reader):
                    break
                else:
                    row = self.parse_row(reader.readline())
                    if len(row) == 1 and row[0] == '':
                        reader.step(-1)
                        break

                    entries = []
                    for i, align in enumerate(aligns):
                        try:
                            text = row[i].strip()
                        except IndexError:
                            text = ''

                        entry = nodes.entry()
                        if text:
                            entry += nodes.paragraph(text, text)
                        entry.source, entry.line = reader.get_source_and_line()
                        if align:
                            entry['align'] = align
                        entries.append(entry)
                    rows.append(nodes.row('', *entries))
        except IOError:
            pass

        return rows
Exemple #2
0
    def run(self, reader: LineReader, document: Element) -> bool:
        location = reader.get_source_and_line(incr=1)

        lines = []
        underline = None
        try:
            for line in reader:
                lines.append(line.lstrip())
                if self.pattern.match(reader.next_line):
                    underline = reader.readline()
                    break
                elif self.parser.is_interrupted(reader):
                    break
        except IOError:
            pass

        if underline is None:
            # underline of heading not found. backtracking.
            reader.step(-len(lines))
            return False
        else:
            text = ''.join(lines).strip()
            depth = self.section_level[underline.strip()[0]]
            section = nodes.section(depth=depth)
            section += nodes.title(text, text)
            location.set_source_info(section[0])
            get_root_document(document).note_implicit_target(section)

            document += section
            return True
Exemple #3
0
def test_WalledBlockReader():
    text = ("===wall\n"
            "Lorem ipsum dolor sit amet, \n"
            "consectetur adipiscing elit, \n"
            "\n"
            "=====nested_wall\n"
            "    sed do eiusmod tempor incididunt \n"
            "    ut labore et dolore magna aliqua.\n"
            "===\n"
            "\n"
            "===\n"
            "Ut enim ad minim veniam, quis nostrud")

    reader = LineReader(text.splitlines(True), source='dummy.md')
    assert reader.readline() == "===wall\n"

    walled_block_reader = WalledBlockReader(reader)
    assert walled_block_reader.eof() is False
    assert walled_block_reader.get_source_and_line() == ('dummy.md', 1)

    # read first line
    assert walled_block_reader.readline() == "Lorem ipsum dolor sit amet, \n"
    assert walled_block_reader.current_line == "Lorem ipsum dolor sit amet, \n"
    assert walled_block_reader.fetch() == "Lorem ipsum dolor sit amet, \n"
    assert walled_block_reader.get_source_and_line() == ('dummy.md', 2)

    # read consequence lines
    assert walled_block_reader.readline() == "consectetur adipiscing elit, \n"
    assert walled_block_reader.readline() == "\n"
    assert walled_block_reader.readline() == "=====nested_wall\n"

    # nested WalledBlockReader
    nested_wbreader = WalledBlockReader(walled_block_reader)
    assert nested_wbreader.readline(
    ) == "    sed do eiusmod tempor incididunt \n"
    assert nested_wbreader.readline(
    ) == "    ut labore et dolore magna aliqua.\n"

    # reach the end of the nested block
    assert nested_wbreader.eof() is True
    try:
        nested_wbreader.readline()
        assert False
    except IOError:
        pass

    # read consequence lines by parent reader
    nested_wbreader.consume_endmarker()
    assert walled_block_reader.readline() == "\n"

    # reach the end of the parent block
    assert walled_block_reader.eof() is True
    try:
        walled_block_reader.readline()
        assert False
    except IOError:
        pass

    walled_block_reader.consume_endmarker()
    assert reader.readline() == "Ut enim ad minim veniam, quis nostrud"
Exemple #4
0
def test_FencedCodeBlockReader():
    text = ("Lorem ipsum dolor sit amet, \n"
            "   consectetur adipiscing elit, \n"
            "    sed do eiusmod tempor incididunt \n"
            "    ```\n"
            "        ut labore et dolore magna aliqua.\n"
            "   ```\n"
            "Ut enim ad minim veniam, quis nostrud")

    reader = LineReader(text.splitlines(True), source='dummy.md')
    codeblock_reader = FencedCodeBlockReader(reader, 0, '```')
    assert codeblock_reader.readline() == "Lorem ipsum dolor sit amet, \n"
    assert codeblock_reader.readline() == "   consectetur adipiscing elit, \n"
    assert codeblock_reader.readline(
    ) == "    sed do eiusmod tempor incididunt \n"
    assert codeblock_reader.readline() == "    ```\n"
    assert codeblock_reader.readline(
    ) == "        ut labore et dolore magna aliqua.\n"
    assert codeblock_reader.eof()

    reader = LineReader(text.splitlines(True), source='dummy.md')
    codeblock_reader = FencedCodeBlockReader(reader, 3, '```')
    assert codeblock_reader.readline() == "Lorem ipsum dolor sit amet, \n"
    assert codeblock_reader.readline() == "consectetur adipiscing elit, \n"
    assert codeblock_reader.readline(
    ) == " sed do eiusmod tempor incididunt \n"
    assert codeblock_reader.readline() == " ```\n"
    assert codeblock_reader.readline(
    ) == "     ut labore et dolore magna aliqua.\n"
    assert codeblock_reader.eof()
Exemple #5
0
def test_LazyLineReader():
    reader = LineReader(quoted_text.splitlines(True), source='dummy.md')
    lazy_reader = LazyLineReader(BlockQuoteReader(reader))
    assert lazy_reader.eof() is False
    assert lazy_reader.get_source_and_line() == ('dummy.md', 0)

    # read first line
    assert lazy_reader.readline() == "Lorem ipsum dolor sit amet, \n"
    assert lazy_reader.current_line == "Lorem ipsum dolor sit amet, \n"
    assert lazy_reader.fetch() == "Lorem ipsum dolor sit amet, \n"
    assert lazy_reader.get_source_and_line() == ('dummy.md', 1)

    # read second line
    assert lazy_reader.readline() == " consectetur adipiscing elit, \n"

    # empty line causes IOError
    try:
        lazy_reader.readline()
        assert False
    except IOError:
        pass

    assert reader.readline() == '\n'
    assert reader.readline() == "sed do eiusmod tempor incididunt \n"
    assert reader.readline() == "ut labore et dolore magna aliqua."
 def consume_blanklines(self, reader: LineReader, list_item: nodes.list_item) -> None:
     """Skip over blank lines at beginning of the list item."""
     try:
         while reader.next_line.strip() == '':
             reader.step()
             list_item += addnodes.blankline()
     except IOError:
         pass
Exemple #7
0
    def run(self, reader: LineReader, document: Element) -> bool:
        marker, title = self.pattern.match(reader.readline()).groups()
        title = self.trailing_hashes.sub('', title).strip()
        title_node = nodes.title(title, title)
        title_node.source, title_node.line = reader.get_source_and_line()
        section = nodes.section('', title_node, depth=len(marker))
        get_root_document(document).note_implicit_target(section)

        document += section
        return True
    def run(self, reader: LineReader, document: Element) -> bool:
        line = reader.readline()
        klass = line.strip().strip('=').strip()
        container = nodes.container(classes=[klass])
        container.source, container.line = reader.get_source_and_line()
        document += container

        walled_block_reader = WalledBlockReader(reader)
        self.parser.parse(walled_block_reader, container)
        walled_block_reader.consume_endmarker()
        return True
Exemple #9
0
 def run(self, reader: LineReader, document: Element) -> bool:
     lineno = reader.lineno
     try:
         multiline_reader = MultiLineReader(reader)
         target = self.parse_linkref_definition(multiline_reader, document)
         if target:
             document += target
             return True
         else:
             reader.step(lineno - reader.lineno)  # rollback
             return False
     except IOError:
         reader.step(lineno - reader.lineno)  # rollback
         return False
Exemple #10
0
def test_nested_line_readers():
    text = ("> 1. > Blockquote\n" "continued here.\n")
    reader = LineReader(text.splitlines(True))
    reader = BlockQuoteReader(reader)
    reader = ListItemReader(reader, r'1\.', BlockProcessor(None))
    reader = BlockQuoteReader(reader)
    reader = LazyLineReader(reader)
    assert reader.readline() == 'Blockquote\n'
    assert reader.eof() is False
    assert reader.next_line == 'continued here.\n'
    assert reader.readline() == 'continued here.\n'
Exemple #11
0
    def run(self, reader: LineReader, document: Element) -> bool:
        location = reader.get_source_and_line(incr=1)

        indent, marker, info = self.pattern.match(reader.readline()).groups()
        code = ''.join(FencedCodeBlockReader(reader, len(indent), marker))

        literal_block = nodes.literal_block(code, code, classes=['code'])
        location.set_source_info(literal_block)
        if info.strip():
            language = unescape(entitytrans._unescape(info.split()[0].strip()))
            literal_block['language'] = language
            literal_block['classes'].append('language-%s' %
                                            language.split()[0])
        document += literal_block

        return True
Exemple #12
0
def test_ListItemReader():
    text = ("- Lorem ipsum dolor sit amet, \n"
            "- consectetur adipiscing elit, \n"
            "\n"
            "  sed do eiusmod tempor incididunt \n"
            "ut labore et dolore magna aliqua.")
    reader = LineReader(text.splitlines(True))
    list_reader = ListItemReader(reader, '-', BlockProcessor(None))
    assert list_reader.readline() == "Lorem ipsum dolor sit amet, \n"

    # reached next item
    try:
        list_reader.readline()
        assert False
    except IOError:
        pass

    list_reader = ListItemReader(reader, '-', BlockProcessor(None))
    assert list_reader.readline() == "consectetur adipiscing elit, \n"
    assert list_reader.readline() == "\n"
    assert list_reader.readline() == "sed do eiusmod tempor incididunt \n"

    # reached the end of list
    try:
        list_reader.readline()
        assert False
    except IOError:
        pass

    # can read the next line with laziness
    assert list_reader.readline(
        lazy=True) == "ut labore et dolore magna aliqua."
Exemple #13
0
 def parse(self, reader: LineReader, document: Element) -> None:
     """Parses a text and build document."""
     while not reader.eof():
         for _, processor in self.processors:
             if processor.match(reader):
                 if processor.run(reader, document):
                     break
         else:
             raise RuntimeError('Failed to parse')
Exemple #14
0
    def run(self, reader: LineReader, document: Element) -> bool:
        location = reader.get_source_and_line(incr=1)

        code = ''.join(IndentedCodeBlockReader(reader))
        code = re.sub('^\n+', '', code)  # strip blank lines
        code = re.sub('\n+$', '\n', code)  # strip blank lines
        document += nodes.literal_block(code, code, classes=['code'])
        location.set_source_info(document[-1])
        return True
Exemple #15
0
def test_IndentedCodeBlockReader():
    text = ("    Lorem ipsum dolor sit amet, \n"
            "       consectetur adipiscing elit, \n"
            "\n"
            "  sed do eiusmod tempor incididunt \n")

    reader = LineReader(text.splitlines(True), source='dummy.md')
    codeblock_reader = IndentedCodeBlockReader(reader)
    assert codeblock_reader.readline() == "Lorem ipsum dolor sit amet, \n"
    assert codeblock_reader.readline() == "   consectetur adipiscing elit, \n"
    assert codeblock_reader.readline() == "\n"
    assert codeblock_reader.eof()
Exemple #16
0
    def run(self, reader: LineReader, document: Element) -> bool:
        location = reader.get_source_and_line(incr=1)
        content = ''
        for line in reader:
            content += line
            if self.closing_pattern.search(line):
                break

        content = re.sub('\n+$', '\n', content)  # strip multiple CRs on tail
        document += nodes.raw(content, content, format='html')
        location.set_source_info(document[-1])
        return True
Exemple #17
0
def test_BlockQuoteReader():
    reader = LineReader(quoted_text.splitlines(True), source='dummy.md')
    quoted_reader = BlockQuoteReader(reader)
    assert quoted_reader.eof() is False
    assert quoted_reader.get_source_and_line() == ('dummy.md', 0)

    # read first line
    assert quoted_reader.readline() == "Lorem ipsum dolor sit amet, \n"
    assert quoted_reader.current_line == "Lorem ipsum dolor sit amet, \n"
    assert quoted_reader.fetch() == "Lorem ipsum dolor sit amet, \n"
    assert quoted_reader.get_source_and_line() == ('dummy.md', 1)

    # laziness: off
    try:
        quoted_reader.readline()
        assert False
    except IOError:
        pass

    # lazyness allows texts hanging on quoted block
    assert quoted_reader.readline(
        lazy=True) == " consectetur adipiscing elit, \n"

    # empty line causes IOError
    try:
        quoted_reader.readline()
        assert False
    except IOError:
        pass

    # empty line causes IOError even if lazy
    try:
        quoted_reader.readline(lazy=True)
        assert False
    except IOError:
        pass

    assert reader.readline() == '\n'
    assert reader.readline() == "sed do eiusmod tempor incididunt \n"
    assert reader.readline() == "ut labore et dolore magna aliqua."
    def read_table_header(self,
                          reader: LineReader) -> Tuple[nodes.row, List[str]]:
        try:
            location = reader.get_source_and_line(incr=1)
            header = self.parse_row(reader.readline())
            if self.parser.is_interrupted(reader):
                raise IOError
            elif not self.delimiter_pattern.match(reader.next_line):
                raise IOError

            delimiters = self.parse_row(reader.next_line)
            aligns = [align(d) for d in delimiters]
            if len(header) != len(delimiters):
                raise IOError
        except IOError:
            reader.step(-1)
            return None, None

        reader.step()

        row = nodes.row()
        for i, cell in enumerate(header):
            text = cell.strip()
            entry = nodes.entry()
            location.set_source_info(entry)
            if text:
                entry += nodes.paragraph(text, text)
            if aligns[i]:
                entry['align'] = aligns[i]
            row += entry
        return row, aligns
Exemple #19
0
    def run(self, reader: LineReader, document: Element) -> bool:
        if reader.lineno != 0:
            return False

        reader.readline()
        field_list = nodes.field_list()
        field_list.source, field_list.line = reader.get_source_and_line()
        for line in reader:
            if self.pattern.match(line):
                break
            elif ':' in line:
                key, value = line.split(':')
                field_name = nodes.field_name('', key.strip())
                field_body = nodes.field_body('', nodes.paragraph('', value.strip()))
                field_list += nodes.field('', field_name, field_body)
            else:
                # Not a frontmatter, rollback
                lines = len(field_list) + 2
                reader.step(-lines)
                return False

        document += field_list
        return True
Exemple #20
0
    def run(self, reader: LineReader, document: Element) -> bool:
        location = reader.get_source_and_line(incr=1)
        reader = LazyLineReader(reader)

        text = ''
        for line in reader:
            text += line.lstrip()
            if self.parser.is_interrupted(reader):
                break

        node = nodes.paragraph(text.strip(), text.strip())
        location.set_source_info(node)
        document += node

        return True
    def run(self, reader: LineReader, document: Element) -> bool:
        location = reader.get_source_and_line(incr=1)
        header_row, aligns = self.read_table_header(reader)
        if header_row is None:
            return False
        body_rows = self.read_table_body(reader, aligns)

        colspecs = [
            nodes.colspec('', colwidth=int(100 / len(aligns))) for _ in aligns
        ]
        thead = nodes.thead('', header_row)
        tgroup = nodes.tgroup('', *colspecs, thead, cols=len(aligns))
        if body_rows:
            tgroup += nodes.tbody('', *body_rows)
        table = nodes.table('', tgroup)
        location.set_source_info(table)
        document += table
        return True
Exemple #22
0
def test_LineReader():
    reader = LineReader(text.splitlines(), source='dummy.md')
    assert reader.eof() is False
    assert reader.get_source_and_line() == ('dummy.md', 0)

    # read first line
    assert reader.readline() == "Lorem ipsum dolor sit amet, "
    assert reader.current_line == "Lorem ipsum dolor sit amet, "
    assert reader.fetch() == "Lorem ipsum dolor sit amet, "
    assert reader.fetch(1) == "consectetur adipiscing elit, "
    assert reader.next_line == "consectetur adipiscing elit, "
    assert reader.fetch(2) == ""
    assert reader.get_source_and_line() == ('dummy.md', 1)

    # read second line
    assert reader.readline() == "consectetur adipiscing elit, "
    assert reader.current_line == "consectetur adipiscing elit, "
    assert reader.fetch() == "consectetur adipiscing elit, "
    assert reader.fetch(1) == ""
    assert reader.get_source_and_line() == ('dummy.md', 2)

    # rollback a line
    reader.step(-1)
    assert reader.current_line == "Lorem ipsum dolor sit amet, "
    assert reader.get_source_and_line() == ('dummy.md', 1)

    # step a line again
    reader.step()
    assert reader.current_line == "consectetur adipiscing elit, "

    # read until the end
    assert reader.readline() == ""
    assert reader.readline() == "    sed do eiusmod tempor incididunt "
    assert reader.readline() == "    ut labore et dolore magna aliqua."
    assert reader.readline() == ""
    assert reader.readline() == "Ut enim ad minim veniam, quis nostrud"
    assert reader.eof() is True

    try:
        assert reader.readline()
        assert False, "reader does not raise IOError on EOF"
    except IOError:
        pass
Exemple #23
0
 def run(self, reader: LineReader, document: Element) -> bool:
     reader.readline()  # skip the line
     document += addnodes.blankline()
     return True
Exemple #24
0
 def run(self, reader: LineReader, document: Element) -> bool:
     reader.readline()
     document += nodes.transition()
     return True
Exemple #25
0
 def parse(self, inputtext: str, document: nodes.document) -> None:
     """Parses a text and build document."""
     document.settings.inline_processors = self.get_inline_processors()
     reader = LineReader(inputtext.splitlines(True), source=document['source'])
     block_parser = self.create_block_parser()
     block_parser.parse(reader, document)
 def run(self, reader: LineReader, document: Element) -> bool:
     quote = nodes.block_quote()
     quote.source, quote.line = reader.get_source_and_line(incr=1)
     document += quote
     self.parser.parse(BlockQuoteReader(reader), quote)
     return True