---
title: External tooling design notes
...

Subplot can invoke `plantuml` as well as other external tools which, at this time, are compiled into the binary. It would be good to enable generic handling of these tools, and so we should come up with a way to do that.

This document details the current design thoughts which, if finally accepted will be implemented.

# Current tools supported by Subplot

## `dot`

The graphviz tool `dot` is supported.

The CLI for that is `--dot` or `SUBPLOT_DOT_PATH`.

## `plantuml`

The `plantuml` tool is supported via Java.

The CLI for that is `--plantuml-jar` or `SUBPLOT_PLANTUML_JAR_PATH` as well as `--java` and `SUBPLOT_JAVA_PATH`.

# Other formats supported internally

There is also support for internally supported diagram formats such as `pikchr` which is currently supported via the `pikchr` crate.

# Possible design approach

We **will** be making a breaking change with this, because the CLI will be removed in favour of resource files which describe tools, but that also means that in theory we can support dynamically provided tooling including from projects themselves.

All non-internal diagram formats are first removed from Subplot. Then we add resource files of the form below, named as `embeds/translate-$class.yaml`.

```yaml
name: The name of the tool which can be used to transform the embed
format: mime/type
env:
  SUBPLOT_TOOL_PATH: default_tool_path
command:
- @SUBPLOT_TOOL_PATH@
- @INPUT_FILENAME@
- @OUTPUT_FILENAME@
```

The `@INPUT_FILENAME@` and `@OUTPUT_FILENAME@` would be substituted and allows for tooling which cannot deal with stdin/stdout.  If `@INPUT_FILENAME@` is not present in one of the arguments then subplot will pass the input on stdin, and if `@OUTPUT_FILENAME@` is not present in one of the arguments then subplot will expect the output to be on stdout.

The listed environment variables are inherited if present, set to their default value if given, and unset otherwise.

Here's what the existing tools would look like done like this:

```yaml
name: Graphviz dot
format: image/svg+xml
env:
  SUBPLOT_DOT_PATH: dot
command:
- @SUBPLOT_DOT_PATH@
- "-Tsvg"
```

and

```yaml
name: PlantUML
format: image/svg+xml
env:
  SUBPLOT_PLANTUML_JAR_PATH: /usr/share/plantuml/plantuml.jar
  JAVA_PATH: java
  JAVA_HOME:
  SUBPLOT_DOT_PATH: dot
command:
- @JAVA_PATH@
- "-Djava.awt.headless=true"
- "-jar"
- @SUBPLOT_PLANTUML_JAR_PATH@
- "--"
- "-pipe"
- "-tsvg"
- "-v"
- "-graphvizdot"
- @SUBPLOT_DOT_PATH@
```

# How tools are invoked

If a code block is encountered whose class is found as one of these YAML files then the input is gathered up and provided to the tool. This is done either on stdin or a temporary file provided as the `@INPUT_FILENAME@`. When the tool runs then the output is collected either from stdout or from `@OUTPUT_FILENAME@` which is also a known temporary file.

If the class is not known then we do the usual unknown-class work which might be syntax highlighting or it might be a warning/error. That is not decided by this document.

# Possible new tools to consider

We could consider then adding any or all of the following:

- D2 <https://d2lang.com/>
- Mermaid <https://mermaid.ai/open-source/> (even though it's AI, blech)

# Other YAML thoughts

We *could* use `$..` instead of `@..@` for variable substitution, and we could also allow for builtin default overrides for nixos etc. at compile time at least. Details for that can be thought up if we decide to do this.
