Browse Source

Miscellaneous bugfixes, a huge TeX mess.

pull/28/head
Jan Černohorský 1 year ago
parent
commit
241e001023
  1. 3
      .gitmodules
  2. 4
      formatitko.py
  3. 36
      formatitko.tex
  4. 5
      html.py
  5. 2
      test-import.md
  6. 48
      test.md
  7. 81
      tex.py
  8. 2
      transform.py
  9. 1
      ucwmac
  10. 6
      whitespace.py

3
.gitmodules

@ -0,0 +1,3 @@
[submodule "ucwmac"]
path = ucwmac
url = git://git.ucw.cz/ucwmac.git

4
formatitko.py

@ -22,9 +22,9 @@ print(show(doc))
context = Context(doc, sys.argv[1]) context = Context(doc, sys.argv[1])
doc = doc.walk(transform, context) doc = doc.walk(transform, context)
print("---------------------") print("---------------------")
#print(show(doc)) print(show(doc))
#print(convert_text(doc, input_format="panflute", output_format="markdown")) #print(convert_text(doc, input_format="panflute", output_format="markdown"))
katexClient = KatexClient() katexClient = KatexClient()
open("output.html", "w").write("<head> <meta charset='utf-8'> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css' integrity='sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0' crossorigin='anonymous'> </head>" + html(doc, katexClient)) open("output.html", "w").write("<head> <meta charset='utf-8'> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css' integrity='sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0' crossorigin='anonymous'> </head>" + html(doc, katexClient))
open("output.tex", "w").write(tex(doc)) open("output.tex", "w").write("\input formatitko.tex\n" + tex(doc))
#print(tex(doc)) #print(tex(doc))

36
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}

5
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: 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): if isinstance(e, ListContainer):
return ''.join([html(child, k, indent_level, indent_str) for child in e]) 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 "" return ""
if isinstance(e, Inline): 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 = "" out_str = ""
if not isinstance(e, Plain): if not isinstance(e, Plain):

2
test-import.md

@ -3,5 +3,5 @@ appendChildren(element.content)
``` ```
```python {define=opendatatask} ```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.")
``` ```

48
test.md

@ -9,6 +9,11 @@ are_we_there_yet: False
This is an *example* **yay**! 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} :::{partial=test-partial.md}
::: :::
@ -33,6 +38,8 @@ def bruh(no):
wat wat
``` ```
Inline `code`
::::{if=cat} ::::{if=cat}
This should only be shown to cats the second time 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) ![This is a figure, go figure...](/this/image/does/not/exist.jpg)
```python {.run}
ctx.set_metadata("language", "cs")
```
[!opendatatask]{} [!opendatatask]{}
```python {.run}
ctx.unset_metadata("language")
```
[This too!]{if=cat} [This too!]{if=cat}
[What]{.co} [What]{.co}
[An inline command with contents and **bold** and another [!nop]{} inside!]{c=nop} [An inline command with contents and **bold** and another [!nop]{} inside!]{c=nop}
[!nop]{a=b} <!-- A special command! WOW --> [!nop]{a=b}<!-- A special command! WOW -->
> OOO a blockquote mate init
>
>> Nesting??
>> Woah
A non-breakable&nbsp;space bro A non-breakable&nbsp;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: A text with some inline math: $\sum_{i=1}^nn^2$. Plus some display math:
<!--
:::{only=tex}
$$
\eqalign{
2 x_2 + 6 x_3 &= 14 \cr
x_1 - 3 x_2 + 2 x_3 &= 5 \cr
-x_1 + 4 x_2 + \phantom{1} x_3 &= 2
}
$$
:::
:::{only=html}
$$ $$
\def\eqalign#1{\begin{align*}#1\end{align*}} \def\eqalign#1{\begin{align*}#1\end{align*}}
\eqalign{ \eqalign{
@ -66,16 +94,21 @@ $$
x_1 - 3 x_2 + 2 x_3 &= 5 \cr x_1 - 3 x_2 + 2 x_3 &= 5 \cr
-x_1 + 4 x_2 + \phantom{1} x_3 &= 2 -x_1 + 4 x_2 + \phantom{1} x_3 &= 2
} }
$$--> $$
:::
<!-- TODO: This sucks -->
--- ---
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 | Matematicko-fyzikální fakulta University Karlovy
| Malostranské nám. 2/25 | Malostranské nám. 2/25
| 118 00 Praha 1 | 118 00 Praha 1
More footnotes.^[I am a foot]
To Do: To Do:
- buy eggs - buy eggs
@ -88,6 +121,8 @@ To Do:
2. Wooo 2. Wooo
3. no 3. no
4) WOO
``` {=html} ``` {=html}
<figure> <figure>
<video src="woah.mp4" autoplay></video> <video src="woah.mp4" autoplay></video>
@ -102,6 +137,7 @@ To Do:
i. bro i. bro
ii. wym bro ii. wym bro
<!--
+---------------------+-----------------------+ +---------------------+-----------------------+
| Location | Temperature 1961-1990 | | Location | Temperature 1961-1990 |
| | in degree Celsius | | | in degree Celsius |
@ -119,4 +155,4 @@ ii. wym bro
123 123 123 123 123 123 123 123
1 1 1 1 1 1 1 1
------- ------ ---------- ------- ------- ------ ---------- -------
-->

81
tex.py

@ -6,12 +6,28 @@ from transform import FQuoted
# Heavily inspired by: git://git.ucw.cz/labsconf2022.git # Heavily inspired by: git://git.ucw.cz/labsconf2022.git
def tex(e, indent_level: int=0, indent_str: str="\t") -> str: def tex(e, indent_level: int=0, indent_str: str="\t") -> str:
content_foot = "" if hasattr(e, "attributes") and "only" in e.attributes and e.attributes["only"] != "tex":
content_head = "" return ""
if isinstance(e, ListContainer): if isinstance(e, ListContainer):
return ''.join([tex(child, indent_level, indent_str) for child in e]) 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 = { not_implemented = {
Citation: True, Citation: True,
Cite: True, Cite: True,
@ -28,7 +44,7 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str:
Null: "", Null: "",
LineBreak: f"\\\\", LineBreak: f"\\\\",
SoftBreak: f" ", SoftBreak: f" ",
HorizontalRule: "% TODO: hrule" HorizontalRule: "\\hr\n\n"
} }
if type(e) in simple_string: if type(e) in simple_string:
return simple_string[type(e)] 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): if isinstance(e, Para):
return tex(e.content, 0, "")+"\n\n" 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 isinstance(e, FQuoted):
if e.style == "cs": if e.style == "cs":
if e.quote_type == "SingleQuote": if e.quote_type == "SingleQuote":
@ -64,12 +74,53 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str:
else: else:
return f'"{tex(e.content, 0, "")}"' 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 isinstance(e, Math):
if e.format == "DisplayMath": if e.format == "DisplayMath":
return f'$${e.text}$$\n' return f'$${e.text}$$\n'
else: else:
return f'${e.text}$' 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 isinstance(e, RawInline):
if e.format == "tex": if e.format == "tex":
return e.text 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): if isinstance(e, Span) or isinstance(e, Plain):
return tex(e.content, 0, "") 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): if isinstance(e, Div):
return f'{tex(e.content, indent_level+1, indent_str)}' 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" return tex(e.content, indent_level, indent_str)+"\n\\bye"
if isinstance(e, Inline): 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 = ""
out_str = f"({e.tag}){{" out_str = f"\\{tag}{arguments}{open}\n"
out_str += content_head out_str += content_head
if hasattr(e, "_content"): if hasattr(e, "_content"):
out_str += tex(e.content, indent_level+1, indent_str) out_str += tex(e.content, indent_level+1, indent_str)
if hasattr(e, "text"): if hasattr(e, "text"):
out_str += 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 return out_str

2
transform.py

@ -97,7 +97,7 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element
elif isinstance(val, MetaBool): elif isinstance(val, MetaBool):
e = Span(Str(str(val.boolean))) e = Span(Str(str(val.boolean)))
else: 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 ## Execute commands
# panflute's walk transforms the children first, then the root element, so # panflute's walk transforms the children first, then the root element, so

1
ucwmac

@ -0,0 +1 @@
Subproject commit 18104ac1a84b61b09564bd3d8ab0948e502c51e3

6
whitespace.py

@ -14,8 +14,10 @@ def bavlna(e: Whitespace, c: Context) -> bool:
if c.get_metadata("language") == "cs": if c.get_metadata("language") == "cs":
if isinstance(e.prev, Str) and isinstance(e.next, Str): 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)
if e.prev.text.lower() in ['k', 's', 'v', 'z', 'o', 'u', 'a', 'i']: 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 return True
if isinstance(e.prev, Str) and isinstance(e.next, Str): if isinstance(e.prev, Str) and isinstance(e.next, Str):

Loading…
Cancel
Save