1 | const {
|
2 | noopTest,
|
3 | edit,
|
4 | merge
|
5 | } = require('./helpers.js');
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | const block = {
|
11 | newline: /^(?: *(?:\n|$))+/,
|
12 | code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
|
13 | fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,
|
14 | hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
|
15 | heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
|
16 | blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
|
17 | list: /^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?! {0,3}bull )\n*|\s*$)/,
|
18 | html: '^ {0,3}(?:'
|
19 | + '<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)'
|
20 | + '|comment[^\\n]*(\\n+|$)'
|
21 | + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)'
|
22 | + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)'
|
23 | + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)'
|
24 | + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)'
|
25 | + '|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)'
|
26 | + '|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)'
|
27 | + ')',
|
28 | def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
|
29 | nptable: noopTest,
|
30 | table: noopTest,
|
31 | lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
32 |
|
33 |
|
34 | _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,
|
35 | text: /^[^\n]+/
|
36 | };
|
37 |
|
38 | block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
|
39 | block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
|
40 | block.def = edit(block.def)
|
41 | .replace('label', block._label)
|
42 | .replace('title', block._title)
|
43 | .getRegex();
|
44 |
|
45 | block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
|
46 | block.item = /^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/;
|
47 | block.item = edit(block.item, 'gm')
|
48 | .replace(/bull/g, block.bullet)
|
49 | .getRegex();
|
50 |
|
51 | block.listItemStart = edit(/^( *)(bull)/)
|
52 | .replace('bull', block.bullet)
|
53 | .getRegex();
|
54 |
|
55 | block.list = edit(block.list)
|
56 | .replace(/bull/g, block.bullet)
|
57 | .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
|
58 | .replace('def', '\\n+(?=' + block.def.source + ')')
|
59 | .getRegex();
|
60 |
|
61 | block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
|
62 | + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
|
63 | + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
|
64 | + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
|
65 | + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
|
66 | + '|track|ul';
|
67 | block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
|
68 | block.html = edit(block.html, 'i')
|
69 | .replace('comment', block._comment)
|
70 | .replace('tag', block._tag)
|
71 | .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
|
72 | .getRegex();
|
73 |
|
74 | block.paragraph = edit(block._paragraph)
|
75 | .replace('hr', block.hr)
|
76 | .replace('heading', ' {0,3}#{1,6} ')
|
77 | .replace('|lheading', '')
|
78 | .replace('blockquote', ' {0,3}>')
|
79 | .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
80 | .replace('list', ' {0,3}(?:[*+-]|1[.)]) ')
|
81 | .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)')
|
82 | .replace('tag', block._tag)
|
83 | .getRegex();
|
84 |
|
85 | block.blockquote = edit(block.blockquote)
|
86 | .replace('paragraph', block.paragraph)
|
87 | .getRegex();
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | block.normal = merge({}, block);
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | block.gfm = merge({}, block.normal, {
|
100 | nptable: '^ *([^|\\n ].*\\|.*)\\n'
|
101 | + ' {0,3}([-:]+ *\\|[-| :]*)'
|
102 | + '(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)',
|
103 | table: '^ *\\|(.+)\\n'
|
104 | + ' {0,3}\\|?( *[-:]+[-| :]*)'
|
105 | + '(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)'
|
106 | });
|
107 |
|
108 | block.gfm.nptable = edit(block.gfm.nptable)
|
109 | .replace('hr', block.hr)
|
110 | .replace('heading', ' {0,3}#{1,6} ')
|
111 | .replace('blockquote', ' {0,3}>')
|
112 | .replace('code', ' {4}[^\\n]')
|
113 | .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
114 | .replace('list', ' {0,3}(?:[*+-]|1[.)]) ')
|
115 | .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)')
|
116 | .replace('tag', block._tag)
|
117 | .getRegex();
|
118 |
|
119 | block.gfm.table = edit(block.gfm.table)
|
120 | .replace('hr', block.hr)
|
121 | .replace('heading', ' {0,3}#{1,6} ')
|
122 | .replace('blockquote', ' {0,3}>')
|
123 | .replace('code', ' {4}[^\\n]')
|
124 | .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
125 | .replace('list', ' {0,3}(?:[*+-]|1[.)]) ')
|
126 | .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)')
|
127 | .replace('tag', block._tag)
|
128 | .getRegex();
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 | block.pedantic = merge({}, block.normal, {
|
135 | html: edit(
|
136 | '^ *(?:comment *(?:\\n|\\s*$)'
|
137 | + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)'
|
138 | + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
|
139 | .replace('comment', block._comment)
|
140 | .replace(/tag/g, '(?!(?:'
|
141 | + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
|
142 | + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
|
143 | + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
|
144 | .getRegex(),
|
145 | def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
|
146 | heading: /^(#{1,6})(.*)(?:\n+|$)/,
|
147 | fences: noopTest,
|
148 | paragraph: edit(block.normal._paragraph)
|
149 | .replace('hr', block.hr)
|
150 | .replace('heading', ' *#{1,6} *[^\n]')
|
151 | .replace('lheading', block.lheading)
|
152 | .replace('blockquote', ' {0,3}>')
|
153 | .replace('|fences', '')
|
154 | .replace('|list', '')
|
155 | .replace('|html', '')
|
156 | .getRegex()
|
157 | });
|
158 |
|
159 |
|
160 |
|
161 |
|
162 | const inline = {
|
163 | escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
|
164 | autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
|
165 | url: noopTest,
|
166 | tag: '^comment'
|
167 | + '|^</[a-zA-Z][\\w:-]*\\s*>'
|
168 | + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>'
|
169 | + '|^<\\?[\\s\\S]*?\\?>'
|
170 | + '|^<![a-zA-Z]+\\s[\\s\\S]*?>'
|
171 | + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
|
172 | link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
|
173 | reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
|
174 | nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
|
175 | reflinkSearch: 'reflink|nolink(?!\\()',
|
176 | strong: {
|
177 | start: /^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/,
|
178 | middle: /^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,
|
179 | endAst: /[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/,
|
180 | endUnd: /[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/
|
181 | },
|
182 | em: {
|
183 | start: /^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/,
|
184 | middle: /^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,
|
185 | endAst: /[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/,
|
186 | endUnd: /[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/
|
187 | },
|
188 | code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
|
189 | br: /^( {2,}|\\)\n(?!\s*$)/,
|
190 | del: noopTest,
|
191 | text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n)))/,
|
192 | punctuation: /^([\s*punctuation])/
|
193 | };
|
194 |
|
195 |
|
196 |
|
197 | inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
|
198 | inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
|
199 |
|
200 |
|
201 | inline._blockSkip = '\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>';
|
202 | inline._overlapSkip = '__[^_]*?__|\\*\\*\\[^\\*\\]*?\\*\\*';
|
203 |
|
204 | inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
|
205 |
|
206 | inline.em.start = edit(inline.em.start)
|
207 | .replace(/punctuation/g, inline._punctuation)
|
208 | .getRegex();
|
209 |
|
210 | inline.em.middle = edit(inline.em.middle)
|
211 | .replace(/punctuation/g, inline._punctuation)
|
212 | .replace(/overlapSkip/g, inline._overlapSkip)
|
213 | .getRegex();
|
214 |
|
215 | inline.em.endAst = edit(inline.em.endAst, 'g')
|
216 | .replace(/punctuation/g, inline._punctuation)
|
217 | .getRegex();
|
218 |
|
219 | inline.em.endUnd = edit(inline.em.endUnd, 'g')
|
220 | .replace(/punctuation/g, inline._punctuation)
|
221 | .getRegex();
|
222 |
|
223 | inline.strong.start = edit(inline.strong.start)
|
224 | .replace(/punctuation/g, inline._punctuation)
|
225 | .getRegex();
|
226 |
|
227 | inline.strong.middle = edit(inline.strong.middle)
|
228 | .replace(/punctuation/g, inline._punctuation)
|
229 | .replace(/overlapSkip/g, inline._overlapSkip)
|
230 | .getRegex();
|
231 |
|
232 | inline.strong.endAst = edit(inline.strong.endAst, 'g')
|
233 | .replace(/punctuation/g, inline._punctuation)
|
234 | .getRegex();
|
235 |
|
236 | inline.strong.endUnd = edit(inline.strong.endUnd, 'g')
|
237 | .replace(/punctuation/g, inline._punctuation)
|
238 | .getRegex();
|
239 |
|
240 | inline.blockSkip = edit(inline._blockSkip, 'g')
|
241 | .getRegex();
|
242 |
|
243 | inline.overlapSkip = edit(inline._overlapSkip, 'g')
|
244 | .getRegex();
|
245 |
|
246 | inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
|
247 |
|
248 | inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
|
249 | inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
|
250 | inline.autolink = edit(inline.autolink)
|
251 | .replace('scheme', inline._scheme)
|
252 | .replace('email', inline._email)
|
253 | .getRegex();
|
254 |
|
255 | inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
|
256 |
|
257 | inline.tag = edit(inline.tag)
|
258 | .replace('comment', inline._comment)
|
259 | .replace('attribute', inline._attribute)
|
260 | .getRegex();
|
261 |
|
262 | inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
|
263 | inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
|
264 | inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
|
265 |
|
266 | inline.link = edit(inline.link)
|
267 | .replace('label', inline._label)
|
268 | .replace('href', inline._href)
|
269 | .replace('title', inline._title)
|
270 | .getRegex();
|
271 |
|
272 | inline.reflink = edit(inline.reflink)
|
273 | .replace('label', inline._label)
|
274 | .getRegex();
|
275 |
|
276 | inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
|
277 | .replace('reflink', inline.reflink)
|
278 | .replace('nolink', inline.nolink)
|
279 | .getRegex();
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 | inline.normal = merge({}, inline);
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 | inline.pedantic = merge({}, inline.normal, {
|
292 | strong: {
|
293 | start: /^__|\*\*/,
|
294 | middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
295 | endAst: /\*\*(?!\*)/g,
|
296 | endUnd: /__(?!_)/g
|
297 | },
|
298 | em: {
|
299 | start: /^_|\*/,
|
300 | middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
|
301 | endAst: /\*(?!\*)/g,
|
302 | endUnd: /_(?!_)/g
|
303 | },
|
304 | link: edit(/^!?\[(label)\]\((.*?)\)/)
|
305 | .replace('label', inline._label)
|
306 | .getRegex(),
|
307 | reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
|
308 | .replace('label', inline._label)
|
309 | .getRegex()
|
310 | });
|
311 |
|
312 |
|
313 |
|
314 |
|
315 |
|
316 | inline.gfm = merge({}, inline.normal, {
|
317 | escape: edit(inline.escape).replace('])', '~|])').getRegex(),
|
318 | _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
|
319 | url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
|
320 | _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
|
321 | del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
|
322 | text: /^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
|
323 | });
|
324 |
|
325 | inline.gfm.url = edit(inline.gfm.url, 'i')
|
326 | .replace('email', inline.gfm._extended_email)
|
327 | .getRegex();
|
328 |
|
329 |
|
330 |
|
331 |
|
332 | inline.breaks = merge({}, inline.gfm, {
|
333 | br: edit(inline.br).replace('{2,}', '*').getRegex(),
|
334 | text: edit(inline.gfm.text)
|
335 | .replace('\\b_', '\\b_| {2,}\\n')
|
336 | .replace(/\{2,\}/g, '*')
|
337 | .getRegex()
|
338 | });
|
339 |
|
340 | module.exports = {
|
341 | block,
|
342 | inline
|
343 | };
|