__author__ = "Aleksandr Slepchenkov"
__email__ = "Sl.aleksandr28@gmail.com"

from typing import (
    Any,
    Dict,
    Iterable,
    List,
    Match,
    Optional,
    Pattern,
    Sequence,
    Tuple,
    Type,
)

Tokens = List[Dict[str, Any]]
# There are too much levels of optional unions of lists of text in cell and align 385 and 396 lines in mistune

def escape(text: str, quote: bool = ..., smart_amp: bool = ...) -> str: ...

class BlockGrammar:
    def_links: Pattern[str]
    def_footnotes: Pattern[str]
    newline: Pattern[str]
    block_code: Pattern[str]
    fences: Pattern[str]
    hrule: Pattern[str]
    heading: Pattern[str]
    lheading: Pattern[str]
    block_quote: Pattern[str]
    list_block: Pattern[str]
    list_item: Pattern[str]
    list_bullet: Pattern[str]
    paragraph: Pattern[str]
    block_html: Pattern[str]
    table: Pattern[str]
    nptable: Pattern[str]
    text: Pattern[str]

class BlockLexer:
    grammar_class: Type[BlockGrammar]
    default_rules: List[str]
    list_rules: Tuple[str]
    footnote_rules: Tuple[str]
    tokens: Tokens
    def_links: Dict[str, Dict[str, str]]
    def_footnotes: Dict[str, int]
    rules = ...  # type: BlockGrammar
    def __init__(self, rules: Optional[BlockGrammar] = ..., **kwargs: Any) -> None: ...
    def __call__(self, text: str, rules: Optional[Sequence[str]] = ...) -> Tokens: ...
    def parse(self, text: str, rules: Optional[Sequence[str]] = ...) -> Tokens: ...
    def parse_newline(self, m: Match[str]) -> None: ...
    def parse_block_code(self, m: Match[str]) -> None: ...
    def parse_fences(self, m: Match[str]) -> None: ...
    def parse_heading(self, m: Match[str]) -> None: ...
    def parse_lheading(self, m: Match[str]) -> None: ...
    def parse_hrule(self, m: Match[str]) -> None: ...
    def parse_list_block(self, m: Match[str]) -> None: ...
    def parse_block_quote(self, m: Match[str]) -> None: ...
    def parse_def_links(self, m: Match[str]) -> None: ...
    def parse_def_footnotes(self, m: Match[str]) -> None: ...
    def parse_table(self, m: Match[str]) -> None: ...
    def parse_nptable(self, m: Match[str]) -> None: ...
    def parse_block_html(self, m: Match[str]) -> None: ...
    def parse_paragraph(self, m: Match[str]) -> None: ...
    def parse_text(self, m: Match[str]) -> None: ...

class InlineGrammar:
    escape: Pattern[str]
    inline_html: Pattern[str]
    autolink: Pattern[str]
    link: Pattern[str]
    reflink: Pattern[str]
    nolink: Pattern[str]
    url: Pattern[str]
    double_emphasis: Pattern[str]
    emphasis: Pattern[str]
    code: Pattern[str]
    linebreak: Pattern[str]
    strikethrough: Pattern[str]
    footnote: Pattern[str]
    text: Pattern[str]
    def hard_wrap(self) -> None: ...

class InlineLexer:
    grammar_class: Type[InlineGrammar]
    default_rules: List[str]
    inline_html_rules: List[str]
    renderer: Renderer
    links: Dict[str, Dict[str, str]]
    footnotes: Dict[str, int]
    footnote_index: int
    _in_link: bool
    _in_footnote: bool
    _parse_inline_html: bool
    rules: InlineGrammar
    def __init__(
        self, renderer: Renderer, rules: Optional[InlineGrammar] = ..., **kwargs: Any
    ) -> None: ...
    def __call__(self, text: str, rules: Optional[Sequence[str]] = ...) -> str: ...
    def setup(
        self,
        links: Optional[Dict[str, Dict[str, str]]],
        footnotes: Optional[Dict[str, int]],
    ) -> None: ...
    line_match: Match[str]
    line_started: bool
    def output(self, text: str, rules: Optional[Sequence[str]] = ...) -> str: ...
    def output_escape(self, m: Match[str]) -> str: ...
    def output_autolink(self, m: Match[str]) -> str: ...
    def output_url(self, m: Match[str]) -> str: ...
    def output_inline_html(self, m: Match[str]) -> str: ...
    def output_footnote(self, m: Match[str]) -> Optional[str]: ...
    def output_link(self, m: Match[str]) -> str: ...
    def output_reflink(self, m: Match[str]) -> Optional[str]: ...
    def output_nolink(self, m: Match[str]) -> Optional[str]: ...
    def output_double_emphasis(self, m: Match[str]) -> str: ...
    def output_emphasis(self, m: Match[str]) -> str: ...
    def output_code(self, m: Match[str]) -> str: ...
    def output_linebreak(self, m: Match[str]) -> str: ...
    def output_strikethrough(self, m: Match[str]) -> str: ...
    def output_text(self, m: Match[str]) -> str: ...

class Renderer:
    options: Dict[str, str]
    def __init__(self, **kwargs: Any) -> None: ...
    def placeholder(self) -> str: ...
    def block_code(
        self, code: str, lang: Any = ...
    ) -> str: ...  # It seems that lang should be string, however other types are valid as well
    def block_quote(self, text: str) -> str: ...
    def block_html(self, html: str) -> str: ...
    def header(self, text: str, level: int, raw: Optional[str] = ...) -> str: ...
    def hrule(self) -> str: ...
    def list(
        self, body: Any, ordered: bool = ...
    ) -> str: ...  # body - same reason as for lang above, and for other Any in this class
    def list_item(self, text: Any) -> str: ...
    def paragraph(self, text: str) -> str: ...
    def table(self, header: Any, body: Any) -> str: ...
    def table_row(self, content: Any) -> str: ...
    def table_cell(self, content: Any, **flags: Dict[str, Any]) -> str: ...
    def double_emphasis(self, text: Any) -> str: ...
    def emphasis(self, text: Any) -> str: ...
    def codespan(self, text: str) -> str: ...
    def linebreak(self) -> str: ...
    def strikethrough(self, text: Any) -> str: ...
    def text(self, text: Any) -> str: ...
    def escape(self, text: Any) -> str: ...
    def autolink(self, link: Any, is_email: bool = ...) -> str: ...
    def link(self, link: Any, title: Any, text: Any) -> str: ...
    def image(self, src: Any, title: Any, text: Any) -> str: ...
    def inline_html(self, html: Any) -> str: ...
    def newline(self) -> str: ...
    def footnote_ref(self, key: Any, index: int) -> str: ...
    def footnote_item(self, key: Any, text: str) -> str: ...
    def footnotes(self, text: Any) -> str: ...

class Markdown:
    renderer = ...  # type: Renderer
    inline = ...  # type: InlineLexer
    block = ...  # type: BlockLexer
    footnotes = ...  # type: List[Dict[str, Any]]
    tokens = ...  # type: Tokens
    def __init__(
        self,
        renderer: Optional[Renderer] = ...,
        inline: Optional[InlineLexer] = ...,
        block: Optional[BlockLexer] = ...,
        **kwargs: Any,
    ) -> None: ...
    def __call__(self, text: str) -> str: ...
    def render(self, text: str) -> str: ...
    def parse(self, text: str) -> str: ...
    token = ...  # type: Dict[str, Any]
    def pop(self) -> Optional[Dict[str, Any]]: ...
    def peek(self) -> Optional[Dict[str, Any]]: ...
    def output(self, text: str, rules: Optional[Sequence[str]] = ...) -> str: ...
    def tok(self) -> str: ...
    def tok_text(self) -> str: ...
    def output_newline(self) -> str: ...
    def output_hrule(self) -> str: ...
    def output_heading(self) -> str: ...
    def output_code(self) -> str: ...
    def output_table(self) -> str: ...
    def output_block_quote(self) -> str: ...
    def output_list(self) -> str: ...
    def output_list_item(self) -> str: ...
    def output_loose_item(self) -> str: ...
    def output_footnote(self) -> str: ...
    def output_close_html(self) -> str: ...
    def output_open_html(self) -> str: ...
    def output_paragraph(self) -> str: ...
    def output_text(self) -> str: ...

def markdown(text: str, escape: bool = ..., **kwargs: Any) -> str: ...
