-
Notifications
You must be signed in to change notification settings - Fork 33
Creating an Extension
This is a simple example of creating a custom markdown element. The extension is actually replacing some markdown text with a custom directive. The directive is <video video-data="someVar"></video>
. The extension assumes that someVar
already exists on the page that the markdown is running on.
Here's the code:
(function () {
var videoHTML = '<video video-data="someAngularVarriableLocalToThisPage"></video>';
function video() {
var replace = function () {
return videoHTML;
};
return [
// Inline style
{
type: 'lang',
regex: '\\[\\s*?!\\[[^()]*\\([^\\(]*\\s*?\\(.* "video"\\)',
replace: replace
}];
}
// Client-side export
if (showdown && showdown.extensions) {
showdown.extensions.video = video;
}
})();
To load this into ng-showdown, you can reference it like so.
angular
.module('example')
.config(function ($showdownProvider) {
$showdownProvider.loadExtension('video');
});
Taken from @jspizziri. See Issue #28 for more details.
I created my own markdown
directive as an alternative to the mardown-to-html
directive:
// directive/markdown/markdown.js
'use strict';
angular.module('myApp')
.directive('markdown', function($showdown, $sanitize, $sce) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch('model', function (newValue) {
var showdownHTML;
if (typeof newValue === 'string') {
showdownHTML = $showdown.makeHtml(newValue);
scope.trustedHtml = ($showdown.getOption('sanitize')) ? $sanitize(showdownHTML) : $sce.trustAsHtml(showdownHTML);
} else {
scope.trustedHtml = typeof newValue;
}
});
},
scope: {
model: '=markdown'
},
template: '<div bind-html-compile="trustedHtml"></div>'
};
});
Please note that this is an exact copy of the markdown-to-html
directive with the exception of this: template: '<div bind-html-compile="trustedHtml"></div>'
.
With that being done, I created another directive bind-html-compile
which compiled the html given to it which looks like so:
// directive/bindHtmlCompile/bindHtmlCompile.js
'use strict';
angular.module('myApp')
.directive('bindHtmlCompile', function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(function() {
return scope.$eval(attrs.bindHtmlCompile);
}, function(value) {
element.html(value);
$compile(element.contents())(scope);
});
}
};
});
Usage:
<!-- instead of this: -->
<div markdown-to-html="myMarkdown"></div>
<!-- use this: -->
<div markdown="myMarkdown"></div>
Voilà!
Additionally, to keep my organization a little cleaner, I created the showdown extensions
as angular constants like so:
// constants/myExt.js
(function(){
'use strict';
angular.module('myApp')
.constant('myExt',
function myExt() {
var myext1 = {
type: 'lang',
regex: /markdown/g,
replace: 'showdown'
};
var myext2 = {
/* extension code */
};
return [myext1, myext2];
});
})();
And then injected and registered them in the config:
// app.js
.config(function($showdownProvider, myExt) {
$showdownProvider.setOption('tables', true);
//...
$showdownProvider.loadExtension(myExt);
//...
})