This can be already done without any features, but with an extra step (writing rust service).
This is done using load_data(url=...)
function.
For example, how to generate svg
formulas in .md
files.
Step 0. Install tex2svg
sudo apt install nodejs npm
sudo npm install --global mathjax-node-cli
Commands are taken from here.
Step 1. Create Rust service
Cargo.toml
:
[package]
name = "zola_ext"
version = "0.1.0"
edition = "2018"
[dependencies]
rocket = "0.5.0-rc.1"
base64 = "0.13.0"
main.rs
use rocket::*;
use std::hash::Hash;
use std::process::Command;
const PATH: &str = "/home/zorax/my/zola/static";
fn calculate_hash<T: Hash>(t: &T) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
let mut s = DefaultHasher::new();
t.hash(&mut s);
s.finish()
}
#[get("/tex2svg/<formula>")]
fn tex2svg(formula: &str) -> Option<String> {
let formula = String::from_utf8(base64::decode(formula).ok()?).ok()?;
let file = format!("formulas/h{}.svg", calculate_hash(&formula));
let full_file = format!("{}/{}", PATH, file);
if !std::path::Path::new(&full_file).exists() {
let result = Command::new("tex2svg").args(&[&formula]).output().ok()?;
if result.stdout.is_empty() {
return None;
}
std::fs::write(&full_file, result.stdout).ok()?;
}
Some(format!("{{\"file\": \"{}\"}}", file))
}
#[launch]
fn rocket() -> Rocket<Build> {
let config = Config {
port: 1234,
..Config::debug_default()
};
rocket::custom(&config).mount("/", routes![tex2svg])
}
Modify PATH
variable to /static
directory of your zola site.
This code already does:
- Use a hash of input to generate a file.
- Don’t run the command when a file exists.
Notice that you can return information in json
format to zola.
Also, base64
is just convenient to escape.
Unfortunately, if you return Result<String, BadRequest<String>>
from tex2svg
, the error will not be shown in zola, only that it is 403
. So, you need to print an error by yourself in this app.
Step 2. Create shortcode
templates/shortcodes/formula.html
:
{% set formula = formula | base64_encode %}
{% set url = "http://127.0.0.1:1234/tex2svg/" ~ formula %}
{% set result = load_data(url=url, format="json") %}
<img src="{{"/" ~ result.file}}">
Step 3. Use
Write this in any your .md
file:
{{ formula(formula="\sin^2{\theta} + \cos^2{\theta} = 1") }}
And this will just work.