fix: stabilies heading slug generations#1334
Conversation
| visit(tree, 'element', (node: Element) => { | ||
| if (isHeading(node) && !node.properties.id) { | ||
| const text = | ||
| sourceHeadingTexts && headingIndex < sourceHeadingTexts.length |
There was a problem hiding this comment.
Can you put a comment here explaining that sourceHeadingTexts is for legacy variables, and the other is for mdx variables 🙏
| return /^h[1-6]$/.test(node.tagName); | ||
| } | ||
|
|
||
| /** Extract text content from a HAST node, reconstructing {user.*} from <variable> elements. */ |
There was a problem hiding this comment.
Also explain that at this point the {user.*} is converted to a variable node, and that we're try to get back the variable name from it
There was a problem hiding this comment.
I think the tests here can be in a new file specific to test the heading id's
__tests__/lib/mdxish/mdxish.test.ts
Outdated
| }); | ||
|
|
||
| describe('heading slugs', () => { | ||
| it('should generate slugs from variable names, not resolved values', () => { |
There was a problem hiding this comment.
Can we also add tests where there's other {} expressions? To verify that they don't get picked up as variables & cause issues
|
Code looks good for the approach you're trying to do! I think we should verify if we should go with this approach cause I agree needing to pass in the legacy variables list through |
|
the current approach works but is a bit hacky imo... legacy variables with the hence, why we require passing the new however, this is not the case for the modern variables. superhub variables with the ideally, we could convert all legacy variables into the superhub one before entering the if this renaming is acceptable, then i would generally prefer this option |
Absolutely not what we want. The new editor is only going to receive resolved values as text instead of the correct ast nodes.
If we're talking ideal path the <<>> syntax should have a tokenizer that creates the correct variable or glossary node within the pipeline right? Regardless this should absolutely be happening somewhere IN the pipeline, even if you think the best approach is to move preprocessing into the pipeline but before the remark phase. Currently it looks like we do it on the application side before calling mdxish? https://github.com/readmeio/readme/blob/787c869a9836d30bcad115984d7758b8fb4dcd8b/packages/react/src/ui/RDMD/RMDXISH.tsx#L78-L82 Consumers shouldn't have to handle this.
Not the end of the world if we approached it this way BUT:
|
I tried doing this but even in mdx, if I have a variable say like cc @kevinports |
Yea it shouldn't save in MDX since anything between An issue currently is that the MDX editor serialises standalone bracket notation variables in a weird way, e.g. |
|
I think we should move this PR to #1340 |
[![PR App][icn]][demo] | Fix CX-2929 :-------------------:|:----------: ## 🧰 Changes Retake of #1334 because now we have legacy variable tokenizer ready and no longer need to pass in the legacy variables mapping. Refactors the slug generation logic for headings (which will be used for anchor section links) in MDXish so that if it contains a legacy <<>> or {} variable, the generated slug will use the variable name instead of the variable value. The change is in the heading id generation, which later will be converted to slugs in `renderMdxish`. We wanted to this to make the anchor slug more stable. In legacy, the variable part will actually get dropped in the slug generation, so it can unexpectedly clash with other headings & look incomplete. In mdxish, before it was resolving the variable value in the slugs, which means the slugs can change if the value change, and a hardcoded link can get outdated without the user knowing. This is the first step in addressing this Akamai QA issue: https://linear.app/readme-io/issue/CX-2867/links-to-section-headings-that-involve-variables-personalized-docs **Note:** This change will modify the anchor slug url if it has variables in them, which would make hardcoded links not work for those cases. But given MDXish hasn't been on for a long time, hopefully there's not much customers doing that yet. ## 🧬 QA & Testing 1. I think it's best to test this by locally linking this branch to readme 2. In the [MDXish RDMD here](https://github.com/readmeio/readme/blob/169a94b6372bd68282d78cd8ea70d9f14ce78fa3/packages/react/src/ui/RDMD/RMDXISH.tsx#L79), remove the `opts.mdxish` part to avoid preprocessing legacy variables 3. In an mdxish project in the site, create several H1-H3 headings that contain legacy <<>> and {} variables in them 4. When hovering the anchor logo next to the headings, look at the bottom left of your screen for the slug. The slug should use the variable name and not the value [demo]: https://markdown-pr-PR_NUMBER.herokuapp.com [prod]: https://SUBDOMAIN.readme.io [icn]: https://user-images.githubusercontent.com/886627/160426047-1bee9488-305a-4145-bb2b-09d8b757d38a.svg
🧰 Changes
Replaces
rehype-slugwith a custom slug plugin (mdxish-slug) that reconstructs{user.*}text from<variable>HAST elements when generating heading IDs, so## Hello {user.name}produces slughello-usernameinstead ofhello.For legacy
<<VARIABLE>>syntax (resolved before the pipeline), the consumer extracts heading texts from the raw markdown and passes them assourceHeadingTexts, letting slugs stay stable regardless of variable values.🧬 QA & Testing