marked 2.0.6 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/marked.esm.js +222 -63
- package/lib/marked.js +292 -93
- package/marked.min.js +1 -1
- package/package.json +15 -15
- package/src/Lexer.js +69 -7
- package/src/Parser.js +25 -2
- package/src/Tokenizer.js +15 -14
- package/src/defaults.js +1 -0
- package/src/marked.js +108 -36
- package/src/rules.js +3 -3
package/src/marked.js
CHANGED
|
@@ -141,46 +141,114 @@ marked.defaults = defaults;
|
|
|
141
141
|
* Use Extension
|
|
142
142
|
*/
|
|
143
143
|
|
|
144
|
-
marked.use = function(
|
|
145
|
-
const opts = merge({},
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
144
|
+
marked.use = function(...args) {
|
|
145
|
+
const opts = merge({}, ...args);
|
|
146
|
+
const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} };
|
|
147
|
+
let hasExtensions;
|
|
148
|
+
|
|
149
|
+
args.forEach((pack) => {
|
|
150
|
+
// ==-- Parse "addon" extensions --== //
|
|
151
|
+
if (pack.extensions) {
|
|
152
|
+
hasExtensions = true;
|
|
153
|
+
pack.extensions.forEach((ext) => {
|
|
154
|
+
if (!ext.name) {
|
|
155
|
+
throw new Error('extension name required');
|
|
154
156
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
if (ext.renderer) { // Renderer extensions
|
|
158
|
+
const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null;
|
|
159
|
+
if (prevRenderer) {
|
|
160
|
+
// Replace extension with func to run new extension but fall back if false
|
|
161
|
+
extensions.renderers[ext.name] = function(...args) {
|
|
162
|
+
let ret = ext.renderer.apply(this, args);
|
|
163
|
+
if (ret === false) {
|
|
164
|
+
ret = prevRenderer.apply(this, args);
|
|
165
|
+
}
|
|
166
|
+
return ret;
|
|
167
|
+
};
|
|
168
|
+
} else {
|
|
169
|
+
extensions.renderers[ext.name] = ext.renderer;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (ext.tokenizer) { // Tokenizer Extensions
|
|
173
|
+
if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
|
|
174
|
+
throw new Error("extension level must be 'block' or 'inline'");
|
|
175
|
+
}
|
|
176
|
+
if (extensions[ext.level]) {
|
|
177
|
+
extensions[ext.level].unshift(ext.tokenizer);
|
|
178
|
+
} else {
|
|
179
|
+
extensions[ext.level] = [ext.tokenizer];
|
|
180
|
+
}
|
|
181
|
+
if (ext.start) { // Function to check for start of token
|
|
182
|
+
if (ext.level === 'block') {
|
|
183
|
+
if (extensions.startBlock) {
|
|
184
|
+
extensions.startBlock.push(ext.start);
|
|
185
|
+
} else {
|
|
186
|
+
extensions.startBlock = [ext.start];
|
|
187
|
+
}
|
|
188
|
+
} else if (ext.level === 'inline') {
|
|
189
|
+
if (extensions.startInline) {
|
|
190
|
+
extensions.startInline.push(ext.start);
|
|
191
|
+
} else {
|
|
192
|
+
extensions.startInline = [ext.start];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (ext.childTokens) { // Child tokens to be visited by walkTokens
|
|
198
|
+
extensions.childTokens[ext.name] = ext.childTokens;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
157
201
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
ret
|
|
202
|
+
|
|
203
|
+
// ==-- Parse "overwrite" extensions --== //
|
|
204
|
+
if (pack.renderer) {
|
|
205
|
+
const renderer = marked.defaults.renderer || new Renderer();
|
|
206
|
+
for (const prop in pack.renderer) {
|
|
207
|
+
const prevRenderer = renderer[prop];
|
|
208
|
+
// Replace renderer with func to run extension, but fall back if false
|
|
209
|
+
renderer[prop] = (...args) => {
|
|
210
|
+
let ret = pack.renderer[prop].apply(renderer, args);
|
|
211
|
+
if (ret === false) {
|
|
212
|
+
ret = prevRenderer.apply(renderer, args);
|
|
213
|
+
}
|
|
214
|
+
return ret;
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
opts.renderer = renderer;
|
|
218
|
+
}
|
|
219
|
+
if (pack.tokenizer) {
|
|
220
|
+
const tokenizer = marked.defaults.tokenizer || new Tokenizer();
|
|
221
|
+
for (const prop in pack.tokenizer) {
|
|
222
|
+
const prevTokenizer = tokenizer[prop];
|
|
223
|
+
// Replace tokenizer with func to run extension, but fall back if false
|
|
224
|
+
tokenizer[prop] = (...args) => {
|
|
225
|
+
let ret = pack.tokenizer[prop].apply(tokenizer, args);
|
|
226
|
+
if (ret === false) {
|
|
227
|
+
ret = prevTokenizer.apply(tokenizer, args);
|
|
228
|
+
}
|
|
229
|
+
return ret;
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
opts.tokenizer = tokenizer;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// ==-- Parse WalkTokens extensions --== //
|
|
236
|
+
if (pack.walkTokens) {
|
|
237
|
+
const walkTokens = marked.defaults.walkTokens;
|
|
238
|
+
opts.walkTokens = (token) => {
|
|
239
|
+
pack.walkTokens.call(this, token);
|
|
240
|
+
if (walkTokens) {
|
|
241
|
+
walkTokens(token);
|
|
168
242
|
}
|
|
169
|
-
return ret;
|
|
170
243
|
};
|
|
171
244
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
walkTokens(token);
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
marked.setOptions(opts);
|
|
245
|
+
|
|
246
|
+
if (hasExtensions) {
|
|
247
|
+
opts.extensions = extensions;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
marked.setOptions(opts);
|
|
251
|
+
});
|
|
184
252
|
};
|
|
185
253
|
|
|
186
254
|
/**
|
|
@@ -207,7 +275,11 @@ marked.walkTokens = function(tokens, callback) {
|
|
|
207
275
|
break;
|
|
208
276
|
}
|
|
209
277
|
default: {
|
|
210
|
-
if (token.
|
|
278
|
+
if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions
|
|
279
|
+
marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) {
|
|
280
|
+
marked.walkTokens(token[childTokens], callback);
|
|
281
|
+
});
|
|
282
|
+
} else if (token.tokens) {
|
|
211
283
|
marked.walkTokens(token.tokens, callback);
|
|
212
284
|
}
|
|
213
285
|
}
|
package/src/rules.js
CHANGED
|
@@ -176,9 +176,9 @@ const inline = {
|
|
|
176
176
|
emStrong: {
|
|
177
177
|
lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
|
|
178
178
|
// (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
|
|
179
|
-
// () Skip other delimiter (1) #***
|
|
180
|
-
rDelimAst: /\_\_[^_]*?\*[^_]*?\_\_|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
|
|
181
|
-
rDelimUnd: /\*\*[
|
|
179
|
+
// () Skip other delimiter (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
|
|
180
|
+
rDelimAst: /\_\_[^_*]*?\*[^_*]*?\_\_|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
|
|
181
|
+
rDelimUnd: /\*\*[^_*]*?\_[^_*]*?\*\*|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
|
|
182
182
|
},
|
|
183
183
|
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
|
|
184
184
|
br: /^( {2,}|\\)\n(?!\s*$)/,
|