Comments (14)
@ShimShamSam String.protoype.link is provided by the browser, it's not modifiable. The reason we can't add global options like that is because the size impact would be enormous. Just for the snippet you posted, we'd have to add serialization support for arbitrary attributes, classify tokens as named entities ("link"), etc - essentially that would require an AST, and this module just can't afford that. The reason snarkdown is small is because of design decisions, not just compact code - breaking out of those design decisions/constraints makes it just another Markdown parser, and in that regard a fairly poor one.
Now that I'm maintaining a fair number of these micro-modules, I've been finding it difficult to explain the importance of constraints. Everyone has a set of features they want, and no two people want the same set. The problem is, a project with the goal of being minimal simply cannot accommodate the superset of features that would provide everyone with their desired features - that would make it a normal module, not a minimal one. There are already excellent Markdown parser modules out there that do these things better than Snarkdown - it's important to understand that small modules are by nature an exercise in tradeoff management.
from snarkdown.
I would go a step further and ask that we can also modify the link's rel attribute so we can add things like nofollow, noopener, etc...
from snarkdown.
FWIW here's a function that would do it after innerHTML:
div.innerHTML = snarkdown(md);
retarget(div);
function retarget(el) {
if (el.nodeName==='A' && !el.target && el.origin!==location.origin) {
el.setAttribute('target', '_blank');
el.setAttribute('rel', 'noreferrer noopener');
}
for (let i=el.children.length; i--; ) retarget(el.children[i]);
}
Personally I think it's nice to be able to take advantage of DOM traversal here.
from snarkdown.
@abhishiv I like the idea, but it's probably impossible to convert tokens to nice function names like that given the filesize.
Currently it'd be like:
snarkdown(str, (md, html) => {
return html.replace(/^<a /, '<a target="_blank" rel="nofollow" ')
});
edit: @tunnckoCore pretty much exactly what I was thinking haha. just would do it after all the blocks.
Just thinking though, you could pretty much apply that transformation anyway:
let html = snarkdown(md).replace(
/(<a href="(https?:)?\/\/.*?")>/g,
'$1 target="_blank" rel="nofollow">'
);
edit 2: here's Showdown's target="_blank" plugin
from snarkdown.
Seems like a good idea, though maybe a little bit presumptive? An option seems good.
Also, this library actually uses a little-known method String.prototype.link
to generate HTML links with proper encoding, and there's no option to add attributes. Will have to switch to an inline creation in order to get the target attribute.
https://github.com/developit/snarkdown/blob/master/snarkdown.js#L82
FWIW I tend to pipe the output of this lib into something that converts the HTML to Virtual DOM, which makes it super easy to attach arbitrary behavior (and attributes) to any element.
from snarkdown.
If links are already being processed by their own logic (currently String.prototype.link), it makes sense to allow devs to hook into it. Running a regexp replace on the entire output to fix links seems inefficient.
Why not just add some global options to the parse function? Something like:
snarkdown(text, {
links : {
nofollow : true,
noopener : true,
}
});
from snarkdown.
@ShimShamSam yup - I had originally tested out a target change, but then realized target isn't good enough on it's own since that's actually a vulnerability without proper rel
set.
I want to collect some use-cases here: are you guys piping the HTML straight into the DOM, or through something like a VDOM renderer?
from snarkdown.
I use templates for a project, not a virtual DOM, so I'm ultimately setting innerHTML directly.
from snarkdown.
Ah ok, that helps me understand. Maybe we can add something really low-level like a "chunk processor" API. Just thinking of ways to keep the size down. Issue I ran into immediately after adding target="_blank"
was that it doesn't make sense for same-domain and #anchor links.
from snarkdown.
@developit yeah same for me, setting innerHTML.
What about a url builder?
md.parse(str, {
linkBuilder: function(href) {
return {target: "_blank", rel: "nofollow"}
}
})
from snarkdown.
Yea maybe we can allow kinda "plugin" api. Just a function or array as second argument which will be passed with the token in final else {}
(after all the if else-es)
edit: @abhishiv seems like a too much code :D but yea, maybe
from snarkdown.
Mm, maybe. I was thinking to pass the token
array to that transform function, too. But, not sure because... nah.. maybe would need too much docs which token is what 😆
Just thinking though, you could pretty much apply that transformation anyway:
Yea.. So it just ends up that it should be enough to say (and emphasize somewhere) that Snarkdown does not do anything so magical and relies absolutely on RegExps, and so you can just continue to do regex things after it returns its result, haha.
edit: but yea, people likes "plugins", haha
from snarkdown.
String.protoype.link is provided by the browser, it's not modifiable.
I know that. What I meant was we already have branching logic that says "this is a link, do x". Being able to hook into that should be as easy as setting a few options. Are you open to a pull request so I can take a stab at it?
from snarkdown.
I'm always happy to review a PR, just I don't want to give you the impression it's going to be something we can necessarily merge. There's very little that can be done to mitigate the file size hit it will incur, which I am fairly certain makes it a non-starter.
from snarkdown.
Related Issues (20)
- Strikethrough not working HOT 3
- HR not working after PRE
- Nested lists not working HOT 3
- unexpected link generated HOT 1
- feature request: fenced divs
- Add id to headings HOT 1
- Issue with ruler after <h3>
- The output for nested italic and bold is incorrect. HOT 3
- Exposiing the parser API
- Add usage example with PrismJS HOT 1
- pre+code tag instead of just pre HOT 1
- module not defined HOT 1
- Type declarations missing in npm package HOT 2
- v2.0 breaking changes HOT 1
- Angle-bracket link/url syntax not supported
- Date formatting support
- Unexpected parsing with single characters such as * HOT 1
- Markdown code not formatting correctly on uptime website HOT 3
- export declarations may only appear at top level of a module
- in inline html, attribute values are incorrectly parsed as markdown HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from snarkdown.