|
|
@ -1,11 +1,12 @@ |
|
|
|
from panflute import * |
|
|
|
from whitespace import NBSP |
|
|
|
from transform import FQuoted |
|
|
|
from katex import KatexClient |
|
|
|
|
|
|
|
def html(e: Element, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
|
|
|
|
if isinstance(e, ListContainer): |
|
|
|
return ''.join([html(child, indent_level, indent_str) for child in e]) |
|
|
|
return ''.join([html(child, k, indent_level, indent_str) for child in e]) |
|
|
|
|
|
|
|
tag = e.tag.lower() |
|
|
|
attributes = "" |
|
|
@ -67,14 +68,14 @@ def html(e: Element, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
tag = "pre" |
|
|
|
|
|
|
|
if isinstance(e, Figure): |
|
|
|
content_foot = html(e.caption, indent_level+1, indent_str) |
|
|
|
content_foot = html(e.caption, k, indent_level+1, indent_str) |
|
|
|
|
|
|
|
if isinstance(e, Caption): |
|
|
|
tag = "figcaption" |
|
|
|
|
|
|
|
if isinstance(e, Image): |
|
|
|
# TODO: Image processing |
|
|
|
return f'<img src="{e.url}" alt="{e.title or html(e.content, 0, "")}">' |
|
|
|
return f'<img src="{e.url}" alt="{e.title or html(e.content, k, 0, "")}">' |
|
|
|
|
|
|
|
if isinstance(e, Header): |
|
|
|
tag = "h"+str(e.level) |
|
|
@ -86,13 +87,13 @@ def html(e: Element, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
attributes += f' title="{e.title}"' |
|
|
|
|
|
|
|
if isinstance(e, LineItem): |
|
|
|
return indent_level*indent_str + html(e.content) + "<br>\n" |
|
|
|
return indent_level*indent_str + html(e.content, k) + "<br>\n" |
|
|
|
|
|
|
|
if isinstance(e, Note): |
|
|
|
content_head = "(" |
|
|
|
content_foot = ")" |
|
|
|
if len(e.content) == 1 and isinstance(e.content[0], Para): |
|
|
|
return f' <note>({html(e.content[0].content, 0, "")})</note>' |
|
|
|
return f' <note>({html(e.content[0].content, k, 0, "")})</note>' |
|
|
|
|
|
|
|
if isinstance(e, OrderedList): |
|
|
|
tag = "ol" |
|
|
@ -110,8 +111,8 @@ def html(e: Element, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
# FIXME: Delimeter styles |
|
|
|
|
|
|
|
if isinstance(e, Table): |
|
|
|
content_head = html(e.head, indent_level+1, indent_str) |
|
|
|
content_foot = html(e.foot, indent_level+1, indent_str) |
|
|
|
content_head = html(e.head, k, indent_level+1, indent_str) |
|
|
|
content_foot = html(e.foot, k, indent_level+1, indent_str) |
|
|
|
# FIXME: Fancy pandoc tables, using colspec |
|
|
|
|
|
|
|
if isinstance(e, TableCell): |
|
|
@ -131,28 +132,34 @@ def html(e: Element, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
if isinstance(e, FQuoted): |
|
|
|
if e.style == "cs": |
|
|
|
if e.quote_type == "SingleQuote": |
|
|
|
return f'‚{html(e.content, 0, "")}‘' |
|
|
|
return f'‚{html(e.content, k, 0, "")}‘' |
|
|
|
elif e.quote_type == "DoubleQuote": |
|
|
|
return f'„{html(e.content, 0, "")}“' |
|
|
|
return f'„{html(e.content, k, 0, "")}“' |
|
|
|
elif e.style == "en": |
|
|
|
if e.quote_type == "SingleQuote": |
|
|
|
return f'‘{html(e.content, 0, "")}’' |
|
|
|
return f'‘{html(e.content, k, 0, "")}’' |
|
|
|
elif e.quote_type == "DoubleQuote": |
|
|
|
return f'“{html(e.content, 0, "")}”' |
|
|
|
return f'“{html(e.content, k, 0, "")}”' |
|
|
|
else: |
|
|
|
if e.quote_type == "SingleQuote": |
|
|
|
return f'\'{html(e.content, 0, "")}\'' |
|
|
|
return f'\'{html(e.content, k, 0, "")}\'' |
|
|
|
elif e.quote_type == "DoubleQuote": |
|
|
|
return f'"{html(e.content, 0, "")}"' |
|
|
|
return f'"{html(e.content, k, 0, "")}"' |
|
|
|
else: |
|
|
|
return f'"{html(e.content, 0, "")}"' |
|
|
|
return f'"{html(e.content, k, 0, "")}"' |
|
|
|
|
|
|
|
if isinstance(e, Str): |
|
|
|
return e.text.replace(" ", " ") |
|
|
|
|
|
|
|
if isinstance(e, Math): |
|
|
|
# TODO |
|
|
|
return "TODO: MATH" |
|
|
|
formats = { |
|
|
|
"DisplayMath": True, |
|
|
|
"InlineMath": False |
|
|
|
} |
|
|
|
# FIXME: Currently, all bits of math are isolated from each other, this |
|
|
|
# means that \defs and and alike work only inside a single math block |
|
|
|
# and are forgotten in the next one. |
|
|
|
return indent_level*indent_str + k.render(e.text, {"displayMode": formats[e.format]}) |
|
|
|
|
|
|
|
if isinstance(e, RawInline) and e.format == "html": |
|
|
|
return e.text |
|
|
@ -161,7 +168,7 @@ def html(e: Element, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
return f'{e.text}\n' |
|
|
|
|
|
|
|
if isinstance(e, Inline): |
|
|
|
return f"<{tag}{attributes}>{content_head}{html(e.content, 0, '')}{content_foot}</{tag}>" |
|
|
|
return f"<{tag}{attributes}>{content_head}{html(e.content, k, 0, '')}{content_foot}</{tag}>" |
|
|
|
|
|
|
|
out_str = "" |
|
|
|
if not isinstance(e, Plain): |
|
|
@ -170,7 +177,7 @@ def html(e: Element, indent_level: int=0, indent_str: str="\t") -> str: |
|
|
|
if hasattr(e, "_content"): |
|
|
|
if len(e.content) > 0 and isinstance(e.content[0], Inline): |
|
|
|
out_str += (indent_level+1)*indent_str |
|
|
|
out_str += html(e.content, indent_level+1, indent_str) |
|
|
|
out_str += html(e.content, k, indent_level+1, indent_str) |
|
|
|
if hasattr(e, "text"): |
|
|
|
out_str += e.text |
|
|
|
out_str += f"{content_foot}\n" |
|
|
|