An attempt at making it simpler to embed the OCaml interpreter, Merlin and OCamlformat, in any webpage thanks to WebComponents:
The different editors follow each others and can reference previous definitions:
And of course, effect support:
There's also experimental support for outputing HTML visualizations, using the X_ocaml_lib.output_html
function:
See a longer example on how to integrate x-ocaml
with tyxml or graphviz.
To convert markdown files to html, the command-line tool xocmd by @patricoferris will automatically insert the <x-ocaml>
tags!
Just link the scripts with:
<script async src="https://cdn.jsdelivr.net/gh/art-w/x-ocaml.js@6/x-ocaml.js" src-worker="https://cdn.jsdelivr.net/gh/art-w/x-ocaml.js@6/x-ocaml.worker+effects.js" integrity="sha256-3ITn2LRgP/8Rz6oqP5ZQTysesNaSi6/iEdbDvBfyCSE=" crossorigin="anonymous" ></script>
Importing those scripts will define a new HTML element <x-ocaml>
thanks to WebComponents, which can be used to add new editors in the page with: (also check the html source of this page):
<x-ocaml>let x = 42</x-ocaml>
The x-ocaml.js
defines the webcomponent and code-mirror integration, while the x-ocaml.worker.js
will spawn a webworker to run the OCaml interpreter, Merlin and OCamlformat in a separate thread.
The support for effect handlers adds a couple mb to the runtime and libraries, so instead you might want to use the version without effect handlers x-ocaml.worker.js
(instead of x-ocaml.worker+effects.js
):
<script async src="https://cdn.jsdelivr.net/gh/art-w/x-ocaml.js@6/x-ocaml.js" src-worker="https://cdn.jsdelivr.net/gh/art-w/x-ocaml.js@6/x-ocaml.worker.js " integrity="sha256-3ITn2LRgP/8Rz6oqP5ZQTysesNaSi6/iEdbDvBfyCSE=" crossorigin="anonymous" ></script>
To avoid relying on a CDN to serve the javascript files, please check out the x-ocaml repository for instructions to reproduce them.
There's also a shell utility to export OCaml libraries and PPX: (drop the --effects
if using the worker without effects)
$ x-ocaml --effects re digestif.ocaml -o re_digestif.js
$ x-ocaml --effects re digestif.ocaml--ppx ppx_deriving.show -o re_digestif_show.js
Which can be linked in the html page with:
<script async src="..." src-worker="..."src-load="./re_digestif_show.js" ></script>
So that they become accessible in the notebook cells:
PPX support only works for the toplevel atm, as Merlin doesn't yet see that the ppx generates show
: (wip!)
To avoid the page layout shifting once CodeMirror loads, we recommend the following CSS:
x-ocaml:not(:defined) { display: block; white-space: pre-wrap; padding: 4px 0.3em 4px 48px; line-height: 1.4em; font-family: monospace; font-size: 1.2em; }
You can also style the WebComponent when loading the script with the attribute inline-style="..."
and/or load an external stylesheet with the tag src-style="./extra.css"
<script async src="..." src-worker="..."inline-style="font-size:2em" src-style="./extra.css" ></script>
If you opt for an external stylesheet, the WebComponent DOM root is called :host
, for example:
:host { font-family: 2em }
OCamlformat configuration can be passed with the x-ocamlformat="..."
attribute:
<script async src="..." src-worker="..."x-ocamlformat=" profile=janestreet margin=60 ..." ></script>
As a special case, you can disable the pretty formatting with x-ocamlformat="disable"