Skip to content

Commit

Permalink
readme: revamp introduction
Browse files Browse the repository at this point in the history
- Fix dead links
- Improve organization
- Update the `using` clause's version
- Add a compatability section. One TODO remains.
- Make the example more interesting
  (by introducing an unintentional compilation error)
  • Loading branch information
sorawee committed Dec 2, 2023
1 parent af8547a commit c0b63bf
Showing 1 changed file with 91 additions and 65 deletions.
156 changes: 91 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@

# MDX

MDX allows to execute code blocks inside markdown and mli/mld documentation
to help keeping them up to date.
MDX is a tool that generates evaluation results for code interactions inside Markdown (`.md`)
and `.ml{i,d}` documentation.

Use the
[dune stanza](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4)
to enable it on your documentation.

`mdx` is released on opam and can be installed by running:
MDX is released on opam and can be installed by running:

```sh
$ opam install mdx
Expand All @@ -18,110 +14,140 @@ $ opam install mdx
If you want to contribute to the project, please see the
[CONTRIBUTING.md](CONTRIBUTING.md).

## Basic Usage
## Setup

You can use MDX with your Markdown or `.ml{i,d}` documentation, which ensures
code in multi-line or verbatim code blocks is correct.
MDX is integrated with Dune. To enable MDX for your Dune project,
you must first add a [`dune-project` stanza](https://dune.readthedocs.io/en/latest/dune-files.html#mdx) to allow Dune to recognize MDX:

To enable MDX on specific files you must first enable it for your project by
adding the following stanza to your `dune-project`:
```
(using mdx 0.2)
(using mdx 0.4)
```

Note that version `0.2` of the MDX stanza is only available in dune `3.0` or
higher. You can use the first, `0.1` version with dune `2.4` or higher.
See [compatibility](#compatibility) for more details about version compatibility.

Then add the following MDX stanza in relevant `dune` files:

Then add the following in the relevant `dune` file:
```
(mdx)
(mdx (files :standard *.mli))
```
That enables MDX on all markdown files in the folder.

Under a folder with a `dune` file, `:standard` enables MDX on all Markdown files (`*.md`)
and odoc's documentation pages (`*.mld`); `*.mli` enables MDX on the OCaml interface files.
The MDX stanza can be further configured. Please visit the relevant section of
[dune's manual](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4)
for more information.
[Dune's manual](https://dune.readthedocs.io/en/latest/dune-files.html#mdx) and
the rest of this README for more information.

### Compatibility

- `(using mdx 0.1)` requires Dune 2.4 or higher, with no restriction on MDX version.
- `(using mdx 0.2)` requires Dune 3.0 or higher and MDX 1.9.0 or higher.
- `(using mdx 0.3)` requires TODO
- `(using mdx 0.4)` requires Dune 3.8 or higher and MDX 2.3.0 or higher.

## Getting Started

MDX supports various type of code blocks but the most common are OCaml toplevel
blocks. We illustrate one in our example below. In a Markdown file, you
would write something similar to this:
MDX ensures that your code examples behave the way you expect by actually running them.

MDX supports various types of code blocks but the most common ones are
_OCaml interactive toplevel blocks_.
We illustrate one in the example below. In a Markdown file, we may have:

````markdown
Let's look at how good OCaml is with integers and strings:
Let's look at how good OCaml is with integers and floats:
```ocaml
# 1 + 2;;
- : int = 2
# "a" ^ "bc";;
- : string = "ab"
# 1.2 + 3.4;;
- : float = 4.6
```
````
or in an `mli` file:
```ocaml
(** Let's look at how good OCaml is with integers and strings:
(** Let's look at how good OCaml is with integers and floats:
{@ocaml[
# 1 + 2;;
- : int = 2
# "a" ^ "bc";;
- : string = "ab"
# 1.2 + 3.4;;
- : float = 4.6
]}
*)
```

The content of the toplevel blocks looks just like an interactive toplevel
session. Phrases, i.e., the toplevel "input", start with a `#` and end with `;;`.
The content of the interactive toplevel blocks looks just like an interactive toplevel
session. _Phrases_, i.e., the toplevel "input", start with a `#` and end with `;;`.
The toplevel evaluation, or "output" follows each phrase.

Now you probably have noticed that `1 + 2` is not equal to `2` nor is `"a" ^ "bc"`
to `"ab"`. Somebody must have updated the phrases, but then forgot to update
the evaluation.
Now you probably have noticed that `1 + 2` is not equal to `2` nor is `1.2 + 3.4` type-checked.
Somebody must have introduced a typo, or updated the phrases but then forgot to update the evaluation result.

That's exactly why MDX is here!

If you enable MDX for this file and then ran `dune runtest`, this would be the
result:
If we run `dune runtest`, this would be the result:

````sh
$ dune runtest
File "README.md", line 1, characters 0-0:
diff --git a/_build/default/README.md b/_build/default/.mdx/README.md.corrected
index e74437a..dfeeb64 100644
--- a/_build/default/README.md
+++ b/_build/default/.mdx/README.md.corrected
@@ -1,7 +1,9 @@
Let's look at how good OCaml is with integers and floats:
```ocaml
# 1 + 2;;
-- : int = 2
+- : int = 3
# 1.2 + 3.4;;
-- : float = 4.6
+Line 1, characters 1-4:
+Error: This expression has type float but an expression was expected of type
+ int
```
````
The test run just failed, and Dune showed the diff between what we have
locally and what we should have, according to MDX.
This uses Dune's promotion workflow so that at this point we can investigate
it further if we are surprised by this diff. In this case, we may want to fix
the second phrase to `# 1.2 +. 3.4;;`. Then, we can re-run `dune runtest` again.

````sh
$ dune runtest
File "README.md", line 1, characters 0-0:
git (internal) (exit 1)
(cd _build/default && /usr/bin/git --no-pager diff --no-index --color=always -u README.md .mdx/README.md.corrected)
diff --git a/README.md b/.mdx/README.md.corrected
index 181b86f..458ecec 100644
--- a/README.md
+++ b/.mdx/README.md.corrected
@@ -1,13 +1,13 @@
Let's look at how good OCaml is with integers and strings:
```ocaml
# 1 + 2;;
diff --git a/_build/default/README.md b/_build/default/.mdx/README.md.corrected
index 760debc..8e5878b 100644
--- a/_build/default/README.md
+++ b/_build/default/.mdx/README.md.corrected
@@ -1,7 +1,7 @@
Let's look at how good OCaml is with integers and floats:
```ocaml
# 1 + 2;;
-- : int = 2
+- : int = 3
# "a" ^ "bc";;
-- : string = "ab"
+- : string = "abc"
```
# 1.2 +. 3.4;;
- : float = 4.6
```
````
The test run just failed and dune is showing the diff between what we have
locally and what should be, according to MDX.
This uses dune's promotion workflow so at this point you can either investigate
it further if you're surprised by this diff or if you're happy with it, simply
accept it by running:
Since we are now happy with the diff, we can accept it by running:
```
dune promote
```
Now the documentation is up-to-date and running `dune runtest` again should be
successful!

Note that to use the `dune runtest/promote` workflow with `mli` or `mld` files,
you will need to adjust the `mdx` stanza in the `dune` file, as by
[default](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4),
Dune only checks markdown files with `mdx`. E.g.,
Now the documentation is up-to-date with the content:
````markdown
Let's look at how good OCaml is with integers and floats:
```ocaml
# 1 + 2;;
- : int = 3
# 1.2 +. 3.4;;
- : float = 4.6
```
(mdx
(files :standard *.mli))
```
````

and running `dune runtest` again should be successful!

## Supported Extensions

Expand Down

0 comments on commit c0b63bf

Please sign in to comment.