Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom InlineLexer Rule #504

Closed
elennaro opened this issue Oct 22, 2014 · 4 comments
Closed

Custom InlineLexer Rule #504

elennaro opened this issue Oct 22, 2014 · 4 comments

Comments

@elennaro
Copy link

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?

@Feder1co5oave
Copy link
Contributor

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

@dotcore
Copy link

dotcore commented Feb 2, 2015

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;
};

@Rugal
Copy link

Rugal commented May 5, 2017

@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>
*/

@joshbruce
Copy link
Member

Closing as not part of the current focus. See #1106 and #1216

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants