How do I find a project's inventory file?

The documentation generator should generate an inventory file in the root of its output folder. These then get deployed with the rest of the documentation. For most projects, this "root" ends up in a subfolder named after the version or branch.

For example, you will find objects.inv inventory files under the following URLs:

If it is not obvious where an inventory file is located, simply try to load it in the REPL until you find a working URL:

julia> using DocInventories
julia> Inventory("")ERROR: RequestError: HTTP/2 404 while requesting
julia> Inventory("")Inventory( project="Sphinx", version="7.4.0", root_url="", items=[ InventoryItem(":js:function:`\$.getJSON`" => "usage/domains/javascript.html#getJSON"), InventoryItem(":c:member:``" => "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"), ] )

If you cannot find any inventory file, see What if I want to link to a project that does not provide an inventory file?

How do I figure out the correct name for the @extref link?

Use the search capabilities of InterLinks or DocInventories.Inventory.

If you have set up an InterLinks object named links in your docs/make.jl as described before, you are presumably able to build your documentation locally by starting a Julia REPL in the appropriate environment (e.g., julia --project=docs) and then running include("docs/make.jl").

This also puts the links object into your REPL, allowing you to search it interactively.

julia> # include("docs/make.jl")
julia> linksInterLinks( "sphinx" => Inventory(""), "matplotlib" => Inventory(""), "Documenter" => Inventory("/home/runner/work/DocumenterInterLinks.jl/DocumenterInterLinks.jl/docs/build/inventories/Documenter.toml"; root_url=""), "Julia" => Inventory("/home/runner/work/DocumenterInterLinks.jl/DocumenterInterLinks.jl/docs/build/inventories/Julia.toml"; root_url=""), )

For example, trying to find the appropriate @extref link to to the LaTeX Syntax section in the Documenter manual, you might search for

julia> links["Documenter"]("latex")9-element Vector{InventoryItem}:
 InventoryItem(":std:label:`Compiling-using-natively-installed-latex`" => "man/other-formats/#\$", dispname="Compiling using natively installed latex")
 InventoryItem(":std:label:`Display-Equations`" => "man/latex/#\$", dispname="Display Equations")
 InventoryItem(":std:label:`Escaping-Characters-in-Docstrings`" => "man/latex/#\$", dispname="Escaping Characters in Docstrings")
 InventoryItem(":std:label:`Inline-Equations`" => "man/latex/#\$", dispname="Inline Equations")
 InventoryItem(":std:label:`Printing-LaTeX-from-Julia`" => "man/latex/#\$", dispname="Printing LaTeX from Julia")
 InventoryItem(":std:label:`Set-math-engine-and-define-macros-for-LaTeX`" => "man/latex/#\$", dispname="Set math engine and define macros for LaTeX")
 InventoryItem(":std:label:`custom-latex`" => "man/other-formats/#\$", dispname="Custom LaTeX style")
 InventoryItem(":std:label:`latex_syntax`" => "man/latex/#\$", dispname="LaTeX Syntax")
 InventoryItem(":std:doc:`man/latex`" => "man/latex/", dispname="LaTeX Syntax")

and determine that an appropriate @extref would be

[LaTeX Syntax](@extref Documenter :label:`latex_syntax`)

This search is quite flexible. Using regular expression, you could do something crazy like search the Julia documentation for docstrings of any method that involves two or more strings:

julia> links["Julia"](r":method:`.*-.*AbstractString.*AbstractString.*`")11-element Vector{InventoryItem}:
 InventoryItem(":jl:method:`Base.:*-Tuple{Union{AbstractChar, AbstractString}, Vararg{Union{AbstractChar, AbstractString}}}`" => "base/strings/#Base.%3A%2A-Tuple%7BUnion%7BAbstractChar%2C%20AbstractString%7D%2C%20Vararg%7BUnion%7BAbstractChar%2C%20AbstractString%7D%7D%7D")
 InventoryItem(":jl:method:`Base.:==-Tuple{AbstractString, AbstractString}`" => "base/strings/#Base.%3A%3D%3D-Tuple%7BAbstractString%2C%20AbstractString%7D")
 InventoryItem(":jl:method:`Base.cmp-Tuple{AbstractString, AbstractString}`" => "base/strings/#Base.cmp-Tuple%7BAbstractString%2C%20AbstractString%7D")
 InventoryItem(":jl:method:`Base.findfirst-Tuple{AbstractString, AbstractString}`" => "base/strings/#Base.findfirst-Tuple%7BAbstractString%2C%20AbstractString%7D")
 InventoryItem(":jl:method:`Base.findlast-Tuple{AbstractString, AbstractString}`" => "base/strings/#Base.findlast-Tuple%7BAbstractString%2C%20AbstractString%7D")
 InventoryItem(":jl:method:`Base.findnext-Tuple{AbstractString, AbstractString, Integer}`" => "base/strings/#Base.findnext-Tuple%7BAbstractString%2C%20AbstractString%2C%20Integer%7D")
 InventoryItem(":jl:method:`Base.findprev-Tuple{AbstractString, AbstractString, Integer}`" => "base/strings/#Base.findprev-Tuple%7BAbstractString%2C%20AbstractString%2C%20Integer%7D")
 InventoryItem(":jl:method:`Base.isless-Tuple{AbstractString, AbstractString}`" => "base/strings/#Base.isless-Tuple%7BAbstractString%2C%20AbstractString%7D")
 InventoryItem(":jl:method:`Dates.Date-Tuple{AbstractString, AbstractString}`" => "stdlib/Dates/#Dates.Date-Tuple%7BAbstractString%2C%20AbstractString%7D")
 InventoryItem(":jl:method:`Dates.DateTime-Tuple{AbstractString, AbstractString}`" => "stdlib/Dates/#Dates.DateTime-Tuple%7BAbstractString%2C%20AbstractString%7D")
 InventoryItem(":jl:method:`Dates.Time-Tuple{AbstractString, AbstractString}`" => "stdlib/Dates/#Dates.Time-Tuple%7BAbstractString%2C%20AbstractString%7D")

You can also search across all projects, using a lookup in the InterLinks object directly, e.g.,

julia> links("`index`")6-element Vector{String}:
 "@extref sphinx :rst:directive:`index`"
 "@extref sphinx :rst:role:`index`"
 "@extref sphinx :std:doc:`index`"
 "@extref matplotlib :std:doc:`index`"
 "@extref Documenter :std:doc:`index`"
 "@extref Julia :std:doc:`index`"

These matching @extref links should be modified according to the Recommended Syntax.

What if I want to link to a project that does not provide an inventory file?

Inventory files really should be created automatically using a documentation generator. Try to get the project to use one that produces inventory files or help them set up their documentation system so that it does.

For a Documenter-based project that does not have an inventory file (presumably because it is using Documenter < v1.3.0), you can use the DocumenterInventoryWritingBackport package to create one locally. As an example, let's create an inventory file for Documenter v1.2 itself:

# Obtain a copy of the Documenter 1.2.0 source
git clone
cd Documenter.jl
git checkout -b inventory-writing v1.2.0

# Instantiate the environment for building the documentation
julia --project=docs -e '
    using Pkg

# Build the documentation and convert the resulting inventory to TOML
julia --project=docs -e '
    using DocInventories
    using DocumenterInventoryWritingBackport
    DocInventories.convert("docs/build/objects.inv", "Documenter.toml")'

Essentially, what we've done here is to open a Julia REPL like we normally would when building the package documentation locally. Before executing the docs/make.jl script, we've loaded the DocInventories and DocumenterInventoryWritingBackport packages. The latter one ensures that when Documenter runs, it will automatically create a compressed objects.inv inventory file in the docs/build folder. In the last step, we've converted that to the TOML Format.

The above routine is how the local inventory files used in this documentation were generated. Using the TOML format is recommended for any inventory that will be committed to Git, as it is both human-readable and easier for git to track.


Make sure that prettyurls=true in Documenter.makedocs, or, more specifically, that the prettyurls option is not set conditionally with something like prettyurls = get(ENV, "CI", nothing) == "true". This would cause a mismatch between the locally generated inventory and the deployed documentation.

Some local inventory files are also available in the project wiki. You may contribute your own generated inventories there.

There may be projects that legitimately do not provide inventories. For example, some simple Julia projects write out their entire documentation in their README on Github. In that case, you should either use standard links or manually create an inventory file. The easiest way to do this is to write out an inventory in TOML Format by hand.

Documenter's markdown flavor lacks the ability for reference links. If you link to the same very long URLs repeatedly, this becomes cumbersome.

In principle, you could manually write out an inventory file that defines link labels and their associated URLs, along the lines of the discussion in Documenter's PR #1351. Whether you should abuse DocumenterInterLinks in this way might be a matter of debate.

A situation where I do think this makes sense is if you repeatedly link to some website with very structured content, e.g. Wikipedia or the Julia Discourse Forum. As shown in the DocInventories documentation, you could write a Wikipedia inventory file just for the articles you want to link to, and then have a link such as

[Julia](@extref Wikipedia)

in your documentation to link to Julia (programming language).