Beispiel #1
0
def parse_container(ctx: CTX, mark: str, location: Location, content: Content,
                    indentation_before_mark: int) -> int:
    if mark != container_area_begin_mark:
        return PASS

    content.read_spaces()

    function = try_parse_entry(content)

    content.expect_end_of_line()

    with ctx.using_stop_mark(container_area_end_mark):
        component = capture_component(ctx, indentation_before_mark)

    content.pull(container_area_end_mark)
    content.expect_end_of_line()

    if function is not None:
        component = FunctionCall(
            location,
            inline=False,
            key=function.name,
            options=function.value,
            argument=component,
        )

    ctx.composer.add(component)

    return CONSUMED
Beispiel #2
0
def parse_literal(ctx: CTX, mark: str, location: Location, content: Content,
                  indentation_before_mark: int) -> int:
    if mark != literal_area_mark:
        return PASS

    content.read_spaces()

    function_location = content.get_location()

    function = try_parse_entry(content)

    content.expect_end_of_line()

    out = StringIO()

    while True:
        line = content.read_line(indentation_before_mark)

        if line is None:
            raise StxError(f'Expected: {mark}', content.get_location())
        elif line.startswith(escape_char):
            line = line[1:]  # remove escape char

            if not line.startswith(mark) and not line.startswith(escape_char):
                raise StxError(f'Invalid escaped sequence, expected:'
                               f' {see(mark)} or {see(escape_char)}.')
        elif line.rstrip() == mark:
            break

        out.write(line)

    text = out.getvalue()

    if function is not None:
        component = FunctionCall(
            function_location,
            inline=False,
            key=function.name,
            options=function.value,
            argument=Literal(location, text),
        )
    else:
        component = Literal(location, text)

    ctx.composer.add(component)

    return CONSUMED
Beispiel #3
0
def parse_inline_text(ctx: CTX, mark: str, location: Location,
                      content: Content, indentation: int) -> int:
    if mark is not None:
        return PASS

    out = StringIO()

    completed = False

    while content.peek() is not None:
        # Check if the text is broken by an inline or stop mark
        if content.test_any(inline_marks):
            break
        elif content.test(ctx.stop_mark):
            break

        c = content.peek()

        if c == '\n':
            out.write(c)
            content.move_next()

            # Check if the text is completed by an empty line
            if content.consume_empty_line():
                completed = True
                break

            loc0 = content.get_location()

            spaces = content.read_spaces(indentation)

            # Check if the text is completed by indentation change
            if spaces < indentation:
                content.go_back(loc0)
                completed = True
                break

            # Check if the text is completed by a non-inline mark
            if content.test_any(not_inline_marks):
                content.go_back(loc0)
                completed = True
                break
        elif c == escape_char:
            content.move_next()

            escaped_mark = content.pull_any(all_marks)
            if escaped_mark is not None:
                out.write(escaped_mark)
            elif content.pull(ctx.stop_mark):
                out.write(ctx.stop_mark)
            elif content.pull(escape_char):
                out.write(escape_char)
            else:
                raise StxError('invalid escaped char')
        else:
            out.write(c)
            content.move_next()

    text = out.getvalue()

    if text == '':
        return EXIT

    ctx.composer.add(PlainText(location, text))

    if completed:
        return EXIT
    return CONSUMED
Beispiel #4
0
def parse_table(ctx: CTX, mark: str, location: Location,
                content: Content) -> int:
    if mark == header_row_block_mark:
        header = True
        reuse_row = False
    elif mark == normal_row_block_mark:
        header = False
        reuse_row = False
    elif mark == cell_block_mark:
        header = False
        reuse_row = True
    else:
        return PASS

    table = ctx.composer.get_last_component()

    if not isinstance(table, Table):
        table = Table(location)

        ctx.composer.add(table)

    row = table.get_last_row() if reuse_row else None

    if row is None:
        row = TableRow(location, header)

        table.rows.append(row)

    # TODO is this ok?
    skip_void(content)

    indentation0 = content.column
    indentation = indentation0

    while True:
        with ctx.using_stop_mark(cell_block_mark):
            cell = capture_component(ctx, indentation, True)

            row.cells.append(cell)

        if not ctx.reader.active():
            break

        content = ctx.reader.get_content()

        loc0 = content.get_location()

        # Consume indentation when it is the beginning of the line
        if content.column == 0:
            if content.read_spaces(indentation0) < indentation0:
                content.go_back(loc0)
                break

        if content.peek() == cell_block_mark:
            content.move_next()
            content.read_spaces()

            indentation = content.column
        else:
            break

    return CONSUMED