We are pleased to announce the first release of Oloop, which helps you auto-evaluate OCaml code for inclusion in educational materials such as books and blogs. An example of the command line tool is below. It evaluates an input script, silences the output of directives, and prints other output in a manner similar to the normal OCaml toplevel. Most compiler options such as -short-paths are supported as well as utop style determination of Lwt and Async values. This is an early release and we hope additional printers, e.g. to html and latex, will be added by the community.

The library provides additional power. You create a handle to a toplevel, to which you can then feed OCaml phrases to evaluate. The types returned are very precise, so you can define printers exactly to your needs. For example, you can optionally distinguish between stdout and stderr or merge them, and the compiler's out phrase is kept distinct from stdout. In educational material, you often want to show incorrect code. Oloop captures errors, such as syntax errors, type errors, and exceptions, and returns them as values you can work with. Scripts can be split into parts by including OCaml comments in the form (* part N *), so you can include parts piecemeal in your overall text.

Install: Should be in opam soon. Run `opam update`, then `opam install oloop`.
Source code: https://github.com/ocaml/oloop.
API reference: see mli files in the source code, starting with oloop.mli
Command line reference: run `oloop -help`

Please join the project. See the Issues list for small tasks. Bigger tasks would be to provide a whitespace preserving parser and a syntax highlighter.

$ cat a.ml 
#use "topfind";;
#thread;;
#camlp4o;;
#require "core";;
#require "core.syntax";;
open Core_kernel.Std;;
let x = List.reduce_exn ~f:(+) [1;2;3;4;5];;
let () = printf "x = %d\n" x;;

$ oloop -silent-directives a.ml
(* part 0 *)
# #use "topfind";;
# #thread;;
# #camlp4o;;
# #require "core";;
# #require "core.syntax";;
# open Core_kernel.Std;;
# let x = List.reduce_exn ~f:(+) [1;2;3;4;5];;
val x : int = 15
# let () = printf "x = %d\n" x;;
x = 15