-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Extensions
Showdown allows additional functionality to be loaded via extensions.
<script src="src/showdown.js" />
<script src="src/extensions/twitter.js" />
var converter = new showdown.Converter({ extensions: ['twitter'] });
// Using a bundled extension
var Showdown = require('showdown');
var converter = new showdown.Converter({ extensions: ['twitter'] });
// Using a custom extension
var mine = require('./custom-extensions/mine');
var converter = new showdown.Converter({ extensions: ['twitter', mine] });
- table
- prettify
- github
A showdown extension is simply a function which returns an array of language extensions and/or output modifiers:
- Language Extension -- Language extensions are specified with the
lang
type, and add new markdown syntax to showdown. For example, say you wanted^^youtube http://www.youtube.com/watch?v=oHg5SJYRHA0
to automatically render as an embedded YouTube video, that would be a language extension. - Output Modifiers -- Output Modifiers are specified with the
output
type. After showdown has generated HTML, an output modifier can make changes to the generated HTML. For example, if you wanted to change<div class="header">
to be<header>
, you could implement an output modifier.
Each showdown extension can provide language extensions and/or output modifiers.
Regex/replace style extensions are very similar to javascripts string.replace
function. Two properties are given, regex
and replace
. regex
is a string and replace
can be either a string or a function. If replace
is a string, it can use the $1
syntax for group substitution, exactly as if it were making use of string.replace
(internally it does this actually); The value of regex
is assumed to be a global replacement.
Example:
var demo = function(converter) {
return [
// Replace escaped @ symbols
{ type: 'lang', regex: '\\@', replace: '@' }
];
}
Alternately, if you'd just like to do everything yourself, you can specify a filter which is a callback with a single input parameter, text (the current source text within the showdown engine).
Example:
var demo = function(converter) {
return [
// Replace escaped @ symbols
{ type: 'lang', filter: function(text) {
return text.replace(/\\@/g, '@');
}}
];
}
One bit which should be taken into account is maintaining both client-side and server-side compatibility. This can be achieved with a few lines of boilerplate code. First, to prevent polluting the global scope for client-side code, the extension definition should be wrapped in a self-executing function.
(function(){
// Your extension here
}());
Second, client-side extensions should add a property onto Showdown.extensions
which matches the name of the file. As an example, a file named demo.js
should then add Showdown.extensions.demo
. Server-side extensions can simply export themselves.
(function(){
var demo = function(converter) {
// ... extension code here ...
};
// Client-side export
if (typeof window !== 'undefined' && window.showdown && window.showdown.extensions) {
window.Showdown.extensions.demo = demo;
}
// Server-side export
if (typeof module !== 'undefined') module.exports = demo;
}());
The showdown test runner is setup to automatically test cases for extensions. To add test cases for an extension, create a new folder under ./test/extensions
which matches the name of the .js
file in ./src/extensions
. Place any test cases into the filter using the md/html format and they will automatically be run when tests are run.