With Marked I can easily ovverride/add/change lexer rules during implementation, and its great!
For example I can force to use space between hash sign an text to make a header like this:
var lexer = new marked.Lexer(options);
console.log(lexer);
lexer.rules.heading = /^\s*(#{1,6})\s+([^\n]+?) *#* *(?:\n+|$)/
console.log(marked.parser(lexer.lex('#hashtag?'), options));
//<p>#hashtag?</p>
console.log(marked.parser(lexer.lex('# heading?'), options));
//<h1 id="undefinedheading-">heading?</h1>
Cool!
But is there a way, to easily do same for inline lexer?
Like i need to make people be able to add an images with next sequence: %[My Image](http://example.com/img.jpg)?
So i modified:
var inlineLexer = marked.InlineLexer;
inlineLexer.rules.link = /^[!%]{0,1}?\[((?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*)\]\(\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*\)/;
What should I do next?
How to bind a custom inlineLexer to a marked instance?
Please show me an example of how to do this! How can I modify/add custom inline lexer rules?
I'm pretty sure there is no way to do this without editing the code itself.
The use of the InlineLexer is hardcoded inside the parser.parse function:
https://github.com/chjj/marked/blob/7be419324986c7a37c8d3e2fd580e925e236db52/lib/marked.js#L918
Actually there is a way without editing the code of marked itself, if you overwrite the prototype. (In this example I surpress parsing of em tags).
marked.prototype.constructor.Parser.prototype.parse = function (src) {
this.inline = new marked.InlineLexer(src.links, this.options, this.renderer);
this.inline.rules.em = { exec: $.noop }
this.tokens = src.reverse();
var out = '';
while (this.next()) {
out += this.tok();
}
return out;
};
@dotcore 's method solved my problem.
For people coming later, after overriding the constructor, you can also add custom renderer.
var marked = require('marked');
//Override buildin parser constructor
marked.prototype.constructor.Parser.prototype.parse = function (src) {
this.inline = new marked.InlineLexer(src.links, this.options, this.renderer);
//custom rule/syntax
this.inline.rules.link = /^[!@]?\[((?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*)\]\(\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*\)/;
this.tokens = src.reverse();
var out = '';
while (this.next()) {
out += this.tok();
}
return out;
};
//Customize the outputLink Inline lexer
marked.InlineLexer.prototype.outputLink = function(cap, link) {
var href = escape(link.href)
, title = link.title ? escape(link.title) : null;
console.log(title);
if (cap[0].charAt(0) === '@') {
return this.renderer.articles(
cap[1],
cap[2]
);
}
return cap[0].charAt(0) !== '!'
? this.renderer.link(href, title, this.output(cap[1]))
: this.renderer.image(href, title, escape(cap[1]));
};
//Add renderer for the new rule.
marked.Renderer.prototype.articles = function(title, parameters) {
let json = JSON.parse(parameters);
return '<h1 id="articles"'
+ ' paginable="' + json.paginable + '"'
+ ' pageSize="' + json.pageSize + '"'
+ '>'
+ title
+ '</h1>\n';
};
console.log(marked('@[articleComponent]({"paginable":true, "pagsSize":3, "title":"Articles of Doctors"})'));
/*
output is:
<p><h1 id="articles" paginable="true" pageSize="undefined">articleComponent</h1>
</p>
*/
Closing as not part of the current focus. See #1106 and #1216
Most helpful comment
Actually there is a way without editing the code of marked itself, if you overwrite the prototype. (In this example I surpress parsing of em tags).