|
|
@ -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 TableRow, TableCell, Caption, Doc |
|
|
|
from panflute import MetaValue |
|
|
|
from panflute import stringify |
|
|
|
from typing import Union, Callable |
|
|
|
|
|
|
|
from .whitespace import NBSP |
|
|
|
from .elements import FQuoted |
|
|
|
from .context import Group, InlineGroup, BlockGroup, Context |
|
|
|
|
|
|
|
import re |
|
|
|
|
|
|
|
import sys |
|
|
|
|
|
|
|
class UnknownElementError(Exception): |
|
|
|
"An unknown Element has been passed to the OutputGenerator, probably because panflute introduced a new one." |
|
|
|
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: |
|
|
|
_empty_lines: int |
|
|
|
context: Union[Context, None] |
|
|
@ -101,6 +139,7 @@ class OutputGenerator: |
|
|
|
} |
|
|
|
|
|
|
|
def generate(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]]): |
|
|
|
try: |
|
|
|
if isinstance(e, Group): |
|
|
|
old_context = self.context |
|
|
|
self.context = e.context |
|
|
@ -119,10 +158,16 @@ class OutputGenerator: |
|
|
|
else: |
|
|
|
try: |
|
|
|
self.TYPE_DICT_MISC[type(e)](e) |
|
|
|
except KeyError: |
|
|
|
raise UnknownElementError(type(e)) |
|
|
|
except KeyError as err: |
|
|
|
raise UnknownElementError(type(e)) from err |
|
|
|
if isinstance(e, Group): |
|
|
|
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: |
|
|
|
return text |
|
|
|