Skip to content

Commit daf23ed

Browse files
authored
Merge pull request #370 from NathanReb/update-readme
Update README with mli compatibility and dune stanza reference
2 parents cf176d7 + 9fefc3d commit daf23ed

File tree

1 file changed

+113
-111
lines changed

1 file changed

+113
-111
lines changed

README.md

Lines changed: 113 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,135 @@
11
[![Build Status](https://img.shields.io/endpoint?url=https%3A%2F%2Fci.ocamllabs.io%2Fbadge%2Frealworldocaml%2Fmdx%2Fmain&logo=ocaml)](https://ci.ocamllabs.io/github/realworldocaml/mdx)
22

3-
## mdx -- executable code blocks inside markdown files
3+
## MDX
44

5-
`mdx` allows to execute code blocks inside markdown files.
6-
There are (currently) two sub-commands, corresponding
7-
to two modes of operations: pre-processing (`ocaml-mdx pp`)
8-
and tests (`ocaml-mdx test`).
5+
MDX allows to execute code blocks inside markdown and mli documentation
6+
to help keeping them up to date.
97

10-
The pre-processor mode allows to mix documentation and code,
11-
and to practice "literate programming" using markdown and OCaml.
8+
Use the
9+
[dune stanza](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4)
10+
to enable it on your documentation.
1211

13-
The test mode allows to ensure that shell scripts and OCaml fragments
14-
in the documentation always stays up-to-date.
15-
16-
`mdx` is released as a single binary (called `ocaml-mdx`) and
17-
can be installed using opam:
12+
`mdx` is released on opam and can be installed by running:
1813

1914
```sh
2015
$ opam install mdx
2116
```
2217

23-
If you want to contribute or hack on the project, please see the
18+
If you want to contribute to the project, please see the
2419
[CONTRIBUTING.md](CONTRIBUTING.md).
2520

21+
### Basic Usage
22+
23+
You can use MDX with your Markdown or `.mli` documentation, which ensures
24+
code in multi-line or verbatim code blocks is correct.
25+
26+
To enable MDX on specific files you must first enable it for your project by
27+
adding the following stanza to your `dune-project`:
28+
```
29+
(using mdx 0.2)
30+
```
31+
32+
Note that version `0.2` of the MDX stanza is only available in dune `3.0` or
33+
higher. You can use the first, `0.1` version with dune `2.4` or higher.
34+
35+
Then add the following in the relevant `dune` file:
36+
```
37+
(mdx)
38+
```
39+
That enables MDX on all markdown files in the folder.
40+
The MDX stanza can be further configured. Please visit the relevant section of
41+
[dune's manual](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4)
42+
for more information.
43+
44+
MDX supports various type of code blocks but the most common are OCaml toplevel
45+
blocks. We illustrate one in our example below. In a Markdown file, you
46+
would write something similar to this:
47+
48+
````markdown
49+
Let's look at how good OCaml is with integers and strings:
50+
```ocaml
51+
# 1 + 2;;
52+
- : int = 2
53+
# "a" ^ "bc";;
54+
- : string = "ab"
55+
```
56+
````
57+
or in an `mli` file:
58+
```ocaml
59+
(** Let's look at how good OCaml is with integers and strings:
60+
{@ocaml[
61+
# 1 + 2;;
62+
- : int = 2
63+
# "a" ^ "bc";;
64+
- : string = "ab"
65+
]}
66+
*)
67+
```
68+
69+
The content of the toplevel blocks looks just like an interactive toplevel
70+
session. Phrases, i.e., the toplevel "input", start with a `#` and end with `;;`.
71+
The toplevel evaluation, or "output" follows each phrase.
72+
73+
Now you probably have noticed that `1 + 2` is not equal to `2` nor is `"a" ^ "bc"`
74+
to `"ab"`. Somebody must have updated the phrases, but then forgot to update
75+
the evaluation.
76+
77+
That's exactly why MDX is here!
78+
79+
If you enable MDX for this file and then ran `dune runtest`, this would be the
80+
result:
81+
82+
````
83+
$ dune runtest
84+
File "README.md", line 1, characters 0-0:
85+
git (internal) (exit 1)
86+
(cd _build/default && /usr/bin/git --no-pager diff --no-index --color=always -u README.md .mdx/README.md.corrected)
87+
diff --git a/README.md b/.mdx/README.md.corrected
88+
index 181b86f..458ecec 100644
89+
--- a/README.md
90+
+++ b/.mdx/README.md.corrected
91+
@@ -1,13 +1,13 @@
92+
Let's look at how good OCaml is with integers and strings:
93+
```ocaml
94+
# 1 + 2;;
95+
-- : int = 2
96+
+- : int = 3
97+
# "a" ^ "bc";;
98+
-- : string = "ab"
99+
+- : string = "abc"
100+
```
101+
````
102+
103+
The test run just failed and dune is showing the diff between what we have
104+
locally and what should be, according to MDX.
105+
This uses dune's promotion workflow so at this point you can either investigate
106+
it further if you're surprised by this diff or if you're happy with it, simply
107+
accept it by running:
108+
109+
```
110+
dune promote
111+
```
112+
113+
Now the documentation is up-to-date and running `dune runtest` again should be
114+
successful!
115+
26116
### Supported Extensions
27117

28118
#### Labels
29119

30-
The blocks in markdown files can be parameterized by `mdx`-specific labels, that
120+
The blocks can be parameterized by `mdx`-specific labels, that
31121
will change the way `mdx` interprets the block.
32122

33-
The syntax is: `<!-- $MDX LABELS -->`, where `LABELS` is a list of valid labels
34-
separated by a comma. This line has to immediately precede the block it is
35-
attached to.
123+
The markdown syntax is: `<!-- $MDX LABELS -->`, where `LABELS` is a list of
124+
valid labels separated by a comma. This line has to immediately precede the
125+
block it is attached to.
36126

37127
<!-- $MDX LABELS -->
38128
```ocaml
39129
```
40130

41-
This syntax is the recommended way to define labels since `mdx` 1.7.0, to use
42-
the previous syntax please refer to the
43-
[mdx 1.6.0 README](https://github.com/realworldocaml/mdx/blob/1.6.0/README.md).
44-
45-
It is also possible to use labels in OCaml interface files (`mli`), the syntax
46-
for this is is slightly different to match the conventions of OCaml
47-
documentation comments:
131+
The `.mli` syntax for this is is slightly different to match the conventions of
132+
OCaml documentation comments:
48133

49134
(** This is an documentation comment with an ocaml block
50135
{@ocaml LABELS [
@@ -93,7 +178,7 @@ with a padding of 3:
93178
10
94179
```
95180

96-
`ocaml-mdx` will also consider exit codes when the syntax `[<exit code>]`is used:
181+
MDX will also consider exit codes when the syntax `[<exit code>]`is used:
97182

98183
```sh
99184
$ exit 1
@@ -105,7 +190,7 @@ of success).
105190

106191
#### OCaml Code
107192

108-
`ocaml-mdx` interprets OCaml fragments. It understands _normal_ code fragments and
193+
MDX interprets OCaml fragments. It understands _normal_ code fragments and
109194
_toplevel_ code fragments (starting with a `#` sign and optionally ending with
110195
`;;`). Arbitrary whitespace padding is supported, at long as it stays
111196
consistent within a code block.
@@ -126,7 +211,8 @@ Here is an examples of toplevel OCaml code:
126211
```
127212

128213
### File sync
129-
`mdx` is also capable of including content from files in fenced code blocks
214+
215+
MDX is also capable of including content from files in fenced code blocks
130216
using the label `file`. OCaml files can be sliced using named blocks:
131217

132218
```ocaml
@@ -149,38 +235,6 @@ Non-OCaml files can also be read and included in a block:
149235
```
150236
However, part splitting is only supported for OCaml files.
151237

152-
### Pre-processing
153-
154-
`ocaml-mdx pp` allows to transform a markdown file into a valid
155-
OCaml file, which can be passed to OCaml using the `-pp`
156-
option.
157-
158-
For instance, given the following `file.md` document:
159-
160-
```ocaml
161-
# print_endline "42"
162-
42
163-
```
164-
165-
Can be compiled and executed using:
166-
167-
```sh
168-
$ ocamlc -pp 'ocaml-mdx pp' -impl file.md -o file.exe
169-
$ ./file.exe
170-
42
171-
```
172-
173-
This can be automated using `dune`:
174-
175-
```
176-
(rule
177-
((targets (file.ml))
178-
(deps (file.md))
179-
(action (with-stdout-to ${@} (run ocaml-mdx pp ${<})))))
180-
181-
(executable ((name file)))
182-
```
183-
184238
### Tests
185239

186240
#### Cram Tests
@@ -209,51 +263,6 @@ To execute OCaml code and toplevel fragments, uses `ocaml-mdx test <file.md>`.
209263
If the output is not consistent with what is expected
210264
`<file.md>.corrected` is generated.
211265

212-
#### Integration with Dune
213-
214-
To test that the code blocks of `file.md` stay consistent, one can use
215-
dune's `mdx` stanza:
216-
217-
```
218-
(mdx
219-
(files file.md))
220-
```
221-
222-
This allows to test the consistency of a markdown file using the normal dev
223-
workflow:
224-
225-
```
226-
$ dune runtest
227-
```
228-
229-
will display a diff of the output if something has changed. For instance:
230-
231-
```
232-
$ dune runtest
233-
------ file.md
234-
++++++ file.md.corrected
235-
File "file.md", line 23, characters 0-1:
236-
|
237-
|```sh
238-
-| $ for i in `seq 1 3`; do echo $i; done
239-
+| $ for i in `seq 1 4`; do echo $i; done
240-
| 1
241-
| 2
242-
| 3
243-
+| 4
244-
|```
245-
```
246-
247-
And the changes can then be accepted using:
248-
249-
```
250-
$ dune promote
251-
```
252-
253-
For further details about the mdx stanza you should read the
254-
[according section](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4)
255-
in the dune documentation.
256-
257266
#### Non-deterministic Tests
258267

259268
**Non-deterministic Outputs**
@@ -373,10 +382,3 @@ Those variables are then available in the subsequent blocks
373382
bar
374383
- : unit = ()
375384
```
376-
377-
### Sections
378-
379-
It is possible to test or execute only a subset of the file using
380-
sections using the `--section` option (short name is `-s`). For
381-
instance `ocaml-mdx pp -s foo` will only consider the section matching the
382-
perl regular expression `foo`.

0 commit comments

Comments
 (0)