Browse Source

Partials are now also isolated in output TeX and KaTeX. Also language is now so special it pops out to TeX as a macro at the start of each group.

pull/28/head
Jan Černohorský 2 years ago
parent
commit
5e475f6881
  1. 2
      context.py
  2. 11
      formatitko.py
  3. 2
      formatitko.tex
  4. 8
      group.py
  5. 7
      html.py
  6. 18
      katex-server/index.mjs
  7. 10
      katex.py
  8. 6
      test-partial.md
  9. 19
      test.md
  10. 8
      tex.py
  11. 4
      transform.py

2
context.py

@ -51,6 +51,8 @@ class Context:
return None
def set_metadata(self, key, value):
if key == "language":
print("WARN: Setting language this way doesn't propagate to TeX. Either use the Front Matter or specify it additionally using the \\languagexx macro.")
meta = self.doc.metadata
key = key.split(".")
for k in key[:-1]:

11
formatitko.py

@ -9,6 +9,7 @@ from typing import List
from transform import transform
from util import *
from context import Context
from group import Group
from katex import KatexClient
from html import html
from tex import tex
@ -16,15 +17,17 @@ from tex import tex
from mj_show import show
doc = import_md(open(sys.argv[1], "r").read())
language = doc.get_metadata("language", None, True)
print(show(doc))
context = Context(doc, sys.argv[1])
doc = doc.walk(transform, context)
print("---------------------")
print(show(doc))
doc.content = [Group(*doc.content, metadata={"language":language})]
#print("---------------------")
#print(show(doc))
#print(convert_text(doc, input_format="panflute", output_format="markdown"))
katexClient = KatexClient()
#print(katexClient.render("\\def\\Bruh{K^A\\TeX}"))
#print(katexClient.render("\\Bruh"))
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("\input formatitko.tex\n" + tex(doc))
#print(tex(doc))

2
formatitko.tex

@ -35,6 +35,8 @@
\def\figure#1#2{\vskip5pt\centerline{#1}\centerline{#2}\vskip5pt}
\def\caption#1{{\it #1}}
\let\image\putimage
\def\languagecs{} % KSP should define this to \cze probably
\def\languageen{} % KSP should define this to \eng probably
\def\table#1{#1}
\def\tablebody#1{#1}
\def\tablerow#1{#1}

8
group.py

@ -0,0 +1,8 @@
from panflute import Block
from typing import Dict
class Group(Block):
def __init__(self, *args, identifier='', classes=[], attributes={}, metadata={}):
self._set_ica(identifier, classes, attributes)
self._set_content(args, Block)
self.metadata = metadata

7
html.py

@ -8,6 +8,7 @@ from whitespace import NBSP
from transform import FQuoted
from katex import KatexClient
from util import inlinify
from group import Group
def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t") -> str:
@ -174,6 +175,12 @@ 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, Group):
k.begingroup()
ret = html(e.content, k, indent_level, indent_str)
k.endgroup()
return ret
if isinstance(e, Math):
formats = {
"DisplayMath": True,

18
katex-server/index.mjs

@ -77,17 +77,29 @@ function socketWrite(socket, data) {
* */
async function handleClient(client) {
const rl = readline.createInterface({ input: client })
const macroStack = [{}]
for await (const line of rl) {
try {
if (line === "begingroup") {
macroStack.push({...macroStack.slice(-1)[0]})
continue
} else if (line === "endgroup") {
macroStack.pop()
continue
}
const query = JSON.parse(line)
const results = []
for (const input of query.formulas) {
const options = input.options ?? query.options ?? defaultOptions
if (options.macros) {
for (const macro of Object.keys(options.macros)) {
macroStack.slice(-1)[macro] = options.macros[macro]
}
}
options.macros = macroStack.slice(-1)[0]
try {
const html = katex.renderToString(input.tex, options)
results.push({ html })
} catch (e) {
results.push({ error: String(e) })

10
katex.py

@ -25,8 +25,9 @@ class KatexClient:
break
def render(self, tex: str, options: Dict={}):
self._client.sendall((json.dumps({"formulas":[{"tex":tex, "options": options}]})+"\n").encode("utf-8"))
data = self._client.recv(128)
options["globalGroup"] = True
self._client.sendall((json.dumps({"formulas":[{"tex":tex}], "options":options})+"\n").encode("utf-8"))
data = self._client.recv(1024)
while data[-1] != 0x0a:
data += self._client.recv(128)
response = json.loads(data)
@ -37,3 +38,8 @@ class KatexClient:
else:
return response["results"][0]["html"]
def begingroup(self):
self._client.sendall("begingroup\n".encode("utf-8"))
def endgroup(self):
self._client.sendall("endgroup\n".encode("utf-8"))

6
test-partial.md

@ -1,5 +1,6 @@
---
title: A subfile!
language: "cs"
---
I am a little piece of content
@ -45,3 +46,8 @@ I am a duck.
This should be only shown to included cats.
:::
$$
\def\eqalign#1{NO, just, nooooo}
\eqalign{}
$$

19
test.md

@ -2,6 +2,7 @@
title: 'Wooooo a title'
subtitle: 'A subtitle'
are_we_there_yet: False
language: "en"
---
[#test-import.md]{}
@ -52,14 +53,14 @@ This should only be shown to cats the second time
![This is a figure, go figure...](/tmp/logo.png){width=10em}
![This is a figure, go figure...](/tmp/logo.svg){width=10em}
![Fakt epesní reproduktor](/tmp/reproduktor.jpeg){width=10em}
```python {.run}
ctx.set_metadata("language", "cs")
```
[!opendatatask]{}
```python {.run}
ctx.unset_metadata("language")
ctx.set_metadata("language","en")
```
[This too!]{if=cat}
@ -86,28 +87,22 @@ H~2~O is a liquid. 2^10^ is 1024.
[Underline]{.underline}
:::{only=tex}
:::{only=html}
$$
\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
}
\def\eqalign#1{\begin{align*}#1\end{align*}}
$$
:::
:::{only=html}
$$
\def\eqalign#1{\begin{align*}#1\end{align*}}
\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
}
$$
:::
<!-- TODO: This sucks -->
:::{partial=test-partial.md}
:::
---

8
tex.py

@ -3,6 +3,7 @@ from panflute import *
from whitespace import NBSP
from transform import FQuoted
from util import inlinify
from group import Group
# Heavily inspired by: git://git.ucw.cz/labsconf2022.git
def tex(e, indent_level: int=0, indent_str: str="\t") -> str:
@ -156,6 +157,13 @@ def tex(e, indent_level: int=0, indent_str: str="\t") -> str:
if isinstance(e, LineBlock):
return f'{tex(e.content, indent_level+1, indent_str)}\n'
if isinstance(e, Group):
tag = "begingroup"
open = ""
if "language" in e.metadata and e.metadata["language"] is not None:
open = "\\language"+e.metadata["language"]
close = "\\endgroup"
if isinstance(e, Div):
return f'{tex(e.content, indent_level+1, indent_str)}'

4
transform.py

@ -6,6 +6,7 @@ from whitespace import *
from command import *
from util import *
from context import *
from group import Group
class FQuoted(Quoted):
def __init__(self, *args, **kwargs):
@ -41,8 +42,9 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element
if (isinstance(e, Div)) and "partial" in e.attributes:
includedDoc = import_md(open(e.attributes["partial"], "r").read())
nContext = Context(includedDoc, e.attributes["partial"], c)
language = includedDoc.get_metadata("language")
includedDoc = includedDoc.walk(transform, nContext)
e = Div(*includedDoc.content)
e = Group(*includedDoc.content, metadata={"language": language})
if isinstance(e, Quoted):

Loading…
Cancel
Save