Odoc 2.0.0

Hot on the heels of the OCaml 4.13 announcement(s!), the odoc team is pleased to announce the release of odoc 2.0.0!

tl;dr: The new version produces much better output than the old version, it's the engine at the core of the package docs in v3.ocaml.org, and it also has a new website.

This release has been a long time coming -- years! -- and contains several notable improvements over the odoc 1.5 series: a new language model, a new rendering layer allowing output in several formats, and improved control over the output structure.

New Features

New Language Model

The internal library used by odoc that models the OCaml module system has been completely rewritten over a multi-year effort by @jonludlam and @Julow, according to a design by @lpw25. The rewrite gives odoc a much better understanding of the module system compared to the original implementation. This library is used for two main processes:

  1. To perform expansions, which is the process where odoc takes complex module type expressions like this one from tyxml:
module Make
    (Xml : Xml_sigs.T with type ('a, 'b) W.ft = 'a -> 'b)
    (Svg : Svg_sigs.T with module Xml := Xml)
  : Html_sigs.Make(Xml)(Svg).T
    with type +'a elt = Xml.elt
     and type +'a attrib = Xml.attrib

Then turns it into an output page containing the correct types, values, modules, includes, and documentation.

  1. To perform resolutions, which is where odoc handles complex paths found in OCaml source in order to calculate the correct definition link. For example, in the following snippet:
module type A = sig
  module M : sig module type S end
  module N : M.S
end

module B : sig module type S = sig type t end end

module C : A with module M = B with type N.t = int

type t = C.N.t

resolution is the process by which odoc determines which documentation page to take you when you click on C.N.t.

The new model has logic to handle many features of the OCaml language, as can be explored here.

A particularly important improvement is in handling canonical modules (explained in the link above). The upshot of this is that there should never be any more odd double underscores leaking into your docs!

For some more info on this, as well as the new output renderers, see our talk at the OCaml workshop last year

New Output Renderers

@Drup put a considerable amount of work into replacing the odoc 1.5 custom HTML generator with a new rendering layer. This features a new intermediate format allowing new output formats to be added far more easily than before.

Included in odoc 2.0 are renderers for HTML and man pages (both contributed by @Drup) and LaTeX (contributed by @Octachron). The LaTeX renderer has already been integrated into the OCaml build process to generate docs (see https://github.com/ocaml/ocaml/pull/9997 and related PRs). @jonludlam also made an alternative HTML renderer designed specifically for v3.ocaml.org. Finally, a new markdown renderer is being prepared by @lubegasimon and should land in the next release.

We look forward to many new renderers being created for the varied use cases present in the community!

Output Structure

odoc 2.0 introduces a new mechanism to specify the structure of the files produced. Although it's a relatively simple new feature, it nevertheless has enabled odoc to be used in new ways. In particular, it has allowed odoc to construct the package documentation for the new OCaml website, v3.ocaml.org. There is also an example driver, showing how odoc can be used to construct a stand-alone website for an OCaml package that contains fully-linked documentation for a package and all of its dependencies. This has been used to create odoc's new website.

New Drivers

Like the OCaml compiler itself, running odoc on your code requires careful sequencing of the invocations to produce the correct result. Fortunately both dune and odig understand how to do this, so most users don't need to know the details. If you want more than these tools provide though, we've written a simple reference driver, documenting exactly what's necessary to use odoc to produce rich documentation. A more complete (and more complex) example is the tool voodoo, which is being used to create the docs for v3.ocaml.org.

v3.ocaml.org

As previously posted, the new version of the OCaml website has been under development for some time now, and an important new feature is the integration of package listings, including documentation for every version of every package. More has been written about this elsewhere, but it's important to note that the new OCaml.org website required a preview version of odoc 2.0 to work. We've made a few bug fixes since then, so we will update the pipeline to use the released version very soon. For more info on the pipeline to build the docs, see our recent talk at this year's OCaml Workshop.

New Website

The website for odoc has been improved with guides for documentation authors, integrators, and contributors. This site is intended to grow over time with more content to help people write docs for their packages.

OCamldoc?

This release, particularly because of the new output renderers, puts odoc in a place where it supercedes OCamldoc in most respects. There are a few features we're missing (see the comparison in the docs), including most notably that we don't render the source (OCamldoc's --keep-code argument), and that there is no support for custom tags. If odoc is lacking features that you're currently relying on in OCamldoc, we'd love to hear from you!

More Docs!

Finally, I'd like to use this opportunity to launch an invitation. With v3.ocaml.org now showing all the package docs in their current state, I'd like to invite all our package authors, maintainers, contributors, and users to take a look over their favourite packages and see what the documentation looks like. Good documentation is one of the most important requests from the previous OCaml developer surveys, and with v3.ocaml.org as a new documentation hub, now is a great time to be making improvements where they're required. With this new release of odoc, previewing your docs should be as simple as dune build @doc.

Some packages already have great docs - a few examples are:

many others have more patchy docs. Let's fix that!

We're also looking for more contributors to odoc. It's much improved now, but there's still plenty more to do. Come and join the fun!

See full changelog

Breaking changes

  • Refactor the comment parser in preparation for it to be octavius 2 (@jonludlam, #621)
  • Remove odoc-parser into a separate repository (@jonludlam, #700)

Additions

  • New model for expanding and cross referencing (@jonludlam, @Julow, @lubegasimon)
  • New document output layer, supporting HTML, LaTeX and man page output (@Drup, @Octachron, @jonludlam, @Julow, @lubegasimon)
  • Experimental parent/child support for structured output (@jonludlam)
  • Add the ability to specifiy canonical paths for types and module types (@jonludlam, #596)
  • Several improvements to the HTML tree (@dbuenzli, #600, #605, #589, @Drup, #579)
  • Render module synopses in {!modules:...} (@Julow, #597)
  • Better HTML rendering (@dbuenzli, #607, #612, #615)
  • Better handling of signature comments (@Julow, #627, #629, #640, #643, #647, #654)
  • Centre, left and right alignment constructs now parse correctly (@lubegasimon, #624)
  • Allow reference to pages that contain hyphens and dots (@lubegasimon, #622)
  • Allow type definitions to be copied and pasted with correct syntax (@Drup, #626)
  • Install Ocamlary as a library for testing (@dbuenzli, #639)
  • Handle @canonical tags on compilation units (@Julow, #649)
  • Alias more when strengthening (@jonludlam, #653)
  • Light theme fixes (@xvw, #660)
  • Handle @canonical tags in the top-comment of modules (@Julow, #662)
  • Simplify paths referring to Stdlib (@jonludlam, #677)
  • New odoc command to report warnings encountered during compilation/linking (@Julow, #667)
  • Anchors on type extensions (@Julow, #684)
  • OCaml 4.13 support (@octachron, #687, #689)
  • Better errors/warnings (@Julow, #692, #717, #720, #732)
  • ModuleType 'Alias' support (@jonludlam, #703)
  • Improved test suite (@lubegasimon, #697)
  • Improved documentation (@lubegasimon, @jonludlam, #702, #733)
  • Strengthen module types (@jonludlam, #731)

Bugs fixed

  • Fix for resolving references in mld files (@jonludlam, #611)
  • Fix placement of documentation in module aliases (@Julow, #606)
  • Fix breakage involving includes and shadowing (@jonludlam, #603)
  • Don't link to hidden items (@lubegasimon, #583)
  • Don't remove docs of inlined includes (@Julow, #595)
  • Don't render shadowed values (@lubegasimon, #580)
  • Fix unresolved references in the first comment of a file (@Julow, #592)
  • LaTeX: Hardened description environments (@Octachron, #608)
  • Resolve references in module synopses (@Julow, #658)
  • Fix reference resolution in the presence of shadowing (@Julow, #682)
  • uwt now can be documented (@jonludlam, #708)
  • Fix resolution involving deeply nested substitutions (@jonludlam, #727)
  • Fix off-by-one error in error reporting (@asavahista, #736)