From 241e001023df7f670ef8569f45e6d3cf9b8d1e72 Mon Sep 17 00:00:00 2001 From: Greenscreener Date: Sat, 4 Feb 2023 18:49:24 +0100 Subject: [PATCH] Miscellaneous bugfixes, a huge TeX mess. --- .gitmodules | 3 ++ formatitko.py | 4 +-- formatitko.tex | 36 ++++++++++++++++++++++ html.py | 5 +++- test-import.md | 2 +- test.md | 48 ++++++++++++++++++++++++++---- tex.py | 81 ++++++++++++++++++++++++++++++++++++++++++-------- transform.py | 2 +- ucwmac | 1 + whitespace.py | 6 ++-- 10 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 .gitmodules create mode 100644 formatitko.tex create mode 160000 ucwmac diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..611d4fc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ucwmac"] + path = ucwmac + url = git://git.ucw.cz/ucwmac.git diff --git a/formatitko.py b/formatitko.py index 15c9fcf..e4587ea 100755 --- a/formatitko.py +++ b/formatitko.py @@ -22,9 +22,9 @@ print(show(doc)) context = Context(doc, sys.argv[1]) doc = doc.walk(transform, context) print("---------------------") -#print(show(doc)) +print(show(doc)) #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)) +open("output.tex", "w").write("\input formatitko.tex\n" + tex(doc)) #print(tex(doc)) diff --git a/formatitko.tex b/formatitko.tex new file mode 100644 index 0000000..fbcf448 --- /dev/null +++ b/formatitko.tex @@ -0,0 +1,36 @@ +\input luatex85.sty +\input ucwmac2.tex +\ucwmodule{luaofs} +\ucwmodule{link} +\ucwmodule{verb} +\parskip=3pt plus 2pt minus 1pt +\parindent=0sp + +\def\strong#1{{% +\def\emph##1{{\bi{}##1}}% +\bf{}#1% +}} +\def\emph#1{{% +\def\strong##1{{\bi{}##1}}% +\it{}#1% +}} + +\newcount\fncount +\fncount=1 +\def\fnmark{\leavevmode\raise3pt\hbox{\fiverm\the\fncount}} +\def\fn#1{\footnote\fnmark{#1}\advance\fncount by 1} + +\def\hA#1{{\parskip1em\settextsize{14}\bf #1}} +\def\hB#1{{\parskip1em\settextsize{12}\bf #1}} +\def\hC#1{{\parskip1em\settextsize{10}\bf #1}} +\def\hr{{\vskip5pt\hrule\vskip5pt}} +\long\def\blockquote#1{\vskip\lineskip\vskip\parskip\hbox{\vrule\hskip5pt\vbox{#1}}} +\def\code#1{{\tt #1}} +\let\codeblock\verbatim +\def\figure#1{#1} +\def\image#1{#1} +\def\table#1{#1} +\def\tablebody#1{#1} +\def\tablerow#1{#1} +\def\tablehead#1{#1} +\def\tablecell#1{#1} diff --git a/html.py b/html.py index 8421d0b..3074d26 100644 --- a/html.py +++ b/html.py @@ -10,6 +10,9 @@ from katex import KatexClient def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") -> str: + if hasattr(e, "attributes") and "only" in e.attributes and e.attributes["only"] != "html": + return "" + if isinstance(e, ListContainer): return ''.join([html(child, k, indent_level, indent_str) for child in e]) @@ -191,7 +194,7 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") return "" if isinstance(e, Inline): - return f"<{tag}{attributes}>{content_head}{html(e.content, k, 0, '')}{content_foot}" + return f'<{tag}{attributes}>{content_head}{html(e.content, k, 0, "") if hasattr(e, "_content") else ""}{e.text if hasattr(e, "text") else ""}{content_foot}' out_str = "" if not isinstance(e, Plain): diff --git a/test-import.md b/test-import.md index 678371b..c4f0a5c 100644 --- a/test-import.md +++ b/test-import.md @@ -3,5 +3,5 @@ appendChildren(element.content) ``` ```python {define=opendatatask} -println("Toto je praktická open-data úloha. V [odevzdávátku](https://ksp.mff.cuni.cz/h/odevzdavatko/) si necháte vygenerovat vstupy a odevzdáte příslušné výstupy. Záleží jen na vás, jak výstupy vyrobíte.") +println("Toto je praktická open-data úloha. V [odevzdávátku](https://ksp.mff.cuni.cz/h/odevzdavatko/) si necháte vygenerovat vstupy a odevzdáte příslušné výstupy. Záleží jen na vás, jak výstupy vyrobíte.") ``` diff --git a/test.md b/test.md index 931dcb3..f74b8c0 100644 --- a/test.md +++ b/test.md @@ -9,6 +9,11 @@ are_we_there_yet: False This is an *example* **yay**! +This is *very **strongly** emphasised* + +Příliš žluťoučký kůň pěl dábelské ódy. *Příliš žluťoučký kůň pěl dábelské ódy.* **Příliš žluťoučký kůň pěl dábelské ódy.** ***Příliš žluťoučký kůň pěl dábelské ódy.*** + + :::{partial=test-partial.md} ::: @@ -33,6 +38,8 @@ def bruh(no): wat ``` +Inline `code` + ::::{if=cat} This should only be shown to cats the second time :::: @@ -41,16 +48,25 @@ This should only be shown to cats the second time ![This is a figure, go figure...](/this/image/does/not/exist.jpg) +```python {.run} +ctx.set_metadata("language", "cs") +``` [!opendatatask]{} - +```python {.run} +ctx.unset_metadata("language") +``` [This too!]{if=cat} [What]{.co} [An inline command with contents and **bold** and another [!nop]{} inside!]{c=nop} -[!nop]{a=b} +[!nop]{a=b} +> OOO a blockquote mate init +> +>> Nesting?? +>> Woah A non-breakable space bro @@ -58,7 +74,19 @@ 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]. +This should be seen by all.^[This is a footnote] | Matematicko-fyzikální fakulta University Karlovy | Malostranské nám. 2/25 | 118 00 Praha 1 +More footnotes.^[I am a foot] + To Do: - buy eggs @@ -88,6 +121,8 @@ To Do: 2. Wooo 3. no +4) WOO + ``` {=html}
@@ -102,6 +137,7 @@ To Do: i. bro ii. wym bro + diff --git a/tex.py b/tex.py index 26a17e9..2c9e849 100644 --- a/tex.py +++ b/tex.py @@ -6,12 +6,28 @@ 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 hasattr(e, "attributes") and "only" in e.attributes and e.attributes["only"] != "tex": + return "" if isinstance(e, ListContainer): return ''.join([tex(child, indent_level, indent_str) for child in e]) + content_foot = "" + content_head = "" + + arguments = "" + open = "{" + close = "}" + + tag = e.tag.lower() + + tags = { + Header: "h"+chr(64 + e.level) if hasattr(e, "level") else "", + } + if type(e) in tags: + tag = tags[type(e)] + + not_implemented = { Citation: True, Cite: True, @@ -28,7 +44,7 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str: Null: "", LineBreak: f"\\\\", SoftBreak: f" ", - HorizontalRule: "% TODO: hrule" + HorizontalRule: "\\hr\n\n" } if type(e) in simple_string: return simple_string[type(e)] @@ -39,12 +55,6 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str: 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": @@ -64,12 +74,53 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str: else: return f'"{tex(e.content, 0, "")}"' + if isinstance(e, BulletList): + tag = "list" + open = "" + arguments = "{o}" + close = "\\endlist" + + if isinstance(e, OrderedList): + tag = "list" + open = "" + styles = { + "DefaultStyle": "n", + "Decimal": "n", + "LowerRoman": "i", + "UpperRoman:": "I", + "LowerAlpha": "a", + "UpperAlpha": "A" + } + style = styles[e.style] + delimiters = { + "DefaultDelim": f"{style}.", + "Period": f"{style}.", + "OneParen": f"{style})", + "TwoParens": f"({style})" + } + style = delimiters[e.delimiter] + arguments = f"{{{style}}}" + close = "\\endlist" + # FIXME: Starting number of list + + if isinstance(e, ListItem): + tag = ":" + + if isinstance(e, Link): + tag = "linkurl" + arguments = f'{{{e.url}}}' + if isinstance(e, Math): if e.format == "DisplayMath": return f'$${e.text}$$\n' else: return f'${e.text}$' + if isinstance(e, Note): + tag = "fn" + if len(e.content) == 1 and isinstance(e.content[0], Para): + return f'\\fn{{{tex(e.content[0].content, 0, "")}}}' + if isinstance(e, RawInline): if e.format == "tex": return e.text @@ -85,6 +136,12 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str: if isinstance(e, Span) or isinstance(e, Plain): return tex(e.content, 0, "") + if isinstance(e, LineItem): + return tex(e.content, 0, "") + ("\\\\\n" if e.next else "\n") + + if isinstance(e, LineBlock): + return f'{tex(e.content, indent_level+1, indent_str)}\n' + if isinstance(e, Div): return f'{tex(e.content, indent_level+1, indent_str)}' @@ -92,15 +149,15 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str: 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})" + return f'\\{tag}{arguments}{open}{content_head}{tex(e.content, 0, "") if hasattr(e, "_content") else ""}{e.text if hasattr(e, "text") else ""}{content_foot}{close}' out_str = "" - out_str = f"({e.tag}){{" + out_str = f"\\{tag}{arguments}{open}\n" 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" + out_str += f"{content_foot}\n{close}\n\n" return out_str diff --git a/transform.py b/transform.py index be158d6..87dff03 100644 --- a/transform.py +++ b/transform.py @@ -97,7 +97,7 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element elif isinstance(val, MetaBool): e = Span(Str(str(val.boolean))) else: - raise ValueError(f"Cannot print value of metadatum {e.content[0].text[1:]}") + raise TypeError(f"Cannot print value of metadatum '{e.content[0].text[1:]}' of type '{type(val)}'") ## Execute commands # panflute's walk transforms the children first, then the root element, so diff --git a/ucwmac b/ucwmac new file mode 160000 index 0000000..18104ac --- /dev/null +++ b/ucwmac @@ -0,0 +1 @@ +Subproject commit 18104ac1a84b61b09564bd3d8ab0948e502c51e3 diff --git a/whitespace.py b/whitespace.py index 5b1ecc1..28a5336 100644 --- a/whitespace.py +++ b/whitespace.py @@ -14,8 +14,10 @@ def bavlna(e: Whitespace, c: Context) -> bool: if c.get_metadata("language") == "cs": - if isinstance(e.prev, Str) and isinstance(e.next, Str): - if e.prev.text.lower() in ['k', 's', 'v', 'z', 'o', 'u', 'a', 'i']: + prev = e.prev if isinstance(e.prev, Str) else (e.prev.content[-1] if hasattr(e.prev, "content") and len(e.prev.content) != 0 else None) + next = e.next if isinstance(e.next, Str) else (e.next.content[0] if hasattr(e.next, "content") and len(e.next.content) != 0 else None) + if isinstance(prev, Str) and isinstance(next, Str): + if prev.text.lower() in ['k', 's', 'v', 'z', 'o', 'u', 'a', 'i']: return True if isinstance(e.prev, Str) and isinstance(e.next, Str):