|
|
|
// Main perser class
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
|
|
var assign = require('./common/utils').assign;
|
|
|
|
var isString = require('./common/utils').isString;
|
|
|
|
var Renderer = require('./renderer');
|
|
|
|
var ParserCore = require('./parser_core');
|
|
|
|
var ParserBlock = require('./parser_block');
|
|
|
|
var ParserInline = require('./parser_inline');
|
|
|
|
var Ruler = require('./ruler');
|
|
|
|
|
|
|
|
var config = {
|
|
|
|
'default': require('./configs/default'),
|
|
|
|
full: require('./configs/full'),
|
|
|
|
commonmark: require('./configs/commonmark')
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
function StateCore(self, src, env) {
|
|
|
|
this.src = src;
|
|
|
|
this.env = env;
|
|
|
|
this.options = self.options;
|
|
|
|
this.tokens = [];
|
|
|
|
this.inlineMode = false;
|
|
|
|
|
|
|
|
this.inline = self.inline;
|
|
|
|
this.block = self.block;
|
|
|
|
this.renderer = self.renderer;
|
|
|
|
this.typographer = self.typographer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Main class
|
|
|
|
//
|
|
|
|
function Remarkable(presetName, options) {
|
|
|
|
if (!options) {
|
|
|
|
if (!isString(presetName)) {
|
|
|
|
options = presetName || {};
|
|
|
|
presetName = 'default';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.inline = new ParserInline();
|
|
|
|
this.block = new ParserBlock();
|
|
|
|
this.core = new ParserCore();
|
|
|
|
this.renderer = new Renderer();
|
|
|
|
this.ruler = new Ruler();
|
|
|
|
|
|
|
|
this.options = {};
|
|
|
|
this.configure(config[presetName]);
|
|
|
|
|
|
|
|
if (options) { this.set(options); }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set options, if you did not passed those to constructor
|
|
|
|
//
|
|
|
|
Remarkable.prototype.set = function (options) {
|
|
|
|
assign(this.options, options);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Batch loader for components rules states & options
|
|
|
|
//
|
|
|
|
Remarkable.prototype.configure = function (presets) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
if (!presets) { throw new Error('Wrong `remarkable` preset, check name/content'); }
|
|
|
|
|
|
|
|
if (presets.options) { self.set(presets.options); }
|
|
|
|
|
|
|
|
if (presets.components) {
|
|
|
|
Object.keys(presets.components).forEach(function (name) {
|
|
|
|
if (presets.components[name].rules) {
|
|
|
|
self[name].ruler.enable(presets.components[name].rules, true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Sugar for curried plugins init:
|
|
|
|
//
|
|
|
|
// var md = new Remarkable();
|
|
|
|
//
|
|
|
|
// md.use(plugin1)
|
|
|
|
// .use(plugin2, opts)
|
|
|
|
// .use(plugin3);
|
|
|
|
//
|
|
|
|
Remarkable.prototype.use = function (plugin, opts) {
|
|
|
|
plugin(this, opts);
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Parse input string, returns tokens array. Modify `env` with
|
|
|
|
// definitions data.
|
|
|
|
//
|
|
|
|
Remarkable.prototype.parse = function (src, env) {
|
|
|
|
var state = new StateCore(this, src, env);
|
|
|
|
|
|
|
|
this.core.process(state);
|
|
|
|
|
|
|
|
return state.tokens;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Main method that does all magic :)
|
|
|
|
//
|
|
|
|
Remarkable.prototype.render = function (src, env) {
|
|
|
|
env = env || {};
|
|
|
|
|
|
|
|
return this.renderer.render(this.parse(src, env), this.options, env);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Parse content as single string
|
|
|
|
//
|
|
|
|
Remarkable.prototype.parseInline = function (src, env) {
|
|
|
|
var state = new StateCore(this, src, env);
|
|
|
|
|
|
|
|
state.inlineMode = true;
|
|
|
|
this.core.process(state);
|
|
|
|
|
|
|
|
return state.tokens;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Render single string, without wrapping it to paragraphs
|
|
|
|
//
|
|
|
|
Remarkable.prototype.renderInline = function (src, env) {
|
|
|
|
env = env || {};
|
|
|
|
|
|
|
|
return this.renderer.render(this.parseInline(src, env), this.options, env);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = Remarkable;
|
|
|
|
|
|
|
|
// Expose helpers, useful for custom renderer functions
|
|
|
|
module.exports.utils = require('./common/utils');
|