|
@ -3,18 +3,56 @@ from panflute import Cite, Code, Emph, Image, LineBreak, Link, Math, Note, Quote |
|
|
from panflute import BlockQuote, BulletList, Citation, CodeBlock, Definition, DefinitionItem, DefinitionList, Div, Figure, Header, HorizontalRule, LineBlock, LineItem, ListItem, MetaBlocks, MetaBool, MetaInlines, MetaList, MetaMap, MetaString, Null, OrderedList, Para, Plain, RawBlock, Table, TableBody, TableFoot, TableHead |
|
|
from panflute import BlockQuote, BulletList, Citation, CodeBlock, Definition, DefinitionItem, DefinitionList, Div, Figure, Header, HorizontalRule, LineBlock, LineItem, ListItem, MetaBlocks, MetaBool, MetaInlines, MetaList, MetaMap, MetaString, Null, OrderedList, Para, Plain, RawBlock, Table, TableBody, TableFoot, TableHead |
|
|
from panflute import TableRow, TableCell, Caption, Doc |
|
|
from panflute import TableRow, TableCell, Caption, Doc |
|
|
from panflute import MetaValue |
|
|
from panflute import MetaValue |
|
|
|
|
|
from panflute import stringify |
|
|
from typing import Union, Callable |
|
|
from typing import Union, Callable |
|
|
|
|
|
|
|
|
from .whitespace import NBSP |
|
|
from .whitespace import NBSP |
|
|
from .elements import FQuoted |
|
|
from .elements import FQuoted |
|
|
from .context import Group, InlineGroup, BlockGroup, Context |
|
|
from .context import Group, InlineGroup, BlockGroup, Context |
|
|
|
|
|
|
|
|
import re |
|
|
|
|
|
|
|
|
import sys |
|
|
|
|
|
|
|
|
class UnknownElementError(Exception): |
|
|
class UnknownElementError(Exception): |
|
|
"An unknown Element has been passed to the OutputGenerator, probably because panflute introduced a new one." |
|
|
"An unknown Element has been passed to the OutputGenerator, probably because panflute introduced a new one." |
|
|
pass |
|
|
pass |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FormatitkoRecursiveError(Exception): |
|
|
|
|
|
"A generic exception which wraps other exceptions and adds element-based traceback" |
|
|
|
|
|
elements: list[Union[Element, ListContainer, list[Union[Element, ListContainer]]]] |
|
|
|
|
|
context: Context |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]], context: Context, *args): |
|
|
|
|
|
self.elements = [e] |
|
|
|
|
|
self.context = context |
|
|
|
|
|
super().__init__(args) |
|
|
|
|
|
|
|
|
|
|
|
def add_element(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]]): |
|
|
|
|
|
self.elements.append(e) |
|
|
|
|
|
|
|
|
|
|
|
def pretty_print(self): |
|
|
|
|
|
def eprint(*args, **kwargs): |
|
|
|
|
|
print(*args, file=sys.stderr, **kwargs) |
|
|
|
|
|
|
|
|
|
|
|
def print_filename_recursive(context: Context): |
|
|
|
|
|
return context.filename +\ |
|
|
|
|
|
((" (included from " + print_filename_recursive(context.parent) + ")") if context.parent else "") |
|
|
|
|
|
eprint(f"Error occured in file {print_filename_recursive(self.context)} in ", end="") |
|
|
|
|
|
line = None |
|
|
|
|
|
for i in range(len(self.elements)-1, 0, -1): |
|
|
|
|
|
if hasattr(self.elements[i], "content") and len(self.elements[i].content) > 0 and isinstance(self.elements[i].content[0], Inline) and line is None: |
|
|
|
|
|
line = self.elements[i] |
|
|
|
|
|
eprint(type(self.elements[i]).__name__ + "[" + (str(self.elements[i-1].index) if isinstance(self.elements[i-1].index, int) else "") + "]", end=": ") |
|
|
|
|
|
if line: |
|
|
|
|
|
eprint() |
|
|
|
|
|
eprint('on line: "' + stringify(line).strip() + '"', end="") |
|
|
|
|
|
eprint() |
|
|
|
|
|
eprint("in element: " + str(self.elements[0]).replace("\n", "\\n")) |
|
|
|
|
|
sys.tracebacklimit = 0 |
|
|
|
|
|
raise self.__cause__ from None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class OutputGenerator: |
|
|
class OutputGenerator: |
|
|
_empty_lines: int |
|
|
_empty_lines: int |
|
|
context: Union[Context, None] |
|
|
context: Union[Context, None] |
|
@ -101,6 +139,7 @@ class OutputGenerator: |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
def generate(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]]): |
|
|
def generate(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]]): |
|
|
|
|
|
try: |
|
|
if isinstance(e, Group): |
|
|
if isinstance(e, Group): |
|
|
old_context = self.context |
|
|
old_context = self.context |
|
|
self.context = e.context |
|
|
self.context = e.context |
|
@ -119,10 +158,16 @@ class OutputGenerator: |
|
|
else: |
|
|
else: |
|
|
try: |
|
|
try: |
|
|
self.TYPE_DICT_MISC[type(e)](e) |
|
|
self.TYPE_DICT_MISC[type(e)](e) |
|
|
except KeyError: |
|
|
except KeyError as err: |
|
|
raise UnknownElementError(type(e)) |
|
|
raise UnknownElementError(type(e)) from err |
|
|
if isinstance(e, Group): |
|
|
if isinstance(e, Group): |
|
|
self.context = old_context |
|
|
self.context = old_context |
|
|
|
|
|
except FormatitkoRecursiveError as err: |
|
|
|
|
|
if not isinstance(e, ListContainer): |
|
|
|
|
|
err.add_element(e) |
|
|
|
|
|
raise err |
|
|
|
|
|
except Exception as err: |
|
|
|
|
|
raise FormatitkoRecursiveError(e, self.context) from err |
|
|
|
|
|
|
|
|
def escape_special_chars(self, text: str) -> str: |
|
|
def escape_special_chars(self, text: str) -> str: |
|
|
return text |
|
|
return text |
|
|