// Main perser class 'use strict'; var assign = require('./common/utils').assign; var isString = require('./common/utils').isString; var Renderer = require('./renderer'); var ParserBlock = require('./parser_block'); var ParserInline = require('./parser_inline'); var Typographer = require('./typographer'); var Ruler = require('./ruler'); var config = { 'default': require('./configs/default'), full: require('./configs/full'), commonmark: require('./configs/commonmark') }; var _rules = [ [ 'block', require('./rules_core/block') ], [ 'references', require('./rules_core/references') ], [ 'inline', require('./rules_core/inline') ], [ 'linkify', require('./rules_core/linkify') ], [ 'typographer', require('./rules_core/typographer') ] ]; function StateCore(self, src, env) { this.src = src; this.env = env; this.options = self.options; this.tokens = []; 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.renderer = new Renderer(); this.ruler = new Ruler(); this.typographer = new Typographer(); this.options = {}; this.configure(config[presetName]); if (options) { this.set(options); } for (var i = 0; i < _rules.length; i++) { this.ruler.push(_rules[i][0], _rules[i][1]); } } // 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 config name'); } 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); } if (presets.components[name].options) { self[name].set(presets.components[name].options); } }); } }; // 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 i, len, rules = this.ruler.getRules(''), state = new StateCore(this, src, env); len = rules.length; for (i = 0; i < len; i++) { rules[i](state); } return state.tokens; }; // Main method that does all magic :) // Remarkable.prototype.render = function (src) { var env = { references: {} }; return this.renderer.render(this.parse(src, env), this.options, env); }; module.exports = Remarkable;