Module Odoc_extension_apiSource
Odoc Extension API
This module provides the interface for odoc tag extensions. Extensions are dynamically loaded plugins that handle custom tags like @note, @rfc, @example, etc.
Re-exported Types
These are the odoc types that extensions need to work with.
Extension Types
type resource = Odoc_extension_registry.resource = | Js_url of string(*External JavaScript: emitted as
*)<script src="…">. Deduplicated by absolute URL on SPA navigation.| Css_url of string(*External CSS: emitted as
*)<link rel="stylesheet" href="…">. Deduplicated by absolute URL on SPA navigation.| Js_inline of string(*Inline JavaScript: emitted as
*)<script data-spa-inline="…">…</script>. Runs once on first encounter; skipped on subsequent SPA navigations that carry an identical script.| Css_inline of string(*Inline CSS: emitted as
*)<style>…</style>. Re-injected on each SPA navigation (idempotent).
Resources that can be injected into the HTML <head>.
See Odoc_extension_registry for full documentation on execution timing, SPA deduplication semantics, and guidance for extension authors.
Summary:
Js_url/Css_url— deduplicated by resolved URL. Loaded at most once across SPA navigations.Js_inline— stamped withdata-spa-inlineat generation time. Executed exactly once: on the first SPA navigation that introduces the script. Do not useDOMContentLoadedinside these; use aMutationObserverif you need to react to content changes on subsequent navigations.Css_inline— injected on every navigation (CSS is additive and idempotent).
type asset = Odoc_extension_registry.asset = {asset_filename : string;(*Filename for the asset, e.g., "diagram-1.png"
*)asset_content : bytes;(*Binary content
*)
}Binary asset generated by an extension. Assets are written alongside the HTML output. To reference an asset in your content, use the placeholder __ODOC_ASSET__filename__ which will be replaced with the correct relative path during HTML generation.
Extension Documentation
Extensions can register documentation describing their options and usage. This information is displayed by odoc extensions --help.
type option_doc = Odoc_extension_registry.option_doc = {opt_name : string;(*Option name, e.g., "width"
*)opt_description : string;(*What the option does
*)opt_default : string option;(*Default value if any
*)
}Documentation for a single option
type extension_info = Odoc_extension_registry.extension_info = {info_kind : [ `Tag | `Code_block ];(*Type of extension
*)info_prefix : string;(*The prefix this extension handles
*)info_description : string;(*Short description
*)info_options : Odoc_extension_api.option_doc list;(*Supported options
*)info_example : string option;(*Example usage
*)
}Documentation/metadata for an extension
type extension_output = {content : Block.t;(*Universal content - used by all backends unless overridden
*)overrides : (string * string) list;(*Backend-specific raw content overrides. E.g.,
*)("html", "<div>...</div>"); ("markdown", "...")resources : Odoc_extension_api.resource list;(*Page-level resources (JS/CSS). Only used by HTML backend. See
*)resourcefor execution and deduplication semantics, especially in SPA (single-page app) shells.assets : Odoc_extension_api.asset list;(*Binary assets to write alongside HTML output. Reference in content using
*)__ODOC_ASSET__filename__placeholder.
}Output from the document phase
Raised when an extension receives a tag variant it doesn't support
Link Environment
Extensions that need to look up other pages or modules during linking can use the cross-reference environment.
Extension Interface
Extensions that also need link-time access to the cross-reference environment implement this extended signature.
Code Block Extensions
Extensions can also handle code blocks like {@dot[...]} or {@mermaid[...]}. These extensions receive the language tag, metadata (key=value pairs), and the code content.
Metadata for code blocks
The signature that code block extensions must implement
Support Files
Extensions can register support files (CSS, JS, images, etc.) that will be output by odoc support-files.
type support_file = Odoc_extension_registry.support_file = {filename : string;(*Relative path, e.g., "extensions/admonition.css"
*)content : Odoc_extension_api.support_file_content;
}Extension Registry
Extensions register themselves here when loaded. odoc queries the registry when processing custom tags.
Helper Functions
val blocks_of_nestable_elements :
Odoc_document.Comment.Comment.nestable_block_element
Odoc_document.Comment.Comment.with_location
list ->
Odoc_document.Types.Block.one listConvert Comment AST to Block elements, preserving references and formatting. This is the proper way to convert tag content to renderable blocks.
Extract plain text from nestable block elements (for simple parsing)
val text_of_nestable_block_elements :
Comment.nestable_block_element Location_.with_location list ->
stringCreate an inline link
Create an empty extension output with just content
Code Block Metadata Helpers
val get_binding :
'a ->
[< `Binding of
'a Odoc_parser.Loc.with_location * 'b Odoc_parser.Loc.with_location
| `Tag of 'c ]
list ->
'b optionGet the value of a binding from code block tags. E.g., for {@dot width=500[...]}, get_binding "width" meta.tags returns Some "500".
val has_tag :
'a ->
[< `Binding of 'b | `Tag of 'a Odoc_parser.Loc.with_location ] list ->
boolCheck if a bare tag is present in code block tags. E.g., for {@ocaml line-numbers[...]}, has_tag "line-numbers" meta.tags returns true.
val get_all_bindings :
[< `Binding of
'a Odoc_parser.Loc.with_location * 'b Odoc_parser.Loc.with_location
| `Tag of 'c ]
list ->
('a * 'b) listGet all bindings as a list of (key, value) pairs
val get_all_tags :
[< `Binding of 'a | `Tag of 'b Odoc_parser.Loc.with_location ] list ->
'b listGet all bare tags as a list of names