package odoc
Hows does odoc
work?
odoc
is built in a very modular fashion, with several modules that take care of mostly orthogonal concerns.
Instead of namedropping them, we will describe a use-case and how they connect to each other as we analyze its execution superficially.
We will begin the flow with an odoc
command that compiles a single cmti
file, Player.cmti
, into its corresponding html
file. Then we will compile the intro.mld
documentation file into html.
- Compiling Player.cmti to Player.odoc
- Compiling Player.odoc to Player/index.html
- Compiling intro.mld to page-intro.odoc
- Compiling page-intro.odoc to intro.html
Off we go!
1 — Compiling Player.cmti to Player.odoc
Superficially, what we need to do is straighforward.
# We must tell odoc what the name of this Package is!
$ odoc compile --package Game -o ./src/Player.odoc ./src/Player.cmti
$ ls src
Player.cmti Player.mli Player.odoc
Voila! We get a Player.odoc
right where we expected it. But what really just happened?
- In
Main
the command was parsed and a decision was made to compile this file into anodoc
file - Compilation is orchestrated by
Main.Compile.compile
, that based on the input extension will delegate to one of manyCompile
functions. In this caseCompile.cmti
- The
cmti
file is read byLoader.read_cmti
into aModel.Root.t
and aCompilation_unit.t
is created - This compilation unit is then turned into an
Env.t
(environment), expanding all found references between modules - And lastly
Compilation_unit.save
takes care of saving this compilation unit into thePlayer.odoc
file in marshalled format.
2 — Compiling Player.odoc to Player/index.html
Now we can compile this to an HTML file:
$ odoc html -I src -o . ./src/Player.odoc
$ cat Game/Player/index.html
# mangled html output here!
In this case, what happened was
- In
Main
the command is parsed as well, and it decides to compile the input into anhtml
file. - Compilation is orchestrated by
Main.Html.html
, that will make sure some global flags are set up (depending on command flags), and delegate toHtml_page.from_odoc
- The
odoc
file is read into aModel.Root.t
- Since it contains a
Model.Root.Odoc_file.Compilation_unit
, anEnv.t
(environment) will be built, with its references expanded, just like in the first step - An
Html.Html_tree.t
will be built, depending on the syntax chosen (in this case the default is OCaml) byHtml.To_html_tree.ML.compilation_unit
- Lastly, this tree will be traversed, the
Game/Player
folder created, and theindex.html
file written to disk.
3 — Compiling page-intro.mld to page-intro.odoc
We will begin by invoking odoc
similarly than we did in the first step.
$ odoc compile --package Game -o ./src/page-intro.odoc ./src/page-intro.mld
$ ls src
page-intro.mld page-intro.odoc
- Again in
Main
the command was parsed and a decision was made to compile this file into anodoc
file - Compilation is orchestrated by
Main.Compile.compile
, and it delegates compilation toCompile.mld
based on the extension of the input - A
Model.Lang.Page.t
will be created from it, and anEnv.t
will be built resolving found references - Lastly, the resulting page will be written down to disk by
Page.save
4 — Compiling page-intro.odoc to intro.html
$ odoc html -I src -o . ./src/page-intro.odoc
$ cat Game/intro.html
# mangled html output here!
This process is in fact almost the same as in the last html compilation. The main differences are that:
- the read
Model.Root.t
contains aModel.Root.Odoc_file.Page
instead, - the output file name will drop the
page-
prefix, - the
Html.Html_tree.t
is built byHtml.To_html_tree.ML.page