From bebccc41b9d78f48fb5c2179d12358e03b0c727d Mon Sep 17 00:00:00 2001 From: Michael Goerz Date: Wed, 5 Jun 2024 15:50:03 -0400 Subject: [PATCH] Update documentation * 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 --- Project.toml | 2 +- README.md | 4 +- docs/make.jl | 5 +- docs/src/fallback.md | 2 +- docs/src/howtos.md | 4 +- docs/src/index.md | 10 ++- .../docs/source/index.rst | 9 ++- .../sphinx-to-documenter-links/pyproject.toml | 2 +- docs/src/sphinx.md | 4 +- docs/src/write_inventory.md | 2 +- src/interlinks.jl | 77 ++++++++----------- 11 files changed, 55 insertions(+), 66 deletions(-) diff --git a/Project.toml b/Project.toml index 3988489..5cf3444 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DocumenterInterLinks" uuid = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656" authors = ["Michael Goerz "] -version = "0.3.2" +version = "0.3.2+dev" [deps] CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193" diff --git a/README.md b/README.md index c4a9d96..9dc6cd5 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 diff --git a/docs/make.jl b/docs/make.jl index 0593f5e..8e1c5da 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -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/", diff --git a/docs/src/fallback.md b/docs/src/fallback.md index a26314b..b806cc9 100644 --- a/docs/src/fallback.md +++ b/docs/src/fallback.md @@ -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 diff --git a/docs/src/howtos.md b/docs/src/howtos.md index 9ccf842..9cdfcf1 100644 --- a/docs/src/howtos.md +++ b/docs/src/howtos.md @@ -15,6 +15,7 @@ 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) @@ -22,9 +23,6 @@ For example, you will find `objects.inv` inventory files under the following URL * [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: diff --git a/docs/src/index.md b/docs/src/index.md index 2c21848..d95f58b 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -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. diff --git a/docs/src/sphinx-to-documenter-links/docs/source/index.rst b/docs/src/sphinx-to-documenter-links/docs/source/index.rst index 5ca4b9f..74eb5a1 100644 --- a/docs/src/sphinx-to-documenter-links/docs/source/index.rst +++ b/docs/src/sphinx-to-documenter-links/docs/source/index.rst @@ -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``` renders as :external+DocInventories:doc:`DocInventories` -* 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 `_. + In older versions of Sphinx, linking to a heading in a Julia project is not possible due to + `issue #12008 `_. diff --git a/docs/src/sphinx-to-documenter-links/pyproject.toml b/docs/src/sphinx-to-documenter-links/pyproject.toml index 39a131e..db8316a 100644 --- a/docs/src/sphinx-to-documenter-links/pyproject.toml +++ b/docs/src/sphinx-to-documenter-links/pyproject.toml @@ -59,7 +59,7 @@ dependencies = [ "ipython", "sphinx-rtd-theme", "six", - "sphinx", + "sphinx~=7.3", "sphinx-autodoc-typehints", ] diff --git a/docs/src/sphinx.md b/docs/src/sphinx.md index 8b626a8..22afec2 100644 --- a/docs/src/sphinx.md +++ b/docs/src/sphinx.md @@ -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)```. @@ -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). diff --git a/docs/src/write_inventory.md b/docs/src/write_inventory.md index f76c453..7a17224 100644 --- a/docs/src/write_inventory.md +++ b/docs/src/write_inventory.md @@ -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. diff --git a/src/interlinks.jl b/src/interlinks.jl index ab29b8a..81846c0 100644 --- a/src/interlinks.jl +++ b/src/interlinks.jl @@ -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, ) @@ -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 @@ -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