Browse Source

Started working on TeX output, minor bugfixes.

pull/28/head
Jan Černohorský 2 years ago
parent
commit
1e9054a909
  1. 5
      formatitko.py
  2. 18
      html.py
  3. 8
      test.md
  4. 106
      tex.py
  5. 8
      transform.py

5
formatitko.py

@ -9,8 +9,9 @@ from typing import List
from transform import transform from transform import transform
from util import * from util import *
from context import Context from context import Context
from html import html
from katex import KatexClient from katex import KatexClient
from html import html
from tex import tex
from mj_show import show from mj_show import show
@ -25,3 +26,5 @@ print("---------------------")
#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))
#print(tex(doc))

18
html.py

@ -18,6 +18,9 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t")
content_foot = "" content_foot = ""
content_head = "" content_head = ""
if isinstance(e, Str):
return e.text.replace(" ", "&nbsp;")
tags = { tags = {
BulletList: "ul", BulletList: "ul",
Doc: "main", Doc: "main",
@ -56,7 +59,7 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t")
Space: " ", Space: " ",
Null: "", Null: "",
LineBreak: f"\n{indent_level*indent_str}<br>\n{indent_level*indent_str}", LineBreak: f"\n{indent_level*indent_str}<br>\n{indent_level*indent_str}",
SoftBreak: f"\n{indent_level*indent_str}<br>\n{indent_level*indent_str}", SoftBreak: f" ",
HorizontalRule: f"{indent_level*indent_str}<hr>\n" HorizontalRule: f"{indent_level*indent_str}<hr>\n"
} }
if type(e) in simple_string: 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: else:
return f'"{html(e.content, k, 0, "")}"' return f'"{html(e.content, k, 0, "")}"'
if isinstance(e, Str):
return e.text.replace(" ", "&nbsp;")
if isinstance(e, Math): if isinstance(e, Math):
formats = { formats = {
"DisplayMath": True, "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. # and are forgotten in the next one.
return indent_level*indent_str + k.render(e.text, {"displayMode": formats[e.format]}) return indent_level*indent_str + k.render(e.text, {"displayMode": formats[e.format]})
if isinstance(e, RawInline) and e.format == "html": if isinstance(e, RawInline):
if e.format == "html":
return e.text return e.text
else:
return ""
if isinstance(e, RawBlock) and e.format == "html": if isinstance(e, RawBlock):
if e.format == "html":
return f'{e.text}\n' return f'{e.text}\n'
else:
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, '')}{content_foot}</{tag}>"

8
test.md

@ -56,6 +56,8 @@ A non-breakable&nbsp;space bro
A lot of spaces 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:
<!--
$$ $$
\def\eqalign#1{\begin{align*}#1\end{align*}} \def\eqalign#1{\begin{align*}#1\end{align*}}
\eqalign{ \eqalign{
@ -63,7 +65,9 @@ $$
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
} }
$$ $$-->
---
This should be seen by all^[This is a footnote]. 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 | Malostranské nám. 2/25
| 118 00 Praha 1 | 118 00 Praha 1
TODO: To Do:
- buy eggs - buy eggs
- buy milk - buy milk

106
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("&nbsp;", "~")
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

8
transform.py

@ -49,13 +49,15 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element
quote_styles = { quote_styles = {
"cs": "cs", "cs": "cs",
"en": "en", "en": "en",
"sk": "cs" "sk": "cs",
None: None
} }
e = FQuoted(*e.content, quote_type=e.quote_type, style=quote_styles[c.get_metadata("language")]) e = FQuoted(*e.content, quote_type=e.quote_type, style=quote_styles[c.get_metadata("language")])
# Execute python code inside source code block # 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: 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 ## Command defines
# possible TODO: def/longdef? # 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"]): if not c.get_command(e.attributes["c"]):
raise NameError(f"Command not defined '{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 = e.replaceSelf(executeCommand(c.get_command(e.attributes["c"]), e, c))
e.walk(transform, c) e = e.walk(transform, c)
return e return e

Loading…
Cancel
Save