Started working on KaTeX integration.
This commit is contained in:
parent
aa46599f2e
commit
f71eea3c06
8 changed files with 160 additions and 2 deletions
|
@ -10,6 +10,7 @@ from transform import transform
|
||||||
from util import *
|
from util import *
|
||||||
from context import Context
|
from context import Context
|
||||||
from html import html
|
from html import html
|
||||||
|
from katex import KatexClient
|
||||||
|
|
||||||
from mj_show import show
|
from mj_show import show
|
||||||
|
|
||||||
|
@ -22,5 +23,7 @@ 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"))
|
||||||
open("output.html", "w").write("<head> <meta charset='utf-8'> </head>" + html(doc))
|
#open("output.html", "w").write("<head> <meta charset='utf-8'> </head>" + html(doc))
|
||||||
|
k = KatexClient()
|
||||||
|
input()
|
||||||
|
print(k)
|
||||||
|
|
1
katex-server/.gitignore
vendored
Normal file
1
katex-server/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
1
katex-server/README.md
Normal file
1
katex-server/README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This was made by Standa Lukeš @exyi
|
1
katex-server/index.js
Normal file
1
katex-server/index.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log(require('katex').renderToString('\\frac{2a}{b}'))
|
105
katex-server/index.mjs
Normal file
105
katex-server/index.mjs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
// KaTeX rendering server
|
||||||
|
// Listens on unix socket, path is provided as first argument
|
||||||
|
// Expects JSON lines, each line is a query with the following schema:
|
||||||
|
// {
|
||||||
|
// formulas: [
|
||||||
|
// {
|
||||||
|
// tex: string,
|
||||||
|
// options?: object
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// options?: object
|
||||||
|
// }
|
||||||
|
|
||||||
|
// see https://katex.org/docs/options.html for list of available options
|
||||||
|
// If options formulas[].options field is used, the global options field is ignored.
|
||||||
|
|
||||||
|
// For each line, returns one JSON line with the following schema:
|
||||||
|
// {
|
||||||
|
// results: [
|
||||||
|
// { html?: string } | { error?: string }
|
||||||
|
// ]
|
||||||
|
// } | { error?: string }
|
||||||
|
|
||||||
|
|
||||||
|
// If one formula is invalid, the error in results is used
|
||||||
|
// If the entire query is invalid (couldn't parse JSON, for example), the outer error field is used
|
||||||
|
|
||||||
|
|
||||||
|
import katex from 'katex'
|
||||||
|
import net from 'net'
|
||||||
|
import * as readline from 'readline'
|
||||||
|
|
||||||
|
const myArgs = process.argv.slice(2)
|
||||||
|
|
||||||
|
const unixSocketPath = myArgs[0]
|
||||||
|
if (!unixSocketPath) {
|
||||||
|
console.error('you must specify socket path')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This server listens on a Unix socket at /var/run/mysocket
|
||||||
|
var unixServer = net.createServer(handleClient);
|
||||||
|
unixServer.listen(unixSocketPath);
|
||||||
|
|
||||||
|
function handleExit(signal) {
|
||||||
|
// unixServer.emit('close')
|
||||||
|
unixServer.close(function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
process.exit(0); // put this into the callback to avoid closing open connections
|
||||||
|
}
|
||||||
|
process.on('SIGINT', handleExit);
|
||||||
|
process.on('SIGQUIT', handleExit);
|
||||||
|
process.on('SIGTERM', handleExit);
|
||||||
|
process.on('exit', handleExit);
|
||||||
|
|
||||||
|
const defaultOptions = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {net.Socket} socket
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
* */
|
||||||
|
function socketWrite(socket, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
socket.write(data, (err) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {net.Socket} client
|
||||||
|
* */
|
||||||
|
async function handleClient(client) {
|
||||||
|
const rl = readline.createInterface({ input: client })
|
||||||
|
|
||||||
|
for await (const line of rl) {
|
||||||
|
try {
|
||||||
|
const query = JSON.parse(line)
|
||||||
|
|
||||||
|
const results = []
|
||||||
|
for (const input of query.formulas) {
|
||||||
|
const options = input.options ?? query.options ?? defaultOptions
|
||||||
|
try {
|
||||||
|
const html = katex.renderToString(input.tex, options)
|
||||||
|
|
||||||
|
results.push({ html })
|
||||||
|
} catch (e) {
|
||||||
|
results.push({ error: String(e) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await socketWrite(client, JSON.stringify({ results }, null, query.debug ? ' ' : undefined))
|
||||||
|
await socketWrite(client, '\n')
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
await socketWrite(client, JSON.stringify({ error: String(e) }))
|
||||||
|
await socketWrite(client, '\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
21
katex-server/package-lock.json
generated
Normal file
21
katex-server/package-lock.json
generated
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "ksp-katex-server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"commander": {
|
||||||
|
"version": "8.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||||
|
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
|
||||||
|
},
|
||||||
|
"katex": {
|
||||||
|
"version": "0.16.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.3.tgz",
|
||||||
|
"integrity": "sha512-3EykQddareoRmbtNiNEDgl3IGjryyrp2eg/25fHDEnlHymIDi33bptkMv6K4EOC2LZCybLW/ZkEo6Le+EM9pmA==",
|
||||||
|
"requires": {
|
||||||
|
"commander": "^8.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
katex-server/package.json
Normal file
14
katex-server/package.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "ksp-katex-server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.mjs",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"katex": "^0.16.3"
|
||||||
|
}
|
||||||
|
}
|
12
katex.py
Normal file
12
katex.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
|
class KatexClient:
|
||||||
|
def __init__(self):
|
||||||
|
self._client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
self._temp_dir = tempfile.TemporaryDirectory(prefix='formatitko')
|
||||||
|
socket_file = self._temp_dir.name + "/katex-socket"
|
||||||
|
self._client.bind(socket_file)
|
||||||
|
self._server = subprocess.Popen(["node", "./katex-server/index.mjs", socket_file])
|
Loading…
Reference in a new issue