from re import Pattern
from typing import ClassVar
from typing_extensions import TypeAlias

from docutils import DataError
from docutils.statemachine import StringList

_Cell: TypeAlias = tuple[int, int, int, list[str]]
_Row: TypeAlias = list[_Cell | None]
_Colspecs: TypeAlias = list[int]

__docformat__: str

class TableMarkupError(DataError):
    offset: int
    def __init__(self, *args, **kwargs) -> None: ...

class TableParser:
    head_body_separator_pat: ClassVar[Pattern[str] | None]
    double_width_pad_char: ClassVar[str]
    def parse(self, block: StringList) -> tuple[_Colspecs, list[_Row], list[_Row]]: ...
    def find_head_body_sep(self) -> None: ...

class GridTableParser(TableParser):
    head_body_separator_pat: ClassVar[Pattern[str]]
    block: StringList
    bottom: int
    right: int
    head_body_sep: int
    done: list[int]
    cells: list[_Cell]
    rowseps: dict[int, list[int]]
    colseps: dict[int, list[int]]
    def setup(self, block: StringList) -> None: ...
    def parse_table(self) -> None: ...
    def mark_done(self, top: int, left: int, bottom: int, right: int) -> None: ...
    def check_parse_complete(self) -> bool: ...
    def scan_cell(self, top: int, left: int) -> tuple[int, int, dict[int, list[int]], dict[int, list[int]]]: ...
    def scan_right(self, top: int, left: int) -> tuple[int, int, dict[int, list[int]], dict[int, list[int]]]: ...
    def scan_down(self, top: int, left: int, right: int) -> tuple[int, dict[int, list[int]], dict[int, list[int]]]: ...
    def scan_left(self, top: int, left: int, bottom: int, right: int) -> tuple[dict[int, list[int]], dict[int, list[int]]]: ...
    def scan_up(self, top: int, left: int, bottom: int, right: int) -> dict[int, list[int]]: ...
    def structure_from_cells(self) -> tuple[_Colspecs, list[_Row], list[_Row]]: ...

class SimpleTableParser(TableParser):
    head_body_separator_pat: ClassVar[Pattern[str]]
    span_pat: ClassVar[Pattern[str]]
    block: StringList
    head_body_sep: int
    columns: list[tuple[int, int]]
    border_end: int
    table: tuple[list[int], list[_Row], list[_Row]]
    done: list[int]
    rowseps: dict[int, tuple[int]]
    colseps: dict[int, tuple[int]]
    def setup(self, block: StringList) -> None: ...
    def parse_table(self) -> None: ...
    def parse_columns(self, line: str, offset: int) -> list[tuple[int, int]]: ...
    def init_row(self, colspec: list[tuple[int, int]], offset: int) -> list[_Cell]: ...
    def parse_row(self, lines: list[str], start: int, spanline: tuple[str, int] | None = ...) -> None: ...
    def check_columns(self, lines: list[str], first_line: int, columns: list[tuple[int, int]]) -> None: ...
    def structure_from_cells(self) -> tuple[_Colspecs, list[_Row], list[_Row]]: ...

def update_dict_of_lists(master: dict[int, list[int]], newdata: dict[int, list[int]]) -> None: ...
