Tighter rules for referencing#2678
Conversation
|
I think that accurately describes the current situation. It's a little bit unfortunate that the explicit link for a DocString is |
Yeah, I thought that too. However, I don't think it's ambiguous if we require that explicit header references are inside double quotes (it is supported at least: Documenter.jl/src/cross_references.jl Line 298 in 9bec14d
And for explicit:
The conditions are mutually exclusive this way. |
|
I made a little progress, but I realized that the rules are indeed ambiguous due to referencing headers by their id: [link](@ref someid)
[# Header](@id someid)
```@docs
someid
``` |
|
If there is an Otherwise, the rules in #2678 (comment) seem correct to me! As far as I can tell, this matches what we have documented, even if the implementation doesn't doesn't match. I'm actually surprised that the current implementation seems to be more.. uhm.. loose.. than I though it would be. What would be nice is to add some tests here (if feasible.. it can be tricky sometimes for this kind of stuff), and also clarify the docs (e.g. the table from the OP would be great to add to the docs probably). What might be good is to build the Julia manual with this PR before merging, just to see if any warnings crop up. |
|
Thank you for your input, Morten.
I see. The problem is though when the user makes a mistake in the id: See [link](@ref header-wrong)
# [Header](@id header-correct)In this case, Implicit references are unambiguous
That means if startswith(text, "#")
# process as an issue reference
elseif occursin(r"^`.+`$", text)
# process as a code reference
else
# process as a header reference
endFor explicit references, we can allow and prefer backticks when referring to docstrings, as Michael pointed out. Then, the explicit references are unambiguous too:
leading to the decision if occursin(r"^\".+\"$", link)
# process as a header reference
elseif startswith(link, "#")
# process as an issue reference
elseif occursin(r"^`.+`$", link)
# process as a code reference
else
# process as a header reference via id
endThe problem is backwards compatibility of code references. Right now,
in this order. So, we can extend the decision algorithm if occursin(r"^\".+\"$", link)
# process as a header reference
elseif startswith(link, "#")
# process as an issue reference
elseif occursin(r"^`.+`$", link)
# process as a code reference
else
# process as a header reference via id if there is such a header
# and otherwise, process as a code reference
endHowever, there's that problem with if occursin(r"^\".+\"$", link)
# process as a header reference
elseif startswith(link, "#")
# process as an issue reference
elseif occursin(r"^`.+`$", link)
# process as a code reference
else
if link consists of multiple dash-delimited words
# process as a header reference via id
else
# process as a header reference via id if there is such a header
# and otherwise, process as a code reference
end
endI don't think that many people try to use the explicit reference After some time, when breaking change is permitted, we can just drop this complicated logic in favor of the simple one above. How does that sound? |
|
Just discovered this PR. @barucden I think your plan sounds good! And I am not worried about someone trying to use So if you are still willing to work on this, that'd be awesome! I see that in the meantime, a merge conflict has crept in -- hopefully it is not too bad. |
|
I completely forgot about this PR, thank you for reminding me, Max. I haven't finished the work even locally, and I am currently busy. If you or anyone else wants to push this forward, please feel free. |
Classify @ref targets by syntax before dispatch. Keep header labels ahead of docstrings and support backticked docs. Add regression coverage, manual syntax docs, and a changelog entry. Co-authored-by: Codex <codex@openai.com>
Normalize docsxref output with sequential replace calls. This avoids the Julia 1.6 method error from the multi-pair String replace path. Co-authored-by: Codex <codex@openai.com>
|
I've rebased it (resolving the merge conflict) and then asked Codex to complete the work, based on the nice plan sketched by @barucden above. It also tweaked the documentation to explicitly explain the new behavior. It introduced a new helper Overall I am happy with the code it produced; it also added tests. But I'll wait with merging this to give @barucden a chance to react. Also perhaps @goerz or @mortenpi would like to have a look? |
While not necessary, I feel people may look at the Documenter sources to figure out what is 'best practice', and so we should do this to send a signal.
|
Oh wow, it looks exactly how I was going to implement it. Thank you for taking over, Max! |
goerz
left a comment
There was a problem hiding this comment.
Love it!
(except for the tiny grammar nitpick)
Co-authored-by: Michael Goerz <mail@michaelgoerz.net>
This is an attempt to clarify the matching criteria for cross-references. I am not very familiar with Documenter's code base, so I am sure the code could be improved, but I am submitting the PR as it is to see if there's broader support for it.
Essentially, the goal is to respect the following rules for references:
[Header name](@ref)[link](@ref "Header name")[#12345](@ref)[link](@ref #12345)[`Module.func`](@ref)[link](@ref Module.func)It means that linking
[Nonexistent header](@ref)will be recognized as a link to a header named "Nonexistent header", and never as link to a docstring forNonexistent-header(ref. #2677).If this direction seems promising, I'd like to get feedback on how to improve the code, especially
linkcontent.Resolves #2677
Resolves JuliaLang/julia#58073