|
@ -5,13 +5,10 @@ |
|
|
|
|
|
|
|
|
var utils = require('./common/utils'); |
|
|
var utils = require('./common/utils'); |
|
|
var helpers = require('./helpers'); |
|
|
var helpers = require('./helpers'); |
|
|
var assign = require('./common/utils').assign; |
|
|
|
|
|
var isString = require('./common/utils').isString; |
|
|
|
|
|
var Renderer = require('./renderer'); |
|
|
var Renderer = require('./renderer'); |
|
|
var ParserCore = require('./parser_core'); |
|
|
var ParserCore = require('./parser_core'); |
|
|
var ParserBlock = require('./parser_block'); |
|
|
var ParserBlock = require('./parser_block'); |
|
|
var ParserInline = require('./parser_inline'); |
|
|
var ParserInline = require('./parser_inline'); |
|
|
var Ruler = require('./ruler'); |
|
|
|
|
|
|
|
|
|
|
|
var config = { |
|
|
var config = { |
|
|
'default': require('./presets/default'), |
|
|
'default': require('./presets/default'), |
|
@ -34,30 +31,178 @@ function StateCore(self, src, env) { |
|
|
this.typographer = self.typographer; |
|
|
this.typographer = self.typographer; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Main class
|
|
|
/** |
|
|
//
|
|
|
* class MarkdownIt |
|
|
|
|
|
* |
|
|
|
|
|
* Main parser/renderer class. |
|
|
|
|
|
* |
|
|
|
|
|
* ##### Usage |
|
|
|
|
|
* |
|
|
|
|
|
* ```javascript
|
|
|
|
|
|
* // node.js, "classic" way:
|
|
|
|
|
|
* var MarkdownIt = require('markdown-it'), |
|
|
|
|
|
* md = new MarkdownIt(); |
|
|
|
|
|
* console.log(md.render('# markdown-it rulezz!')); |
|
|
|
|
|
* |
|
|
|
|
|
* // node.js, the same, but with sugar:
|
|
|
|
|
|
* var md = require('markdown-it')(); |
|
|
|
|
|
* console.log(md.render('# markdown-it rulezz!')); |
|
|
|
|
|
* |
|
|
|
|
|
* // browser without AMD, added to "window" on script load
|
|
|
|
|
|
* // Note, there are no dash.
|
|
|
|
|
|
* var md = window.markdownit(); |
|
|
|
|
|
* console.log(md.render('# markdown-it rulezz!')); |
|
|
|
|
|
* ``` |
|
|
|
|
|
* |
|
|
|
|
|
* Single line rendering, without paragraph wrap: |
|
|
|
|
|
* |
|
|
|
|
|
* ```javascript
|
|
|
|
|
|
* var md = require('markdown-it')(); |
|
|
|
|
|
* console.log(md.renderInline('__markdown-it__ rulezz!')); |
|
|
|
|
|
* ``` |
|
|
|
|
|
**/ |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* new MarkdownIt([presetName, options]) |
|
|
|
|
|
* - presetName (String): optional, `commonmark` / `full` / `zero` |
|
|
|
|
|
* - options (Object) |
|
|
|
|
|
* |
|
|
|
|
|
* Creates parser instanse with given config. Can be called without `new`. |
|
|
|
|
|
* |
|
|
|
|
|
* ##### presetName |
|
|
|
|
|
* |
|
|
|
|
|
* MarkdownIt provides named presets as a convenience to quickly |
|
|
|
|
|
* enable/disable active syntax rules and options for common use cases. |
|
|
|
|
|
* |
|
|
|
|
|
* - ["commonmark"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) -
|
|
|
|
|
|
* configures parser to strict [CommonMark](http://commonmark.org/) mode.
|
|
|
|
|
|
* - ["full"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/full.js) -
|
|
|
|
|
|
* enables all available rules, but still without html, typographer & autolinker. |
|
|
|
|
|
* - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -
|
|
|
|
|
|
* similar to GFM, used when no preset name given. |
|
|
|
|
|
* - ["zero"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) -
|
|
|
|
|
|
* all rules disabled. Useful to quickly setup your config via `.enable()`. |
|
|
|
|
|
* For example, when you need only `bold` and `italic` markup and nothing else. |
|
|
|
|
|
* |
|
|
|
|
|
* ##### options: |
|
|
|
|
|
* |
|
|
|
|
|
* - __html__ - `false`. Set `true` to enable HTML tags in source. Be careful! |
|
|
|
|
|
* That's not safe! You may need external sanitizer to protect output from XSS. |
|
|
|
|
|
* It's better to extend features via plugins, instead of enabling HTML. |
|
|
|
|
|
* - __xhtmlOut__ - `false`. Set `true` to add '/' when closing single tags |
|
|
|
|
|
* (`<br />`). This is needed only for full CommonMark compatibility. In real |
|
|
|
|
|
* world you will need HTML output. |
|
|
|
|
|
* - __breaks__ - `false`. Set `true` to convert `\n` in paragraphs into `<br>`. |
|
|
|
|
|
* - __langPrefix__ - `language-`. CSS language class prefix for fenced blocks. |
|
|
|
|
|
* Can be useful for external highlighters. |
|
|
|
|
|
* - __linkify__ - `false`. Set `true` to autoconvert URL-like text to links. |
|
|
|
|
|
* - __typographer__ - `false`. Set `true` to enable some language-neutral |
|
|
|
|
|
* replacement + quotes beautification (smartquotes). |
|
|
|
|
|
* - __quotes__ - `“”‘’`, string. Double + single quotes replacement pairs, when |
|
|
|
|
|
* typographer enabled and smartquotes on. Set doubles to '«»' for Russian, |
|
|
|
|
|
* '„“' for German. |
|
|
|
|
|
* - __highlight__ - `null`. Highlighter function for fenced code blocks. |
|
|
|
|
|
* Highlighter `function (str, lang)` should return escaped HTML. It can also |
|
|
|
|
|
* return empty string if the source was not changed and should be escaped externaly. |
|
|
|
|
|
* |
|
|
|
|
|
* ##### Example |
|
|
|
|
|
* |
|
|
|
|
|
* ```javascript
|
|
|
|
|
|
* // commonmark mode
|
|
|
|
|
|
* var md = require('markdown-it')('commonmark'); |
|
|
|
|
|
* |
|
|
|
|
|
* // default mode
|
|
|
|
|
|
* var md = require('markdown-it')(); |
|
|
|
|
|
* |
|
|
|
|
|
* // enable everything
|
|
|
|
|
|
* var md = require('markdown-it')('full', { |
|
|
|
|
|
* html: true, |
|
|
|
|
|
* linkify: true, |
|
|
|
|
|
* typographer: true |
|
|
|
|
|
* }); |
|
|
|
|
|
* ``` |
|
|
|
|
|
**/ |
|
|
function MarkdownIt(presetName, options) { |
|
|
function MarkdownIt(presetName, options) { |
|
|
if (!(this instanceof MarkdownIt)) { |
|
|
if (!(this instanceof MarkdownIt)) { |
|
|
return new MarkdownIt(presetName, options); |
|
|
return new MarkdownIt(presetName, options); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!options) { |
|
|
if (!options) { |
|
|
if (!isString(presetName)) { |
|
|
if (!utils.isString(presetName)) { |
|
|
options = presetName || {}; |
|
|
options = presetName || {}; |
|
|
presetName = 'default'; |
|
|
presetName = 'default'; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* MarkdownIt#inline -> ParserInline |
|
|
|
|
|
* |
|
|
|
|
|
* Instance of inline parser. You may need it to add new rules when |
|
|
|
|
|
* writing plugins. For simple rules control use [[MarkdownIt.disable]] and |
|
|
|
|
|
* [[MarkdownIt.enable]]. |
|
|
|
|
|
**/ |
|
|
this.inline = new ParserInline(); |
|
|
this.inline = new ParserInline(); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* MarkdownIt#block -> ParserBlock |
|
|
|
|
|
* |
|
|
|
|
|
* Instance of block parser. You may need it to add new rules when |
|
|
|
|
|
* writing plugins. For simple rules control use [[MarkdownIt.disable]] and |
|
|
|
|
|
* [[MarkdownIt.enable]]. |
|
|
|
|
|
**/ |
|
|
this.block = new ParserBlock(); |
|
|
this.block = new ParserBlock(); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* MarkdownIt#core -> ParserCore |
|
|
|
|
|
* |
|
|
|
|
|
* Instance of core chain executor. You may need it to add new rules when |
|
|
|
|
|
* writing plugins. For simple rules control use [[MarkdownIt.disable]] and |
|
|
|
|
|
* [[MarkdownIt.enable]]. |
|
|
|
|
|
**/ |
|
|
this.core = new ParserCore(); |
|
|
this.core = new ParserCore(); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* MarkdownIt#renderer -> Renderer |
|
|
|
|
|
* |
|
|
|
|
|
* Instance of Renderer. Use it to modify output look. Or to add rendering |
|
|
|
|
|
* rules for new token types, generated by plugins. |
|
|
|
|
|
* |
|
|
|
|
|
* ##### Example |
|
|
|
|
|
* |
|
|
|
|
|
* ```javascript
|
|
|
|
|
|
* var md = require('markdown-it')(); |
|
|
|
|
|
* |
|
|
|
|
|
* function myToken(tokens, idx, options, env, self) { |
|
|
|
|
|
* //...
|
|
|
|
|
|
* return result; |
|
|
|
|
|
* }; |
|
|
|
|
|
* |
|
|
|
|
|
* md.renderer.rules['my_token'] = myToken |
|
|
|
|
|
* ``` |
|
|
|
|
|
* |
|
|
|
|
|
* See [[Renderer]] docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js).
|
|
|
|
|
|
**/ |
|
|
this.renderer = new Renderer(); |
|
|
this.renderer = new Renderer(); |
|
|
this.ruler = new Ruler(); |
|
|
|
|
|
|
|
|
|
|
|
// Expose utils & helpers for easy acces from plugins
|
|
|
// Expose utils & helpers for easy acces from plugins
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* MarkdownIt#utils -> utils |
|
|
|
|
|
* |
|
|
|
|
|
* Assorted utility functions, useful to write plugins. See details |
|
|
|
|
|
* [here](https://github.com/markdown-it/markdown-it/blob/master/lib/common/utils.js).
|
|
|
|
|
|
**/ |
|
|
this.utils = utils; |
|
|
this.utils = utils; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* MarkdownIt#helpers -> helpers |
|
|
|
|
|
* |
|
|
|
|
|
* Link components parser functions, useful to write plugins. See details |
|
|
|
|
|
* [here](https://github.com/markdown-it/markdown-it/blob/master/lib/helpers).
|
|
|
|
|
|
**/ |
|
|
this.helpers = helpers; |
|
|
this.helpers = helpers; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.options = {}; |
|
|
this.options = {}; |
|
|
this.configure(config[presetName]); |
|
|
this.configure(config[presetName]); |
|
|
|
|
|
|
|
@ -65,16 +210,38 @@ function MarkdownIt(presetName, options) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set options, if you did not passed those to constructor
|
|
|
/** chainable |
|
|
//
|
|
|
* MarkdownIt.set(options) |
|
|
|
|
|
* |
|
|
|
|
|
* Set parser options (in the same format as in constructor). Probably, you |
|
|
|
|
|
* will never need it, but you can change options after constructor call. |
|
|
|
|
|
* |
|
|
|
|
|
* ##### Example |
|
|
|
|
|
* |
|
|
|
|
|
* ```javascript
|
|
|
|
|
|
* var md = require('markdown-it')() |
|
|
|
|
|
* .set({ html: true, breaks: true }) |
|
|
|
|
|
* .set({ typographer, true }); |
|
|
|
|
|
* ``` |
|
|
|
|
|
* |
|
|
|
|
|
* __Note:__ To achieve the best possible performance, don't modify a |
|
|
|
|
|
* `markdown-it` instance options on the fly. If you need multiple configurations |
|
|
|
|
|
* it's best to create multiple instances and initialize each with separate |
|
|
|
|
|
* config. |
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.set = function (options) { |
|
|
MarkdownIt.prototype.set = function (options) { |
|
|
assign(this.options, options); |
|
|
utils.assign(this.options, options); |
|
|
return this; |
|
|
return this; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Batch loader for components rules states & options
|
|
|
/** chainable, internal |
|
|
//
|
|
|
* MarkdownIt.configure(presets) |
|
|
|
|
|
* |
|
|
|
|
|
* Batch load of all options and compenent settings. This is internal method, |
|
|
|
|
|
* and you probably will not need it. But if you with - see available presets |
|
|
|
|
|
* and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)
|
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.configure = function (presets) { |
|
|
MarkdownIt.prototype.configure = function (presets) { |
|
|
var self = this; |
|
|
var self = this; |
|
|
|
|
|
|
|
@ -93,8 +260,21 @@ MarkdownIt.prototype.configure = function (presets) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Sugar to enable rules by names in all chains at once
|
|
|
/** chainable |
|
|
//
|
|
|
* MarkdownIt.enable(list) |
|
|
|
|
|
* - list (String|Array): rule name or list of rule names to enable |
|
|
|
|
|
* |
|
|
|
|
|
* Enable list or rules. It will automatically find appropriate components, |
|
|
|
|
|
* containing rules with given names. |
|
|
|
|
|
* |
|
|
|
|
|
* ##### Example |
|
|
|
|
|
* |
|
|
|
|
|
* ```javascript
|
|
|
|
|
|
* var md = require('markdown-it')() |
|
|
|
|
|
* .enable(['sub', 'sup']) |
|
|
|
|
|
* .disable('smartquotes'); |
|
|
|
|
|
* ``` |
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.enable = function (list) { |
|
|
MarkdownIt.prototype.enable = function (list) { |
|
|
[ 'core', 'block', 'inline' ].forEach(function (chain) { |
|
|
[ 'core', 'block', 'inline' ].forEach(function (chain) { |
|
|
this[chain].ruler.enable(list, true); |
|
|
this[chain].ruler.enable(list, true); |
|
@ -103,8 +283,12 @@ MarkdownIt.prototype.enable = function (list) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Sugar to disable rules by names in all chains at once
|
|
|
/** chainable |
|
|
//
|
|
|
* MarkdownIt.disable(list) |
|
|
|
|
|
* - list (String|Array): rule name or list of rule names to disable. |
|
|
|
|
|
* |
|
|
|
|
|
* The same as [[MarkdownIt.enable]], but turn specified rules off. |
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.disable = function (list) { |
|
|
MarkdownIt.prototype.disable = function (list) { |
|
|
[ 'core', 'block', 'inline' ].forEach(function (chain) { |
|
|
[ 'core', 'block', 'inline' ].forEach(function (chain) { |
|
|
this[chain].ruler.disable(list, true); |
|
|
this[chain].ruler.disable(list, true); |
|
@ -113,23 +297,37 @@ MarkdownIt.prototype.disable = function (list) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Sugar for curried plugins init:
|
|
|
/** chainable |
|
|
//
|
|
|
* MarkdownIt.use(plugin, options) |
|
|
// var md = new MarkdownIt();
|
|
|
* |
|
|
//
|
|
|
* Load specified plugin with given options into current parser instance. |
|
|
// md.use(plugin1)
|
|
|
* |
|
|
// .use(plugin2, opts)
|
|
|
* ##### Example |
|
|
// .use(plugin3);
|
|
|
* |
|
|
//
|
|
|
* ```javascript
|
|
|
MarkdownIt.prototype.use = function (plugin, opts) { |
|
|
* var md = require('markdown-it')() |
|
|
plugin(this, opts); |
|
|
* .use(require('makkdown-it-emoji')); |
|
|
|
|
|
* ``` |
|
|
|
|
|
**/ |
|
|
|
|
|
MarkdownIt.prototype.use = function (plugin, options) { |
|
|
|
|
|
plugin(this, options); |
|
|
return this; |
|
|
return this; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse input string, returns tokens array. Modify `env` with
|
|
|
/** internal |
|
|
// definitions data.
|
|
|
* MarkdownIt.parse(src, env) -> Array |
|
|
//
|
|
|
* - src (String): source string |
|
|
|
|
|
* - env (Object): enviroment variables |
|
|
|
|
|
* |
|
|
|
|
|
* Parse input string and returns list of block tokens (special token type |
|
|
|
|
|
* "inline" will contain list of inline tokens). You should not call this |
|
|
|
|
|
* method directly, until you write custom renderer (for example, to produce |
|
|
|
|
|
* AST). |
|
|
|
|
|
* |
|
|
|
|
|
* `env` is modified with additional info. For example, with references data. |
|
|
|
|
|
* Also `env` can be used to pass external info to plugins. |
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.parse = function (src, env) { |
|
|
MarkdownIt.prototype.parse = function (src, env) { |
|
|
var state = new StateCore(this, src, env); |
|
|
var state = new StateCore(this, src, env); |
|
|
|
|
|
|
|
@ -139,8 +337,16 @@ MarkdownIt.prototype.parse = function (src, env) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Main method that does all magic :)
|
|
|
/** |
|
|
//
|
|
|
* MarkdownIt.render(src [, env]) -> String |
|
|
|
|
|
* - src (String): source string |
|
|
|
|
|
* - env (Object): optional, enviroment variables |
|
|
|
|
|
* |
|
|
|
|
|
* Render markdown string into html. It does all magic for you :). |
|
|
|
|
|
* |
|
|
|
|
|
* `env` is `{}` by default. It's not used now directly, but you can pass |
|
|
|
|
|
* with it any additional data to plugins. |
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.render = function (src, env) { |
|
|
MarkdownIt.prototype.render = function (src, env) { |
|
|
env = env || {}; |
|
|
env = env || {}; |
|
|
|
|
|
|
|
@ -148,8 +354,13 @@ MarkdownIt.prototype.render = function (src, env) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse content as single string
|
|
|
/** internal |
|
|
//
|
|
|
* MarkdownIt.parseInline(src, env) -> Array |
|
|
|
|
|
* - src (String): source string |
|
|
|
|
|
* - env (Object): enviroment variables |
|
|
|
|
|
* |
|
|
|
|
|
* The same as [[MarkdownIt.parse]] but skip all block rules. |
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.parseInline = function (src, env) { |
|
|
MarkdownIt.prototype.parseInline = function (src, env) { |
|
|
var state = new StateCore(this, src, env); |
|
|
var state = new StateCore(this, src, env); |
|
|
|
|
|
|
|
@ -160,8 +371,14 @@ MarkdownIt.prototype.parseInline = function (src, env) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Render single string, without wrapping it to paragraphs
|
|
|
/** |
|
|
//
|
|
|
* MarkdownIt.renderInline(src [, env]) -> String |
|
|
|
|
|
* - src (String): source string |
|
|
|
|
|
* - env (Object): optional, enviroment variables |
|
|
|
|
|
* |
|
|
|
|
|
* Similar to [[MarkdownIt.render]] but for single paragraph content. Result |
|
|
|
|
|
* will NOT be wrapped into `<p>` tags. |
|
|
|
|
|
**/ |
|
|
MarkdownIt.prototype.renderInline = function (src, env) { |
|
|
MarkdownIt.prototype.renderInline = function (src, env) { |
|
|
env = env || {}; |
|
|
env = env || {}; |
|
|
|
|
|
|
|
|