Open frankier opened 2 years ago
Does FromFile.jl evaluate the definitions into a generated submodule with a convoluted name?Documenter tries to reflect things as they are, so if a binding lives in a strange submodule, Documenter reflects that. Arguably, FromFile should place the bindings into the top-level module if that is the intended public API.
That said, it might be possible to attach docstrings to different bindings somehow, as they are just stored in a special dictonary object in each module (which you can access via Docs.meta(MyModule)
). That way Documenter wouldn't need to do anything special, and I think this would be preferred as then the information about the "aliasing" is stored with the docstring directly.
IMO this is a serious issue, it's misrepresentation of user package API.
For example, in my package CallableExpressions.jl, I have some doc strings in the top-level module, where the names are imported from private modules. The generated documentation misleadingly mentions the names of the private modules.
The first doc string, for example, is for DynamicExpression
: https://gitlab.com/nsajko/CallableExpressions.jl/-/blob/656b3e70536a7b815f49630d6aa0e4a8315964c8/src/CallableExpressions.jl#L57-62
The generated docs are titled CallableExpressions.DynamicExpressions.DynamicExpression instead of CallableExpressions.DynamicExpression
.
Also affects the docs of Julia itself, resulting in breakage for users: https://github.com/JuliaLang/julia/issues/54534
xref https://github.com/JuliaDocs/Documenter.jl/issues/2087?
julia> CallableExpressions.DynamicExpression === CallableExpressions.DynamicExpressions.DynamicExpression
true
Yes but the doc string is not defined in DynamicExpressions
. If that counts for something.
Also:
julia> Base.ispublic(CallableExpressions, :DynamicExpression)
true
julia> Base.ispublic(CallableExpressions, :DynamicExpressions)
false
Yes but the doc string is not defined in DynamicExpressions. If that counts for something.
You attach the docstring to CallableExpressions.DynamicExpressions.DynamicExpression
.
Also: [...]
Why does that matter?
Why does that matter?
It matters because I want only the public API to be documented.
I sympathize with wanting to document functions under an aliased name. I have the same problem in QuantumControl
: there are a lot of things defined in QuantumControlBase
and re-exported in QuantumControl
. Ideally, the QuantumControlBase
should be more or less hidden from users. For example, I'd prefer if users used QuantumControl.ControlProblem
, not QuantumControlBase.ControlProblem
, even though the latter is the canonical name.
However, from Julia's perspective, each function/type has one and only one canonical fully specified name, and that's the one that Documenter shows. So basically, we'd have to tell Documenter to lie about the canonical name. I don't think there's any way to come up with an automatic way to do this. Certainly, Julia has no way to determine where the docstring for CallableExpressions.DynamicExpression
was attached. It might work to define a mapping canonical path -> canonical alias
for Documenter as a dict that gets passed as an argument to makedocs
. Then, when Documenter renders docstrings, it would show the desired alias instead of canonical path. I'm not sure if this would be easy to implement. At first glance, it seems like it would, but one would have to be careful not to mess with the @ref
-resolution, or anything like that.
By the way, how I (somewhat) get around this limitation is to have a script that generates an API overview with the "canonical aliases": https://juliaquantumcontrol.github.io/QuantumControl.jl/stable/api/quantum_control/.
That page describes the API as I'd like people to use it, but if you click on any of the actual items, you'll still see the canonical path, e.g. QuantumControl.ControlProblem
or QuantumControls.Controls.evaluate
, both of which have their canonical location in other packages.
Certainly, Julia has no way to determine where the docstring for
CallableExpressions.DynamicExpression
was attached.
Actually, technically, I think we do have that metadata (module and/or file). IIRC, we use it to determine if a docstring for e.g. a Base
function/type comes from Base
or from a package extending that function.
You can also just document a new binding in the correct module that is const equal the "internal" one.
You can also just document a new binding in the correct module that is const equal the "internal" one.
This does seem to cause undesirable difference in printing though. Compare:
julia> module Foo
module Internal
struct Bar end
end
using .Internal
const Bar = Internal.Bar
export Bar
end
Main.Foo
julia> using .Foo
julia> Bar
Main.Foo.Internal.Bar
vs.
julia> module Foo
module Internal
struct Bar end
end
using .Internal: Bar
export Bar
end
Main.Foo
julia> using .Foo
julia> Bar
Bar
It should be possible to alias the full paths to modules as generated by autodocs. The general reason is that this gives more flexibility for packge authors to display their public interface as they see it. The specific reason is that currently https://github.com/Roger-luo/FromFile.jl inserts modules that are essentially a private part of its implementation into documentation. It would be nice to have a way to work around this.
For an example, see https://astroautomata.com/SymbolicRegression.jl/stable/types/ . Notice the file paths in the module paths.