tripledoc
Version:
Library to read, create and update documents on a Solid Pod
196 lines (164 loc) • 4.24 kB
JavaScript
'use strict';
/**
* Local dependencies
*/
var assign = require('./common/utils').assign;
var Renderer = require('./renderer');
var ParserCore = require('./parser_core');
var ParserBlock = require('./parser_block');
var ParserInline = require('./parser_inline');
var Ruler = require('./ruler');
/**
* Preset configs
*/
var config = {
'default': require('./configs/default'),
'full': require('./configs/full'),
'commonmark': require('./configs/commonmark')
};
/**
* The `StateCore` class manages state.
*
* @param {Object} `instance` Remarkable instance
* @param {String} `str` Markdown string
* @param {Object} `env`
*/
function StateCore(instance, str, env) {
this.src = str;
this.env = env;
this.options = instance.options;
this.tokens = [];
this.inlineMode = false;
this.inline = instance.inline;
this.block = instance.block;
this.renderer = instance.renderer;
this.typographer = instance.typographer;
}
/**
* The main `Remarkable` class. Create an instance of
* `Remarkable` with a `preset` and/or `options`.
*
* @param {String} `preset` If no preset is given, `default` is used.
* @param {Object} `options`
*/
function Remarkable(preset, options) {
if (typeof preset !== 'string') {
options = preset;
preset = '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[preset]);
this.set(options || {});
}
/**
* Set options as an alternative to passing them
* to the constructor.
*
* ```js
* md.set({typographer: true});
* ```
* @param {Object} `options`
* @api public
*/
Remarkable.prototype.set = function (options) {
assign(this.options, options);
};
/**
* Batch loader for components rules states, and options
*
* @param {Object} `presets`
*/
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);
}
});
}
};
/**
* Use a plugin.
*
* ```js
* var md = new Remarkable();
*
* md.use(plugin1)
* .use(plugin2, opts)
* .use(plugin3);
* ```
*
* @param {Function} `plugin`
* @param {Object} `options`
* @return {Object} `Remarkable` for chaining
*/
Remarkable.prototype.use = function (plugin, options) {
plugin(this, options);
return this;
};
/**
* Parse the input `string` and return a tokens array.
* Modifies `env` with definitions data.
*
* @param {String} `string`
* @param {Object} `env`
* @return {Array} Array of tokens
*/
Remarkable.prototype.parse = function (str, env) {
var state = new StateCore(this, str, env);
this.core.process(state);
return state.tokens;
};
/**
* The main `.render()` method that does all the magic :)
*
* @param {String} `string`
* @param {Object} `env`
* @return {String} Rendered HTML.
*/
Remarkable.prototype.render = function (str, env) {
env = env || {};
return this.renderer.render(this.parse(str, env), this.options, env);
};
/**
* Parse the given content `string` as a single string.
*
* @param {String} `string`
* @param {Object} `env`
* @return {Array} Array of tokens
*/
Remarkable.prototype.parseInline = function (str, env) {
var state = new StateCore(this, str, env);
state.inlineMode = true;
this.core.process(state);
return state.tokens;
};
/**
* Render a single content `string`, without wrapping it
* to paragraphs
*
* @param {String} `str`
* @param {Object} `env`
* @return {String}
*/
Remarkable.prototype.renderInline = function (str, env) {
env = env || {};
return this.renderer.render(this.parseInline(str, env), this.options, env);
};
/**
* Expose `Remarkable`
*/
module.exports = Remarkable;
/**
* Expose `utils`, Useful helper functions for custom
* rendering.
*/
module.exports.utils = require('./common/utils');