Welcome to the odoc
project, and we're thrilled that you're considering contributing!
This guide serves as a roadmap for your contribution journey. It lays out the necessary steps and guidelines to ensure a smooth contribution experience, from setting up your development environment to making a pull request.
The CSS for odoc
is located at src/html_support_files/odoc.css. We're continually working to improve it and welcome your contributions. You can edit CSS using your browser's developer tools or Chrome DevTools. Once you've made your changes, submit a pull request with those changes.
Contributing to the HTML is slightly more complex. The main HTML generator is in src/html/generator.ml. It operates on types defined in Odoc_document.Types
, an intermediate representation used by all output renderers. The type describing an individual HTML page is Odoc_document.Types.Page.t
.
Here's a step-by-step guide to get you set up for HTML contribution:
-
Install requirements:
- Install a recent version of HTML Tidy (used for HTML validity testing). Here's how:
- On MacOS (should be version 5.8 by the date of this writing):
brew install tidy-html5
- On Debian / Ubuntu:
sudo apt-get install tidy
- On MacOS (should be version 5.8 by the date of this writing):
- Install a recent version of
jq
. Here's how:- On MacOS:
brew install jq
- On Debian / Ubuntu:
sudo apt-get install jq
- On MacOS:
- Install a recent version of HTML Tidy (used for HTML validity testing). Here's how:
-
Set up for development: Clone the
odoc
repository, navigate into the new directory, and install dependencies with these commands:git clone https://github.com/ocaml/odoc.git cd odoc opam install --with-test --deps-only ./odoc-parser.opam ./odoc.opam
-
Make and test changes: After making your changes, compile the code with
make
and then run the tests withmake test
. Any changes to the HTML are likely to cause tests to fail - see the Testing section below to understand how to update them. -
Test
odoc
against your project: Clean the build withmake clean
, then installodoc
withopam install odoc
. Becauseodoc
is pinned, this will install your modified version. You can then runodoc
in your project as you normally would:dune build @doc
. -
Submit a pull request: If everything looks good, feel free to submit a pull request. We appreciate your contribution!
odoc
uses a variety of different test types. We are slowly converging on using Dune's Cram tests, though we still have many tests that aren't yet converted.
The tests extensively use these for the model layer and are found in test/xref2. These consist of a directory called something.t
, containing a file run.t
. This file has shell-like syntax and usually runs odoc
on some carefully crafted input files.
For tests of the model layer, it's often useful to use the binary odoc_print
which can dump .odoc
and .odocl
files as JSON. This output can then be piped through jq to verify that values are as expected.
We try to make these test files describe the test and what's expected, which helps when the output isn’t what the test expected. This also means that the tests can serve as documentation of how things work. As an example, see the file test/xref2/multi_file_module_type_of.t/run.t
The tests work by executing the shell script snippets and then comparing the actual output with those in the run.t
files. If these don't match, the difference is rendered as a diff.
If the test is broken, run dune promote
to replace the expected output with the current output.
Many of odoc
's older tests are custom Expect-tests, similar to those run in the Cram test above, but that don't use Dune's promote workflow.
When one of these Expect-tests fail, the output is saved, so the developer can choose to replace the now-incorrect expected string. For these custom Expect-tests, the results may look like the example given in the OCamldoc.
We are slowly shifting these custom Expect-tests over to the Dune promote workflow.
The odoc
repo is set up for coverage analysis. This is most useful if you're writing new tests and want to know what they’re actually touching.
To use it:
- Run
make coverage
. This will run the tests as normal, except at the end you’ll get a message like
See _coverage/index.html
You can then open _coverage/index.html
and see the coverage of the code you’d like your new test to reach.
- Write new tests
- Check coverage again
odoc
is tested by OCaml-CI and by GitHub workflows. One of these also does a coverage build, so we have up-to-date coverage stats on Coveralls.
The tests cover esy and opam builds on Windows, macOS, and Linux. The Linux tests cover all supported versions of OCaml. We strive to retain compatibility back as far as we can (currently 4.02) which is important for supporting ocaml.org/docs.
The odoc.loader
library is responsible for converting from the OCaml Typedtree
representations to the internal representation.
The odoc.model
library contains definitions of the internal types used to represent OCaml interfaces.
Resolution of Paths, Fragments and References, and Expansion of Modules and Module Types are handled by the odoc.xref2
library.
The generic documentation intermediate format is defined in the odoc.document
library.
The three current renderers are implemented within the following libraries: odoc.html
, odoc.latex
, and odoc.manpage
.
The CLI for odoc
and various helper functions for driving the process are contained in the odoc.odoc
library.
There are a couple of libraries used internally for testing - odoc.xref_test
and odoc.model_desc
.
There are several dependency libraries that odoc
uses, whose functions, type, and module declarations are essential for understanding how odoc
works. See the driver page for details on how the documentation for these libraries are included.