Beispiel #1
0
def parse_inline(ctx: CTX, location: Location, content: Content,
                 indentation: int) -> List[Component]:
    ctx.composer.push()

    try:
        while not content.halted():
            if content.test(ctx.stop_mark):
                break

            location = content.get_location()

            mark = content.read_mark(inline_marks)

            signal = (parse_inline_function(ctx, mark, location, content)
                      or parse_inline_container(ctx, mark, location, content,
                                                indentation)
                      or parse_inline_style(ctx, mark, location, content,
                                            indentation)
                      or parse_inline_link(ctx, mark, location, content,
                                           indentation)
                      or parse_inline_token(ctx, mark, location, content,
                                            indentation)
                      or parse_inline_text(ctx, mark, location, content,
                                           indentation))

            if signal == PASS:
                raise StxError(f'Not implemented mark: {mark}')
            elif signal == CONSUMED:
                pass
            elif signal == EXIT:
                break
            else:
                raise AssertionError(f'Illegal signal: {signal}')
    except StxError as e:
        raise StxError('Error parsing inline content.', location) from e

    return ctx.composer.pop()
Beispiel #2
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