Documenter error [:cross_references]

I’d try to add a list of units and constants to Unitful - s. issue 623 (filed by @rafaqz). AFAIU currently the only way to find the symbol used is to look into the source code of pkgdefaults.jl

The references are to be programmatically generated, but at first I set a mock-up file with the following contents

```@meta DocTestSetup = quote
using Unitful
end
```


# Default defined units and constants

## Basic dimensions

### Area
```@docs; canonical=false
Unitful.Area
```

#### Units
```@docs; canonical=false
Unitful.a
```

:sweat_smile: - getting the code without rendering was not that easy - :sweat_smile:

With that, I get an error from the Documenter make script:

ERROR: `makedocs` encountered an error [:cross_references] -- terminating build before rendering.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] runner(#unused#::Type{Documenter.Builder.RenderDocument}, doc::Documenter.Document)
   @ Documenter ~/.julia/packages/Documenter/nQAq5/src/builder_pipeline.jl:253
 [3] dispatch(#unused#::Type{Documenter.Builder.DocumentPipeline}, x::Documenter.Document)
   @ Documenter.Selectors ~/.julia/packages/Documenter/nQAq5/src/utilities/Selectors.jl:170
 [4] #79
   @ ~/.julia/packages/Documenter/nQAq5/src/makedocs.jl:248 [inlined]
 [5] withenv(::Documenter.var"#79#81"{Documenter.Document}, ::Pair{String, Nothing}, ::Vararg{Pair{String, Nothing}})
   @ Base ./env.jl:197
 [6] #78
   @ ~/.julia/packages/Documenter/nQAq5/src/makedocs.jl:247 [inlined]
 [7] cd(f::Documenter.var"#78#80"{Documenter.Document}, dir::String)
   @ Base.Filesystem ./file.jl:112
 [8] #makedocs#77
   @ ~/.julia/packages/Documenter/nQAq5/src/makedocs.jl:247 [inlined]
 [9] top-level scope
   @ ~/Julia/Unitful.fork/Unitful.jl/docs/make.jl:7

julia> 

It appears, only Units ( Unitful.a, Unitful.b, Unitful.minute) trigger the error - if I remove the second @docs, the first one (@docs Unitful.Area) will be happily processed.

All Units are properly documented, so I’m @ loss.

The whole context on the Github

Look for errors earlier in the logs. It looks like you’re trying to refer to a docstring that does not exist (or is not included) with at-ref in the Unitful.a etc docstrings.

help?> Unitful.a
  Unitful.a

  The are, a metric unit of area, defined as 100 m^2.

  Dimension: 𝐋^2.

  See Also: Unitful.m.

julia> 

The docstring appears to exist.

What does it mean “not included with at-ref” ?

My current guess, this unit is defined via macro, and therefore Documenter then can’t process it properly.

"    Unitful.a
\nThe are, a metric unit of area, defined as 100 m^2.
\nDimension: 𝐋^2.
\nSee Also: [`Unitful.m`](@ref)."
@unit a      "a"        Are         100m^2                  false

But it @refs (that is what Morten meant) to Unitful.m but you do not have Unitful.m in your documentation?

The whole reference chain appears to have docstrings

help?> Unitful.a
  Unitful.a

  The are, a metric unit of area, defined as 100 m^2.

  Dimension: 𝐋^2.

  See Also: Unitful.m.

help?> Unitful.m
  Unitful.m

  The meter, the SI base unit of length.

  Dimension: Unitful.𝐋 .

help?> Unitful.𝐋
  Unitful.𝐋

  A dimension representing length.

julia> 

And if you manage to get m and L in there as well, does the error vanish? (I have no clue about your automatic generation where you wrote that it was not so easy to extract, but let’s say in your Mockup you add both in the last @docs block?)

I’ve only meant if I paste the markdown source into Discourse it will get automatically rendered and that was not what I wanted, so I added quite a few <code> and <br> tags to get it.

The OP code was written manually and reproduced above literally.

I’d try your suggestion later on

If I include both these references as below, it works. The order is not important, but both other refs must be present.

```@docs; canonical=false

Unitful.a

Unitful.m

Unitful.𝐋

```

This is an interesting fact, but I don’t see how it can help me :frowning_face:

Well it explains the error message that you had above, you can not just list Unitful.a in the docs, since it references to Unitful.m, those docs have to be present as well, and hence also Unitful.L.
So that resolves the error you started with.

Can you maybe explain a bit more why that does not help you?

1 Like

@kellertuer thank you, your explanation certainly helps - that was not clear to me.

The problem is, in Unitful there are about a thousand units defined and and provided with docstrings. Most of them are derived ones, like µm, km, and Ym.

Units are not listed in the documentation - which is what I want to improve on. I’d also document the physical constants provided by Unitful.

I’d like to document only non-derived units like m or inch - that is sufficient if you know how to prefix them. Otherwise the document would become to large and non-ergonomic to use. The only thing I want, that is to give the user a possibility to find the Unitful’s unit name for minute, inch, candela, Avogadro’s constant, etc. without searching for it in the package source.

Though most units would refer to the basic SI units (which are all included anyway), like barn refers to m, there are some edge cases, like inch referring to cm, of g referring to kg.

So now I’m thinking of extracting the docstrings programmatically, then strip them of the @refs and include into the markdown file.

An alternative solution could be to collect all these (directly and indirectly) referenced entities and put them into a separate section of the document (a hidden section maybe :wink: ).

You could write a small function in the docs before calling the make.jl before calling makedocs that generates such a markdown file and contains all units you would like to document?

Was it a question or suggestion?

Anyway, that (was | is | is partially implemented) my intention. “Small function” - depending on definition of “small”. I already have about 100 LOC, and it will probably become at least twice as much in the end.

So now if I am to add (in a separate section) documentation to all directly or indirectly referenced entities, just to satisfy Documenter’s constraints, it is going to explode exponentially, I’m afraid. I’d at least exclude those already referenced in the current documentation. Is there any practical possibility to get a list of such references?

More a suggestion, where I am maybe not 100% sure what your goal is and what your source of information.

Writing a file containing several lines of Unitful.$(myLetter) should be doable in a for loop (where you manually collect all units you want to document) – so that would in my head be <20 lines – but probably more of a manual approach then what you do now.

A more automated approach – sure, could collect for the initial list all referenced Unitful.Y thingies and add them at the end as well – but also then I do not see the 100 LOC, but I probably miss what source of information you use in the beginning.

Collect all documented non-derived units (there are many other entities in the package), sort them into basic dimensions (Length, Time…) and compound ones (Speed, Energy). That is a lot of filtering, mostly done, and took about 80 LOC. That is about half or third of the whole job. There are about 100 identifiers to be documented in a well-structured documentation page. That is already (almost too) much, and I’d like to avoid documenting other (referenced) identifiers just to get make working.

Producing a loop emitting 1000 lines of Unitful.$(myLetter) is surely easy, manually sieving the pile of garbage probably doable - but who will do it for the next package update?

The source of information is Unitful.jl, which is an otherwise well documented package with 946 downstream dependencies (i.e. about 10% of all Julia packages). My contribution to it till now amounts to one like on a github issue :slightly_smiling_face:

1 Like

I see. Then I do not have a good idea how to fix the error directly – you could of course turn the error off, but then still the links in the docsstrings would not work.