Uh oh!
There was an error while loading. Please reload this page.
Add slugger option, remove headerIds / headerPrefix - #1354
Conversation
Don't mind this please... just a little easier to see what was changed (fewer clicks): |
@Martii Oh my, I am embarrassed 😅 I fixed the whitespace issues, thanks! 👍 Note that I haven't fixed the unit tests yet because I wanted to get some early feedback on this (see original post). |
UziTech
commented
Oct 17, 2018
I think this should be an extension. It would be really nice to eventually remove all options and just have extensions. |
Grawl
commented
Oct 17, 2018
What if I have |
styfle
commented
Oct 17, 2018
@UziTech I think I prefer using an extension too, I imagine most users will use Should I modify the unit tests that are failing so they no longer look for a |
styfle
commented
Oct 17, 2018
@Grawl Since the user provides the Slugger implementation, they could hard-code the prefix into their custom slugger. Something like the following varGithubSlugger=require("github-slugger");varghslugger=newGithubSlugger();functionPrefixSlugger(){this.headerPrefix='MARKED-PREFIX-';}PrefixSlugger.prototype.slug=function(value){returnthis.headerPrefix+ghslugger.slug(value);};varoptions={slugger: newPrefixSlugger()};Try it here: https://runkit.com/embed/jzea41wp28cc |
Grawl
commented
Oct 17, 2018
cool but better to make out of the box i think |
UziTech
commented
Oct 17, 2018
@Grawl The problem with integrating it is that there are thousands of things that could be integrated (header ids, LaTex grammer, highlighting, sanitizing, etc.) and we don't want to maintain thousands of options. We just want to convert markdown to HTML according to the spec in a fast and secure way. Which is why it would be better to create an easy way to extend marked so the community can maintain whichever extensions they want. |
Grawl
commented
Oct 17, 2018
Guarantee of unique IDs is not an option. |
This also removes two existing options: `headerIds` and `headerPrefix`
styfle
commented
Dec 2, 2018
@joshbruce@UziTech@davisjam I updated the docs so this PR is ready to be reviewed. |
UziTech
commented
Dec 3, 2018
I still feel like this would be a breaking change that is not worth the trouble if our goal is to get rid of this option at some point. I feel like a better fix for this would just be to have a section in the docs on how to extend the renderer to use github-slugger. |
styfle
commented
Dec 3, 2018
@UziTech By extend, you mean override the renderer like I did here? That seems a little hacky/brittle for a feature that is probably widely used (it is currently enabled by default in marked). Could we get more people to comment on this? @joshbruce@davisjam@Feder1co5oave |
UziTech
commented
Dec 3, 2018
I was thinking more like this. Using the renderer option to extend the renderer the way it shows in the docs. |
I would like to eventually have no options (or as few as possible) and have different modules that add this functionality. Something like: // marked-slugger moduleconstSlugger=require("github-slugger");constslugger=newSlugger();functionmarkedSlugger(marked){// extend rendererconstrenderer=newmarked.Renderer();renderer.heading=function(text,level,raw){constslug=slugger.slug(raw);return`<h${level} id="${slug}">${text}</h${level}>\n`;};constoptions={ renderer };marked.setOptions(options);returnmarked;}module.exports=markedSlugger;// in their moduleconstmarked=require("marked");marked=require("marked-slugger")(marked);marked=require("marked-other-module")(marked);// use marked with pluginsmarked(...)That way their can be lots of community or markedjs maintained modules that don't mess up the marked code base. |
joshbruce
commented
Dec 3, 2018
The feature is widely used because it is on by default. I think we added the ability to turn it off recently - think I did it. To @UziTech's point, while going through the history of tickets we decided to get out of the header ID at some point - version 2.x, I think. Most of the errors related to the issue are from glyph-based languages. Further, given the HTML rules around the uniqueness of IDs on an entire page, it's definitely a good reason to opt for the extending path, imho. If it could be easily done, without breaking changes, in a way that would be easy to remove later, I'd say it might be worth it. |
styfle
commented
Dec 4, 2018
It's a pretty minimal api that accepts a single parameter so I don't think we're taking on a huge maintenance burden see diff. @UziTech I think you're solution will actually lead to more maintenance because now we have to maintain multiple plugin packages and version then appropriately. Then communicate that via docs. Unless we expect the community to really standup here but there hasn't been much interaction so I don't expect this. The whole purpose of this PR was to fix 3 bugs:
If we really want to go this route, maybe we should figure out which options can be implemented externally so that we know what our future goals are and what the minimum set of options that marked should expose could be. |
UziTech
commented
Dec 4, 2018
The biggest reason why the plugin system works is because it allows the community to come up with these fixes without needing the core module to approve it. And each module would ideally be small (like my This code wouldn't be hard to maintain but it would be sending the wrong message to the community, that we are going to be adding options to marked, especially if we are just going to remove it in the future. Anyone who wants header ids (which I assume is a lot of people otherwise this PR doesn't really matter anyways) is going to have to change their code after this PR is merged and again after the slugger option is removed. It would be easier for them to just extend the renderer in the first place. I would support a PR that fixes those issues without changing the options. (i.e. implement github-slugger internally) |
joshbruce
commented
Dec 4, 2018
See #1080 as I started working toward that. Note, Header IDs is under the part to deprecate.
I agree. Having said that, we've also been operating under the idea that it doesn't matter how long stuff takes. Unless we're wanting to shift gears, I appreciate the tone and participation of the community since adopting a more, if you find it, please fix it approach and letting the core manage the management, so to speak. If we, as the core, are recommending this PR, we should talk more because it does alter the current path.
Agreed.
Agreed. See #1114 |
@UziTech Cc: @joshbruce
Which is similar to what we did very long ago somewhere around 2014... albeit with no unique |
styfle
commented
Dec 5, 2018
All, Thanks for the feedback. I realize now that I misinterpreted the original comment
@UziTech When I read "extension", I assumed you were answering my question in the PR description about implementing our our slugger or recommending the extension The problem with your extension example here is that the extensions would not be composable (if you need two extensions). letmarked=require("marked");marked=require("marked-slugger")(marked);// override renderermarked=require("marked-other-module")(marked);// override renderer again (oops) |
Feder1co5oave
commented
Dec 5, 2018
My early idea of designing an extension system was to use the Proxy design pattern to allow modules to modify parameters before rendering to html (for example, rebasing renderer=newmarked.Renderer()renderer.link=function(href,title,text){returnrenderer.__parent__.link(href.replace(/^\//,basePath),title,text);}and use a pseudo-DOM (e.g. ReactDOM) to easily modify the html AST before translating it into its textual representation. For example, open external links to a new window: renderer=newmarked.Renderer()renderer.link=function(href,title,text){anchor=renderer.__parent__.link(href,title,text);if(href.match(externalLinkRegex))anchor.addAttribute('target','_blank');// use pseudo-DOM methods to alter htmlreturnanchor;}I believe I wrote some draft of this a long time ago, and the sole use of ReactDOM made the conversion process twice as slow. I'll see if I can found the WIP branch. |
UziTech
commented
Dec 5, 2018
@styfle Correct, we would have to figure out a better way to compose plugins and allow more of marked to be extendable. |
styfle
commented
Dec 20, 2018
Closing in favor of #1401 |
Marked version: 0.5.1
Markdown flavor: All
Description
Fixes#1280 by adding a
sluggeroption so the user can define how<h1 id="">is generated.This also removes the
headerIdsandheaderPrefixoption since thesluggeroption can handle both use cases.Request for comments
github-sluggerpackage? (we would have to modify unit tests)Sluggerimplementation and fixed tests.headerIdsorheaderPrefixoption?Usage
Try it
https://runkit.com/embed/1cawn0orvsca
Contributor
Committer
In most cases, this should be a different person than the contributor.