|
@ -2,7 +2,7 @@ from panflute import Element, ListContainer, Inline, Block |
|
|
from panflute import Cite, Code, Emph, Image, LineBreak, Link, Math, Note, Quoted, RawInline, SmallCaps, SoftBreak, Space, Span, Str, Strikeout, Strong, Subscript, Superscript, Underline |
|
|
from panflute import Cite, Code, Emph, Image, LineBreak, Link, Math, Note, Quoted, RawInline, SmallCaps, SoftBreak, Space, Span, Str, Strikeout, Strong, Subscript, Superscript, Underline |
|
|
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 typing import Union, Dict, List |
|
|
from typing import Union |
|
|
|
|
|
|
|
|
from .whitespace import NBSP |
|
|
from .whitespace import NBSP |
|
|
from .transform import FQuoted |
|
|
from .transform import FQuoted |
|
@ -20,9 +20,74 @@ class OutputGenerator: |
|
|
self.indent_str = indent_str |
|
|
self.indent_str = indent_str |
|
|
self.indent_level = initial_indent_level |
|
|
self.indent_level = initial_indent_level |
|
|
self._at_start_of_line = True |
|
|
self._at_start_of_line = True |
|
|
|
|
|
|
|
|
def generate(self, e: Union[Element, ListContainer, List[Union[Element, ListContainer]]]): |
|
|
self.TYPE_DICT_MISC = { |
|
|
if isinstance(e, List): |
|
|
TableRow: self.generate_TableRow, |
|
|
|
|
|
TableCell: self.generate_TableCell, |
|
|
|
|
|
Caption: self.generate_Caption, |
|
|
|
|
|
Doc: self.generate_Doc, |
|
|
|
|
|
LineItem: self.generate_LineItem, |
|
|
|
|
|
ListItem: self.generate_ListItem |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self.TYPE_DICT_BLOCK = { |
|
|
|
|
|
BlockQuote: self.generate_BlockQuote, |
|
|
|
|
|
BulletList: self.generate_BulletList, |
|
|
|
|
|
Citation: self.generate_Citation, |
|
|
|
|
|
CodeBlock: self.generate_CodeBlock, |
|
|
|
|
|
Definition: self.generate_Definition, |
|
|
|
|
|
DefinitionItem: self.generate_DefinitionItem, |
|
|
|
|
|
DefinitionList: self.generate_DefinitionList, |
|
|
|
|
|
Div: self.generate_Div, |
|
|
|
|
|
Figure: self.generate_Figure, |
|
|
|
|
|
Header: self.generate_Header, |
|
|
|
|
|
HorizontalRule: self.generate_HorizontalRule, |
|
|
|
|
|
LineBlock: self.generate_LineBlock, |
|
|
|
|
|
MetaBlocks: self.generate_MetaBlocks, |
|
|
|
|
|
MetaBool: self.generate_MetaBool, |
|
|
|
|
|
MetaInlines: self.generate_MetaInlines, |
|
|
|
|
|
MetaList: self.generate_MetaList, |
|
|
|
|
|
MetaMap: self.generate_MetaMap, |
|
|
|
|
|
MetaString: self.generate_MetaString, |
|
|
|
|
|
Null: self.generate_Null, |
|
|
|
|
|
OrderedList: self.generate_OrderedList, |
|
|
|
|
|
Para: self.generate_Para, |
|
|
|
|
|
Plain: self.generate_Plain, |
|
|
|
|
|
RawBlock: self.generate_RawBlock, |
|
|
|
|
|
Table: self.generate_Table, |
|
|
|
|
|
TableBody: self.generate_TableBody, |
|
|
|
|
|
TableFoot: self.generate_TableFoot, |
|
|
|
|
|
TableHead: self.generate_TableHead, |
|
|
|
|
|
Group: self.generate_Group |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self.TYPE_DICT_INLINE = { |
|
|
|
|
|
Cite: self.generate_Cite, |
|
|
|
|
|
Code: self.generate_Code, |
|
|
|
|
|
Emph: self.generate_Emph, |
|
|
|
|
|
Image: self.generate_Image, |
|
|
|
|
|
LineBreak: self.generate_LineBreak, |
|
|
|
|
|
Link: self.generate_Link, |
|
|
|
|
|
Math: self.generate_Math, |
|
|
|
|
|
Note: self.generate_Note, |
|
|
|
|
|
Quoted: self.generate_Quoted, |
|
|
|
|
|
RawInline: self.generate_RawInline, |
|
|
|
|
|
SmallCaps: self.generate_SmallCaps, |
|
|
|
|
|
SoftBreak: self.generate_SoftBreak, |
|
|
|
|
|
Space: self.generate_Space, |
|
|
|
|
|
Span: self.generate_Span, |
|
|
|
|
|
Str: self.generate_Str, |
|
|
|
|
|
Strikeout: self.generate_Strikeout, |
|
|
|
|
|
Strong: self.generate_Strong, |
|
|
|
|
|
Subscript: self.generate_Subscript, |
|
|
|
|
|
Superscript: self.generate_Superscript, |
|
|
|
|
|
Underline: self.generate_Underline, |
|
|
|
|
|
NBSP: self.generate_NBSP, |
|
|
|
|
|
FQuoted: self.generate_FQuoted |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
def generate(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]]): |
|
|
|
|
|
if isinstance(e, list): |
|
|
for el in e: |
|
|
for el in e: |
|
|
self.generate(el) |
|
|
self.generate(el) |
|
|
elif isinstance(e, ListContainer): |
|
|
elif isinstance(e, ListContainer): |
|
@ -33,14 +98,7 @@ class OutputGenerator: |
|
|
self.generate_Block(e) |
|
|
self.generate_Block(e) |
|
|
else: |
|
|
else: |
|
|
try: |
|
|
try: |
|
|
{ |
|
|
self.TYPE_DICT_MISC[type(e)](e) |
|
|
TableRow: self.generate_TableRow, |
|
|
|
|
|
TableCell: self.generate_TableCell, |
|
|
|
|
|
Caption: self.generate_Caption, |
|
|
|
|
|
Doc: self.generate_Doc, |
|
|
|
|
|
LineItem: self.generate_LineItem, |
|
|
|
|
|
ListItem: self.generate_ListItem |
|
|
|
|
|
}[type(e)](e) |
|
|
|
|
|
except KeyError: |
|
|
except KeyError: |
|
|
raise UnknownElementError(type(e)) |
|
|
raise UnknownElementError(type(e)) |
|
|
|
|
|
|
|
@ -80,22 +138,22 @@ class OutputGenerator: |
|
|
self.output_file.write("\n") |
|
|
self.output_file.write("\n") |
|
|
self._at_start_of_line = True |
|
|
self._at_start_of_line = True |
|
|
|
|
|
|
|
|
def start_tag(self, tag: str, attributes: Dict[str,str]={}) -> str: |
|
|
def start_tag(self, tag: str, attributes: dict[str,str]={}) -> str: |
|
|
return tag |
|
|
return tag |
|
|
|
|
|
|
|
|
def end_tag(self, tag: str, attributes: Dict[str,str]={}) -> str: |
|
|
def end_tag(self, tag: str, attributes: dict[str,str]={}) -> str: |
|
|
return "/" + tag |
|
|
return "/" + tag |
|
|
|
|
|
|
|
|
def single_tag(self, tag: str, attributes: Dict[str,str]={}) -> str: |
|
|
def single_tag(self, tag: str, attributes: dict[str,str]={}) -> str: |
|
|
return "/" + tag + "/" |
|
|
return "/" + tag + "/" |
|
|
|
|
|
|
|
|
def tagname(self, e) -> str: |
|
|
def tagname(self, e) -> str: |
|
|
return type(e).__name__ |
|
|
return type(e).__name__ |
|
|
|
|
|
|
|
|
def common_attributes(self, e: Element) -> Dict[str,str]: |
|
|
def common_attributes(self, e: Element) -> dict[str,str]: |
|
|
return {} |
|
|
return {} |
|
|
|
|
|
|
|
|
def generate_simple_tag(self, e: Union[Element, None]=None, tag: str="", attributes: Union[Dict[str,str],None]=None, content: Union[ListContainer, Element, List[Union[Element, ListContainer]], str, None]=None, inline: Union[bool, None]=None): |
|
|
def generate_simple_tag(self, e: Union[Element, None]=None, tag: str="", attributes: Union[dict[str,str],None]=None, content: Union[ListContainer, Element, list[Union[Element, ListContainer]], str, None]=None, inline: Union[bool, None]=None): |
|
|
if not tag and e: |
|
|
if not tag and e: |
|
|
tag = self.tagname(e) |
|
|
tag = self.tagname(e) |
|
|
if attributes is None and e: |
|
|
if attributes is None and e: |
|
@ -124,29 +182,29 @@ class OutputGenerator: |
|
|
else: |
|
|
else: |
|
|
self.generate_simple_block_tag(tag, content, attributes) |
|
|
self.generate_simple_block_tag(tag, content, attributes) |
|
|
|
|
|
|
|
|
def generate_simple_inline_tag(self, tag: str, content: Union[ListContainer, Element, List[Union[Element, ListContainer]]], attributes: Dict[str,str]={}): |
|
|
def generate_simple_inline_tag(self, tag: str, content: Union[ListContainer, Element, list[Union[Element, ListContainer]]], attributes: dict[str,str]={}): |
|
|
self.write(self.start_tag(tag, attributes)) |
|
|
self.write(self.start_tag(tag, attributes)) |
|
|
self.generate(content) |
|
|
self.generate(content) |
|
|
self.write(self.end_tag(tag)) |
|
|
self.write(self.end_tag(tag)) |
|
|
|
|
|
|
|
|
def generate_simple_block_tag(self, tag: str, content: Union[ListContainer, Element, List[Union[Element, ListContainer]]], attributes: Dict[str,str]={}): |
|
|
def generate_simple_block_tag(self, tag: str, content: Union[ListContainer, Element, list[Union[Element, ListContainer]]], attributes: dict[str,str]={}): |
|
|
self.writeln(self.start_tag(tag, attributes)) |
|
|
self.writeln(self.start_tag(tag, attributes)) |
|
|
self.indent_more() |
|
|
self.indent_more() |
|
|
self.generate(content) |
|
|
self.generate(content) |
|
|
self.indent_less() |
|
|
self.indent_less() |
|
|
self.writeln(self.end_tag(tag)) |
|
|
self.writeln(self.end_tag(tag)) |
|
|
|
|
|
|
|
|
def generate_raw_inline_tag(self, tag: str, text: str, attributes: Dict[str,str]={}): |
|
|
def generate_raw_inline_tag(self, tag: str, text: str, attributes: dict[str,str]={}): |
|
|
self.write(self.start_tag(tag, attributes)) |
|
|
self.write(self.start_tag(tag, attributes)) |
|
|
self.write(text) |
|
|
self.write(text) |
|
|
self.write(self.end_tag(tag)) |
|
|
self.write(self.end_tag(tag)) |
|
|
|
|
|
|
|
|
def generate_raw_block_tag(self, tag: str, text: str, attributes: Dict[str,str]={}): |
|
|
def generate_raw_block_tag(self, tag: str, text: str, attributes: dict[str,str]={}): |
|
|
self.writeln(self.start_tag(tag, attributes)) |
|
|
self.writeln(self.start_tag(tag, attributes)) |
|
|
self.writeraw(text) |
|
|
self.writeraw(text) |
|
|
self.writeln(self.end_tag(tag)) |
|
|
self.writeln(self.end_tag(tag)) |
|
|
|
|
|
|
|
|
def generate_empty_block_tag(self, tag: str, attributes: Dict[str,str]={}): |
|
|
def generate_empty_block_tag(self, tag: str, attributes: dict[str,str]={}): |
|
|
self.writeln(self.single_tag(tag, attributes)) |
|
|
self.writeln(self.single_tag(tag, attributes)) |
|
|
|
|
|
|
|
|
def generate_ListContainer(self, e: ListContainer): |
|
|
def generate_ListContainer(self, e: ListContainer): |
|
@ -154,30 +212,7 @@ class OutputGenerator: |
|
|
self.generate(child) |
|
|
self.generate(child) |
|
|
|
|
|
|
|
|
def generate_Inline(self, e: Inline): |
|
|
def generate_Inline(self, e: Inline): |
|
|
{ |
|
|
self.TYPE_DICT_INLINE[type(e)](e) |
|
|
Cite: self.generate_Cite, |
|
|
|
|
|
Code: self.generate_Code, |
|
|
|
|
|
Emph: self.generate_Emph, |
|
|
|
|
|
Image: self.generate_Image, |
|
|
|
|
|
LineBreak: self.generate_LineBreak, |
|
|
|
|
|
Link: self.generate_Link, |
|
|
|
|
|
Math: self.generate_Math, |
|
|
|
|
|
Note: self.generate_Note, |
|
|
|
|
|
Quoted: self.generate_Quoted, |
|
|
|
|
|
RawInline: self.generate_RawInline, |
|
|
|
|
|
SmallCaps: self.generate_SmallCaps, |
|
|
|
|
|
SoftBreak: self.generate_SoftBreak, |
|
|
|
|
|
Space: self.generate_Space, |
|
|
|
|
|
Span: self.generate_Span, |
|
|
|
|
|
Str: self.generate_Str, |
|
|
|
|
|
Strikeout: self.generate_Strikeout, |
|
|
|
|
|
Strong: self.generate_Strong, |
|
|
|
|
|
Subscript: self.generate_Subscript, |
|
|
|
|
|
Superscript: self.generate_Superscript, |
|
|
|
|
|
Underline: self.generate_Underline, |
|
|
|
|
|
NBSP: self.generate_NBSP, |
|
|
|
|
|
FQuoted: self.generate_FQuoted |
|
|
|
|
|
}[type(e)](e) |
|
|
|
|
|
|
|
|
|
|
|
def generate_Str(self, e: Str): |
|
|
def generate_Str(self, e: Str): |
|
|
self.write(self.escape_special_chars(e.text)) |
|
|
self.write(self.escape_special_chars(e.text)) |
|
@ -278,36 +313,7 @@ class OutputGenerator: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generate_Block(self, e: Block): |
|
|
def generate_Block(self, e: Block): |
|
|
{ |
|
|
self.TYPE_DICT_BLOCK[type(e)](e) |
|
|
BlockQuote: self.generate_BlockQuote, |
|
|
|
|
|
BulletList: self.generate_BulletList, |
|
|
|
|
|
Citation: self.generate_Citation, |
|
|
|
|
|
CodeBlock: self.generate_CodeBlock, |
|
|
|
|
|
Definition: self.generate_Definition, |
|
|
|
|
|
DefinitionItem: self.generate_DefinitionItem, |
|
|
|
|
|
DefinitionList: self.generate_DefinitionList, |
|
|
|
|
|
Div: self.generate_Div, |
|
|
|
|
|
Figure: self.generate_Figure, |
|
|
|
|
|
Header: self.generate_Header, |
|
|
|
|
|
HorizontalRule: self.generate_HorizontalRule, |
|
|
|
|
|
LineBlock: self.generate_LineBlock, |
|
|
|
|
|
MetaBlocks: self.generate_MetaBlocks, |
|
|
|
|
|
MetaBool: self.generate_MetaBool, |
|
|
|
|
|
MetaInlines: self.generate_MetaInlines, |
|
|
|
|
|
MetaList: self.generate_MetaList, |
|
|
|
|
|
MetaMap: self.generate_MetaMap, |
|
|
|
|
|
MetaString: self.generate_MetaString, |
|
|
|
|
|
Null: self.generate_Null, |
|
|
|
|
|
OrderedList: self.generate_OrderedList, |
|
|
|
|
|
Para: self.generate_Para, |
|
|
|
|
|
Plain: self.generate_Plain, |
|
|
|
|
|
RawBlock: self.generate_RawBlock, |
|
|
|
|
|
Table: self.generate_Table, |
|
|
|
|
|
TableBody: self.generate_TableBody, |
|
|
|
|
|
TableFoot: self.generate_TableFoot, |
|
|
|
|
|
TableHead: self.generate_TableHead, |
|
|
|
|
|
Group: self.generate_Group |
|
|
|
|
|
}[type(e)](e) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Block elements |
|
|
# Block elements |
|
@ -420,7 +426,7 @@ class OutputGenerator: |
|
|
self.generate_simple_tag(e) |
|
|
self.generate_simple_tag(e) |
|
|
|
|
|
|
|
|
# Maybe move this to ImageProcessor? |
|
|
# Maybe move this to ImageProcessor? |
|
|
def get_image_processor_args(self, attributes:Dict[str,str]) -> Dict: |
|
|
def get_image_processor_args(self, attributes:dict[str,str]) -> dict: |
|
|
# Attributes → image processor args |
|
|
# Attributes → image processor args |
|
|
additional_args = {} |
|
|
additional_args = {} |
|
|
if "file-width" in attributes: |
|
|
if "file-width" in attributes: |
|
|