# Run commands

**URL:** <https://zola.discourse.group/t/run-commands/1018>\
**Category:** Feature requests\
**Created:** [August 20, 2021, 9:21am UTC](https://zola.discourse.group/t/run-commands/1018 "2021-08-20T09:21:29Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![optozorax](https://yyz2.discourse-cdn.com/free1/user_avatar/zola.discourse.group/optozorax/32/587_2.png) [@optozorax](https://zola.discourse.group/u/optozorax)\
**Post date:** [August 22, 2021, 7:17am UTC](https://zola.discourse.group/t/run-commands/1018/3 "2021-08-22T07:17:45Z")

</div>

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

```bash
sudo apt install nodejs npm
sudo npm install --global mathjax-node-cli

```

Commands are taken from [here](https://tex.stackexchange.com/questions/255470/compile-tex-directly-into-svg-using-the-command-line).

# Step 1. Create Rust service

`Cargo.toml`:

```toml
[package]
name = "zola_ext"
version = "0.1.0"
edition = "2018"

[dependencies]
rocket = "0.5.0-rc.1"
base64 = "0.13.0"

```

`main.rs`

```rust
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`:

```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:

```auto
{{ formula(formula="\sin^2{\theta} + \cos^2{\theta} = 1") }}

```

And this will just work.

---

_[View the full topic](https://zola.discourse.group/t/run-commands/1018)._
