aboutsummaryrefslogtreecommitdiff
path: root/node_modules/markdown-it/lib/ruler.js
diff options
context:
space:
mode:
authorruki <waruqi@gmail.com>2018-11-08 00:38:48 +0800
committerruki <waruqi@gmail.com>2018-11-07 21:53:09 +0800
commit26105034da4fcce7ac883c899d781f016559310d (patch)
treec459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/markdown-it/lib/ruler.js
parent2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff)
downloadxmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz
xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip
switch to vuepress
Diffstat (limited to 'node_modules/markdown-it/lib/ruler.js')
-rw-r--r--node_modules/markdown-it/lib/ruler.js352
1 files changed, 352 insertions, 0 deletions
diff --git a/node_modules/markdown-it/lib/ruler.js b/node_modules/markdown-it/lib/ruler.js
new file mode 100644
index 00000000..9ad5da4a
--- /dev/null
+++ b/node_modules/markdown-it/lib/ruler.js
@@ -0,0 +1,352 @@
+/**
+ * class Ruler
+ *
+ * Helper class, used by [[MarkdownIt#core]], [[MarkdownIt#block]] and
+ * [[MarkdownIt#inline]] to manage sequences of functions (rules):
+ *
+ * - keep rules in defined order
+ * - assign the name to each rule
+ * - enable/disable rules
+ * - add/replace rules
+ * - allow assign rules to additional named chains (in the same)
+ * - cacheing lists of active rules
+ *
+ * You will not need use this class directly until write plugins. For simple
+ * rules control use [[MarkdownIt.disable]], [[MarkdownIt.enable]] and
+ * [[MarkdownIt.use]].
+ **/
+'use strict';
+
+
+/**
+ * new Ruler()
+ **/
+function Ruler() {
+ // List of added rules. Each element is:
+ //
+ // {
+ // name: XXX,
+ // enabled: Boolean,
+ // fn: Function(),
+ // alt: [ name2, name3 ]
+ // }
+ //
+ this.__rules__ = [];
+
+ // Cached rule chains.
+ //
+ // First level - chain name, '' for default.
+ // Second level - diginal anchor for fast filtering by charcodes.
+ //
+ this.__cache__ = null;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper methods, should not be used directly
+
+
+// Find rule index by name
+//
+Ruler.prototype.__find__ = function (name) {
+ for (var i = 0; i < this.__rules__.length; i++) {
+ if (this.__rules__[i].name === name) {
+ return i;
+ }
+ }
+ return -1;
+};
+
+
+// Build rules lookup cache
+//
+Ruler.prototype.__compile__ = function () {
+ var self = this;
+ var chains = [ '' ];
+
+ // collect unique names
+ self.__rules__.forEach(function (rule) {
+ if (!rule.enabled) { return; }
+
+ rule.alt.forEach(function (altName) {
+ if (chains.indexOf(altName) < 0) {
+ chains.push(altName);
+ }
+ });
+ });
+
+ self.__cache__ = {};
+
+ chains.forEach(function (chain) {
+ self.__cache__[chain] = [];
+ self.__rules__.forEach(function (rule) {
+ if (!rule.enabled) { return; }
+
+ if (chain && rule.alt.indexOf(chain) < 0) { return; }
+
+ self.__cache__[chain].push(rule.fn);
+ });
+ });
+};
+
+
+/**
+ * Ruler.at(name, fn [, options])
+ * - name (String): rule name to replace.
+ * - fn (Function): new rule function.
+ * - options (Object): new rule options (not mandatory).
+ *
+ * Replace rule by name with new function & options. Throws error if name not
+ * found.
+ *
+ * ##### Options:
+ *
+ * - __alt__ - array with names of "alternate" chains.
+ *
+ * ##### Example
+ *
+ * Replace existing typographer replacement rule with new one:
+ *
+ * ```javascript
+ * var md = require('markdown-it')();
+ *
+ * md.core.ruler.at('replacements', function replace(state) {
+ * //...
+ * });
+ * ```
+ **/
+Ruler.prototype.at = function (name, fn, options) {
+ var index = this.__find__(name);
+ var opt = options || {};
+
+ if (index === -1) { throw new Error('Parser rule not found: ' + name); }
+
+ this.__rules__[index].fn = fn;
+ this.__rules__[index].alt = opt.alt || [];
+ this.__cache__ = null;
+};
+
+
+/**
+ * Ruler.before(beforeName, ruleName, fn [, options])
+ * - beforeName (String): new rule will be added before this one.
+ * - ruleName (String): name of added rule.
+ * - fn (Function): rule function.
+ * - options (Object): rule options (not mandatory).
+ *
+ * Add new rule to chain before one with given name. See also
+ * [[Ruler.after]], [[Ruler.push]].
+ *
+ * ##### Options:
+ *
+ * - __alt__ - array with names of "alternate" chains.
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * var md = require('markdown-it')();
+ *
+ * md.block.ruler.before('paragraph', 'my_rule', function replace(state) {
+ * //...
+ * });
+ * ```
+ **/
+Ruler.prototype.before = function (beforeName, ruleName, fn, options) {
+ var index = this.__find__(beforeName);
+ var opt = options || {};
+
+ if (index === -1) { throw new Error('Parser rule not found: ' + beforeName); }
+
+ this.__rules__.splice(index, 0, {
+ name: ruleName,
+ enabled: true,
+ fn: fn,
+ alt: opt.alt || []
+ });
+
+ this.__cache__ = null;
+};
+
+
+/**
+ * Ruler.after(afterName, ruleName, fn [, options])
+ * - afterName (String): new rule will be added after this one.
+ * - ruleName (String): name of added rule.
+ * - fn (Function): rule function.
+ * - options (Object): rule options (not mandatory).
+ *
+ * Add new rule to chain after one with given name. See also
+ * [[Ruler.before]], [[Ruler.push]].
+ *
+ * ##### Options:
+ *
+ * - __alt__ - array with names of "alternate" chains.
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * var md = require('markdown-it')();
+ *
+ * md.inline.ruler.after('text', 'my_rule', function replace(state) {
+ * //...
+ * });
+ * ```
+ **/
+Ruler.prototype.after = function (afterName, ruleName, fn, options) {
+ var index = this.__find__(afterName);
+ var opt = options || {};
+
+ if (index === -1) { throw new Error('Parser rule not found: ' + afterName); }
+
+ this.__rules__.splice(index + 1, 0, {
+ name: ruleName,
+ enabled: true,
+ fn: fn,
+ alt: opt.alt || []
+ });
+
+ this.__cache__ = null;
+};
+
+/**
+ * Ruler.push(ruleName, fn [, options])
+ * - ruleName (String): name of added rule.
+ * - fn (Function): rule function.
+ * - options (Object): rule options (not mandatory).
+ *
+ * Push new rule to the end of chain. See also
+ * [[Ruler.before]], [[Ruler.after]].
+ *
+ * ##### Options:
+ *
+ * - __alt__ - array with names of "alternate" chains.
+ *
+ * ##### Example
+ *
+ * ```javascript
+ * var md = require('markdown-it')();
+ *
+ * md.core.ruler.push('my_rule', function replace(state) {
+ * //...
+ * });
+ * ```
+ **/
+Ruler.prototype.push = function (ruleName, fn, options) {
+ var opt = options || {};
+
+ this.__rules__.push({
+ name: ruleName,
+ enabled: true,
+ fn: fn,
+ alt: opt.alt || []
+ });
+
+ this.__cache__ = null;
+};
+
+
+/**
+ * Ruler.enable(list [, ignoreInvalid]) -> Array
+ * - list (String|Array): list of rule names to enable.
+ * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
+ *
+ * Enable rules with given names. If any rule name not found - throw Error.
+ * Errors can be disabled by second param.
+ *
+ * Returns list of found rule names (if no exception happened).
+ *
+ * See also [[Ruler.disable]], [[Ruler.enableOnly]].
+ **/
+Ruler.prototype.enable = function (list, ignoreInvalid) {
+ if (!Array.isArray(list)) { list = [ list ]; }
+
+ var result = [];
+
+ // Search by name and enable
+ list.forEach(function (name) {
+ var idx = this.__find__(name);
+
+ if (idx < 0) {
+ if (ignoreInvalid) { return; }
+ throw new Error('Rules manager: invalid rule name ' + name);
+ }
+ this.__rules__[idx].enabled = true;
+ result.push(name);
+ }, this);
+
+ this.__cache__ = null;
+ return result;
+};
+
+
+/**
+ * Ruler.enableOnly(list [, ignoreInvalid])
+ * - list (String|Array): list of rule names to enable (whitelist).
+ * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
+ *
+ * Enable rules with given names, and disable everything else. If any rule name
+ * not found - throw Error. Errors can be disabled by second param.
+ *
+ * See also [[Ruler.disable]], [[Ruler.enable]].
+ **/
+Ruler.prototype.enableOnly = function (list, ignoreInvalid) {
+ if (!Array.isArray(list)) { list = [ list ]; }
+
+ this.__rules__.forEach(function (rule) { rule.enabled = false; });
+
+ this.enable(list, ignoreInvalid);
+};
+
+
+/**
+ * Ruler.disable(list [, ignoreInvalid]) -> Array
+ * - list (String|Array): list of rule names to disable.
+ * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
+ *
+ * Disable rules with given names. If any rule name not found - throw Error.
+ * Errors can be disabled by second param.
+ *
+ * Returns list of found rule names (if no exception happened).
+ *
+ * See also [[Ruler.enable]], [[Ruler.enableOnly]].
+ **/
+Ruler.prototype.disable = function (list, ignoreInvalid) {
+ if (!Array.isArray(list)) { list = [ list ]; }
+
+ var result = [];
+
+ // Search by name and disable
+ list.forEach(function (name) {
+ var idx = this.__find__(name);
+
+ if (idx < 0) {
+ if (ignoreInvalid) { return; }
+ throw new Error('Rules manager: invalid rule name ' + name);
+ }
+ this.__rules__[idx].enabled = false;
+ result.push(name);
+ }, this);
+
+ this.__cache__ = null;
+ return result;
+};
+
+
+/**
+ * Ruler.getRules(chainName) -> Array
+ *
+ * Return array of active functions (rules) for given chain name. It analyzes
+ * rules configuration, compiles caches if not exists and returns result.
+ *
+ * Default chain name is `''` (empty string). It can't be skipped. That's
+ * done intentionally, to keep signature monomorphic for high speed.
+ **/
+Ruler.prototype.getRules = function (chainName) {
+ if (this.__cache__ === null) {
+ this.__compile__();
+ }
+
+ // Chain can be empty, if rules disabled. But we still have to return Array.
+ return this.__cache__[chainName] || [];
+};
+
+module.exports = Ruler;