jonschlinkert / remarkable

Markdown parser, done right. Commonmark support, extensions, syntax plugins, high speed - all in one. Gulp and metalsmith plugins available. Used by Facebook, Docusaurus and many others! Use https://github.com/breakdance/breakdance for HTML-to-markdown conversion. Use https://github.com/jonschlinkert/markdown-toc to generate a table of contents.
https://jonschlinkert.github.io/remarkable/demo/
MIT License
5.74k stars 371 forks source link

Create hooks for autolinks #117

Open kelunik opened 9 years ago

kelunik commented 9 years ago

I want to change several autolinked URLs and replace them with custom HTML.

Example:

There's a new issue at GitHub: https://github.com/jonschlinkert/remarkable/issues/117

Should be rendered as:

<p>There's a new issue at GitHub: <a href="https://github.com/jonschlinkert/remarkable/issues/117" class="github-issue">jonschlinkert/remarkable#117</a></p>

How would I extend remarkable in this way?

puzrin commented 9 years ago

You can write plugin that will replace this rule with your logic: https://github.com/jonschlinkert/remarkable/blob/dev/lib/rules_core/linkify.js

Each separate rule can't be extended, but it can be replaced and new rules can be added.

kelunik commented 9 years ago

@puzrin I created a plugin, but I only get state.pos if parser is just after colons in test/test.js. Plugin: lib/index.js

Current output replaces the URLs two characters before it's expected position:

<p>There's a new issue at GitHub<a href="https://github.com/jonschlinkert/remarkable/issues/117" target="_blank" class="github-issue"><i class="fa fa-github"></i>jonschlinkert/remarkable#117</a>17</p>
puzrin commented 9 years ago

Inline parser will not stop on each char. Everything except special chars is skipped as text https://github.com/jonschlinkert/remarkable/blob/dev/lib/rules_inline/text.js

I gave you description above how to implement it right.

kelunik commented 9 years ago

@puzrin Thanks, I copied that files and replaced the linkify function, but I don't think I did that right, even through it works: https://github.com/kelunik/remarkable-issue-linker/blob/master/index.js#L60

How do I convert this plugin so it's usable in browsers?

puzrin commented 9 years ago

See Ruler interface:

https://github.com/jonschlinkert/remarkable/blob/dev/lib/ruler.js#L47

You need .at() for replace by name. Or you can disable it + add your one with another name bebore/after appropriate. That will work always. At least, until i decide break rule names :)

To work in browser - pack you module as you do with other browser files. I use browserify + bower, see src of this project. There are also webpack and so on. That depends on your project & preferences. You can even write plugin directly for requirejs, if you don't need node compatibility.

Spend some time for reading src. Those are really simple, except particular block/inline rules. If you managed to create your draft so fast, that will not take much time.

PS. Just remembered - there is another alternative. In core chain you can

That will be correct too, without mad hacking. What to choose - depend on how much do you like existing autolinker.

hryanjones commented 9 years ago

Sorry to jump in here, but does anyone know if there's already a plugin to make all links open in a new tab?

kelunik commented 9 years ago

I'm not aware of one. Currently, I just loop though all <a> elements, because they're inserted into the DOM anyway. There may be an option for Autolinker or you may be able to replace the default Autolinker with a extended one.

hryanjones commented 9 years ago

Thanks for the suggestion, we decided to go with something a bit weird and change the default link targets on our whole site using the <base> tag:

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

All of the other link-like things on our site are handled by React, so it seems like the least code change.