Showdown: Passing custom data to an extension

Created on 28 Sep 2017  路  3Comments  路  Source: showdownjs/showdown

Hey,

I'd like to do something like the following:

markdown:

Please install version {{ config.version }}

extension (chopped down code):

return {
  filter(text, converter, options) {
    const regex = null; // TODO get text between {{ }}
    const newText = text.replace(regex, (wholeMatch, m1, m2) => {
      // get config.version from passed through object and replace it
     return '';
    });
  }
}

I'd like to basically be able to replace {{ config.version }} from an object, however I can't use globals in my environment. Is there anyway to pass a custom object through to the extension?

help wanted

Most helpful comment

there's the option of passing the extension directly to showdown instead of registering it globally. what I mean is, instead of

const extension = () => {
return [{
  filter(text, converter, options) {
    const regex = null; // TODO get text between {{ }}
    const newText = text.replace(regex, (wholeMatch, m1, m2) => {
      // get config.version from passed through object and replace it
     return '';
    });
  }]
}
}
showdown.extension('extension', extension)

// listing extension
var converter = new showdown.Converter({ extensions: ['extension'] });

use

const extension = () => {
return [{
  filter(text, converter, options) {
    const regex = null; // TODO get text between {{ }}
    const newText = text.replace(regex, (wholeMatch, m1, m2) => {
      // get config.version from passed through object and replace it
     return '';
    });
  }]
}
}

// passing the extension directly
var converter = new showdown.Converter({ extensions: [extension] });

this allows you to pass config to the extension using partial application

// this is the important part
const extension = config => () => {
return [{
  filter(text, converter, options) {
    const regex = null; // TODO get text between {{ }}
    const newText = text.replace(regex, (wholeMatch, m1, m2) => {
      // use config.version from passed through object and replace it
     return '';
    });
  }]
}
}

var converter = new showdown.Converter({ extensions: [ extension(config) ] });

All 3 comments

there's the option of passing the extension directly to showdown instead of registering it globally. what I mean is, instead of

const extension = () => {
return [{
  filter(text, converter, options) {
    const regex = null; // TODO get text between {{ }}
    const newText = text.replace(regex, (wholeMatch, m1, m2) => {
      // get config.version from passed through object and replace it
     return '';
    });
  }]
}
}
showdown.extension('extension', extension)

// listing extension
var converter = new showdown.Converter({ extensions: ['extension'] });

use

const extension = () => {
return [{
  filter(text, converter, options) {
    const regex = null; // TODO get text between {{ }}
    const newText = text.replace(regex, (wholeMatch, m1, m2) => {
      // get config.version from passed through object and replace it
     return '';
    });
  }]
}
}

// passing the extension directly
var converter = new showdown.Converter({ extensions: [extension] });

this allows you to pass config to the extension using partial application

// this is the important part
const extension = config => () => {
return [{
  filter(text, converter, options) {
    const regex = null; // TODO get text between {{ }}
    const newText = text.replace(regex, (wholeMatch, m1, m2) => {
      // use config.version from passed through object and replace it
     return '';
    });
  }]
}
}

var converter = new showdown.Converter({ extensions: [ extension(config) ] });

As @obedm503 poited out, you can pass an initialized object to showdown (instead of a reference).
This gives you the power to initialize and configure the extension to your hearts content.

You can even create a "class" and change properties on the fly, in the case your config object is not available at showdown initialization. Here's an example: (fiddle here)

var FooExtension = function(version) {
  // to have a valid "pointer" in case of binding
  self = this;
  this.configversion = version || '1.0.0';

  this.extension = function () {
    return [{
      type: 'lang',
      regex: /\{\{([\s\S]+)\}\}/g,
      replace: function (wm, theVar) {
        var otp = '';
        if (theVar.trim() === 'config.version') {
          otp = self.configversion; // this is obviously simplified
        }
        return otp;
      }
    }];
  }
};

and then somewhere around in your code...

// Extension
var myExt = new FooExtension();
showdown.extension('foo', myExt.extension);

// initialize converter
var conv = new showdown.Converter({
  extensions: ['foo']
});

// pass the config object (or string or something)
myExt.configversion = '2.0.0';

//convertion
var html = conv.makeHtml('Please **install** version {{ config.version }}');
console.log(html);

We're currently looking to improve showdown with automated tests in all browsers and a proper domain and webpage. If you like our work, please donate!! Your contribution will be greatly appreciated.

https://www.paypal.me/tiviesantos

Thanks for the indepth explanation guys! Working well 馃憤

Was this page helpful?
0 / 5 - 0 ratings