-
-
Notifications
You must be signed in to change notification settings - Fork 735
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
WIP: Links in type signatures #3471
base: main
Are you sure you want to change the base?
Conversation
Annotated documents allow putting a class, and optionally a link and hover text around another document. We cannot use highlight.js' syntax highlighting anymore if we want links, since highlight.js will strip all existing markup from <code> blocks for XSS reasons. (see https://github.com/highlightjs/highlight.js/wiki/security) This mechanism will be used to annotate expressions/tokens during pretty printing, allowing us to implement our own syntax highlighting inside of the pretty printer. Extend Utf8Writer to DocumentWriter, which has enter/exit callbacks whenever annotations are discovered Implement HtmlWriter which prints hljs-* span tags or links Extends the command queue for fit/pretty to include `AnnotationExit` to keep the spirit of avoiding recursive calls.
- use the new annotations to be able to highlight types using the type pretty printer, as well as the type_ast in the format - a new docs_* functions to the formatter that print using the type_::pretty::Printer instead of the type ast - output signatures in the docs as raw HTML, disabling highlight.js for them
… hex package; fix relative links
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
We don't want to modify the formatter at all for this. As the comment on the documentation generation code says we want to stop using the same code for both, so this would be the point where we split it so we can have two specialised bits of code rather than 1 lowest-common-denominator.
The pretty module must not know anything about Gleam or HTML or code, so the annotation and to-html method must be removed. The thing to add is a ZeroWidthText which would work the same as text but have contents which do not contribute to the size. This would be a very small change to the code.
Loops are used over recursion as Rust doesn't have TCO so the printer would (and used to!) crash if recursion is used.
The tests as you have them look great!
Thank you so much for taking a look at this! I kind of put this on hold, since I wanted to wait what your thoughts in the discussion thread were first 🙂 I had a version with a A special formatter for printing docs and a I understand why the loop is done this way; I just felt like for sure noone is gonna stack-overflow with the depth of the tree 😄 |
I feel like this has already gotten quite big, so I thought I'd stop at the early point before you say it's all unreasonable anyways and I waste a bunch of time :D
First: I cannot "just" generate links, since highlight.js will not allow them..
Instead, all code relevant to type/function/constant signatures is highlighted at compile time, and types are always printed using the
type_::pretty::Printer
in the docs. It introduces a new variant to the Document, and a new DocumentWriter trait that can react on them. Since it looked like the documents formatter goes to great length to avoid being recursive, I've also tried to do that. This introduces another newCmd
type that gets used instead of the list of(indent, mode, doc)
triples, and consequently changes a lot of types around in format. Just doing recursion would basically get rid of all of that.Overall, this allows for all signatures (with small extensions all parseable Gleam code) to be highlighted by the compiler directly, without relying on Javascript. This could potentially also be used to add colors/links to error messages, or annotate all examples in the docs as well.
If a resolved type (ignoring aliases) is publicly exposed, a link to its documentation will be generated as well. Versions are currently ignored. Ignoring aliases means that a common pattern doesn't work currently (lustre for example does this with every type), where an internal type is re-exported using a type alias.
Questions
fix #3461 #828