diff --git a/formatitko.py b/formatitko.py index 5d51685..15c9fcf 100755 --- a/formatitko.py +++ b/formatitko.py @@ -9,8 +9,9 @@ from typing import List from transform import transform from util import * from context import Context -from html import html from katex import KatexClient +from html import html +from tex import tex from mj_show import show @@ -25,3 +26,5 @@ print("---------------------") #print(convert_text(doc, input_format="panflute", output_format="markdown")) katexClient = KatexClient() open("output.html", "w").write(" " + html(doc, katexClient)) +open("output.tex", "w").write(tex(doc)) +#print(tex(doc)) diff --git a/html.py b/html.py index 835a4fb..8421d0b 100644 --- a/html.py +++ b/html.py @@ -18,6 +18,9 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") content_foot = "" content_head = "" + if isinstance(e, Str): + return e.text.replace(" ", " ") + tags = { BulletList: "ul", Doc: "main", @@ -56,7 +59,7 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") Space: " ", Null: "", LineBreak: f"\n{indent_level*indent_str}
\n{indent_level*indent_str}", - SoftBreak: f"\n{indent_level*indent_str}
\n{indent_level*indent_str}", + SoftBreak: f" ", HorizontalRule: f"{indent_level*indent_str}
\n" } if type(e) in simple_string: @@ -165,9 +168,6 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") else: return f'"{html(e.content, k, 0, "")}"' - if isinstance(e, Str): - return e.text.replace(" ", " ") - if isinstance(e, Math): formats = { "DisplayMath": True, @@ -178,11 +178,17 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") # 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 + if isinstance(e, RawInline): + if e.format == "html": + return e.text + else: + return "" - if isinstance(e, RawBlock) and e.format == "html": - return f'{e.text}\n' + if isinstance(e, RawBlock): + if e.format == "html": + return f'{e.text}\n' + else: + return "" if isinstance(e, Inline): return f"<{tag}{attributes}>{content_head}{html(e.content, k, 0, '')}{content_foot}" diff --git a/test.md b/test.md index bff9df2..8febf7a 100644 --- a/test.md +++ b/test.md @@ -56,6 +56,8 @@ A non-breakable space bro A lot of spaces A text with some inline math: $\sum_{i=1}^nn^2$. Plus some display math: + + + +--- This should be seen by all^[This is a footnote]. @@ -71,7 +75,7 @@ This should be seen by all^[This is a footnote]. | Malostranské nám. 2/25 | 118 00 Praha 1 -TODO: +To Do: - buy eggs - buy milk diff --git a/tex.py b/tex.py new file mode 100644 index 0000000..26a17e9 --- /dev/null +++ b/tex.py @@ -0,0 +1,106 @@ +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 diff --git a/transform.py b/transform.py index e9ba497..4478570 100644 --- a/transform.py +++ b/transform.py @@ -49,13 +49,15 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element quote_styles = { "cs": "cs", "en": "en", - "sk": "cs" + "sk": "cs", + None: None } e = FQuoted(*e.content, quote_type=e.quote_type, style=quote_styles[c.get_metadata("language")]) # Execute python code inside source code block if isinstance(e, CodeBlock) and hasattr(e, "classes") and "python" in e.classes and "run" in e.classes: - e = executeCommand(e.text, None, c) + e = Div(*executeCommand(e.text, None, c)) + e = e.walk(transform, c) ## Command defines # possible TODO: def/longdef? @@ -91,6 +93,6 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element if not c.get_command(e.attributes["c"]): raise NameError(f"Command not defined '{e.attributes['c']}'.") e = e.replaceSelf(executeCommand(c.get_command(e.attributes["c"]), e, c)) - e.walk(transform, c) + e = e.walk(transform, c) return e