marksonnet 0.1.1

An experimental Markdown (CommonMark) preprocessor for evaluating Jsonnet
Documentation
# `marksonnet`

<!-- What is this project? -->

This project is an experimental tool (and library) implementing an extension of [CommonMark].
It adds a special codeblock "language" for evaluating [Jsonnet] programs which can be used to inject output in the rendered document.
It can be used to include other markdown files as snippets,
embed configuration sources alongside relevant documentation,
display Jsonnet-generated Kubernetes manifests or Tanka environments,
or even generate templated markdown documentation from JSON or YAML sources.

> [!CAUTION]
> `marksonnet` is a personal project for the purpose of learning Rust.
> While I think it has the potential to be a useful tool, it is not a seriously-maintained one.

## Installation

<!-- How can I use this project? -->

The command line tool `marksonnet` can be installed from `crates.io` using `cargo install`.

```bash
cargo install marksonnet
```

To add the `marksonnet` library to your project, use `cargo add`.

```bash
cargo add marksonnet
```

Then, use the crate in your project like so.

```rust
use marksonnet;

for event in marksonnet::Parser::new(&text) {
    println!("{:?}", event)
}
```

## Operation

`marksonnet` is both a Rust library crate and a binary crate.
This means that it can be used as a command line tool, or from other Rust projects.

The library provides an interface similar to `pulldown-cmark`, as it is a thin wrapper over that.
The command line tool reads a file or `stdin`, evaluates `marksonnet` blocks, and writes to a file or `stdout`.

In either case, `marksonnet` parses the input using `pulldown-cmark`, replacing `marksonnet`-labeled codeblocks with its Jsonnet evaluation result, and re-serializing the input to CommonMark using `pulldown-cmark-to-cmark`.
Jsonnet is evaluated using `jrsonnet`, and the type of the result determines the nature of the output.
If the result is a string, the codeblock is substituted with it, and it is parsed again as though it were part of the original document.
If the result is anything else, it is serialized as indented JSON, embedded in a `json`-labeled codeblock, and substituted.

## Examples

### This File

This README is authored using `marksonnet` in [`README.src.md`](./README.src.md), and rendered as [`README.md`](./README.md).
This is accomplished using the command line tool, invoked like so:

```marksonnet
"```bash\n%s```\n" % (importstr './scripts/generate-readme.sh')
```

### Computing Values

This `marksonnet` codeblock displays the first five Fibonacci numbers as a JSON array.

```
    ```marksonnet
    local fib(n) = if (n <= 2) then 1 else (fib(n-1) + fib(n-2));
    [fib(n) for n in std.range(1, 5)]
    ```
```

is transformed into:

```marksonnet
local fib(n) = if (n <= 2) then 1 else (fib(n-1) + fib(n-2));
[fib(n) for n in std.range(1, 5)]
```

### Assembling Strings

This `marksonnet` codeblock is evaluated and its result is injected as CommonMark.

```
    ```marksonnet
    std.format('> %s, %s!', ['Hello', 'World'])
    ```
```

```marksonnet
std.format('> %s, %s!', ['Hello', 'World'])
```

*Note*: CommonMark in the result string is parsed as normal.

### Imports

Imports are supported as in normal Jsonnet.

```
    ```marksonnet
    import 'example/sample.json'
    ```
```

```marksonnet
import 'example/sample.json'
```

Imports can also be used to include strings, such as other markdown files.

```
    ```marksonnet
    importstr 'example/sample.md'
    ```
```

```marksonnet
importstr 'example/sample.md'
```

> [!WARNING]
> Nested imports are not yet supported.

[CommonMark]: https://commonmark.org/
[Jsonnet]: https://jsonnet.org/