Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Alternative equivalent syntaxes for hyperlinks #70

Open
octogonz opened this issue Sep 25, 2018 · 7 comments
Open

RFC: Alternative equivalent syntaxes for hyperlinks #70

octogonz opened this issue Sep 25, 2018 · 7 comments
Labels
request for comments A proposed addition to the TSDoc spec

Comments

@octogonz
Copy link
Collaborator

In a separate issue @yume-chan asked:

As a @link can link to either a URI or a declaration, will markdown links ([MyClass](Myclass)) supports this syntax as well?

Let's discuss this as a separate issue, since it's unrelated to the declaration references topic.

@octogonz
Copy link
Collaborator Author

octogonz commented Sep 25, 2018

The quick answer is that the TSDoc parser library does not yet support Markdown links at all. Probably it would be counterintuitive not to, however I would hesitate to mix declaration references into this requirement, because the CommonMark link destination is already a pretty complex structure (see below).

<digression>
In general I tend to follow Python's design philosophy of one obvious way, i.e. I find that multiple equivalent syntaxes make things worse rather than better. Some reasons being: a code base that is inconsistent between different authors, a steeper learning curve since people need to memorize what each syntax does, and a more tricky test surface for any tool that processes the inputs.

It's important to recognize that Markdown takes an exact opposite "everything but the kitchen sink" philosophy: Even strict CommonMark will accept all sorts of obscure notations that rarely occur in the wild. I spent a lot of time thinking about this difference of philosophy, and will probably include a small essay about it in the TSDoc spec document. :-) But basically I believe Markdown's design is optimized for fairly different requirements: It doesn't need to be interoperable (i.e. a Markdown scanner can usually assume that it's the only tool that needs to process an input, which is why its extensions can get away with having proprietary grammars). It also doesn't need to be predictable (i.e. we can assume an interactive editor will render the result in realtime). Whereas TSDoc clearly needs to be interoperable and predictable to be successful.
</digression>

So the way TSDoc is framed today, people would expect three different ways of making a link:

JSDoc style

The notation I'm working on supporting in my current PR:

Supported by TSDoc:

/**
 * NOTE: The "link text" here currently does not support Markdown
 * and should never support nested tags because brace-balancing is error-prone.
 *
 * {@link http://example.com | link text}
 * {@link package#controls.Button | link text}
 * {@link http://example.com}
 * {@link package#controls.Button}
 */

...but not the other redundant JSDoc notations that I've been trying to avoid incorporating:

NOT supported by TSDoc:

/**
 * Missing pipes, which seems error-prone with no obvious benefit:
 * {@link http://example.com link text}
 * {@link package#controls.Button link text}
 *
 * Looks confusingly like a Markdown link, an it would be an irregular grammar rule
 * since custom inline tags don't have a need for link text:
 * [link text]{@link http://example.com}
 * [link text]{@link package#controls.Button} 
 */

HTML style

Just like CommonMark, TSDoc allows HTML tags and will also support HTML character references as an escaping mechanism.

Supported by TSDoc:

/**
 * <a href="http://example.com">
 * link text, with markup and TSDoc inline tags allowed here 
 * </a>
 */

It would be reasonable to support declaration references, in which case I would suggest a custom tag such as <tsdoc-link>:

Possibly supported by TSDoc in the future:

/**
 * <tsdoc-link dref="package#controls.Button"> 
 * link text, with markup and TSDoc inline tags allowed here 
 * </tsdoc-link>
 */

CommonMark style

Okay, strap in folks... Let's now take a look at the hyperlink notations that a strict CommonMark parser would accept:

Some subset of this might be a good idea: (?)

/**
 * [link text](http://example.com)
 *
 * Paths can be relative, although in TSDoc it's unclear what they're relative to:
 * [link text](/url-path)
 *
 * NOTE: The "title text" is the `<a title="...">` attribute from HTML.
 * [link text](/url-path "title text")
 *
 * NOTE: But quotes are interpreted as a URL path if they come first:
 * [link text]("url-path")
 *
 * NOTE: Parentheses are allowed in the URL, but only if they're balanced to avoid "confusion":
 * [link](/url-path?query=(thing))
 *
 * NOTE: The `<>` brackets can be used to escape unbalanced parentheses.
 * [link](</url-path?query=(thing>)
 *
 * NOTE: But hey you can also use backslashes to escape them.
 * [link](/url-path?query=\(thing)
 *
 * NOTE: This escaping matters, because here's two more syntaxes for title text, why not:
 * [link text](/url-path (title text))
 * [link text](/url-path 'title text')
 *
 * Each one has its own escaping rules, so these double quotes are part of the title:
 * [link text](/url-path 'title "inside" text')
 *
 * The link text may contain Markup:
 * [link `text`](/url-path)
 *
 * The link text can't contain nested links, but it can contain other CommonMark
 * constructs that confusingly use brackets:
 * [![moon](moon.jpg)](http://example.com)
 */

The CommonMark spec doesn't say very much about the link destination itself except that it is a "URI." The spec makes it clear that all sorts of relative URIs are supported, e.g. #webhashtag, /server-relative-path, file-relative-path, and //example.com are all fine.

Whereas so far with TSDoc we have been assuming that {@link} tags must include absolute URLs.

Conclusion

It seems that TSDoc must support some form of {@link} in order to remain aligned with JSDoc, but it's probably reasonable to limit the syntax to eliminate unnecessary variations. We have a very good reason for allowing HTML tags in TSDoc (it's the most robust representation for people who need nesting custom tags), so it also makes sense to support hyperlinks via the <a> tag.

By contrast, Markdown links bring along a lot of complexity, but without contributing any new capabilities. So I'm somewhat undecided to what extent we want to pursue that. What do people think?

@octogonz octogonz added the request for comments A proposed addition to the TSDoc spec label Sep 25, 2018
@willingc
Copy link

@pgonzal It would be great to be able to specify a Markdown link using the most frequently used Markdown practices:

  • [link text](https://example.com)
  • [link text](/url-path)

I agree with the "one obvious way" approach from Python. Looking at the reality, in many open source projects, the software developer will be writing the docstrings. To encourage documentation of code, it's helpful to have syntax that devs are familiar with from GitHub: markdown.

It would be great for TSDoc to be able to support something like:

{@mdlink [link text](https://example.com)} the most general Markdown case

which is familiar and easy to type and let developers decide whether to use vanilla JSDoc {@link} or {@mdlink}

@octogonz
Copy link
Collaborator Author

@willingc I have some questions about this:

If you specify [link text](/url-path) how would a documentation engine process this link, since it's not an absolute URL? In our system, the final server URLs are determined by a later stage of the pipeline, and it can be different depending on whether the documentation is being rendered for staging or production. The TSDoc {@link} tag does not support relative URLs for this reason.

Do you expect the Markdown-style URL to support declaration references? For example, TSDoc allows something like this:

/**
 * {@link @scope/package/path1/path2#core.MyClass.("constructor":static) | some link text}
 */

So would your Markdown notation need to support something like this?

/**
 * [some link text](@scope/package/path1/path2#core.MyClass.("constructor":static))
 */

@vassudanagunta
Copy link

vassudanagunta commented Jan 26, 2020

A simple and intuitive way to integrate Markdown links and TSDoc links:

This method is part of the [Statistics subsystem]({@link core-library#Statistics}).

The regular TSDoc equivilent (taken from the README):

This method is part of the {@link core-library#Statistics | Statistics subsystem}.

Justification:

  • This is standard Markdown link syntax and semantics. {@link core-library#Statistics} is semantically a link destination, the thing Markdown expects within the parenthesis.

    Alternatively the braces could be excluded:

    [Statistics subsystem](@link core-library#Statistics)

    What matters is to distinguish link types, or "protocols" if you will, TSDoc vs HTTP.
    The @link is sufficient I think. But including the braces may be more consistent
    with regular TSDoc links.

  • It is easier to read because the link text comes first.

  • Both forms can continue to be supported without conflict.

  • Easy to implement. Nearly every Markdown parser will parse this without issue, simply passing the {@link ...} reference to the renderer. The TSDoc code can hook into the renderer and replace the reference with a resolved link.

  • Users can add a link title if desired, again using standard Markdown syntax:

    [Statistics subsystem]({@link core-library#Statistics} "Core Statistics")
    

@brandonkal
Copy link

The syntax @vassudanagunta proposes looks clean and readable and TSDoc should support this 👍 . It makes more sense to name the thing first and then provide the link implementation in quotes.

@vassudanagunta
Copy link

@brandonkal Thank you.

provide the link implementation in quotes.

You mean "in the link destination parenthesis" right? I just now clarified my reasoning in the first justification point I gave.

@brandonkal
Copy link

brandonkal commented Feb 6, 2020

@vassudanagunta Yes, I mean the destination.
I like the idea of excluding braces. The renderer can give special handling to a link that starts with "@" which is simple to understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
request for comments A proposed addition to the TSDoc spec
Projects
None yet
Development

No branches or pull requests

4 participants