Discourse recently moved to a new Markdown engine called Markdown-it.
Here are some dev notes that will help you either fix bugs in core or create your new plugins.
The basics
Discourse only contains a few helpers on top of the engine, so the vast majority of learning that needs to be done, is understanding Markdown It.
The docs directory contains the current documentation.
I strongly recommend reading:
While I develop extensions for the engine I usually open up a second editor looking at existing rules. The engine consists of a long list of rules and each rule is in a dedicated file that is reasonably easy to follow.
If I am working on an inline rule I will think of what existing inline rule works more or less like it and base my work on it.
Keep in mind, you can sometimes get away with just changing a renderer to get desired functionality which is usually much easier.
How to structure an extension?
When the markdown engine initializes it searches through all the modules.
If any module is called /discourse-markdown\/|markdown-it\//
(meaning it lives in a discoruse-markdown or markdown-it directory) it will be a candidate for initialization.
If the module exports a method called setup
it will be called by the engine during initialization.
The setup protocol
/my-plugins/assets/javascripts/discourse-markdown/awesome-extension.js.es6
export function setup(helper) {
// ... your code goes here
}
A setup
method gets access to a helper object it can use for initialization. This contains the following methods and vars:
-
markdownIt
: this property is set to true
when the new engine is in use. For proper backwards compatibility you want to check it.
-
registerOptions(opts, siteSettings, state)
: this method is called before the markdown engine is initialized, you can use it to determine if to enable or disable the engine.
-
whiteList(obj)
: this method is used to whitelist HTML with our sanitizer.
-
registerPlugin(md)
: this method is used to register a Markdown It plugin.
Putting it all together
function amazingMarkdownItInline(state, silent) {
// standard markdown it inline extension goes here.
return false;
}
export function setup(helper) {
if(!helper.markdownIt) { return; }
helper.registerOptions((opts,siteSettings)=>{
opts.features.['my_extension'] = !!siteSettings.my_extension_enabled;
});
helper.whiteList(['span.amazing', 'div.amazing']);
helper.registerPlugin(md=>{
md.inline.push('amazing', amazingMarkdownItInline);
});
}
Discourse specific extensions
Discourse contains 2 rulers you can use for custom BBCode tags. An inline and block level ruler.
(Documentation to be added tomorrow)