Better link syntax for cross-references
See original GitHub issueDescribe the problem/need and solution
I’ve been using MyST for a bit and it’s quite nice being able to use Markdown instead of RST. However, a major pain point is using the cross-referencing syntax. The {ref}`target`
and {ref}`name <target>`
feel like I am just using a slightly modified version of RST. They aren’t very Markdownic, if that is a word. For me, they fail the basic smell tests of good Markdown syntax:
- Easy to remember The link syntax is basically the same as the RST syntax, except with brackets instead of colons. The RST syntax is notoriously hard to remember.
- Composable It’s impossible to format a link as code (or if it is possible, only with some trick that I haven’t yet figured out), because it reuses backticks.
- Joy to use Every time I have to make a cross-reference I feel the same slight pain I feel whenever I use RST. It’s even worse if I haven’t used it in a while and have to go lookup the syntax (and I think I’ve mentioned this a dozen times before but I’ll mention it again, please use the word link in the docs to refer to link syntax. No one knows what a “roll” is).
Basically, it feels like RST syntax that has been shoved into Markdown rather than the way Markdown would actually implement such a thing.
MyST does let you write [name](target)
and even [](target)
, and these are both great. But this only works when the target can be accessed with any
. This unfortunately virtually never works for my use-case (cross-referencing functions with autodoc in the SymPy documentation).
I would propose extending the usual Markdown link syntax so that you can add the target type before the target name somehow. My suggestion would be to use a colon, like [name](func:target)
, but if can’t work for whatever reason there could be other options. Another suggestion, which is less syntactically nice but would at least make sense logically, would be to allow {ref}`target`
inside of a Markdown link, like [name]({ref}`target`)
(IMO this should be done regardless of whether any other new syntax is added).
I would also suggest implementing this in a way so that the ~.
style works so that something like [name](func:~.target)
works (see https://github.com/executablebooks/MyST-Parser/issues/468), i.e., get the target for :func:`target`
and then convert that into a link rather than just rewriting it to :func:`name <target>`
.
Guide for implementation
No response
Tasks and updates
No response
Issue Analytics
- State:
- Created a year ago
- Reactions:3
- Comments:10 (9 by maintainers)
Top GitHub Comments
Just as a note, I have opened up an issue here which is aiming to track various places where there are suggestions/problems/improvements around cross references (including this issue). Another potential avenue that has been discussed is to adopt pandoc citation/reference syntax (starting with an
@
).For what it’s worth, I’ve always felt that the most intuitive Markdown link syntax extension for MyST would work as follows:
[title](target)
(i.e., with parentheses) works as it would otherwise. Thetarget
would usually be an explicit link, likehttps://example.com
, but may also be a relative link inside the project. There could be some magic there, along the lines of what GitHub does, like mapping thetarget
index.md
toindex.html
But nothing that surprises users. Like the implicitdownload
role tends to do (in my opinion).[title][target]
, wheretarget
is looked up elsewhere.The look-up for reference targets would essentially do what Python does when it looks up the name of an identifier:
[target]:
is defined elsewhere in the same document, use that. I.e., standard Markdown behavior.target
with theany
role.target
with Intersphinx.The
any
look-up might be ambiguous, so maybe allow to specify Sphinx roles such asfunc:
ordownload:
(or:func:
,:download:
) as a prefix fortarget
.I know this would break a lot of stuff that’s already working somewhat differently in MyST. But I feel(!?) this should be easy on the implementation side, once refactored, and line up better with what users would expect a “multi-document Markdown renderer” to do.