You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.5 KiB
106 lines
2.5 KiB
from panflute import *
|
|
|
|
from whitespace import NBSP
|
|
from transform import FQuoted
|
|
|
|
# Heavily inspired by: git://git.ucw.cz/labsconf2022.git
|
|
def tex(e, indent_level: int=0, indent_str: str="\t") -> str:
|
|
|
|
content_foot = ""
|
|
content_head = ""
|
|
|
|
if isinstance(e, ListContainer):
|
|
return ''.join([tex(child, indent_level, indent_str) for child in e])
|
|
|
|
not_implemented = {
|
|
Citation: True,
|
|
Cite: True,
|
|
Definition: True,
|
|
DefinitionItem: True,
|
|
DefinitionList: True
|
|
}
|
|
if type(e) in not_implemented:
|
|
return f'% FIXME: {type(e)}s not implemented \n'
|
|
|
|
simple_string = {
|
|
NBSP: "~",
|
|
Space: " ",
|
|
Null: "",
|
|
LineBreak: f"\\\\",
|
|
SoftBreak: f" ",
|
|
HorizontalRule: "% TODO: hrule"
|
|
}
|
|
if type(e) in simple_string:
|
|
return simple_string[type(e)]
|
|
|
|
if isinstance(e, Str):
|
|
return e.text.replace(" ", "~").replace(" ", "~")
|
|
|
|
if isinstance(e, Para):
|
|
return tex(e.content, 0, "")+"\n\n"
|
|
|
|
if isinstance(e, Emph):
|
|
return f'{{\\it {tex(e.content, 0, "")}}}'
|
|
|
|
if isinstance(e, Strong):
|
|
return f'{{\\bf {tex(e.content, 0, "")}}}'
|
|
|
|
if isinstance(e, FQuoted):
|
|
if e.style == "cs":
|
|
if e.quote_type == "SingleQuote":
|
|
return f'‚{tex(e.content, 0, "")}‘'
|
|
elif e.quote_type == "DoubleQuote":
|
|
return f'„{tex(e.content, 0, "")}“'
|
|
elif e.style == "en":
|
|
if e.quote_type == "SingleQuote":
|
|
return f'‘{tex(e.content, 0, "")}’'
|
|
elif e.quote_type == "DoubleQuote":
|
|
return f'“{tex(e.content, 0, "")}”'
|
|
else:
|
|
if e.quote_type == "SingleQuote":
|
|
return f'\'{tex(e.content, 0, "")}\''
|
|
elif e.quote_type == "DoubleQuote":
|
|
return f'"{tex(e.content, 0, "")}"'
|
|
else:
|
|
return f'"{tex(e.content, 0, "")}"'
|
|
|
|
if isinstance(e, Math):
|
|
if e.format == "DisplayMath":
|
|
return f'$${e.text}$$\n'
|
|
else:
|
|
return f'${e.text}$'
|
|
|
|
if isinstance(e, RawInline):
|
|
if e.format == "tex":
|
|
return e.text
|
|
else:
|
|
return ""
|
|
|
|
if isinstance(e, RawBlock):
|
|
if e.format == "tex":
|
|
return f'{e.text}\n'
|
|
else:
|
|
return ""
|
|
|
|
if isinstance(e, Span) or isinstance(e, Plain):
|
|
return tex(e.content, 0, "")
|
|
|
|
if isinstance(e, Div):
|
|
return f'{tex(e.content, indent_level+1, indent_str)}'
|
|
|
|
if isinstance(e, Doc):
|
|
return tex(e.content, indent_level, indent_str)+"\n\\bye"
|
|
|
|
if isinstance(e, Inline):
|
|
return f"({e.tag}){content_head}{tex(e.content, 0, '')}{content_foot}(/{e.tag})"
|
|
|
|
out_str = ""
|
|
out_str = f"({e.tag}){{"
|
|
out_str += content_head
|
|
if hasattr(e, "_content"):
|
|
out_str += tex(e.content, indent_level+1, indent_str)
|
|
if hasattr(e, "text"):
|
|
out_str += e.text
|
|
out_str += f"{content_foot}}}\n\n"
|
|
|
|
return out_str
|
|
|