[ANN] WhereIsMyDocstring.jl (aka "what do `@docs` blocks do")

Hi all,

after spending too much time wrestling with @docs blocks when writing documentation, I decided to put together a small package to help with that: WhereIsMyDocstring.jl. The main application is helping you to find and include the right docstring if there is a function/binding with multiple different docstrings.

It is kind of an interactive version of @docs blocks and gives you a hint for the right syntax to include a specific docstring. The only exported functionality is the macro @docmatch with the following signature:

@docmatch funname [module]
@docmatch funname(signature) [module]

which lists all the docstrings that get pulled in when writing

```@docs
funname
funname(signature)
```

(This has the nice side effect, that you can list all docstrings for a specific binding.)

Example without signature

julia> using WhereIsMyDocstring

julia> @docmatch sin
2-element Vector{WhereIsMyDocstring.DocStr}:
 Base.sin
  Content:
    sin(x) [...]
  Signature type:
    Tuple{Number}
  Include in ```@docs``` block:
    Base.sin(::Number)
  Source:
   math.jl:490
===============================================
 Base.sin
  Content:
    sin(A::AbstractMatrix) [...]
  Signature type:
    Tuple{AbstractMatrix{<:Real}}
  Include in ```@docs``` block:
    Base.sin(::AbstractMatrix{<:Real})
  Source:
   /usr/share/julia/stdlib/v1.10/LinearAlgebra/src/dense.jl:956
==============================================

Example with signature

You can simulate what happens if you specify a signature:

julia> @docmatch sin(::Real)
1-element Vector{WhereIsMyDocstring.DocStr}:
 Base.sin
  Content:
    sin(x) [...]
  Signature type:
    Tuple{Number}
  Include in ```@docs``` block:
    Base.sin(::Number)
  Source:
   math.jl:490
===========================================

Type parameters

The real reason why I wrote this package is Docsystem confused by where syntax · Issue #29437 · JuliaLang/julia · GitHub, which messes up everything related to docstrings in case the signature has explicit parameters, as is shown in the following example. Note the messed up type for the signature. The package tries to give a useful hint on how to include this.

julia> "blub"
       function foo(x::Vector{S}, z::Matrix{T} = 1; y::Number = 2) where {S, T <: S}
       end

julia> @docmatch foo
1-element Vector{WhereIsMyDocstring.DocStr}:
 foo
  Content:
    blub [...]
  Signature type:
    Union{Tuple{Vector{S}}, Tuple{T}, Tuple{S}, Tuple{Vector{S}, Matrix{T}}} where {S, T<:S}
  Include in ```@docs``` block:
    foo(::Union{Tuple{Vector{S}}, Tuple{T}, Tuple{S}, Tuple{Vector{S}, Matrix{T}}} where {S, T<:S})
    try the following:
    foo(::Array{S, 1}, ::Array{T, 2}) where {S, T<:S}
  Source:
   REPL[2]:1

(Small warning: the hint is heuristic in nature and might give nonsensical results for complicated signatures. But staring long enough at the type signature often helps to find some variant that pulls in the right docstring.)

6 Likes