Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
* The Julia documentation now has an inventory
* Sphinx 7.3 can now link to Julia projects
* Various improvements in preparation of a 1.0 release
  • Loading branch information
goerz committed Jun 5, 2024
1 parent afacf7c commit bebccc4
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 66 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DocumenterInterLinks"
uuid = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656"
authors = ["Michael Goerz <[email protected]>"]
version = "0.3.2"
version = "0.3.2+dev"

[deps]
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

A plugin for [Documenter.jl](https://documenter.juliadocs.org/) that enables linking between projects.

The package provides an [`InterLinks`](https://juliadocs.org/DocumenterInterLinks.jl/stable/internals/#DocumenterInterLinks.InterLinks) plugin that loads [inventory files](#inventories) from other project documentations built with [Documenter](https://documenter.juliadocs.org/) or [Sphinx](https://www.sphinx-doc.org/en/master/). It then extends Documenter's markdown link syntax to recognize an `@extref` link target and resolve it with a link to the external project (similarly to the built-in `@ref` links for internal links), see [External References](#external-references).
The package provides an [`InterLinks`](http://juliadocs.org/DocumenterInterLinks.jl/stable/api/internals/#DocumenterInterLinks.InterLinks) plugin that loads [inventory files](#inventories) from other project documentations built with [Documenter](https://documenter.juliadocs.org/) or [Sphinx](https://www.sphinx-doc.org/en/master/). It then extends Documenter's markdown link syntax to recognize an `@extref` link target and resolve it with a link to the external project (similarly to the built-in `@ref` links for internal links), see [External References](#external-references).


## Installation
Expand All @@ -30,7 +30,7 @@ to the relevant `Project.toml` file (e.g., `docs/Project.toml`).

## Plugin Instantiation

In `docs/make.jl`, instantiate an [`InterLinks`](https://juliadocs.org/DocumenterInterLinks.jl/stable/internals/#DocumenterInterLinks.InterLinks) object, e.g.,
In `docs/make.jl`, instantiate an [`InterLinks`](http://juliadocs.org/DocumenterInterLinks.jl/stable/api/internals/#DocumenterInterLinks.InterLinks) object, e.g.,

```julia
using DocumenterInterLinks
Expand Down
5 changes: 1 addition & 4 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ AUTHORS = join(PROJECT_TOML["authors"], ", ") * " and contributors"
GITHUB = "https://github.com/JuliaDocs/DocumenterInterLinks.jl"

links = InterLinks(
"Julia" => (
"https://docs.julialang.org/en/v1/",
joinpath(@__DIR__, "src", "inventories", "Julia.toml")
),
"Julia" => "https://docs.julialang.org/en/v1/",
"Documenter" => "https://documenter.juliadocs.org/stable/",
"DocInventories" => "https://juliadocs.org/DocInventories.jl/stable/",
"sphinx" => "https://www.sphinx-doc.org/en/master/",
Expand Down
2 changes: 1 addition & 1 deletion docs/src/fallback.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fallbacks = ExternalFallbacks(
!!! warning
Like any plugin, `fallbacks` must be passed to [`Documenter.makedocs`](@extref) as an element of `plugins`.

The "slug" on the left-hand-side of the mapping can be obtained from message that `Documenter` prints when it fails to resolve the `@ref` link. Generally, for `[Section Title](@ref)` or `[text](@ref "Section Title)`, the slug is a "sluggified" version of the title (determined internally by `Documenter`, mostly just replacing spaces with dashes); and for ```[`code`](@ref)``` or `[text](@ref code)`, it is `"code"`. The right-hand-side of the mapping is a full `@extref` link. The plugin simply replaces the link target of original `@ref` link with the given `@extref`.
The "slug" on the left-hand-side of the mapping can be obtained from the message that `Documenter` prints when it fails to resolve the `@ref` link. Generally, for `[Section Title](@ref)` or `[text](@ref "Section Title)`, the slug is a "sluggified" version of the title (determined internally by `Documenter`, mostly just replacing spaces with dashes); and for ```[`code`](@ref)``` or `[text](@ref code)`, it is `"code"`. The right-hand-side of the mapping is a full `@extref` link. The plugin simply replaces the link target of original `@ref` link with the given `@extref`.

If there are any unresolvable `@ref` links, and there is no explicit `@extref`-mapping, [`ExternalFallbacks`](@ref) will search in all available inventories to resolve the link in an "automatic" mode. In this case, you will see messages like

Expand Down
4 changes: 1 addition & 3 deletions docs/src/howtos.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@ The documentation generator [should generate an inventory file](@ref Inventory-G

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

* [https://docs.julialang.org/en/v1/objects.inv](https://docs.julialang.org/en/v1/objects.inv)
* [https://www.sphinx-doc.org/en/master/objects.inv](https://www.sphinx-doc.org/en/master/objects.inv)
* [https://matplotlib.org/3.7.3/objects.inv](https://matplotlib.org/3.7.3/objects.inv)
* [https://docs.python.org/3/objects.inv](https://docs.python.org/3/objects.inv)
* [https://juliadocs.org/DocInventories.jl/stable/objects.inv](https://juliadocs.org/DocInventories.jl/stable/objects.inv)
* [https://juliadocs.org/DocInventories.jl/v0.2/objects.inv](https://juliadocs.org/DocInventories.jl/v0.2/objects.inv)
* [https://documenter.juliadocs.org/stable/objects.inv](https://documenter.juliadocs.org/stable/objects.inv)

The [Julia language](@extref Julia :doc:`index`) currently does not provide an inventory file, but if it did, it would be immediately underneath

* [https://docs.julialang.org/en/v1/](https://docs.julialang.org/en/v1/)

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:

Expand Down
10 changes: 6 additions & 4 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,15 @@ links = InterLinks(
nothing # hide
```

defines the external projects "[sphinx](https://www.sphinx-doc.org/)", "[matplotlib](https://matplotlib.org)", and "[Julia](https://docs.julialang.org/en/v1/)". For each project, it specifies the root URL of that project's online documentation and the location of an [inventory file](@ref Inventories).
defines the external projects "[sphinx](https://www.sphinx-doc.org/)", "[matplotlib](https://matplotlib.org)", "[Julia](https://docs.julialang.org/en/v1/)" and "[Documenter](https://documenter.juliadocs.org/stable/)". For each project, it specifies the root URL of that project's online documentation and the location of an [inventory file](@ref Inventories).

The above examples illustrates three possibilities for specifying the root url and inventory location
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. This is the recommended from 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.
* 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](https://github.com/JuliaDocs/DocumenterInterLinks.jl/tree/master/docs/src/inventories) 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](https://docs.julialang.org/en/v1/) 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`](@ref) for details.

Expand Down
9 changes: 6 additions & 3 deletions docs/src/sphinx-to-documenter-links/docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ We can link to various elements of the :external+DocumenterInterLinks:doc:`Docum
* ``:jl:type:`DocumenterInterLinks.InterLinks``` renders as :jl:type:`DocumenterInterLinks.InterLinks`
* ``:jl:const:`DocInventories.MIME_TYPES``` renders as :jl:const:`DocInventories.MIME_TYPES`
* ``:jl:method:`DocInventories.save``` renders as :jl:method:`DocInventories.save`
* ``:jl:method:`DocInventories.spec-Tuple{InventoryItem}``` renders as :jl:method:`DocInventories.spec-Tuple{InventoryItem}`
* ``:jl:method:`DocInventories.spec-Tuple{InventoryItem}``` renders as :jl:method:`DocInventories.spec-Tuple{InventoryItem}`
* ``:external+DocInventories:doc:`DocInventories<index>``` renders as :external+DocInventories:doc:`DocInventories<index>`
* Referencing a heading is currently not possible due to a bug in Sphinx: ``:external+DocumenterInterLinks:std:ref:`Syntax``` does not work because Sphinx lowercases the "Syntax"
* In Python, anchor names are lowercased, so referencing headings works: ``:external+sphinx:std:ref:`glossary``` renders as :external+sphinx:std:ref:`glossary`
* ``:external+DocumenterInterLinks:std:ref:`Syntax``` renders as
:external+DocumenterInterLinks:std:ref:`Syntax`. Note that this
`requires Sphinx 7.3 <https://www.sphinx-doc.org/en/master/changes.html#release-7-3-0-released-apr-16-2024>`_.
In older versions of Sphinx, linking to a heading in a Julia project is not possible due to
`issue #12008 <https://github.com/sphinx-doc/sphinx/issues/12008>`_.
2 changes: 1 addition & 1 deletion docs/src/sphinx-to-documenter-links/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ dependencies = [
"ipython",
"sphinx-rtd-theme",
"six",
"sphinx",
"sphinx~=7.3",
"sphinx-autodoc-typehints",
]

Expand Down
4 changes: 2 additions & 2 deletions docs/src/sphinx.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

`DocumenterInterLinks` is interoperable with [Sphinx](@extref sphinx :doc:`index`) and [Intersphinx](@extref sphinx :doc:`usage/extensions/intersphinx`): The [`InterLinks`](@ref) object can refer to the [`objects.inv`](@extref sphinx :doc:`usage/extensions/intersphinx`) file that Sphinx automatically writes out for every project. This makes it possible to easily link to virtually every Python project (as well as any other C/C++/Fortran project that uses Sphinx for its documentation).

The possible specification ```:domain:role:`name` ``` in an `@extref` link mimics [the cross-referencing syntax in Sphinx](@extref sphinx xref-syntax). However, Sphinx [reStructuredText](@extref sphinx :doc:`usage/restructuredtext/index`) is much more explicit than Documenter's [markdown syntax](@extref Documenter :doc:`man/syntax`). In particular, the domain and role are *required* for every reference (although projects can set up a default domain, usually `py`, which can then be omitted). This is not the case in the `@extref` syntax defined by `DocumenterInterLinks`, where domain and role are for disambiguation only and can (and usually should) be omitted.
The possible specification ```:domain:role:`name` ``` in an `@extref` link mimics [the cross-referencing syntax in Sphinx](@extref sphinx xref-syntax). However, Sphinx [reStructuredText](@extref sphinx :doc:`usage/restructuredtext/index`) is much more explicit than Documenter's [markdown syntax](@extref Documenter :doc:`man/syntax`). In particular, the domain and role are *required* for every reference (although projects can set up a default domain, usually `py`, which can then be omitted). This is not the case in the `@extref` syntax defined by `DocumenterInterLinks`, where the domain and role are for disambiguation only and can (and usually should) be omitted.

Moreover, [domains and roles](@extref sphinx :module:`sphinx.domains`) must be *formally defined* in Sphinx. In fact, Sphinx makes a distinction between "type" and "role". Strictly speaking, the `objects.inv` file records an "object type", like `function` or `module`, which [`DocInventories.InventoryItem`](@extref) reads in as `role`. A Sphinx domain then defines "roles" on top of that which are used for *referencing* object. The formal definition of the domain includes a mapping between an object type and one or more roles. Consider for example the code of the [`PythonDomain`](https://www.sphinx-doc.org/en/master/_modules/sphinx/domains/python.html#PythonDomain), which defines an object type `function` with associated roles `func` and `obj`. In contrast, `DocumenterInterLinks` has no formally defined domains and makes no distinction between object types and roles. Thus, the inventory item ```links["matplotlib"][":py:function:`matplotlib.get_backend`"]``` would be referenced as ```:py:func:`matplotlib.get_backend` ``` (using `:func:`, not `:function:`!) or ```:py:obj:`matplotlib.get_backend` ``` in Sphinx, but as ```[`get_backend`](@extref :py:function:`matplotlib.get_backend`)``` in `DocumenterInterLinks`, or more simply without any domain or role as ```[`matplotlib.get_backend`](@extref)```.

Expand Down Expand Up @@ -36,4 +36,4 @@ $(read(julia_domain_py, String))

We have used Sphinx' [Domain API](@extref sphinx domain-api) here to define the object types matching our [Julia Domain](@ref The-Julia-Domain). For each object type, we define a role of the same name, as well as abbreviated roles in line with Sphinx' usual conventions, such as `:func:` as a shorthand for `:function:` and `obj` for any type.

See [`sphinx-to-documenter-links`](https://github.com/JuliaDocs/DocumenterInterLinks.jl/tree/master/docs/src/sphinx-to-documenter-links) for a full example of a Python project with documentation linking to the documentation of Julia projects.
See [`sphinx-to-documenter-links`](https://github.com/JuliaDocs/DocumenterInterLinks.jl/tree/master/docs/src/sphinx-to-documenter-links) for a full example of a Python project with documentation linking to the documentation of Julia projects. Note that for this to work without restrictions, [Sphinx v7.3](https://www.sphinx-doc.org/en/master/changes.html#release-7-3-0-released-apr-16-2024) is required. In older versions of Sphinx, linking to a heading in a Julia project is not possible due to [issue #12008](https://github.com/sphinx-doc/sphinx/issues/12008).
2 changes: 1 addition & 1 deletion docs/src/write_inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The inventory files that get loaded into [`InterLinks`](@ref) should be automati
* The [Sphinx documentation generator](@extref sphinx :doc:`index`) used by most Python packages automatically [creates an `objects.inv` inventory file](@extref sphinx :doc:`usage/extensions/intersphinx`) in the root of every HTML build.
* For Julia projects that build their documentation with [`Documenter`](@extref Documenter :doc:`index`) `≥ v1.3`, an `objects.inv` inventory file in the same format is automatically created in the `docs/build/` folder.
* [`DocumenterInventoryWritingBackport.jl`](https://github.com/JuliaDocs/DocumenterInventoryWritingBackport.jl) backports the automatic inventory writing to older versions of `Documenter` (`≥ v0.25`). This package simply needs to be loaded in a project's `docs/make.jl` file.
* Any package loading `DocumenterInterLinks` in `docs/make.jl` also gets the `DocumenterInventoryWritingBackport` automatically.
* Any package loading `DocumenterInterLinks` in `docs/make.jl` also gets the `DocumenterInventoryWritingBackport` automatically. This is an experimental feature that may be removed in any future version.

The inventory file should be deployed together with the rest of the documentation, so that it is [accessible to other projects](@ref howto-inventory-location). When a project does not use a documentation generator that writes an inventory file, it may be possible to [maintain an inventory by hand](@ref howto-manual-inventory). See also the [Wiki](https://github.com/JuliaDocs/DocumenterInterLinks.jl/wiki/Inventory-File-Repository) for a collection of inventory files for Julia and other projects.

Expand Down
77 changes: 33 additions & 44 deletions src/interlinks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ Plugin for enabling external links in `Documenter.jl.`
```julia
links = InterLinks(
"project1" => "https://project1.url/",
"project2" => "https://project2.url/inventory.file",
"project3" => (
"https://project3.url/",
joinpath(@__DIR__, "src", "interlinks", "inventory.file")
);
mapping;
default_inventory_file="objects.inv",
alias_methods_as_function=true,
)
Expand All @@ -21,7 +16,22 @@ links = InterLinks(
instantiates a plugin object that must be passed as an element of the `plugins`
keyword argument to [`Documenter.makedocs`](@extref). This then
enables `@extref` links in the project's documentation to be resolved, see the
Documentation for details.
[Syntax](@ref) documentation for details. The `mapping` connects project names
to project root URLs and inventories, e.g.,
```julia
links = InterLinks(
"Julia" => (
"https://docs.julialang.org/en/v1/",
"https://docs.julialang.org/en/v1/objects.inv",
joinpath(@__DIR__, "inventories", "Julia.toml")
),
"Documenter" => "https://documenter.juliadocs.org/stable/objects.inv",
"sphinx" => "https://www.sphinx-doc.org/en/master/";
)
```
See the details below.
# Arguments
Expand All @@ -33,49 +43,28 @@ string. For Julia projects, it should be the name of the package without the
should be the name of project's main module.
The root url / inventory location (the value of the mapping), can be given in
any of the following forms:
* A single string with a URL of the inventory file, e.g.
```
"sphinx" => "https://www.sphinx-doc.org/en/master/objects.inv"
````
any of the following forms (from most common to least common):
The root URL relative which all URIs inside the inventory are taken to be
relative is everything up to the final slash in the inventory URL,
`"https://www.sphinx-doc.org/en/master/"` in this case.
* A single string with a project root URL, for example,
```
"sphinx" => "https://www.sphinx-doc.org/en/master/",
````
which must end with slash. This looks for the inventory file with the name
corresponding to `default_inventory_file` directly underneath the given root
URL.
* A single string with a project root URL, e.g., the `"sphinx"` entry in the
above example. The URL must end with a slash. This looks for the inventory
file with the name corresponding to `default_inventory_file` directly
underneath the given root URL. This is the most common form.
* A tuple of strings, where the first element is the project root URL and all
subsequent elements are locations (URLs or local file paths) to an inventory
file, e.g.,
```
"Julia" => (
"https://docs.julialang.org/en/v1/",
joinpath(@__DIR__, "src", "interlinks", "Julia.toml")
),
"Documenter" => (
"https://documenter.juliadocs.org/stable/",
"https://documenter.juliadocs.org/stable/inventory.toml.gz",
joinpath(@__DIR__, "src", "interlinks", "Documenter.toml")
)
```
The first reachable inventory file will be used. This enables, e.g., to
file. The first reachable inventory file will be used. This enables, e.g., to
define a local inventory file as a fallback in case the online inventory file
location is unreachable, as in the last example.
location is unreachable, as in the `"Julia"` entry in the above example.
* A single string with a URL of the inventory file, e.g., the `"Documenter"`
entry in the above example. The root URL relative to which all URIs inside
the inventory are taken is everything up to the final slash in the inventory
URL, `"https://documenter.juliadocs.org/stable/"` in this case. Note that the
string has to be a URL, not a local file path, as a file path contains no
implicit information about a project's root URL.
* A [`DocInventories.Inventory`](@extref) instance.
* A [`DocInventories.Inventory`](@extref) instance. This may be useful for
using a dynamically constructed inventory.
# Keyword arguments
Expand Down

0 comments on commit bebccc4

Please sign in to comment.