summaryrefslogtreecommitdiff
path: root/node_modules/marked/src/marked.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/marked/src/marked.js')
-rw-r--r--node_modules/marked/src/marked.js416
1 files changed, 416 insertions, 0 deletions
diff --git a/node_modules/marked/src/marked.js b/node_modules/marked/src/marked.js
new file mode 100644
index 0000000..36ec040
--- /dev/null
+++ b/node_modules/marked/src/marked.js
@@ -0,0 +1,416 @@
+import { Lexer } from './Lexer.js';
+import { Parser } from './Parser.js';
+import { Tokenizer } from './Tokenizer.js';
+import { Renderer } from './Renderer.js';
+import { TextRenderer } from './TextRenderer.js';
+import { Slugger } from './Slugger.js';
+import { Hooks } from './Hooks.js';
+import {
+ checkSanitizeDeprecation,
+ escape
+} from './helpers.js';
+import {
+ getDefaults,
+ changeDefaults,
+ defaults
+} from './defaults.js';
+
+function onError(silent, async, callback) {
+ return (e) => {
+ e.message += '\nPlease report this to https://github.com/markedjs/marked.';
+
+ if (silent) {
+ const msg = '<p>An error occurred:</p><pre>'
+ + escape(e.message + '', true)
+ + '</pre>';
+ if (async) {
+ return Promise.resolve(msg);
+ }
+ if (callback) {
+ callback(null, msg);
+ return;
+ }
+ return msg;
+ }
+
+ if (async) {
+ return Promise.reject(e);
+ }
+ if (callback) {
+ callback(e);
+ return;
+ }
+ throw e;
+ };
+}
+
+function parseMarkdown(lexer, parser) {
+ return (src, opt, callback) => {
+ if (typeof opt === 'function') {
+ callback = opt;
+ opt = null;
+ }
+
+ const origOpt = { ...opt };
+ opt = { ...marked.defaults, ...origOpt };
+ const throwError = onError(opt.silent, opt.async, callback);
+
+ // throw error in case of non string input
+ if (typeof src === 'undefined' || src === null) {
+ return throwError(new Error('marked(): input parameter is undefined or null'));
+ }
+ if (typeof src !== 'string') {
+ return throwError(new Error('marked(): input parameter is of type '
+ + Object.prototype.toString.call(src) + ', string expected'));
+ }
+
+ checkSanitizeDeprecation(opt);
+
+ if (opt.hooks) {
+ opt.hooks.options = opt;
+ }
+
+ if (callback) {
+ const highlight = opt.highlight;
+ let tokens;
+
+ try {
+ if (opt.hooks) {
+ src = opt.hooks.preprocess(src);
+ }
+ tokens = lexer(src, opt);
+ } catch (e) {
+ return throwError(e);
+ }
+
+ const done = function(err) {
+ let out;
+
+ if (!err) {
+ try {
+ if (opt.walkTokens) {
+ marked.walkTokens(tokens, opt.walkTokens);
+ }
+ out = parser(tokens, opt);
+ if (opt.hooks) {
+ out = opt.hooks.postprocess(out);
+ }
+ } catch (e) {
+ err = e;
+ }
+ }
+
+ opt.highlight = highlight;
+
+ return err
+ ? throwError(err)
+ : callback(null, out);
+ };
+
+ if (!highlight || highlight.length < 3) {
+ return done();
+ }
+
+ delete opt.highlight;
+
+ if (!tokens.length) return done();
+
+ let pending = 0;
+ marked.walkTokens(tokens, function(token) {
+ if (token.type === 'code') {
+ pending++;
+ setTimeout(() => {
+ highlight(token.text, token.lang, function(err, code) {
+ if (err) {
+ return done(err);
+ }
+ if (code != null && code !== token.text) {
+ token.text = code;
+ token.escaped = true;
+ }
+
+ pending--;
+ if (pending === 0) {
+ done();
+ }
+ });
+ }, 0);
+ }
+ });
+
+ if (pending === 0) {
+ done();
+ }
+
+ return;
+ }
+
+ if (opt.async) {
+ return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
+ .then(src => lexer(src, opt))
+ .then(tokens => opt.walkTokens ? Promise.all(marked.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
+ .then(tokens => parser(tokens, opt))
+ .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
+ .catch(throwError);
+ }
+
+ try {
+ if (opt.hooks) {
+ src = opt.hooks.preprocess(src);
+ }
+ const tokens = lexer(src, opt);
+ if (opt.walkTokens) {
+ marked.walkTokens(tokens, opt.walkTokens);
+ }
+ let html = parser(tokens, opt);
+ if (opt.hooks) {
+ html = opt.hooks.postprocess(html);
+ }
+ return html;
+ } catch (e) {
+ return throwError(e);
+ }
+ };
+}
+
+/**
+ * Marked
+ */
+export function marked(src, opt, callback) {
+ return parseMarkdown(Lexer.lex, Parser.parse)(src, opt, callback);
+}
+
+/**
+ * Options
+ */
+
+marked.options =
+marked.setOptions = function(opt) {
+ marked.defaults = { ...marked.defaults, ...opt };
+ changeDefaults(marked.defaults);
+ return marked;
+};
+
+marked.getDefaults = getDefaults;
+
+marked.defaults = defaults;
+
+/**
+ * Use Extension
+ */
+
+marked.use = function(...args) {
+ const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} };
+
+ args.forEach((pack) => {
+ // copy options to new object
+ const opts = { ...pack };
+
+ // set async to true if it was set to true before
+ opts.async = marked.defaults.async || opts.async || false;
+
+ // ==-- Parse "addon" extensions --== //
+ if (pack.extensions) {
+ pack.extensions.forEach((ext) => {
+ if (!ext.name) {
+ throw new Error('extension name required');
+ }
+ if (ext.renderer) { // Renderer extensions
+ const prevRenderer = extensions.renderers[ext.name];
+ if (prevRenderer) {
+ // Replace extension with func to run new extension but fall back if false
+ extensions.renderers[ext.name] = function(...args) {
+ let ret = ext.renderer.apply(this, args);
+ if (ret === false) {
+ ret = prevRenderer.apply(this, args);
+ }
+ return ret;
+ };
+ } else {
+ extensions.renderers[ext.name] = ext.renderer;
+ }
+ }
+ if (ext.tokenizer) { // Tokenizer Extensions
+ if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
+ throw new Error("extension level must be 'block' or 'inline'");
+ }
+ if (extensions[ext.level]) {
+ extensions[ext.level].unshift(ext.tokenizer);
+ } else {
+ extensions[ext.level] = [ext.tokenizer];
+ }
+ if (ext.start) { // Function to check for start of token
+ if (ext.level === 'block') {
+ if (extensions.startBlock) {
+ extensions.startBlock.push(ext.start);
+ } else {
+ extensions.startBlock = [ext.start];
+ }
+ } else if (ext.level === 'inline') {
+ if (extensions.startInline) {
+ extensions.startInline.push(ext.start);
+ } else {
+ extensions.startInline = [ext.start];
+ }
+ }
+ }
+ }
+ if (ext.childTokens) { // Child tokens to be visited by walkTokens
+ extensions.childTokens[ext.name] = ext.childTokens;
+ }
+ });
+ opts.extensions = extensions;
+ }
+
+ // ==-- Parse "overwrite" extensions --== //
+ if (pack.renderer) {
+ const renderer = marked.defaults.renderer || new Renderer();
+ for (const prop in pack.renderer) {
+ const prevRenderer = renderer[prop];
+ // Replace renderer with func to run extension, but fall back if false
+ renderer[prop] = (...args) => {
+ let ret = pack.renderer[prop].apply(renderer, args);
+ if (ret === false) {
+ ret = prevRenderer.apply(renderer, args);
+ }
+ return ret;
+ };
+ }
+ opts.renderer = renderer;
+ }
+ if (pack.tokenizer) {
+ const tokenizer = marked.defaults.tokenizer || new Tokenizer();
+ for (const prop in pack.tokenizer) {
+ const prevTokenizer = tokenizer[prop];
+ // Replace tokenizer with func to run extension, but fall back if false
+ tokenizer[prop] = (...args) => {
+ let ret = pack.tokenizer[prop].apply(tokenizer, args);
+ if (ret === false) {
+ ret = prevTokenizer.apply(tokenizer, args);
+ }
+ return ret;
+ };
+ }
+ opts.tokenizer = tokenizer;
+ }
+
+ // ==-- Parse Hooks extensions --== //
+ if (pack.hooks) {
+ const hooks = marked.defaults.hooks || new Hooks();
+ for (const prop in pack.hooks) {
+ const prevHook = hooks[prop];
+ if (Hooks.passThroughHooks.has(prop)) {
+ hooks[prop] = (arg) => {
+ if (marked.defaults.async) {
+ return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then(ret => {
+ return prevHook.call(hooks, ret);
+ });
+ }
+
+ const ret = pack.hooks[prop].call(hooks, arg);
+ return prevHook.call(hooks, ret);
+ };
+ } else {
+ hooks[prop] = (...args) => {
+ let ret = pack.hooks[prop].apply(hooks, args);
+ if (ret === false) {
+ ret = prevHook.apply(hooks, args);
+ }
+ return ret;
+ };
+ }
+ }
+ opts.hooks = hooks;
+ }
+
+ // ==-- Parse WalkTokens extensions --== //
+ if (pack.walkTokens) {
+ const walkTokens = marked.defaults.walkTokens;
+ opts.walkTokens = function(token) {
+ let values = [];
+ values.push(pack.walkTokens.call(this, token));
+ if (walkTokens) {
+ values = values.concat(walkTokens.call(this, token));
+ }
+ return values;
+ };
+ }
+
+ marked.setOptions(opts);
+ });
+};
+
+/**
+ * Run callback for every token
+ */
+
+marked.walkTokens = function(tokens, callback) {
+ let values = [];
+ for (const token of tokens) {
+ values = values.concat(callback.call(marked, token));
+ switch (token.type) {
+ case 'table': {
+ for (const cell of token.header) {
+ values = values.concat(marked.walkTokens(cell.tokens, callback));
+ }
+ for (const row of token.rows) {
+ for (const cell of row) {
+ values = values.concat(marked.walkTokens(cell.tokens, callback));
+ }
+ }
+ break;
+ }
+ case 'list': {
+ values = values.concat(marked.walkTokens(token.items, callback));
+ break;
+ }
+ default: {
+ if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions
+ marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) {
+ values = values.concat(marked.walkTokens(token[childTokens], callback));
+ });
+ } else if (token.tokens) {
+ values = values.concat(marked.walkTokens(token.tokens, callback));
+ }
+ }
+ }
+ }
+ return values;
+};
+
+/**
+ * Parse Inline
+ * @param {string} src
+ */
+marked.parseInline = parseMarkdown(Lexer.lexInline, Parser.parseInline);
+
+/**
+ * Expose
+ */
+marked.Parser = Parser;
+marked.parser = Parser.parse;
+marked.Renderer = Renderer;
+marked.TextRenderer = TextRenderer;
+marked.Lexer = Lexer;
+marked.lexer = Lexer.lex;
+marked.Tokenizer = Tokenizer;
+marked.Slugger = Slugger;
+marked.Hooks = Hooks;
+marked.parse = marked;
+
+export const options = marked.options;
+export const setOptions = marked.setOptions;
+export const use = marked.use;
+export const walkTokens = marked.walkTokens;
+export const parseInline = marked.parseInline;
+export const parse = marked;
+export const parser = Parser.parse;
+export const lexer = Lexer.lex;
+export { defaults, getDefaults } from './defaults.js';
+export { Lexer } from './Lexer.js';
+export { Parser } from './Parser.js';
+export { Tokenizer } from './Tokenizer.js';
+export { Renderer } from './Renderer.js';
+export { TextRenderer } from './TextRenderer.js';
+export { Slugger } from './Slugger.js';
+export { Hooks } from './Hooks.js';