# Generated by sourcer, using the command `make parser`

"""
# Grammar definition:
start = List(Text | VisibleSection | HiddenSection | HtmlComment)

Text = (ExpectNot(Marker) >> /.|\\n/)+
    |> `lambda x: ''.join(x)`

Marker = "```" | "~~~" | "<!--"

class VisibleSection {
    is_visible: `True`
    tag: Opt(InlineTag) << /[\\s\\n]*/
    code: Code
}

class HiddenSection {
    is_visible: `False`
    tag: StartComment >> DanglingTag
    code: Code << /(\\s|\\n)*-->/
}

HtmlComment = /<!--(.|\\n)*?-->/

InlineTag = StartComment >> /.*?(?=\\s*-->)/ << /\\s*-->/
    |> `lambda x: x.lower() or None`

DanglingTag = (/[^\\n]*/ << /(\\s|\\n)*/)
    |> `lambda x: x.strip().lower() or None`

HiddenBody = /(.|\\n)*?(?=\\s*-->)/

StartComment = /<!--[ \\t]*/

Code = CodeSection("```") | CodeSection("~~~")

class CodeSection(marker) {
    open: marker
    language: /[^\\n]*/ |> `lambda x: x.strip().lower() or None` << /\\n/
    body: List(ExpectNot(marker) >> /.|\\n/) |> `lambda x: ''.join(x)`
    close: marker
}

"""

from collections import namedtuple as _nt
from re import compile as _compile_re, IGNORECASE as _IGNORECASE



class Node:
    _fields = ()

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return False
        for field in self._fields:
            if getattr(self, field) != getattr(other, field):
                return False
        return True

    def _asdict(self):
        return {k: getattr(self, k) for k in self._fields}

    def _replace(self, **kw):
        for field in self._fields:
            if field not in kw:
                kw[field] = getattr(self, field)
        return self.__class__(**kw)


class Rule:
    def __init__(self, name, parse, definition):
        self.name = name
        self.parse = parse
        self.definition = definition

    def __repr__(self):
        return (f'Rule(name={self.name!r}, parse={self.parse.__name__},'
            f' definition={self.definition!r})')



class SourcerError(Exception):
    """Common superclass for ParseError and PartialParseError."""


class ParseError(SourcerError):
    def __init__(self, message, index, line, column):
        super().__init__(message)
        self.position = _Position(index, line, column)


class PartialParseError(SourcerError):
    def __init__(self, partial_result, last_position, excerpt):
        super().__init__('Incomplete parse. Unexpected input on line'
            f' {last_position.line}, column {last_position.column}:\n{excerpt}')
        self.partial_result = partial_result
        self.last_position = last_position


class Infix(Node):
    _fields = ('left', 'operator', 'right')

    def __init__(self, left, operator, right):
        self.left = left
        self.operator = operator
        self.right = right

    def __repr__(self):
        return f'Infix({self.left!r}, {self.operator!r}, {self.right!r})'


class Postfix(Node):
    _fields = ('left', 'operator')

    def __init__(self, left, operator):
        self.left = left
        self.operator = operator

    def __repr__(self):
        return f'Postfix({self.left!r}, {self.operator!r})'


class Prefix(Node):
    _fields = ('operator', 'right')

    def __init__(self, operator, right):
        self.operator = operator
        self.right = right

    def __repr__(self):
        return f'Prefix({self.operator!r}, {self.right!r})'


def parse(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_start, fullparse)


_PositionInfo = _nt('_PositionInfo', 'start, end')

_Position = _nt('_Position', 'index, line, column')


class _ParseFunction(_nt('_ParseFunction', 'func, args, kwargs')):
    def __call__(self, _text, _pos):
        return self.func(_text, _pos, *self.args, **dict(self.kwargs))


class _StringLiteral(str):
    def __call__(self, _text, _pos):
        return self._parse_function(_text, _pos)


def _wrap_string_literal(string_value, parse_function):
    result = _StringLiteral(string_value)
    result._parse_function = parse_function
    return result


def _run(text, pos, start, fullparse):
    memo = {}
    result = None

    key = (3, start, pos)
    gtor = start(text, pos)
    stack = [(key, gtor)]

    while stack:
        key, gtor = stack[-1]
        result = gtor.send(result)

        if result[0] != 3:
            stack.pop()
            memo[key] = result
        elif result in memo:
            result = memo[result]
        else:
            gtor = result[1](text, result[2])
            stack.append((result, gtor))
            result = None

    if result[0]:
        return _finalize_parse_info(text, result[1], result[2], fullparse)
    else:
        pos = result[2]
        message = result[1](text, pos)
        raise ParseError(message, pos)


def visit(node):
    visited = set()
    stack = [node]
    while stack:
        node = stack.pop()

        if isinstance(node, (list, tuple)):
            stack.extend(node)

        elif isinstance(node, dict):
            stack.extend(node.values())

        elif isinstance(node, Node):
            node_id = id(node)
            if node_id in visited:
                continue
            visited.add(node_id)

            yield node

            if hasattr(node, '_fields'):
                stack.extend(getattr(node, x) for x in node._fields)


def transform(node, *callbacks):
    if not callbacks:
        return node

    if len(callbacks) == 1:
        callback = callbacks[0]
    else:
        def callback(node):
            for f in callbacks:
                node = f(node)
            return node

    return _transform(node, callback)


def _transform(node, callback):
    if isinstance(node, list):
        return [_transform(x, callback) for x in node]

    if not isinstance(node, Node):
        return node

    updates = {}
    for field in node._fields:
        was = getattr(node, field)
        now = _transform(was, callback)
        if was is not now:
            updates[field] = now

    if updates:
        node = node._replace(**updates)

    return callback(node)


def _finalize_parse_info(text, nodes, pos, fullparse):
    line_numbers, column_numbers = _map_index_to_line_and_column(text)

    for node in visit(nodes):
        pos_info = getattr(node, '_position_info', None)
        if pos_info:
            start, end = pos_info
            end -= 1
            node._position_info = _PositionInfo(
                start=_Position(start, line_numbers[start], column_numbers[start]),
                end=_Position(end, line_numbers[end], column_numbers[end]),
            )

    if fullparse and pos < len(text):
        line, col = line_numbers[pos], column_numbers[pos]
        position = _Position(pos, line, col)
        excerpt = _extract_excerpt(text, pos, col)
        raise PartialParseError(nodes, position, excerpt)

    return nodes


def _extract_excerpt(text, pos, col):
    if isinstance(text, bytes):
        return repr(text[max(0, pos - 1) : pos + 2])

    start = pos - (col - 1)
    match = _compile_re('\n').search(text, pos + 1)
    end = len(text) if match is None else match.start()

    if end - start < 96:
        return text[start : end] + _caret_at(col - 1)

    if col < 60:
        # Chop the line off at the end.
        return text[start : start + 90] + ' ...' + _caret_at(col - 1)

    elif end - pos < 40:
        # Chop the line off at the start.
        return '... ' + text[end - 90 : end] + _caret_at(pos - (end - 90) + 4)

    else:
        # Chop the line off at both ends.
        return '... ' + text[pos - 42 : pos + 42] + ' ...' + _caret_at(42 + 4)


def _caret_at(index):
    return '\n' + (' ' * index) + '^'


def _get_line_and_column(text, pos):
    line_numbers, column_numbers = _map_index_to_line_and_column(text)
    return line_numbers[pos], column_numbers[pos]


def _map_index_to_line_and_column(text):
    line_numbers = []
    column_numbers = []

    current_line = 1
    current_column = 0

    for c in text:
        if c == '\n':
            current_line += 1
            current_column = 0
        else:
            current_column += 1
        line_numbers.append(current_line)
        column_numbers.append(current_column)

    return line_numbers, column_numbers



matcher1 = _compile_re('.|\\n', flags=0).match
matcher2 = _compile_re('[\\s\\n]*', flags=0).match
matcher3 = _compile_re('(\\s|\\n)*-->', flags=0).match
matcher4 = _compile_re('<!--(.|\\n)*?-->', flags=0).match
matcher5 = _compile_re('.*?(?=\\s*-->)', flags=0).match
matcher6 = _compile_re('\\s*-->', flags=0).match
matcher7 = _compile_re('[^\\n]*', flags=0).match
matcher8 = _compile_re('(\\s|\\n)*', flags=0).match
matcher9 = _compile_re('(.|\\n)*?(?=\\s*-->)', flags=0).match
matcher10 = _compile_re('<!--[ \\t]*', flags=0).match
matcher11 = _compile_re('\\n', flags=0).match


def _cont_start(_text, _pos):
    # Rule 'start'
    # <List>
    # (Text | VisibleSection | HiddenSection | HtmlComment)*
    staging1 = []
    while True:
        checkpoint1 = _pos
        # <Choice>
        backtrack1 = farthest_pos1 = _pos
        farthest_err1 = _raise_error3
        while True:
            # Option 1:
            # <Ref name='Text'>
            (_status, _result, _pos,) = (yield (3, _cont_Text, _pos,))
            # </Ref>
            if _status:
                break
            if (farthest_pos1 < _pos):
                farthest_pos1 = _pos
                farthest_err1 = _result
            _pos = backtrack1
            # Option 2:
            # <Ref name='VisibleSection'>
            (_status, _result, _pos,) = (yield (3, _cont_VisibleSection, _pos,))
            # </Ref>
            if _status:
                break
            if (farthest_pos1 < _pos):
                farthest_pos1 = _pos
                farthest_err1 = _result
            _pos = backtrack1
            # Option 3:
            # <Ref name='HiddenSection'>
            (_status, _result, _pos,) = (yield (3, _cont_HiddenSection, _pos,))
            # </Ref>
            if _status:
                break
            if (farthest_pos1 < _pos):
                farthest_pos1 = _pos
                farthest_err1 = _result
            _pos = backtrack1
            # Option 4:
            # <Ref name='HtmlComment'>
            (_status, _result, _pos,) = (yield (3, _cont_HtmlComment, _pos,))
            # </Ref>
            if _status:
                break
            if (farthest_pos1 < _pos):
                farthest_pos1 = _pos
                farthest_err1 = _result
            _pos = farthest_pos1
            _result = farthest_err1
            break
        # </Choice>
        if (not _status):
            _pos = checkpoint1
            break
        staging1.append(_result)
    _result = staging1
    _status = True
    # </List>
    (yield (_status, _result, _pos,))


def _parse_start(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_start, fullparse)


start = Rule('start', _parse_start, """
    start = (Text | VisibleSection | HiddenSection | HtmlComment)*
""")

def _raise_error3(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'start' rule, at the expression:\n"
    '    Text | VisibleSection | HiddenSection | HtmlComment\n\n'
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_Text(_text, _pos):
    # Rule 'Text'
    # <Apply>
    # (ExpectNot(Marker) >> /.|\\n/)+ |> `lambda x: ''.join(x)`
    # <List>
    # (ExpectNot(Marker) >> /.|\\n/)+
    staging2 = []
    while True:
        checkpoint2 = _pos
        # <Discard>
        # ExpectNot(Marker) >> /.|\\n/
        while True:
            # <ExpectNot>
            # ExpectNot(Marker)
            backtrack2 = _pos
            # <Ref name='Marker'>
            (_status, _result, _pos,) = (yield (3, _cont_Marker, _pos,))
            # </Ref>
            _pos = backtrack2
            if _status:
                _status = False
                _result = _raise_error12
            else:
                _status = True
                _result = None
            # </ExpectNot>
            if (not _status):
                break
            # <Regex pattern='.|\\n'>
            match1 = matcher1(_text, _pos)
            if match1:
                _pos = match1.end()
                _status = True
                _result = match1.group(0)
            else:
                _status = False
                _result = _raise_error14
            # </Regex>
            break
        # </Discard>
        if (not _status):
            _pos = checkpoint2
            break
        staging2.append(_result)
    if staging2:
        _result = staging2
        _status = True
    # </List>
    if _status:
        arg1 = _result
        _result = lambda x: ''.join(x)
        _status = True
        _result = _result(arg1)
    # </Apply>
    (yield (_status, _result, _pos,))


def _parse_Text(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_Text, fullparse)


Text = Rule('Text', _parse_Text, """
    Text = (ExpectNot(Marker) >> /.|\\n/)+ |> `lambda x: ''.join(x)`
""")

def _raise_error12(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Text' rule, at the expression:\n"
    '    ExpectNot(Marker)\n\n'
    'Did not expect to match: Marker'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error14(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Text' rule, at the expression:\n"
    '    /.|\\\\n/\n\n'
    'Expected to match the regular expression /.|\\n/'
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_Marker(_text, _pos):
    # Rule 'Marker'
    # <Choice>
    backtrack3 = farthest_pos2 = _pos
    farthest_err2 = _raise_error17
    while True:
        # Option 1:
        # <String value='```'>
        value1 = '```'
        end1 = (_pos + 3)
        if (_text[_pos : end1] == value1):
            _pos = end1
            _status = True
            _result = value1
        else:
            _status = False
            _result = _raise_error18
        # </String>
        if _status:
            break
        if (farthest_pos2 < _pos):
            farthest_pos2 = _pos
            farthest_err2 = _result
        _pos = backtrack3
        # Option 2:
        # <String value='~~~'>
        value2 = '~~~'
        end2 = (_pos + 3)
        if (_text[_pos : end2] == value2):
            _pos = end2
            _status = True
            _result = value2
        else:
            _status = False
            _result = _raise_error19
        # </String>
        if _status:
            break
        if (farthest_pos2 < _pos):
            farthest_pos2 = _pos
            farthest_err2 = _result
        _pos = backtrack3
        # Option 3:
        # <String value='<!--'>
        value3 = '<!--'
        end3 = (_pos + 4)
        if (_text[_pos : end3] == value3):
            _pos = end3
            _status = True
            _result = value3
        else:
            _status = False
            _result = _raise_error20
        # </String>
        if _status:
            break
        if (farthest_pos2 < _pos):
            farthest_pos2 = _pos
            farthest_err2 = _result
        _pos = farthest_pos2
        _result = farthest_err2
        break
    # </Choice>
    (yield (_status, _result, _pos,))


def _parse_Marker(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_Marker, fullparse)


Marker = Rule('Marker', _parse_Marker, """
    Marker = '```' | '~~~' | '<!--'
""")

def _raise_error17(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Marker' rule, at the expression:\n"
    "    '```' | '~~~' | '<!--'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error18(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Marker' rule, at the expression:\n"
    "    '```'\n\n"
    "Expected to match the string '```'"
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error19(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Marker' rule, at the expression:\n"
    "    '~~~'\n\n"
    "Expected to match the string '~~~'"
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error20(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Marker' rule, at the expression:\n"
    "    '<!--'\n\n"
    "Expected to match the string '<!--'"
    )
    raise ParseError((title + details), _pos, line, col)


class VisibleSection(Node):
    """
    class VisibleSection {
        is_visible: `True`
        tag: Opt(InlineTag) << /[\\s\\n]*/
        code: Code
    }
    """
    _fields = ('is_visible', 'tag', 'code',)

    def __init__(self, is_visible, tag, code):
        self.is_visible = is_visible
        self.tag = tag
        self.code = code
        self._position_info = None

    def __repr__(self):
        return f'VisibleSection(is_visible={self.is_visible!r}, tag={self.tag!r}, code={self.code!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _cont_VisibleSection, fullparse)



def _cont_VisibleSection(_text, _pos):
    # <Seq>
    start_pos1 = _pos
    while True:
        _result = True
        _status = True
        is_visible = _result
        # <Discard>
        # Opt(InlineTag) << /[\\s\\n]*/
        while True:
            # <Opt>
            # Opt(InlineTag)
            backtrack4 = _pos
            # <Ref name='InlineTag'>
            (_status, _result, _pos,) = (yield (3, _cont_InlineTag, _pos,))
            # </Ref>
            if (not _status):
                _status = True
                _pos = backtrack4
                _result = None
            # </Opt>
            staging3 = _result
            # <Regex pattern='[\\s\\n]*'>
            match2 = matcher2(_text, _pos)
            if match2:
                _pos = match2.end()
                _status = True
                _result = match2.group(0)
            else:
                _status = False
                _result = _raise_error29
            # </Regex>
            if _status:
                _result = staging3
            break
        # </Discard>
        if (not _status):
            break
        tag = _result
        # <Ref name='Code'>
        (_status, _result, _pos,) = (yield (3, _cont_Code, _pos,))
        # </Ref>
        if (not _status):
            break
        code = _result
        _result = VisibleSection(is_visible, tag, code)
        _result._position_info = (start_pos1, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


def _raise_error29(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'VisibleSection' rule, at the expression:\n"
    '    /[\\\\s\\\\n]*/\n\n'
    'Expected to match the regular expression /[\\s\\n]*/'
    )
    raise ParseError((title + details), _pos, line, col)


class HiddenSection(Node):
    """
    class HiddenSection {
        is_visible: `False`
        tag: StartComment >> DanglingTag
        code: Code << /(\\s|\\n)*-->/
    }
    """
    _fields = ('is_visible', 'tag', 'code',)

    def __init__(self, is_visible, tag, code):
        self.is_visible = is_visible
        self.tag = tag
        self.code = code
        self._position_info = None

    def __repr__(self):
        return f'HiddenSection(is_visible={self.is_visible!r}, tag={self.tag!r}, code={self.code!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _cont_HiddenSection, fullparse)



def _cont_HiddenSection(_text, _pos):
    # <Seq>
    start_pos2 = _pos
    while True:
        _result = False
        _status = True
        is_visible = _result
        # <Discard>
        # StartComment >> DanglingTag
        while True:
            # <Ref name='StartComment'>
            (_status, _result, _pos,) = (yield (3, _cont_StartComment, _pos,))
            # </Ref>
            if (not _status):
                break
            # <Ref name='DanglingTag'>
            (_status, _result, _pos,) = (yield (3, _cont_DanglingTag, _pos,))
            # </Ref>
            break
        # </Discard>
        if (not _status):
            break
        tag = _result
        # <Discard>
        # Code << /(\\s|\\n)*-->/
        while True:
            # <Ref name='Code'>
            (_status, _result, _pos,) = (yield (3, _cont_Code, _pos,))
            # </Ref>
            if (not _status):
                break
            staging4 = _result
            # <Regex pattern='(\\s|\\n)*-->'>
            match3 = matcher3(_text, _pos)
            if match3:
                _pos = match3.end()
                _status = True
                _result = match3.group(0)
            else:
                _status = False
                _result = _raise_error43
            # </Regex>
            if _status:
                _result = staging4
            break
        # </Discard>
        if (not _status):
            break
        code = _result
        _result = HiddenSection(is_visible, tag, code)
        _result._position_info = (start_pos2, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


def _raise_error43(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'HiddenSection' rule, at the expression:\n"
    '    /(\\\\s|\\\\n)*-->/\n\n'
    'Expected to match the regular expression /(\\s|\\n)*-->/'
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_HtmlComment(_text, _pos):
    # Rule 'HtmlComment'
    # <Regex pattern='<!--(.|\\n)*?-->'>
    match4 = matcher4(_text, _pos)
    if match4:
        _pos = match4.end()
        _status = True
        _result = match4.group(0)
    else:
        _status = False
        _result = _raise_error45
    # </Regex>
    (yield (_status, _result, _pos,))


def _parse_HtmlComment(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_HtmlComment, fullparse)


HtmlComment = Rule('HtmlComment', _parse_HtmlComment, """
    HtmlComment = /<!--(.|\\n)*?-->/
""")

def _raise_error45(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'HtmlComment' rule, at the expression:\n"
    '    /<!--(.|\\\\n)*?-->/\n\n'
    'Expected to match the regular expression /<!--(.|\\n)*?-->/'
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_InlineTag(_text, _pos):
    # Rule 'InlineTag'
    # <Apply>
    # ((StartComment >> /.*?(?=\\s*-->)/) << /\\s*-->/) |> `lambda x: x.lower() or None`
    # <Discard>
    # (StartComment >> /.*?(?=\\s*-->)/) << /\\s*-->/
    while True:
        # <Discard>
        # StartComment >> /.*?(?=\\s*-->)/
        while True:
            # <Ref name='StartComment'>
            (_status, _result, _pos,) = (yield (3, _cont_StartComment, _pos,))
            # </Ref>
            if (not _status):
                break
            # <Regex pattern='.*?(?=\\s*-->)'>
            match5 = matcher5(_text, _pos)
            if match5:
                _pos = match5.end()
                _status = True
                _result = match5.group(0)
            else:
                _status = False
                _result = _raise_error51
            # </Regex>
            break
        # </Discard>
        if (not _status):
            break
        staging5 = _result
        # <Regex pattern='\\s*-->'>
        match6 = matcher6(_text, _pos)
        if match6:
            _pos = match6.end()
            _status = True
            _result = match6.group(0)
        else:
            _status = False
            _result = _raise_error52
        # </Regex>
        if _status:
            _result = staging5
        break
    # </Discard>
    if _status:
        arg2 = _result
        _result = lambda x: x.lower() or None
        _status = True
        _result = _result(arg2)
    # </Apply>
    (yield (_status, _result, _pos,))


def _parse_InlineTag(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_InlineTag, fullparse)


InlineTag = Rule('InlineTag', _parse_InlineTag, """
    InlineTag = ((StartComment >> /.*?(?=\\s*-->)/) << /\\s*-->/) |> `lambda x: x.lower() or None`
""")

def _raise_error51(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'InlineTag' rule, at the expression:\n"
    '    /.*?(?=\\\\s*-->)/\n\n'
    'Expected to match the regular expression /.*?(?=\\s*-->)/'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error52(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'InlineTag' rule, at the expression:\n"
    '    /\\\\s*-->/\n\n'
    'Expected to match the regular expression /\\s*-->/'
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_DanglingTag(_text, _pos):
    # Rule 'DanglingTag'
    # <Apply>
    # (/[^\\n]*/ << /(\\s|\\n)*/) |> `lambda x: x.strip().lower() or None`
    # <Discard>
    # /[^\\n]*/ << /(\\s|\\n)*/
    while True:
        # <Regex pattern='[^\\n]*'>
        match7 = matcher7(_text, _pos)
        if match7:
            _pos = match7.end()
            _status = True
            _result = match7.group(0)
        else:
            _status = False
            _result = _raise_error57
        # </Regex>
        if (not _status):
            break
        staging6 = _result
        # <Regex pattern='(\\s|\\n)*'>
        match8 = matcher8(_text, _pos)
        if match8:
            _pos = match8.end()
            _status = True
            _result = match8.group(0)
        else:
            _status = False
            _result = _raise_error58
        # </Regex>
        if _status:
            _result = staging6
        break
    # </Discard>
    if _status:
        arg3 = _result
        _result = lambda x: x.strip().lower() or None
        _status = True
        _result = _result(arg3)
    # </Apply>
    (yield (_status, _result, _pos,))


def _parse_DanglingTag(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_DanglingTag, fullparse)


DanglingTag = Rule('DanglingTag', _parse_DanglingTag, """
    DanglingTag = (/[^\\n]*/ << /(\\s|\\n)*/) |> `lambda x: x.strip().lower() or None`
""")

def _raise_error57(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'DanglingTag' rule, at the expression:\n"
    '    /[^\\\\n]*/\n\n'
    'Expected to match the regular expression /[^\\n]*/'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error58(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'DanglingTag' rule, at the expression:\n"
    '    /(\\\\s|\\\\n)*/\n\n'
    'Expected to match the regular expression /(\\s|\\n)*/'
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_HiddenBody(_text, _pos):
    # Rule 'HiddenBody'
    # <Regex pattern='(.|\\n)*?(?=\\s*-->)'>
    match9 = matcher9(_text, _pos)
    if match9:
        _pos = match9.end()
        _status = True
        _result = match9.group(0)
    else:
        _status = False
        _result = _raise_error61
    # </Regex>
    (yield (_status, _result, _pos,))


def _parse_HiddenBody(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_HiddenBody, fullparse)


HiddenBody = Rule('HiddenBody', _parse_HiddenBody, """
    HiddenBody = /(.|\\n)*?(?=\\s*-->)/
""")

def _raise_error61(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'HiddenBody' rule, at the expression:\n"
    '    /(.|\\\\n)*?(?=\\\\s*-->)/\n\n'
    'Expected to match the regular expression /(.|\\n)*?(?=\\s*-->)/'
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_StartComment(_text, _pos):
    # Rule 'StartComment'
    # <Regex pattern='<!--[ \\t]*'>
    match10 = matcher10(_text, _pos)
    if match10:
        _pos = match10.end()
        _status = True
        _result = match10.group(0)
    else:
        _status = False
        _result = _raise_error63
    # </Regex>
    (yield (_status, _result, _pos,))


def _parse_StartComment(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_StartComment, fullparse)


StartComment = Rule('StartComment', _parse_StartComment, """
    StartComment = /<!--[ \\t]*/
""")

def _raise_error63(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'StartComment' rule, at the expression:\n"
    '    /<!--[ \\\\t]*/\n\n'
    'Expected to match the regular expression /<!--[ \\t]*/'
    )
    raise ParseError((title + details), _pos, line, col)


def _parse_function_68(_text, _pos):
    # <String value='```'>
    value4 = '```'
    end4 = (_pos + 3)
    if (_text[_pos : end4] == value4):
        _pos = end4
        _status = True
        _result = value4
    else:
        _status = False
        _result = _raise_error68
    # </String>
    (yield (_status, _result, _pos,))


def _parse_function_71(_text, _pos):
    # <String value='~~~'>
    value5 = '~~~'
    end5 = (_pos + 3)
    if (_text[_pos : end5] == value5):
        _pos = end5
        _status = True
        _result = value5
    else:
        _status = False
        _result = _raise_error71
    # </String>
    (yield (_status, _result, _pos,))


def _cont_Code(_text, _pos):
    # Rule 'Code'
    # <Choice>
    backtrack5 = farthest_pos3 = _pos
    farthest_err3 = _raise_error65
    while True:
        # Option 1:
        # <Call>
        # CodeSection('```')
        arg4 = _wrap_string_literal('```', _parse_function_68)
        func1 = _ParseFunction(_cont_CodeSection, (arg4,), ())
        (_status, _result, _pos,) = (yield (3, func1, _pos,))
        # </Call>
        if _status:
            break
        if (farthest_pos3 < _pos):
            farthest_pos3 = _pos
            farthest_err3 = _result
        _pos = backtrack5
        # Option 2:
        # <Call>
        # CodeSection('~~~')
        arg5 = _wrap_string_literal('~~~', _parse_function_71)
        func2 = _ParseFunction(_cont_CodeSection, (arg5,), ())
        (_status, _result, _pos,) = (yield (3, func2, _pos,))
        # </Call>
        if _status:
            break
        if (farthest_pos3 < _pos):
            farthest_pos3 = _pos
            farthest_err3 = _result
        _pos = farthest_pos3
        _result = farthest_err3
        break
    # </Choice>
    (yield (_status, _result, _pos,))


def _parse_Code(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_Code, fullparse)


Code = Rule('Code', _parse_Code, """
    Code = CodeSection('```') | CodeSection('~~~')
""")

def _raise_error65(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Code' rule, at the expression:\n"
    "    CodeSection('```') | CodeSection('~~~')\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error68(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Code' rule, at the expression:\n"
    "    '```'\n\n"
    "Expected to match the string '```'"
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error71(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Code' rule, at the expression:\n"
    "    '~~~'\n\n"
    "Expected to match the string '~~~'"
    )
    raise ParseError((title + details), _pos, line, col)


class CodeSection(Node):
    """
    class CodeSection(marker) {
        open: marker
        language: /[^\\n]*/ |> (`lambda x: x.strip().lower() or None` << /\\n/)
        body: (ExpectNot(marker) >> /.|\\n/)* |> `lambda x: ''.join(x)`
        close: marker
    }
    """
    _fields = ('open', 'language', 'body', 'close',)

    def __init__(self, open, language, body, close):
        self.open = open
        self.language = language
        self.body = body
        self.close = close
        self._position_info = None

    def __repr__(self):
        return f'CodeSection(open={self.open!r}, language={self.language!r}, body={self.body!r}, close={self.close!r})'

    @staticmethod
    def parse(marker):
        closure = _ParseFunction(_cont_CodeSection, (marker,), {})
        return lambda text, pos=0, fullparse=True: _run(text, pos, closure, fullparse)



def _cont_CodeSection(_text, _pos, marker):
    # <Seq>
    start_pos3 = _pos
    while True:
        # <Ref name='marker'>
        (_status, _result, _pos,) = (yield (3, marker, _pos,))
        # </Ref>
        if (not _status):
            break
        open = _result
        # <Apply>
        # /[^\\n]*/ |> (`lambda x: x.strip().lower() or None` << /\\n/)
        # <Regex pattern='[^\\n]*'>
        match11 = matcher7(_text, _pos)
        if match11:
            _pos = match11.end()
            _status = True
            _result = match11.group(0)
        else:
            _status = False
            _result = _raise_error78
        # </Regex>
        if _status:
            arg6 = _result
            # <Discard>
            # `lambda x: x.strip().lower() or None` << /\\n/
            while True:
                _result = lambda x: x.strip().lower() or None
                _status = True
                staging7 = _result
                # <Regex pattern='\\n'>
                match12 = matcher11(_text, _pos)
                if match12:
                    _pos = match12.end()
                    _status = True
                    _result = match12.group(0)
                else:
                    _status = False
                    _result = _raise_error81
                # </Regex>
                if _status:
                    _result = staging7
                break
            # </Discard>
            if _status:
                _result = _result(arg6)
        # </Apply>
        if (not _status):
            break
        language = _result
        # <Apply>
        # (ExpectNot(marker) >> /.|\\n/)* |> `lambda x: ''.join(x)`
        # <List>
        # (ExpectNot(marker) >> /.|\\n/)*
        staging8 = []
        while True:
            checkpoint3 = _pos
            # <Discard>
            # ExpectNot(marker) >> /.|\\n/
            while True:
                # <ExpectNot>
                # ExpectNot(marker)
                backtrack6 = _pos
                # <Ref name='marker'>
                (_status, _result, _pos,) = (yield (3, marker, _pos,))
                # </Ref>
                _pos = backtrack6
                if _status:
                    _status = False
                    _result = _raise_error86
                else:
                    _status = True
                    _result = None
                # </ExpectNot>
                if (not _status):
                    break
                # <Regex pattern='.|\\n'>
                match13 = matcher1(_text, _pos)
                if match13:
                    _pos = match13.end()
                    _status = True
                    _result = match13.group(0)
                else:
                    _status = False
                    _result = _raise_error88
                # </Regex>
                break
            # </Discard>
            if (not _status):
                _pos = checkpoint3
                break
            staging8.append(_result)
        _result = staging8
        _status = True
        # </List>
        arg7 = _result
        _result = lambda x: ''.join(x)
        _status = True
        _result = _result(arg7)
        # </Apply>
        body = _result
        # <Ref name='marker'>
        (_status, _result, _pos,) = (yield (3, marker, _pos,))
        # </Ref>
        if (not _status):
            break
        close = _result
        _result = CodeSection(open, language, body, close)
        _result._position_info = (start_pos3, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


def _raise_error78(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'CodeSection' rule, at the expression:\n"
    '    /[^\\\\n]*/\n\n'
    'Expected to match the regular expression /[^\\n]*/'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error81(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'CodeSection' rule, at the expression:\n"
    '    /\\\\n/\n\n'
    'Expected to match the regular expression /\\n/'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error86(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'CodeSection' rule, at the expression:\n"
    '    ExpectNot(marker)\n\n'
    'Did not expect to match: marker'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error88(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col,) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'CodeSection' rule, at the expression:\n"
    '    /.|\\\\n/\n\n'
    'Expected to match the regular expression /.|\\n/'
    )
    raise ParseError((title + details), _pos, line, col)


