-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wishlist: server-side KaTeX #6651
Comments
Isn't this something that could, in principle, be done in a filter too? |
I don’t think this is currently possible from a Lua filter; pandoc.pipe can
only run a subprocess synchronously to completion AFAICT. It’d need to be
more like python’s subprocess.Popen and frankly I’m not sure that would be
worth the effort.
A JSON filter certainly can do this but then the question is whether the
JSON serialization overhead eats all the performance gain from only
invoking the node interpreter once.
|
Doesn't lua have primitives allowing you to open a subprocess and pipe things to it? |
There are no built-in primitives, but there are libraries which provide this functionality. E.g., the posix library comes with This requires pandoc to be compiled against the system's Lua installation. Distro-packages usually do this, as do the official Docker images. The Lua posix package can conveniently be installed via the distro's package manager. |
yes, sounds like that's the way to go here. you'll need node.js anyway to run in, so no particular advantage in using a lua filter here. btw. see also https://pandoc.org/MANUAL.html#math-rendering-in-html for built-in alternatives |
Well, Lua filters should be a bit faster, and more so if there are only a few math elements in a very long document. But I agree that using a node.js filter is probably the better approach here. |
Another option: set up a server that does the conversions, and use |
Sounds a lot like this filter! |
There is also https://github.com/lierdakil/mathjax-pandoc-filter. It's written in TypeScript so it doesn't fork for every equation. Not sure how MathJax compares with KaTeX, though. |
For those worried about starting a new process for every math element, I came up with a very over-engineered solution for my project. The Lua filter uses luaposix to communicate over a Unix socket with katex.ts, a server running on Deno. With Deno there's no package.json, node_modules, etc., just a single TypeScript file. It works nicely since KaTeX provides an ECMAScript Module. |
Writing a node.js-json-filter is probably still the way to go here to transform the HTML to what KaTeX CSS needs (so you don't have to run JS in the browser). But we could of course reimplement this in Haskell in the HTML writer... I'm not saying this is worthwhile, but we can keep the issue open for that feature request. |
I came up with another solution: invoke JS from the Lua filter, but batch everything into one invocation. Comparison:
math.ts: import { readLines } from "https://deno.land/std@0.134.0/io/mod.ts";
import katex from "https://cdn.jsdelivr.net/npm/katex@0.15.3/dist/katex.mjs";
for await (const line of readLines(Deno.stdin)) {
try {
console.log(katex.renderToString(line, {
displayMode: false,
strict: "error",
throwOnError: true,
}));
} catch (error) {
throw new Error(`Input: ${line}\n\nError: ${error}`);
}
} filter.lua: function Pandoc(doc)
-- We have to use a temporary file because Lua does not support
-- bidirectional communication with a subprocess:
-- http://lua-users.org/lists/lua-l/2007-10/msg00189.html
local tmp_name = os.tmpname()
local math = assert(io.popen("deno run math.ts > " .. tmp_name, "w"))
doc:walk({
Math = function(el)
assert(math:write(el.text:gsub("\n", " ") .. "\n"))
end
})
math:close()
local tmp = assert(io.open(tmp_name, "r"))
doc = doc:walk({
Math = function(el)
return pandoc.RawInline(FORMAT, tmp:read())
end
})
tmp:close()
os.remove(tmp_name)
return doc
end |
Here's an existing nodejs KaTeX filter that I've started using and it is working well so far: |
+ This is now part of site.hs, with a tiny bit of shelling out to a math.ts script. + Remove the (deprecated) mathjax-node-page as a dependency. + Instead of making the build shell script parallel, remove it completely and utilise Hakyll's built-in parallelism—as well as KaTeX's general speed advantage over MathJax—to make compilation acceptably fast. + Move the fonts directory from /fonts to /css/fonts, as katex.css expects this, and it seems easier to change fonts.css to accommodate this than the other way around—especially with an eye on updating to new KaTeX releases. Related: jgm/pandoc#6651
There is also this package which is published on |
These are all great links! It seems that there are many options. But this issue can be closed, because no changes to pandoc itself are called for. |
KaTeX can be used to render math to HTML in advance. You need node.js and the
katex
command line tool at render time, but then no JavaScript needs to be executed in the browser (a CSS file is still necessary). I've written a proof-of-concept Lua filter that implements this mode in Pandoc and it works reasonably well:Due to the need to start a fairly heavyweight program (the node.js interpreter) for every math element, though, it's quite slow. I'm going to experiment with using a JSON filter written in node.js instead, but I wonder whether native support for this mode in Pandoc might be even faster -- it could fork off the
katex
utility the first time it ran into a math element, and pipe it the math markup as it arrives. Native support would also allow--standalone
to know when it should link to the KaTeX CSS instead of the JS.The text was updated successfully, but these errors were encountered: