From 4a0b817c6fec51efd204f6c0284e4b299df1c90f Mon Sep 17 00:00:00 2001 From: Nathan Rebours Date: Mon, 28 Feb 2022 11:10:50 +0100 Subject: [PATCH 1/6] Update README with mli compatibility and dune stanza reference This is a temporary update until we get the manual in #355 merged Signed-off-by: Nathan Rebours --- README.md | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 890db02c5..bb3c86a85 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,21 @@ [![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) -## mdx -- executable code blocks inside markdown files +## mdx -- executable code blocks inside documentation -`mdx` allows to execute code blocks inside markdown files. -There are (currently) two sub-commands, corresponding -to two modes of operations: pre-processing (`ocaml-mdx pp`) -and tests (`ocaml-mdx test`). +`mdx` allows to execute code blocks inside markdown and mli documentation +to help keeping them up to date. -The pre-processor mode allows to mix documentation and code, -and to practice "literate programming" using markdown and OCaml. +Use the +[dune stanza](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4) +to enable it on your documentation. -The test mode allows to ensure that shell scripts and OCaml fragments -in the documentation always stays up-to-date. - -`mdx` is released as a single binary (called `ocaml-mdx`) and -can be installed using opam: +`mdx` is released on opam and can be installed by running: ```sh $ opam install mdx ``` -If you want to contribute or hack on the project, please see the +If you want to contribute to the project, please see the [CONTRIBUTING.md](CONTRIBUTING.md). ### Supported Extensions From 373b3dd9243e96b451bb6e1128eb605f4aa285db Mon Sep 17 00:00:00 2001 From: Nathan Rebours Date: Mon, 28 Feb 2022 15:40:21 +0100 Subject: [PATCH 2/6] Temporarily import Basic usage section from the WIP manual Signed-off-by: Nathan Rebours --- README.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bb3c86a85..244ba8eeb 100644 --- a/README.md +++ b/README.md @@ -18,28 +18,106 @@ $ opam install mdx If you want to contribute to the project, please see the [CONTRIBUTING.md](CONTRIBUTING.md). +### Basic Usage + +You can use MDX with your Markdown or `.mli` documentation, which ensures +code in multi-line or verbatim code blocks is correct. + +To enable MDX, you need to add `(mdx)` stanzas to the right `dune` files. Before +that you must enable MDX for your project by adding the following to +your `dune-project`: + +``` +(using mdx 0.2) +``` + +Then add the following in the relevant `dune` file: +``` +(mdx) +``` +That enables MDX on all markdown files in the folder. +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. + +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: + +````markdown +Let's look at how good OCaml is with integers and strings: +```ocaml +# 1 + 2;; +- : int = 2 +# "a" ^ "bc";; +- : string = "ab" +``` +```` + +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 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. + +That's exactly why MDX is here! + +If you enable MDX for this file and then ran `dune runtest`, this would be the +result: + +```` +$ 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;; +-- : int = 2 ++- : int = 3 +# "a" ^ "bc";; +-- : string = "ab" ++- : string = "abc" +``` +```` + +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: + +``` +dune promote +``` + +Now the documentation is up-to-date and running `dune runtest` again should be +successful! + ### Supported Extensions #### Labels -The blocks in markdown files can be parameterized by `mdx`-specific labels, that +The blocks can be parameterized by `mdx`-specific labels, that will change the way `mdx` interprets the block. -The syntax is: ``, where `LABELS` is a list of valid labels -separated by a comma. This line has to immediately precede the block it is -attached to. +The markdown syntax is: ``, where `LABELS` is a list of +valid labels separated by a comma. This line has to immediately precede the +block it is attached to. ```ocaml ``` -This syntax is the recommended way to define labels since `mdx` 1.7.0, to use -the previous syntax please refer to the -[mdx 1.6.0 README](https://github.com/realworldocaml/mdx/blob/1.6.0/README.md). - -It is also possible to use labels in OCaml interface files (`mli`), the syntax -for this is is slightly different to match the conventions of OCaml -documentation comments: +The `.mli` syntax for this is is slightly different to match the conventions of +OCaml documentation comments: (** This is an documentation comment with an ocaml block {@ocaml LABELS [ From 14cbc568b0ef2546532c6446ee30db7ef175e1f0 Mon Sep 17 00:00:00 2001 From: Nathan Rebours Date: Mon, 28 Feb 2022 15:46:25 +0100 Subject: [PATCH 3/6] Add mli version of the basic usage example Signed-off-by: Nathan Rebours --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 244ba8eeb..78f4f73a5 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,17 @@ Let's look at how good OCaml is with integers and strings: - : string = "ab" ``` ```` +or in an `mli` file: +```ocaml +(** Let's look at how good OCaml is with integers and strings: + {@ocaml[ + # 1 + 2;; + - : int = 2 + # "a" ^ "bc";; + - : string = "ab" + ]} +*) +``` 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 `;;`. From d54d51ebde1cc32081df96ae453c69568065a90d Mon Sep 17 00:00:00 2001 From: Nathan Rebours Date: Tue, 1 Mar 2022 10:15:52 +0100 Subject: [PATCH 4/6] Simplify the dune integration part to avoid repetition Signed-off-by: Nathan Rebours --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 78f4f73a5..3d92e6734 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,8 @@ If you want to contribute to the project, please see the You can use MDX with your Markdown or `.mli` documentation, which ensures code in multi-line or verbatim code blocks is correct. -To enable MDX, you need to add `(mdx)` stanzas to the right `dune` files. Before -that you must enable MDX for your project by adding the following to -your `dune-project`: - +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) ``` From 7f931b64bf363eb26ee0774de754c218e957ceca Mon Sep 17 00:00:00 2001 From: Nathan Rebours Date: Tue, 1 Mar 2022 10:17:33 +0100 Subject: [PATCH 5/6] Add notes about required dune versions for MDX stanzas Signed-off-by: Nathan Rebours --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3d92e6734..d996cd0bd 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,9 @@ adding the following stanza to your `dune-project`: (using mdx 0.2) ``` +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. + Then add the following in the relevant `dune` file: ``` (mdx) From 9fefc3d5c2b8b64db5033e40df199910fc1a3a79 Mon Sep 17 00:00:00 2001 From: Nathan Rebours Date: Tue, 1 Mar 2022 10:20:36 +0100 Subject: [PATCH 6/6] Remove out of date content and naming Signed-off-by: Nathan Rebours --- README.md | 95 ++++--------------------------------------------------- 1 file changed, 6 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index d996cd0bd..66eedd4d3 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ [![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) -## mdx -- executable code blocks inside documentation +## MDX -`mdx` allows to execute code blocks inside markdown and mli documentation +MDX allows to execute code blocks inside markdown and mli documentation to help keeping them up to date. Use the @@ -178,7 +178,7 @@ with a padding of 3: 10 ``` -`ocaml-mdx` will also consider exit codes when the syntax `[]`is used: +MDX will also consider exit codes when the syntax `[]`is used: ```sh $ exit 1 @@ -190,7 +190,7 @@ of success). #### OCaml Code -`ocaml-mdx` interprets OCaml fragments. It understands _normal_ code fragments and +MDX interprets OCaml fragments. It understands _normal_ code fragments and _toplevel_ code fragments (starting with a `#` sign and optionally ending with `;;`). Arbitrary whitespace padding is supported, at long as it stays consistent within a code block. @@ -211,7 +211,8 @@ Here is an examples of toplevel OCaml code: ``` ### File sync -`mdx` is also capable of including content from files in fenced code blocks + +MDX is also capable of including content from files in fenced code blocks using the label `file`. OCaml files can be sliced using named blocks: ```ocaml @@ -234,38 +235,6 @@ Non-OCaml files can also be read and included in a block: ``` However, part splitting is only supported for OCaml files. -### Pre-processing - -`ocaml-mdx pp` allows to transform a markdown file into a valid -OCaml file, which can be passed to OCaml using the `-pp` -option. - -For instance, given the following `file.md` document: - - ```ocaml - # print_endline "42" - 42 - ``` - -Can be compiled and executed using: - -```sh -$ ocamlc -pp 'ocaml-mdx pp' -impl file.md -o file.exe -$ ./file.exe -42 -``` - -This can be automated using `dune`: - -``` -(rule - ((targets (file.ml)) - (deps (file.md)) - (action (with-stdout-to ${@} (run ocaml-mdx pp ${<}))))) - -(executable ((name file))) -``` - ### Tests #### Cram Tests @@ -294,51 +263,6 @@ To execute OCaml code and toplevel fragments, uses `ocaml-mdx test `. If the output is not consistent with what is expected `.corrected` is generated. -#### Integration with Dune - -To test that the code blocks of `file.md` stay consistent, one can use -dune's `mdx` stanza: - -``` -(mdx - (files file.md)) -``` - -This allows to test the consistency of a markdown file using the normal dev -workflow: - -``` -$ dune runtest -``` - -will display a diff of the output if something has changed. For instance: - -``` -$ dune runtest ------- file.md -++++++ file.md.corrected -File "file.md", line 23, characters 0-1: - | - |```sh --| $ for i in `seq 1 3`; do echo $i; done -+| $ for i in `seq 1 4`; do echo $i; done - | 1 - | 2 - | 3 -+| 4 - |``` -``` - -And the changes can then be accepted using: - -``` -$ dune promote -``` - -For further details about the mdx stanza you should read the -[according section](https://dune.readthedocs.io/en/latest/dune-files.html#mdx-since-2-4) -in the dune documentation. - #### Non-deterministic Tests **Non-deterministic Outputs** @@ -458,10 +382,3 @@ Those variables are then available in the subsequent blocks bar - : unit = () ``` - -### Sections - -It is possible to test or execute only a subset of the file using -sections using the `--section` option (short name is `-s`). For -instance `ocaml-mdx pp -s foo` will only consider the section matching the -perl regular expression `foo`.