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}{tag}>"
+ 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}{tag}>'
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

+```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):