DocumenterInterLinks.jl

Github v1.0.0

DocumenterInterLinks.jl is a plugin for Documenter.jl to link to external projects. It is interoperable with Intersphinx for Python projects.

Installation

As usual, the package can be installed via

] add DocumenterInterLinks

in the Julia REPL, or by adding

DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656"

to the relevant Project.toml file (e.g., docs/Project.toml).

Usage

Declaring External Projects

In docs/make.jl, instantiate an InterLinks object to define external projects you want to link to. For example,

using DocumenterInterLinks

links = InterLinks(
    "sphinx" => "https://www.sphinx-doc.org/en/master/",
    "matplotlib" => "https://matplotlib.org/3.7.3/objects.inv",
    "Julia" => (
        "https://docs.julialang.org/en/v1/",
        joinpath(@__DIR__, "inventories", "Julia.toml")
    ),
    "Documenter" => (
        "https://documenter.juliadocs.org/stable/",
        "https://documenter.juliadocs.org/stable/objects.inv",
        joinpath(@__DIR__, "inventories", "Documenter.toml")
    ),
);

defines the external projects "sphinx", "matplotlib", "Julia" and "Documenter". For each project, it specifies the root URL of that project's online documentation and the location of an inventory file.

The above examples illustrates three possibilities for specifying the root URL and inventory location:

  • Map that project name to project root URL. This will look for an inventory file objects.inv directly underneath the given URL. In the "sphinx" entry of the example, the inventory file would be loaded from https://www.sphinx-doc.org/en/master/objects.inv. This is the recommended form in most cases.
  • Map the project name to the URL of an inventory file. The project root URL is the given URL without the filename. In the "matplotlib" entry of the example, the project root URL would be https://matplotlib.org/3.7.3/. This form would only be used if the name of the inventory file is not the standard objects.inv.
  • Map the project name to a tuple containing the root URL first, and then one or more possible locations for an inventory file. These may be local file paths, which allows using a self-maintained inventory file for a project that does not provide one.
    • In the "Julia" entry of the example, the inventory would be loaded only from the local file docs/src/inventories/Julia.toml. As of Julia 1.11, the online documentation provides an inventory file, so using a local inventory for Julia is no longer necessary.
    • In the "Documenter" entry of the example, the inventory would first be loaded from the standard online location. Only if this fails (e.g., because the network connection fails), a "backup inventory" is loaded from docs/src/inventories/Documenter.toml.

See the doc-string of InterLinks for details.

Warning

The instantiated links object must be passed to Documenter.makedocs as an element to the plugins keyword argument.

Inventories

The inventory files referenced when instantiating InterLinks are assumed to have been created by a documentation generator, see Inventory Generation. The DocInventories package is used as a backend to parse these files into DocInventories.Inventory objects. These are accessible by using links as a dict:

links["sphinx"]
Inventory(
 project="Sphinx",
 version="7.4.0",
 root_url="https://www.sphinx-doc.org/en/master/",
 items=[
  InventoryItem(":js:function:`\$.getJSON`" => "usage/domains/javascript.html#getJSON"),
  InventoryItem(":c:member:`@alias.data`" => "usage/domains/c.html#c.\$", dispname="[anonymous].data"),
  InventoryItem(":c:function:`@alias.f`" => "usage/domains/c.html#c.\$", dispname="[anonymous].f"),
  InventoryItem(":c:functionParam:`@alias.f.k`" => "usage/domains/c.html#c.@alias.f", dispname="[anonymous].f.k"),
  InventoryItem(":cpp:type:`CustomList`" => "tutorial/describing-code.html#_CPPv410\$"),
  ⋮ (1537 elements in total)
  InventoryItem(":std:label:`websupportquickstart`" => "usage/advanced/websupport/quickstart.html#\$", dispname="Web Support Quick Start"),
  InventoryItem(":std:label:`when-deprecation-warnings-are-displayed`" => "man/sphinx-build.html#\$", dispname="Deprecation Warnings"),
  InventoryItem(":std:label:`windows-other-method`" => "usage/installation.html#\$", dispname="Other Methods"),
  InventoryItem(":std:label:`writing-builders`" => "extdev/builderapi.html#\$", dispname="Builder API"),
  InventoryItem(":std:confval:`xml_pretty`" => "usage/configuration.html#confval-\$", priority=1),
  InventoryItem(":std:label:`xref-syntax`" => "usage/referencing.html#\$", dispname="Cross-referencing syntax"),
 ]
)

As we can see, inventories contain a mapping of names to linkable locations relative to the root URL of a project's online documentation, see DocInventories.InventoryItem.

The DocInventories package provides tools for interactively searching inventories for items to reference. See Exploring Inventories and How do I figure out the correct name for the @extref link?.

Using External References

The DocumenterInterLinks plugin adds support for @extref link targets to Documenter. At the most fundamental level, they work just like Documenter's standard @ref link targets. Replacing @ref with @extref switches from a local reference to an external one:

* [`Documenter.makedocs`](@extref)
* [Documenter's `makedocs` function](@extref Documenter.makedocs)
* See the section about Documenter's [Writers](@extref).

The above markdown code renders as follows:

To disambiguate (and speed up) the references, the name of the inventory (as defined when instantiating InterLinks) can be included in the @extref. In particular, the last example should have been written as

* See the section about Documenter's [Writers](@extref Documenter).

to clarify that we are linking to the section name "Writers" found in links["Documenter"]. When the link text and link target differ, the inventory name should be given between @extref and the target name, e.g., [`Regex`](@extref Julia Base.Regex), which turns into "Regex".

Since DocumenterInterLinks is fully compatible with Sphinx inventories, it also provides an extended @extref syntax that builds on the Sphinx concept of "domains" and "roles". You will see these when inspecting an InventoryItem:

using DocInventories

DocInventories.show_full(links["Documenter"]["Documenter.makedocs"])
InventoryItem(
  name="Documenter.makedocs",
  domain="jl",
  role="function",
  priority=1,
  uri="lib/public/#Documenter.makedocs",
  dispname="Documenter.makedocs"
)

We can include the domain and role in an @extref link as

* [`makedocs`](@extref :function:`Documenter.makedocs`)
* [`makedocs`](@extref :jl:function:`Documenter.makedocs`)

using a syntax that is reminiscent of the Sphinx cross-referencing syntax. The use of domains and roles in DocumenterInterLinks (unlike in Sphinx) is for disambiguation only, in case there are multiple items with the same name. In general, follow the Recommended Syntax guidelines.

Public API and Changelog

The DocumenterInterLinks project follows Semantic Versioning. See the CHANGELOG for changes after v1.0. The "public API" extends to the documented @extref Syntax and to the instantiation of the InterLinks plugin. Other Internals or features marked as "experimental" may change in minor versions.