Usage

Loading Inventories

An Inventory object can be instantiated from the URL of an inventory file. For projects whose documentation is generated via Documenter (most Julia projects) or Sphinx (most Python projects), the inventory file should be objects.inv in the root of the online documentation. For example, the inventory file for the popular Python matplotlib library would be loaded as

using DocInventories
inventory = Inventory("https://matplotlib.org/3.7.3/objects.inv")
Inventory(
 project="Matplotlib",
 version="3.7.3",
 root_url="https://matplotlib.org/3.7.3/",
 items=[
  InventoryItem(":std:label:`2dcollections3d`" => "tutorials/toolkits/mplot3d.html#dcollections3d", dispname="2D plots in 3D"),
  InventoryItem(":std:label:`3d_plots`" => "plot_types/3D/index.html#d-plots", dispname="3D"),
  InventoryItem(":std:envvar:`HOME`" => "users/faq/environment_variables_faq.html#envvar-\$", priority=1),
  InventoryItem(":std:envvar:`MPLBACKEND`" => "users/faq/environment_variables_faq.html#envvar-\$", priority=1),
  InventoryItem(":std:envvar:`MPLCONFIGDIR`" => "users/faq/environment_variables_faq.html#envvar-\$", priority=1),
  ⋮ (10231 elements in total)
  InventoryItem(":std:label:`wireframe`" => "tutorials/toolkits/mplot3d.html#\$", dispname="Wireframe plots"),
  InventoryItem(":std:label:`working-with-text`" => "tutorials/introductory/pyplot.html#\$", dispname="Working with text"),
  InventoryItem(":std:label:`writing-docstrings`" => "devel/documenting_mpl.html#\$", dispname="Writing docstrings"),
  InventoryItem(":std:label:`writing-examples-and-tutorials`" => "devel/documenting_mpl.html#\$", dispname="Writing examples and tutorials"),
  InventoryItem(":std:label:`writing-rest-pages`" => "devel/documenting_mpl.html#\$", dispname="Writing ReST pages"),
  InventoryItem(":std:label:`xkcd-colors`" => "tutorials/colors/colors.html#\$", dispname="Comparison between X11/CSS4 and xkcd colors"),
 ]
)

To load an inventory from a local file, instantiate Inventory with the path to the file and a root_url:

inventory = Inventory(
    joinpath(@__DIR__, "inventories", "Julia.toml"),
    root_url="https://docs.julialang.org/en/v1/"
)
Inventory(
 project="The Julia Language",
 version="1.10.0",
 root_url="https://docs.julialang.org/en/v1/",
 items=[
  InventoryItem(":std:label:`\"Value-types\"`" => "manual/types/#%22Value-types%22", dispname="\"Value types\""),
  InventoryItem(":jl:keyword:`&&`" => "base/math/#%26%26"),
  InventoryItem(":jl:keyword:`...`" => "base/base/#\$"),
  InventoryItem(":std:label:`...-combines-many-arguments-into-one-argument-in-function-definitions`" => "manual/faq/#\$", dispname="... combines many arguments into one argument in function definitions"),
  InventoryItem(":std:label:`...-splits-one-argument-into-many-different-arguments-in-function-calls`" => "manual/faq/#\$", dispname="... splits one argument into many different arguments in function calls"),
  ⋮ (3602 elements in total)
  InventoryItem(":std:label:`using-and-import-with-specific-identifiers,-and-adding-methods`" => "manual/modules/#using-and-import-with-specific-identifiers%2C-and-adding-methods", dispname="using and import with specific identifiers, and adding methods"),
  InventoryItem(":jl:keyword:`var\"name\"`" => "base/base/#var%22name%22"),
  InventoryItem(":jl:keyword:`where`" => "base/base/#\$"),
  InventoryItem(":jl:keyword:`while`" => "base/base/#\$"),
  InventoryItem(":std:label:`writing-binary-broadcasting-rules`" => "manual/interfaces/#\$", dispname="Writing binary broadcasting rules"),
  InventoryItem(":jl:keyword:`||`" => "base/math/#%7C%7C"),
 ]
)

Inventory Items

Each Inventory is a collection of InventoryItem objects. We can iterate over these, or look up a particular item with a numerical index or a specification like

item = inventory["Style-Guide"]
InventoryItem(
  ":std:label:`Style-Guide`" => "manual/style-guide/#\$",
  dispname="Style Guide"
)

Conceptually, as indicated above, the inventory item maps a spec to a uri relative to the root_url associated with the Inventory containing the item.

The spec in the mapping adopts the notation of a "domain" and "role" from Sphinx:

DocInventories.show_full(inventory["Style-Guide"])
InventoryItem(
  name="Style-Guide",
  domain="std",
  role="label",
  priority=-1,
  uri="manual/style-guide/#Style-Guide",
  dispname="Style Guide"
)

This makes spec reminiscent of the Sphinx cross-referencing syntax[1]. When looking up an item, the domain and role part of the specification are optional and serve for disambiguation. The above item could also have been obtained with inventory[:label:`Style Guide`] or inventory[:std:label:`Style Guide`].

Exploring Inventories

An Inventory instance is a callable that takes a search and returns a list of InventoryItems that match the search. This is quite flexible, and takes a string or regular expression that will be compared both against the spec and the full string representation (repr(item; context=(:full => true))) of each item.

Thus, we could search for a title as is appears in the documentation:

inventory("Sorting and Related Functions")
2-element Vector{InventoryItem}:
 InventoryItem(":std:label:`Sorting-and-Related-Functions`" => "base/sort/#\$", dispname="Sorting and Related Functions")
 InventoryItem(":std:doc:`base/sort`" => "base/sort/", dispname="Sorting and Related Functions")

Or, with a regular expression, for all Julia functions in Base that have sort in their name:

inventory(r":function:`Base\..*sort.*`")
14-element Vector{InventoryItem}:
 InventoryItem(":jl:function:`Base.Sort.insorted`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.Sort.partialsort`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.Sort.partialsort!`" => "base/sort/#Base.Sort.partialsort%21")
 InventoryItem(":jl:function:`Base.Sort.partialsortperm`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.Sort.partialsortperm!`" => "base/sort/#Base.Sort.partialsortperm%21")
 InventoryItem(":jl:function:`Base.Sort.searchsorted`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.Sort.searchsortedfirst`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.Sort.searchsortedlast`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.Sort.sortperm!`" => "base/sort/#Base.Sort.sortperm%21")
 InventoryItem(":jl:function:`Base.issorted`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.sort`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.sort!`" => "base/sort/#Base.sort%21")
 InventoryItem(":jl:function:`Base.sortperm`" => "base/sort/#\$")
 InventoryItem(":jl:function:`Base.sortslices`" => "base/sort/#\$")

Or, for all linkable items that appear on the page with the relative URI "manual/workflow-tips/"

inventory("manual/workflow-tips/")
6-element Vector{InventoryItem}:
 InventoryItem(":std:label:`A-basic-editor/REPL-workflow`" => "manual/workflow-tips/#A-basic-editor%2FREPL-workflow", dispname="A basic editor/REPL workflow")
 InventoryItem(":std:label:`Browser-based-workflow`" => "manual/workflow-tips/#\$", dispname="Browser-based workflow")
 InventoryItem(":std:label:`REPL-based-workflow`" => "manual/workflow-tips/#\$", dispname="REPL-based workflow")
 InventoryItem(":std:label:`Revise-based-workflows`" => "manual/workflow-tips/#\$", dispname="Revise-based workflows")
 InventoryItem(":std:label:`man-workflow-tips`" => "manual/workflow-tips/#\$", dispname="Workflow Tips")
 InventoryItem(":std:doc:`manual/workflow-tips`" => "manual/workflow-tips/", dispname="Workflow Tips")

The search results will be sorted taking into account the priority field of the items.

Manipulating Inventories

Inventory objects are immutable, with the exception that new InventoryItems can be added to an existing Inventory using push! and append!.

Beyond that, DocInventories.set_metadata can modify the metadata (project and version) both of an Inventory object and an inventory file on disk, but the operation is in-place only for files.

These tools are primarily intended to tweak the inventories automatically generated by Documenter.makedocs, e.g., to set a custom version for a dev-release (alternatively to the inventory_version option in Documenter.HTMLWriter.HTML in Documenter >= 1.3.0), or to use a different project name than the standard project in makedocs. These modifications should be made after the call to Documenter.makedocs, but before Documenter.deploydocs.

Saving Inventories to File

An inventory can be written to file using the DocInventories.save function. For example, to write the inventory in TOML Format, use

DocInventories.save("$(tempname()).toml", inventory)

The MIME type is derived from the extension of the file name, according to the mapping in DocInventories.MIME_TYPES. The MIME-type can also be passed explicitly to save, independent of the file name:

DocInventories.save(tempname(), inventory; mime="application/toml")

It is also possible to write with compression by appending a .gz file extension:

DocInventories.save("$(tempname()).toml.gz", inventory)

See Inventory File Formats for a description of all available output formats.

  • 1We conflate Sphinx' "object types" and "roles". Technically, a Sphinx domain (like the Python py domain) has object types (e.g., function) which in turn have one or more associated roles that are used when referencing the object (e.g., func). DocInventories has no formal definition of domains/types/roles, so it considers types and roles identical. Consequently, a Sphinx reference ":py:func:`matplotlib.pyplot.subplots`" would correspond to the DocInventories spec ":py:function:`matplotlib.pyplot.subplots`".