UNPKG

4.18 kBJavaScriptView Raw
1const Lexer = require('./Lexer.js');
2const Parser = require('./Parser.js');
3const Tokenizer = require('./Tokenizer.js');
4const Renderer = require('./Renderer.js');
5const TextRenderer = require('./TextRenderer.js');
6const Slugger = require('./Slugger.js');
7const {
8 merge,
9 checkSanitizeDeprecation,
10 escape
11} = require('./helpers.js');
12const {
13 getDefaults,
14 changeDefaults,
15 defaults
16} = require('./defaults.js');
17
18/**
19 * Marked
20 */
21function marked(src, opt, callback) {
22 // throw error in case of non string input
23 if (typeof src === 'undefined' || src === null) {
24 throw new Error('marked(): input parameter is undefined or null');
25 }
26 if (typeof src !== 'string') {
27 throw new Error('marked(): input parameter is of type '
28 + Object.prototype.toString.call(src) + ', string expected');
29 }
30
31 if (callback || typeof opt === 'function') {
32 if (!callback) {
33 callback = opt;
34 opt = null;
35 }
36
37 opt = merge({}, marked.defaults, opt || {});
38 checkSanitizeDeprecation(opt);
39 const highlight = opt.highlight;
40 let tokens,
41 pending,
42 i = 0;
43
44 try {
45 tokens = Lexer.lex(src, opt);
46 } catch (e) {
47 return callback(e);
48 }
49
50 pending = tokens.length;
51
52 const done = function(err) {
53 if (err) {
54 opt.highlight = highlight;
55 return callback(err);
56 }
57
58 let out;
59
60 try {
61 out = Parser.parse(tokens, opt);
62 } catch (e) {
63 err = e;
64 }
65
66 opt.highlight = highlight;
67
68 return err
69 ? callback(err)
70 : callback(null, out);
71 };
72
73 if (!highlight || highlight.length < 3) {
74 return done();
75 }
76
77 delete opt.highlight;
78
79 if (!pending) return done();
80
81 for (; i < tokens.length; i++) {
82 (function(token) {
83 if (token.type !== 'code') {
84 return --pending || done();
85 }
86 return highlight(token.text, token.lang, function(err, code) {
87 if (err) return done(err);
88 if (code == null || code === token.text) {
89 return --pending || done();
90 }
91 token.text = code;
92 token.escaped = true;
93 --pending || done();
94 });
95 })(tokens[i]);
96 }
97
98 return;
99 }
100 try {
101 opt = merge({}, marked.defaults, opt || {});
102 checkSanitizeDeprecation(opt);
103 return Parser.parse(Lexer.lex(src, opt), opt);
104 } catch (e) {
105 e.message += '\nPlease report this to https://github.com/markedjs/marked.';
106 if ((opt || marked.defaults).silent) {
107 return '<p>An error occurred:</p><pre>'
108 + escape(e.message + '', true)
109 + '</pre>';
110 }
111 throw e;
112 }
113}
114
115/**
116 * Options
117 */
118
119marked.options =
120marked.setOptions = function(opt) {
121 merge(marked.defaults, opt);
122 changeDefaults(marked.defaults);
123 return marked;
124};
125
126marked.getDefaults = getDefaults;
127
128marked.defaults = defaults;
129
130/**
131 * Use Extension
132 */
133
134marked.use = function(extension) {
135 const opts = merge({}, extension);
136 if (extension.renderer) {
137 const renderer = marked.defaults.renderer || new Renderer();
138 for (const prop in extension.renderer) {
139 const prevRenderer = renderer[prop];
140 renderer[prop] = (...args) => {
141 let ret = extension.renderer[prop].apply(renderer, args);
142 if (ret === false) {
143 ret = prevRenderer.apply(renderer, args);
144 }
145 return ret;
146 };
147 }
148 opts.renderer = renderer;
149 }
150 if (extension.tokenizer) {
151 const tokenizer = marked.defaults.tokenizer || new Tokenizer();
152 for (const prop in extension.tokenizer) {
153 const prevTokenizer = tokenizer[prop];
154 tokenizer[prop] = (...args) => {
155 let ret = extension.tokenizer[prop].apply(tokenizer, args);
156 if (ret === false) {
157 ret = prevTokenizer.apply(tokenizer, args);
158 }
159 return ret;
160 };
161 }
162 opts.tokenizer = tokenizer;
163 }
164 marked.setOptions(opts);
165};
166
167/**
168 * Expose
169 */
170
171marked.Parser = Parser;
172marked.parser = Parser.parse;
173
174marked.Renderer = Renderer;
175marked.TextRenderer = TextRenderer;
176
177marked.Lexer = Lexer;
178marked.lexer = Lexer.lex;
179
180marked.Tokenizer = Tokenizer;
181
182marked.Slugger = Slugger;
183
184marked.parse = marked;
185
186module.exports = marked;