From fc21081aa5d8fb9ceba3ad0d63d9a5402c8f91c0 Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:00:21 +0100 Subject: [PATCH 1/9] Setup mdexp in ci --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0316a7..4e5950f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,12 @@ jobs: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Setup mdexp + uses: mbarbin/mdexp-actions/setup-mdexp@42da13e622de9559da363ef5906ffde63a982efd # v1.0.0-alpha.1 + with: + mdexp-version: 0.0.20260315 + mdexp-digest: sha256:f4fc53bcaa50c9dd979b968804c38322b9b7e6aa699d9d6d2d1f101965332018 + - name: Environment setup run: | echo "DUNE_WORKSPACE=$PWD/dune-workspace-${{ matrix.ocaml-version }}" >> "$GITHUB_ENV" From c92e446fed6486a68c120f5fb22f387db78dfdc6 Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:00:31 +0100 Subject: [PATCH 2/9] Ignore local coverage script --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1a4e553..0d741b8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ _opam _build _coverage *.install +coverage.sh From f2922bd64596813c408f3d30071c418cd3f8c1a5 Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:04:14 +0100 Subject: [PATCH 3/9] Fix link for build mode --- doc/src/pages/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/pages/index.md b/doc/src/pages/index.md index cef2f23..58a43a7 100644 --- a/doc/src/pages/index.md +++ b/doc/src/pages/index.md @@ -1,7 +1,7 @@

OCaml Documentation with Docusaurus and Odoc

Logo From e846ed52f46097d0163b1e28356d36905b23930d Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:05:38 +0100 Subject: [PATCH 4/9] Use mdexp --- doc/docs/tutorials/hello-mylib/README.md | 18 ++++- doc/docs/tutorials/hello-mylib/dune | 34 ++++++++- doc/docs/tutorials/hello-mylib/prelude.txt | 1 - doc/docs/tutorials/hello-mylib/readme.ml | 86 ++++++++++++++++++++++ 4 files changed, 130 insertions(+), 9 deletions(-) delete mode 100644 doc/docs/tutorials/hello-mylib/prelude.txt create mode 100644 doc/docs/tutorials/hello-mylib/readme.ml diff --git a/doc/docs/tutorials/hello-mylib/README.md b/doc/docs/tutorials/hello-mylib/README.md index 65e07d6..0fe988b 100644 --- a/doc/docs/tutorials/hello-mylib/README.md +++ b/doc/docs/tutorials/hello-mylib/README.md @@ -1,19 +1,29 @@ # Hello Mylib -Here we're making use of features offered by ocaml-mdx, with which we can keep -the doc up to date. +Here we're making use of [mdexp](https://github.com/mbarbin/mdexp) to keep +the doc up to date. The code blocks below are extracted from an OCaml test +file and their output is verified on every build. ## Using libraries +We can make use of code defined in libraries in expect tests. + +```ocaml +print_endline Mylib.hello_world; +[%expect {| Hello, World! |}]; +``` + +## Using Libraries in Toplevels + We can make use of code defined in libraries. ```ocaml -# print_endline Mylib.hello_world +# print_endline Mylib.hello_world ;; Hello, World! - : unit = () ``` -## Using executables +## Using Executables in Cram Style We can make use of executables defined in packages. diff --git a/doc/docs/tutorials/hello-mylib/dune b/doc/docs/tutorials/hello-mylib/dune index c8d8c13..5c72d69 100644 --- a/doc/docs/tutorials/hello-mylib/dune +++ b/doc/docs/tutorials/hello-mylib/dune @@ -1,5 +1,31 @@ -(mdx +(toplevel + (name mylib_toplevel) + (libraries mylib)) + +(library + (name hello_mylib_doc) + (package doc-experiment-docusaurus-tests) + (libraries mylib unix) + (inline_tests + (deps mylib_toplevel.exe %{bin:mybin})) + (instrumentation + (backend bisect_ppx)) + (preprocess + (pps ppx_expect))) + +(rule + (target README.output) (package doc-experiment-docusaurus-dev) - (deps - (package mylib)) - (preludes prelude.txt)) + (enabled_if %{bin-available:mdexp}) + (deps readme.ml) + (action + (with-stdout-to + %{target} + (run %{bin:mdexp} pp %{deps})))) + +(rule + (package doc-experiment-docusaurus-dev) + (enabled_if %{bin-available:mdexp}) + (alias runtest) + (action + (diff README.md README.output))) diff --git a/doc/docs/tutorials/hello-mylib/prelude.txt b/doc/docs/tutorials/hello-mylib/prelude.txt deleted file mode 100644 index 3b7c189..0000000 --- a/doc/docs/tutorials/hello-mylib/prelude.txt +++ /dev/null @@ -1 +0,0 @@ -#require "mylib";; diff --git a/doc/docs/tutorials/hello-mylib/readme.ml b/doc/docs/tutorials/hello-mylib/readme.ml new file mode 100644 index 0000000..6c673eb --- /dev/null +++ b/doc/docs/tutorials/hello-mylib/readme.ml @@ -0,0 +1,86 @@ +(* @mdexp + + # Hello Mylib + + Here we're making use of [mdexp](https://github.com/mbarbin/mdexp) to keep + the doc up to date. The code blocks below are extracted from an OCaml test + file and their output is verified on every build. *) + +let eval_toplevel code = + let code = String.trim code in + Printf.printf "# %s\n" code; + let cmd = "./mylib_toplevel.exe -noprompt -no-version" in + let ic, oc, ec = Unix.open_process_full cmd [||] in + output_string oc code; + output_char oc '\n'; + close_out oc; + let stdout_content = In_channel.input_all ic in + let stderr_content = In_channel.input_all ec in + let status = Unix.close_process_full (ic, oc, ec) in + let stdout_trimmed = String.trim stdout_content in + if String.length stdout_trimmed > 0 then print_endline stdout_trimmed; + let stderr_trimmed = String.trim stderr_content in + if String.length stderr_trimmed > 0 then print_endline stderr_trimmed [@coverage off]; + match status with + | WEXITED 0 -> () + | _ -> + (match[@coverage off] status with + | WEXITED n -> Printf.printf "[%d]\n" n + | WSIGNALED n -> Printf.printf "[signal %d]\n" n + | WSTOPPED n -> Printf.printf "[stopped %d]\n" n) +;; + +let mybin args = + let cmd = String.concat " " ("mybin" :: args) in + Printf.printf "$ %s\n" cmd; + let ic = Unix.open_process_in cmd in + print_string (In_channel.input_all ic); + ignore (Unix.close_process_in ic) +;; + +(* @mdexp + + ## Using libraries + + We can make use of code defined in libraries in expect tests. *) + +let%expect_test "using libraries" = + (* @mdexp.code *) + print_endline Mylib.hello_world; + [%expect {| Hello, World! |}]; + (* @mdexp.end *) + () +;; + +(* @mdexp + + ## Using Libraries in Toplevels + + We can make use of code defined in libraries. *) + +let%expect_test "using libraries" = + eval_toplevel {| print_endline Mylib.hello_world ;; |}; + (* @mdexp.snapshot { lang: "ocaml" } *) + [%expect + {| + # print_endline Mylib.hello_world ;; + Hello, World! + - : unit = () + |}] +;; + +(* @mdexp + + ## Using Executables in Cram Style + + We can make use of executables defined in packages. *) + +let%expect_test "using executables" = + mybin [ "print" ]; + (* @mdexp.snapshot { lang: "bash" } *) + [%expect + {| + $ mybin print + Hello, World! + |}] +;; From 9219dfcf3b5be526cca0d59338cdf3869f15aeb2 Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:06:18 +0100 Subject: [PATCH 5/9] Update dependencies --- .ocamlformat | 2 +- doc-experiment-docusaurus-dev.opam | 5 ++--- dune-project | 16 ++++------------ myotherlib.opam | 2 -- src/mylib/bin/dune | 4 +++- src/mylib/dune | 2 ++ src/myotherlib/dune | 6 ++++-- src/myotherlib/myotherlib.ml | 10 ---------- src/myotherlib/myotherlib.mli | 1 - test/mylib/dune | 2 ++ test/myotherlib/dune | 2 ++ 11 files changed, 20 insertions(+), 32 deletions(-) diff --git a/.ocamlformat b/.ocamlformat index 1484724..ccd797c 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1,3 +1,3 @@ -version=0.28.1 +version=0.29.0 profile=janestreet parse-docstrings=true diff --git a/doc-experiment-docusaurus-dev.opam b/doc-experiment-docusaurus-dev.opam index 2d04691..dde879d 100644 --- a/doc-experiment-docusaurus-dev.opam +++ b/doc-experiment-docusaurus-dev.opam @@ -10,12 +10,11 @@ bug-reports: "https://github.com/mbarbin/doc-experiment-docusaurus/issues" depends: [ "dune" {>= "3.17"} "ocaml" {>= "5.2"} + "bisect_ppx" {>= "2.8.3"} "doc-experiment-docusaurus-tests" {= version} "mylib" {= version} "myotherlib" {= version} - "mdx" {>= "2.4"} - "ocamlformat" {= "0.28.1"} - "sherlodoc" {>= "0.2"} + "ocamlformat" {= "0.29.0"} "odoc" {with-doc} ] build: [ diff --git a/dune-project b/dune-project index 7050ea3..042f977 100644 --- a/dune-project +++ b/dune-project @@ -15,8 +15,6 @@ (documentation "https://mbarbin.github.io/doc-experiment-docusaurus/") -(using mdx 0.4) - (implicit_transitive_deps false) (package @@ -37,11 +35,7 @@ (synopsis "Another package named myotherlib in this project") (depends (ocaml - (>= 5.2)) - (cmdlang - (>= 0.0.9)) - (cmdlang-cmdliner-err-runner - (>= 0.0.16)))) + (>= 5.2)))) (package (name doc-experiment-docusaurus-tests) @@ -66,15 +60,13 @@ (depends (ocaml (>= 5.2)) + (bisect_ppx + (>= 2.8.3)) (doc-experiment-docusaurus-tests (= :version)) (mylib (= :version)) (myotherlib (= :version)) - (mdx - (>= 2.4)) (ocamlformat - (= 0.28.1)) - (sherlodoc - (>= 0.2)))) + (= 0.29.0)))) diff --git a/myotherlib.opam b/myotherlib.opam index 21660c3..8fe6c01 100644 --- a/myotherlib.opam +++ b/myotherlib.opam @@ -10,8 +10,6 @@ bug-reports: "https://github.com/mbarbin/doc-experiment-docusaurus/issues" depends: [ "dune" {>= "3.17"} "ocaml" {>= "5.2"} - "cmdlang" {>= "0.0.9"} - "cmdlang-cmdliner-err-runner" {>= "0.0.16"} "odoc" {with-doc} ] build: [ diff --git a/src/mylib/bin/dune b/src/mylib/bin/dune index 9865a81..7aaea63 100644 --- a/src/mylib/bin/dune +++ b/src/mylib/bin/dune @@ -3,4 +3,6 @@ (public_name mybin) (package mylib) (flags :standard -w +a-4-40-41-42-44-45-48-66 -warn-error +a) - (libraries cmdlang-cmdliner-err-runner dune-build-info mylib)) + (libraries cmdlang-cmdliner-err-runner dune-build-info mylib) + (instrumentation + (backend bisect_ppx))) diff --git a/src/mylib/dune b/src/mylib/dune index 7685e3c..bc98cd0 100644 --- a/src/mylib/dune +++ b/src/mylib/dune @@ -3,4 +3,6 @@ (public_name mylib) (flags :standard -w +a-4-40-41-42-44-45-48-66 -warn-error +a -open Cmdlang) (libraries cmdlang) + (instrumentation + (backend bisect_ppx)) (preprocess no_preprocessing)) diff --git a/src/myotherlib/dune b/src/myotherlib/dune index 45ac0a4..7a68198 100644 --- a/src/myotherlib/dune +++ b/src/myotherlib/dune @@ -1,6 +1,8 @@ (library (name myotherlib) (public_name myotherlib) - (flags :standard -w +a-4-40-41-42-44-45-48-66 -warn-error +a -open Cmdlang) - (libraries cmdlang) + (flags :standard -w +a-4-40-41-42-44-45-48-66 -warn-error +a) + (libraries) + (instrumentation + (backend bisect_ppx)) (preprocess no_preprocessing)) diff --git a/src/myotherlib/myotherlib.ml b/src/myotherlib/myotherlib.ml index d58e865..8df3275 100644 --- a/src/myotherlib/myotherlib.ml +++ b/src/myotherlib/myotherlib.ml @@ -1,11 +1 @@ let hello_world = "Hello, World From My Other Lib!" - -let print_cmd = - Command.make - ~summary:"print hello world" - (let open Command.Std in - let+ () = Arg.return () in - print_endline hello_world) -;; - -let main = Command.group ~summary:"" [ "print", print_cmd ] diff --git a/src/myotherlib/myotherlib.mli b/src/myotherlib/myotherlib.mli index 7272bdf..b862756 100644 --- a/src/myotherlib/myotherlib.mli +++ b/src/myotherlib/myotherlib.mli @@ -1,2 +1 @@ val hello_world : string -val main : unit Command.t diff --git a/test/mylib/dune b/test/mylib/dune index 9f33e25..e7376af 100644 --- a/test/mylib/dune +++ b/test/mylib/dune @@ -4,5 +4,7 @@ (flags :standard -w +a-4-40-41-42-44-45-48-66 -warn-error +a) (libraries mylib) (inline_tests) + (instrumentation + (backend bisect_ppx)) (preprocess (pps ppx_expect))) diff --git a/test/myotherlib/dune b/test/myotherlib/dune index 763add7..c27f347 100644 --- a/test/myotherlib/dune +++ b/test/myotherlib/dune @@ -4,5 +4,7 @@ (flags :standard -w +a-4-40-41-42-44-45-48-66 -warn-error +a) (libraries myotherlib) (inline_tests) + (instrumentation + (backend bisect_ppx)) (preprocess (pps ppx_expect))) From 421bdd7cf338ed5239dd8c2c8a6d1b1a138e6aac Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:06:27 +0100 Subject: [PATCH 6/9] Update dunolint config --- dunolint | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/dunolint b/dunolint index 3552342..53f2854 100644 --- a/dunolint +++ b/dunolint @@ -1,10 +1,24 @@ (lang dunolint 1.0) +;; Everything is instrumented + +(rule + (enforce + (dune + (instrumentation + (backend bisect_ppx))))) + +;; Test lib naming + (rule (cond - ((path (glob test/**)) + ((path + (glob test/**)) (enforce (dune (library - (and (not (has_field public_name)) - (package (equals doc-experiment-docusaurus-tests))))))))) + (and + (not + (has_field public_name)) + (package + (equals doc-experiment-docusaurus-tests))))))))) From 9b03352a83d7ff492fbb88139093ddc8fd46d06a Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:10:14 +0100 Subject: [PATCH 7/9] Add alpha repo (bisect_ppx & 5.4) --- dune-workspace-5.4 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dune-workspace-5.4 b/dune-workspace-5.4 index 24220a9..499becf 100644 --- a/dune-workspace-5.4 +++ b/dune-workspace-5.4 @@ -3,7 +3,7 @@ (pkg enabled) (lock_dir - (repositories overlay upstream mbarbin) + (repositories overlay upstream alpha mbarbin) (constraints (ocaml (= 5.4.1)))) @@ -11,3 +11,7 @@ (repository (name mbarbin) (url "git+https://github.com/mbarbin/opam-repository.git")) + +(repository + (name alpha) + (url "git+https://github.com/kit-ty-kate/opam-alpha-repository.git")) From 4f0a2a0d0e5cbb5731bcaef7122e97e46751b4da Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:19:33 +0100 Subject: [PATCH 8/9] Add sherlodoc again --- doc-experiment-docusaurus-dev.opam | 1 + dune-project | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc-experiment-docusaurus-dev.opam b/doc-experiment-docusaurus-dev.opam index dde879d..12be199 100644 --- a/doc-experiment-docusaurus-dev.opam +++ b/doc-experiment-docusaurus-dev.opam @@ -15,6 +15,7 @@ depends: [ "mylib" {= version} "myotherlib" {= version} "ocamlformat" {= "0.29.0"} + "sherlodoc" {>= "3.1.0"} "odoc" {with-doc} ] build: [ diff --git a/dune-project b/dune-project index 042f977..9527624 100644 --- a/dune-project +++ b/dune-project @@ -69,4 +69,6 @@ (myotherlib (= :version)) (ocamlformat - (= 0.29.0)))) + (= 0.29.0)) + (sherlodoc + (>= 3.1.0)))) From 7f231eebb0cfbe288aa67ed9ba4e1d4d5b790dc2 Mon Sep 17 00:00:00 2001 From: Mathieu Barbin Date: Sat, 28 Mar 2026 15:20:56 +0100 Subject: [PATCH 9/9] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7852a26..3dd0ad2 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ We extend our deepest gratitude to the following projects and their contributors - [setup-dune](https://github.com/ocaml-dune/setup-dune): For seting up OCaml environments in our CI workflows. - [setup-ocaml](https://github.com/ocaml/setup-ocaml): Another OCaml CI tool we also used to work on the repo. - [odoc](https://github.com/ocaml/odoc): For the odoc tool, which generates styled HTML documentation from OCaml packages. -- [ocaml-mdx](https://github.com/realworldocaml/mdx): For allowing us to execute code blocks within our markdown files, ensuring our documentation is always up to date. +- [mdexp](https://github.com/mbarbin/mdexp): For authoring markdown files including compiled OCaml code fragment and generated contents, ensuring our documentation is always up to date. - [sherlodoc](https://github.com/art-w/sherlodoc): For its innovative approach to searching OCaml documentation. - [docusaurus](https://github.com/facebook/docusaurus): For providing a platform to bring all our documentation together in a user-friendly and accessible manner.