securemark 0.270.2 → 0.272.0
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/CHANGELOG.md +8 -0
- package/dist/index.js +128 -99
- package/package.json +16 -16
- package/src/parser/api/bind.test.ts +3 -3
- package/src/parser/api/parse.test.ts +5 -5
- package/src/parser/block/extension/aside.ts +3 -3
- package/src/parser/block/extension/table.test.ts +58 -35
- package/src/parser/block/extension/table.ts +67 -31
- package/src/parser/inline/autolink/url.ts +2 -2
- package/src/parser/inline/autolink.ts +3 -3
- package/src/parser/inline/extension/indexee.ts +9 -5
- package/src/parser/inline/media.ts +2 -2
- package/src/parser/inline.ts +3 -3
- package/src/parser/processor/footnote.test.ts +38 -38
- package/src/parser/processor/footnote.ts +25 -30
- package/tsconfig.json +2 -1
- package/webpack.config.js +4 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securemark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.272.0",
|
|
4
4
|
"description": "Secure markdown renderer working on browsers for user input data.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://github.com/falsandtru/securemark",
|
|
@@ -28,35 +28,35 @@
|
|
|
28
28
|
"LICENSE"
|
|
29
29
|
],
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@types/dompurify": "3.0.
|
|
31
|
+
"@types/dompurify": "3.0.2",
|
|
32
32
|
"@types/jquery": "3.5.16",
|
|
33
33
|
"@types/mathjax": "0.0.37",
|
|
34
34
|
"@types/mocha": "10.0.1",
|
|
35
35
|
"@types/power-assert": "1.5.8",
|
|
36
36
|
"@types/prismjs": "1.26.0",
|
|
37
|
-
"@typescript-eslint/parser": "^5.
|
|
37
|
+
"@typescript-eslint/parser": "^5.59.0",
|
|
38
38
|
"babel-loader": "^9.1.2",
|
|
39
39
|
"babel-plugin-unassert": "^3.2.0",
|
|
40
|
-
"concurrently": "^
|
|
41
|
-
"eslint": "^8.
|
|
40
|
+
"concurrently": "^8.0.1",
|
|
41
|
+
"eslint": "^8.39.0",
|
|
42
42
|
"eslint-plugin-redos": "^4.4.5",
|
|
43
|
-
"eslint-webpack-plugin": "^4.0.
|
|
44
|
-
"glob": "^
|
|
45
|
-
"karma": "^6.4.
|
|
46
|
-
"karma-chrome-launcher": "^3.
|
|
43
|
+
"eslint-webpack-plugin": "^4.0.1",
|
|
44
|
+
"glob": "^10.2.1",
|
|
45
|
+
"karma": "^6.4.2",
|
|
46
|
+
"karma-chrome-launcher": "^3.2.0",
|
|
47
47
|
"karma-coverage": "^2.2.0",
|
|
48
48
|
"karma-firefox-launcher": "^2.1.2",
|
|
49
49
|
"karma-mocha": "^2.0.1",
|
|
50
50
|
"karma-power-assert": "^1.0.0",
|
|
51
51
|
"mocha": "^10.2.0",
|
|
52
|
-
"npm-check-updates": "^16.
|
|
53
|
-
"semver": "^7.
|
|
54
|
-
"spica": "0.0.
|
|
52
|
+
"npm-check-updates": "^16.10.9",
|
|
53
|
+
"semver": "^7.5.0",
|
|
54
|
+
"spica": "0.0.721",
|
|
55
55
|
"ts-loader": "^9.4.2",
|
|
56
|
-
"typed-dom": "^0.0.
|
|
57
|
-
"typescript": "
|
|
58
|
-
"webpack": "^5.
|
|
59
|
-
"webpack-cli": "^5.0.
|
|
56
|
+
"typed-dom": "^0.0.330",
|
|
57
|
+
"typescript": "5.0.4",
|
|
58
|
+
"webpack": "^5.80.0",
|
|
59
|
+
"webpack-cli": "^5.0.2",
|
|
60
60
|
"webpack-merge": "^5.8.0"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
@@ -214,15 +214,15 @@ describe('Unit: parser/api/bind', () => {
|
|
|
214
214
|
cfgs.footnotes.references?.outerHTML,
|
|
215
215
|
html('ol', [
|
|
216
216
|
html('li', { id: 'reference::def:1' }, [
|
|
217
|
-
html('span',
|
|
217
|
+
html('span', '1'),
|
|
218
218
|
html('sup', [html('a', { href: '#reference::ref:1' }, '^1')]),
|
|
219
219
|
]),
|
|
220
220
|
html('li', { id: 'reference::def:2' }, [
|
|
221
|
-
html('span',
|
|
221
|
+
html('span', '2'),
|
|
222
222
|
html('sup', [html('a', { href: '#reference::ref:2' }, '^2')]),
|
|
223
223
|
]),
|
|
224
224
|
html('li', { id: 'reference::def:3' }, [
|
|
225
|
-
html('span',
|
|
225
|
+
html('span', '3'),
|
|
226
226
|
html('sup', [html('a', { href: '#reference::ref:3' }, '^3')]),
|
|
227
227
|
]),
|
|
228
228
|
]).outerHTML);
|
|
@@ -124,7 +124,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
124
124
|
'<p><a class="index" href="#index::a">a</a></p>',
|
|
125
125
|
'<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
|
|
126
126
|
'<p><a class="label" data-label="$-a" href="#label:$-a">(1)</a></p>',
|
|
127
|
-
'<p><sup class="annotation" id="annotation::ref:1" title="a"><span hidden="">a</span><a href="#annotation::def:
|
|
127
|
+
'<p><sup class="annotation" id="annotation::ref:1" title="a"><span hidden="">a</span><a href="#annotation::def:a">*1</a></sup></p>',
|
|
128
128
|
'<p><a class="url" href="https://source/x/a" target="_blank">a</a></p>',
|
|
129
129
|
'<p><a class="url" href="https://source/a" target="_blank">/a</a></p>',
|
|
130
130
|
'<p><a class="url" href="/z/a">^/a</a></p>',
|
|
@@ -135,7 +135,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
135
135
|
'<p><a href="https://source/x/a" target="_blank"><img class="media" data-src="https://source/x/a" alt=""></a></p>',
|
|
136
136
|
'<p><a href="/z/a" target="_blank"><img class="media" data-src="/z/a" alt=""></a></p>',
|
|
137
137
|
'<p><a href="https://source/a" target="_blank"><img class="media" data-src="https://source/a" alt=""></a></p>',
|
|
138
|
-
'<ol class="annotations"><li id="annotation::def:
|
|
138
|
+
'<ol class="annotations"><li id="annotation::def:a" data-marker="*1"><span>a</span><sup><a href="#annotation::ref:1">^1</a></sup></li></ol>',
|
|
139
139
|
]);
|
|
140
140
|
assert.deepStrictEqual(
|
|
141
141
|
[...parse([
|
|
@@ -207,12 +207,12 @@ describe('Unit: parser/api/parse', () => {
|
|
|
207
207
|
[...parse('$-a\n$$\n$$\n\n(($-a[[b]][[c_d_]]))', { footnotes }).children].map(el => el.outerHTML),
|
|
208
208
|
[
|
|
209
209
|
'<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
|
|
210
|
-
'<p><sup class="annotation" id="annotation::ref:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference"
|
|
211
|
-
'<ol class="annotations"><li id="annotation::def:1" data-marker="*1"><span
|
|
210
|
+
'<p><sup class="annotation" id="annotation::ref:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference"><span>b</span></sup><sup class="reference"><span>c<em>d</em></span></sup></span><a href="#annotation::def:(1)">*1</a></sup></p>',
|
|
211
|
+
'<ol class="annotations"><li id="annotation::def:(1)" data-marker="*1"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference::ref:1" title="b"><span hidden="">b</span><a href="#reference::def:b">[1]</a></sup><sup class="reference" id="reference::ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference::def:cd">[2]</a></sup></span><sup><a href="#annotation::ref:1">^1</a></sup></li></ol>',
|
|
212
212
|
]);
|
|
213
213
|
assert.deepStrictEqual(
|
|
214
214
|
footnotes.references.outerHTML,
|
|
215
|
-
'<ol><li id="reference::def:
|
|
215
|
+
'<ol><li id="reference::def:b"><span>b</span><sup><a href="#reference::ref:1">^1</a></sup></li><li id="reference::def:cd"><span>c<em>d</em></span><sup><a href="#reference::ref:2">^2</a></sup></li></ol>');
|
|
216
216
|
});
|
|
217
217
|
|
|
218
218
|
it('normalize', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../block';
|
|
2
2
|
import { block, validate, fence, fmap } from '../../../combinator';
|
|
3
|
-
import { identity,
|
|
3
|
+
import { identity, index } from '../../inline/extension/indexee';
|
|
4
4
|
import { parse } from '../../api/parse';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
6
|
|
|
@@ -34,9 +34,9 @@ export const aside: ExtensionParser.AsideParser = block(validate('~~~', fmap(
|
|
|
34
34
|
'data-invalid-type': 'content',
|
|
35
35
|
'data-invalid-message': 'Missing the title at the first line',
|
|
36
36
|
}, `${opener}${body}${closer}`)];
|
|
37
|
-
assert(identity(context.id,
|
|
37
|
+
assert(identity(context.id, index(heading)));
|
|
38
38
|
return [
|
|
39
|
-
html('aside', { id: identity(context.id,
|
|
39
|
+
html('aside', { id: identity(context.id, index(heading)), class: 'aside' }, [
|
|
40
40
|
document,
|
|
41
41
|
html('h2', 'References'),
|
|
42
42
|
references,
|
|
@@ -296,7 +296,7 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
296
296
|
html('tbody', [
|
|
297
297
|
html('tr', [
|
|
298
298
|
html('th', { class: 'highlight' }, '1.1'),
|
|
299
|
-
html('td',
|
|
299
|
+
html('td', '1.2'),
|
|
300
300
|
]),
|
|
301
301
|
]),
|
|
302
302
|
html('tfoot'),
|
|
@@ -307,7 +307,7 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
307
307
|
html('thead'),
|
|
308
308
|
html('tbody', [
|
|
309
309
|
html('tr', [
|
|
310
|
-
html('td',
|
|
310
|
+
html('td', '1.1'),
|
|
311
311
|
html('th', { class: 'highlight' }, '1.2'),
|
|
312
312
|
]),
|
|
313
313
|
]),
|
|
@@ -319,18 +319,40 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
319
319
|
html('thead', [
|
|
320
320
|
html('tr', [html('th', { class: 'highlight' }, '1.1')]),
|
|
321
321
|
]),
|
|
322
|
+
html('tbody', [
|
|
323
|
+
html('tr', [html('td', '2.1')]),
|
|
324
|
+
]),
|
|
325
|
+
html('tfoot'),
|
|
326
|
+
]).outerHTML], '']);
|
|
327
|
+
assert.deepStrictEqual(
|
|
328
|
+
inspect(parser('~~~table\n#! 1.1\n-\n:!+ 2.1\n~~~')),
|
|
329
|
+
[[html('table', [
|
|
330
|
+
html('thead', [
|
|
331
|
+
html('tr', [html('th', { class: 'highlight' }, '1.1')]),
|
|
332
|
+
]),
|
|
333
|
+
html('tbody', [
|
|
334
|
+
html('tr', [html('td', { class: 'invalid' }, '2.1')]),
|
|
335
|
+
]),
|
|
336
|
+
html('tfoot'),
|
|
337
|
+
]).outerHTML], '']);
|
|
338
|
+
assert.deepStrictEqual(
|
|
339
|
+
inspect(parser('~~~table\n#!+ 1.1\n-\n: 2.1\n~~~')),
|
|
340
|
+
[[html('table', [
|
|
341
|
+
html('thead', [
|
|
342
|
+
html('tr', [html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1.1')]),
|
|
343
|
+
]),
|
|
322
344
|
html('tbody', [
|
|
323
345
|
html('tr', [html('td', { class: 'highlight', highlight: 'v' }, '2.1')]),
|
|
324
346
|
]),
|
|
325
347
|
html('tfoot'),
|
|
326
348
|
]).outerHTML], '']);
|
|
327
349
|
assert.deepStrictEqual(
|
|
328
|
-
inspect(parser('~~~table\n
|
|
350
|
+
inspect(parser('~~~table\n#!+ 1.1\n# 1.2\n: 1.3\n~~~')),
|
|
329
351
|
[[html('table', [
|
|
330
352
|
html('thead'),
|
|
331
353
|
html('tbody', [
|
|
332
354
|
html('tr', [
|
|
333
|
-
html('th', { class: 'highlight' }, '1.1'),
|
|
355
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1.1'),
|
|
334
356
|
html('th', '1.2'),
|
|
335
357
|
html('td', '1.3'),
|
|
336
358
|
]),
|
|
@@ -338,23 +360,23 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
338
360
|
html('tfoot'),
|
|
339
361
|
]).outerHTML], '']);
|
|
340
362
|
assert.deepStrictEqual(
|
|
341
|
-
inspect(parser('~~~table\n: 1.1\n# 1.2\n
|
|
363
|
+
inspect(parser('~~~table\n: 1.1\n# 1.2\n#!+ 1.3\n~~~')),
|
|
342
364
|
[[html('table', [
|
|
343
365
|
html('thead'),
|
|
344
366
|
html('tbody', [
|
|
345
367
|
html('tr', [
|
|
346
368
|
html('td', '1.1'),
|
|
347
369
|
html('th', '1.2'),
|
|
348
|
-
html('th', { class: 'highlight' }, '1.3'),
|
|
370
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1.3'),
|
|
349
371
|
]),
|
|
350
372
|
]),
|
|
351
373
|
html('tfoot'),
|
|
352
374
|
]).outerHTML], '']);
|
|
353
375
|
assert.deepStrictEqual(
|
|
354
|
-
inspect(parser('~~~table\n
|
|
376
|
+
inspect(parser('~~~table\n#!+ 1.1\n-\n# 2.1\n-\n: 3.1\n~~~')),
|
|
355
377
|
[[html('table', [
|
|
356
378
|
html('thead', [
|
|
357
|
-
html('tr', [html('th', { class: 'highlight' }, '1.1')]),
|
|
379
|
+
html('tr', [html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1.1')]),
|
|
358
380
|
html('tr', [html('th', '2.1')]),
|
|
359
381
|
]),
|
|
360
382
|
html('tbody', [
|
|
@@ -363,22 +385,22 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
363
385
|
html('tfoot'),
|
|
364
386
|
]).outerHTML], '']);
|
|
365
387
|
assert.deepStrictEqual(
|
|
366
|
-
inspect(parser('~~~table\n#:2
|
|
388
|
+
inspect(parser('~~~table\n#:2!+ 1.1\n: 1.3\n~~~')),
|
|
367
389
|
[[html('table', [
|
|
368
390
|
html('thead'),
|
|
369
391
|
html('tbody', [
|
|
370
392
|
html('tr', [
|
|
371
|
-
html('th', { class: 'highlight', colspan: '2' }, '1.1'),
|
|
393
|
+
html('th', { class: 'highlight', colspan: '2', 'data-highlight-extension': '+' }, '1.1'),
|
|
372
394
|
html('td', { class: 'highlight', highlight: 'h' }, '1.3'),
|
|
373
395
|
]),
|
|
374
396
|
]),
|
|
375
397
|
html('tfoot'),
|
|
376
398
|
]).outerHTML], '']);
|
|
377
399
|
assert.deepStrictEqual(
|
|
378
|
-
inspect(parser('~~~table\n#2
|
|
400
|
+
inspect(parser('~~~table\n#2:!+ 1.1\n-\n: 3.1\n~~~')),
|
|
379
401
|
[[html('table', [
|
|
380
402
|
html('thead', [
|
|
381
|
-
html('tr', [html('th', { class: 'highlight', rowspan: '2' }, '1.1')]),
|
|
403
|
+
html('tr', [html('th', { class: 'highlight', rowspan: '2', 'data-highlight-extension': '+' }, '1.1')]),
|
|
382
404
|
]),
|
|
383
405
|
html('tbody', [
|
|
384
406
|
html('tr', [html('td', { class: 'highlight', highlight: 'v' }, '3.1')]),
|
|
@@ -386,46 +408,46 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
386
408
|
html('tfoot'),
|
|
387
409
|
]).outerHTML], '']);
|
|
388
410
|
assert.deepStrictEqual(
|
|
389
|
-
inspect(parser('~~~table\n-\n# \n
|
|
411
|
+
inspect(parser('~~~table\n-\n# \n#!+ 1.2\n-\n#!+ 2.1\n: 2.2\n~~~')),
|
|
390
412
|
[[html('table', [
|
|
391
413
|
html('thead', [
|
|
392
414
|
html('tr', [
|
|
393
415
|
html('th'),
|
|
394
|
-
html('th', { class: 'highlight' }, '1.2'),
|
|
416
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1.2'),
|
|
395
417
|
]),
|
|
396
418
|
]),
|
|
397
419
|
html('tbody', [
|
|
398
420
|
html('tr', [
|
|
399
|
-
html('th', { class: 'highlight' }, '2.1'),
|
|
421
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '2.1'),
|
|
400
422
|
html('td', { class: 'highlight', highlight: 'v h' }, '2.2'),
|
|
401
423
|
]),
|
|
402
424
|
]),
|
|
403
425
|
html('tfoot'),
|
|
404
426
|
]).outerHTML], '']);
|
|
405
427
|
assert.deepStrictEqual(
|
|
406
|
-
inspect(parser('~~~table\n-\n# \n
|
|
428
|
+
inspect(parser('~~~table\n-\n# \n#!+ 1.2\n-\n#!+ 2.1\n:! 2.2\n~~~')),
|
|
407
429
|
[[html('table', [
|
|
408
430
|
html('thead', [
|
|
409
431
|
html('tr', [
|
|
410
432
|
html('th'),
|
|
411
|
-
html('th', { class: 'highlight' }, '1.2'),
|
|
433
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1.2'),
|
|
412
434
|
]),
|
|
413
435
|
]),
|
|
414
436
|
html('tbody', [
|
|
415
437
|
html('tr', [
|
|
416
|
-
html('th', { class: 'highlight' }, '2.1'),
|
|
417
|
-
html('td', { class: 'highlight', highlight: 'v h c' }, '2.2'),
|
|
438
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '2.1'),
|
|
439
|
+
html('td', { class: 'highlight', 'data-highlight-level': '1', highlight: 'v h c' }, '2.2'),
|
|
418
440
|
]),
|
|
419
441
|
]),
|
|
420
442
|
html('tfoot'),
|
|
421
443
|
]).outerHTML], '']);
|
|
422
444
|
assert.deepStrictEqual(
|
|
423
|
-
inspect(parser('~~~table\n-\n# 1.1\n
|
|
445
|
+
inspect(parser('~~~table\n-\n# 1.1\n#!+ 1.2\n-\n# 2.1\n:2:2 2.2\n: 2.4\n-\n#!+ 3.1\n: 3.4\n-\n# 4.1\n: 4.2\n~~~')),
|
|
424
446
|
[[html('table', [
|
|
425
447
|
html('thead', [
|
|
426
448
|
html('tr', [
|
|
427
449
|
html('th', '1.1'),
|
|
428
|
-
html('th', { class: 'highlight' }, '1.2'),
|
|
450
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1.2'),
|
|
429
451
|
]),
|
|
430
452
|
]),
|
|
431
453
|
html('tbody', [
|
|
@@ -435,7 +457,7 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
435
457
|
html('td', '2.4'),
|
|
436
458
|
]),
|
|
437
459
|
html('tr', [
|
|
438
|
-
html('th', { class: 'highlight' }, '3.1'),
|
|
460
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '3.1'),
|
|
439
461
|
html('td', { class: 'highlight', highlight: 'h' }, '3.4'),
|
|
440
462
|
]),
|
|
441
463
|
html('tr', [
|
|
@@ -446,17 +468,17 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
446
468
|
html('tfoot'),
|
|
447
469
|
]).outerHTML], '']);
|
|
448
470
|
assert.deepStrictEqual(
|
|
449
|
-
inspect(parser('~~~table\n-\n# 1.1\n#:2
|
|
471
|
+
inspect(parser('~~~table\n-\n# 1.1\n#:2!+ 1.2\n-\n#2:!+ 2.1\n: 2.2\n-\n3.2\n3.3\n~~~')),
|
|
450
472
|
[[html('table', [
|
|
451
473
|
html('thead', [
|
|
452
474
|
html('tr', [
|
|
453
475
|
html('th', '1.1'),
|
|
454
|
-
html('th', { class: 'highlight', colspan: '2' }, '1.2'),
|
|
476
|
+
html('th', { class: 'highlight', colspan: '2', 'data-highlight-extension': '+' }, '1.2'),
|
|
455
477
|
]),
|
|
456
478
|
]),
|
|
457
479
|
html('tbody', [
|
|
458
480
|
html('tr', [
|
|
459
|
-
html('th', { class: 'highlight', rowspan: '2' }, '2.1'),
|
|
481
|
+
html('th', { class: 'highlight', rowspan: '2', 'data-highlight-extension': '+' }, '2.1'),
|
|
460
482
|
html('td', { class: 'highlight', highlight: 'v h' }, '2.2'),
|
|
461
483
|
]),
|
|
462
484
|
html('tr', [
|
|
@@ -470,7 +492,7 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
470
492
|
inspect(parser([
|
|
471
493
|
'~~~table',
|
|
472
494
|
`-\n# 1\n${[...Array(32)].map((_, i) => `: ${i + 2}`).join('\n')}`,
|
|
473
|
-
`-\n
|
|
495
|
+
`-\n#!+ 1\n${[...Array(32)].map((_, i) => `: ${i + 2}`).join('\n')}`,
|
|
474
496
|
'~~~'
|
|
475
497
|
].join('\n'))),
|
|
476
498
|
[[html('table', [
|
|
@@ -481,7 +503,7 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
481
503
|
...[...Array(32)].map((_, i) => html('td', `${i + 2}`)),
|
|
482
504
|
]),
|
|
483
505
|
html('tr', [
|
|
484
|
-
html('th', { class: 'highlight' }, '1'),
|
|
506
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1'),
|
|
485
507
|
...[...Array(32)].map((_, i) => html('td', { class: 'highlight', highlight: 'h' }, `${i + 2}`)),
|
|
486
508
|
]),
|
|
487
509
|
]),
|
|
@@ -490,7 +512,7 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
490
512
|
inspect(parser([
|
|
491
513
|
'~~~table',
|
|
492
514
|
`-\n${[...Array(32)].map((_, i) => `: ${i + 1}`).join('\n')}\n# 33`,
|
|
493
|
-
`-\n${[...Array(32)].map((_, i) => `: ${i + 1}`).join('\n')}\n
|
|
515
|
+
`-\n${[...Array(32)].map((_, i) => `: ${i + 1}`).join('\n')}\n#!+ 33`,
|
|
494
516
|
'~~~'
|
|
495
517
|
].join('\n'))),
|
|
496
518
|
[[html('table', [
|
|
@@ -502,14 +524,14 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
502
524
|
]),
|
|
503
525
|
html('tr', [
|
|
504
526
|
...[...Array(32)].map((_, i) => html('td', { class: 'highlight', highlight: 'h' }, `${i + 1}`)),
|
|
505
|
-
html('th', { class: 'highlight' }, '33'),
|
|
527
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '33'),
|
|
506
528
|
]),
|
|
507
529
|
]),
|
|
508
530
|
html('tfoot')]).outerHTML], '']);
|
|
509
531
|
assert.deepStrictEqual(
|
|
510
532
|
inspect(parser([
|
|
511
533
|
'~~~table',
|
|
512
|
-
`-\n${[...Array(32)].map((_, i) => `# ${i + 1}`).join('\n')}\n
|
|
534
|
+
`-\n${[...Array(32)].map((_, i) => `# ${i + 1}`).join('\n')}\n#!+ 33`,
|
|
513
535
|
`-\n${[...Array(33)].map((_, i) => `: ${i + 1}`).join('\n')}`,
|
|
514
536
|
'~~~'
|
|
515
537
|
].join('\n'))),
|
|
@@ -517,7 +539,7 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
517
539
|
html('thead', [
|
|
518
540
|
html('tr', [
|
|
519
541
|
...[...Array(32)].map((_, i) => html('th', `${i + 1}`)),
|
|
520
|
-
html('th', { class: 'highlight' }, '33'),
|
|
542
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '33'),
|
|
521
543
|
]),
|
|
522
544
|
]),
|
|
523
545
|
html('tbody', [
|
|
@@ -537,7 +559,8 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
537
559
|
html('thead', [
|
|
538
560
|
html('tr', [
|
|
539
561
|
html('th', { class: 'highlight' }, '1'),
|
|
540
|
-
...[...Array(
|
|
562
|
+
...[...Array(5)].map((_, i) => html('th', { class: 'highlight', 'data-highlight-level': `${i + 2}` }, `${i + 2}`)),
|
|
563
|
+
html('th', { class: 'invalid' }, '7'),
|
|
541
564
|
]),
|
|
542
565
|
]),
|
|
543
566
|
html('tbody'),
|
|
@@ -561,14 +584,14 @@ describe('Unit: parser/block/extension/table', () => {
|
|
|
561
584
|
html('tfoot'),
|
|
562
585
|
]).outerHTML], '']);
|
|
563
586
|
assert.deepStrictEqual(
|
|
564
|
-
inspect(parser('~~~table\n
|
|
587
|
+
inspect(parser('~~~table\n#!+ 1\n: 2\n:! 3\n~~~')),
|
|
565
588
|
[[html('table', [
|
|
566
589
|
html('thead'),
|
|
567
590
|
html('tbody', [
|
|
568
591
|
html('tr', [
|
|
569
|
-
html('th', { class: 'highlight' }, '1'),
|
|
592
|
+
html('th', { class: 'highlight', 'data-highlight-extension': '+' }, '1'),
|
|
570
593
|
html('td', { class: 'highlight', highlight: 'h' }, '2'),
|
|
571
|
-
html('td', { class: 'highlight', highlight: 'h c' }, '3'),
|
|
594
|
+
html('td', { class: 'highlight', 'data-highlight-level': '1', highlight: 'h c' }, '3'),
|
|
572
595
|
]),
|
|
573
596
|
]),
|
|
574
597
|
html('tfoot'),
|
|
@@ -75,10 +75,10 @@ const align: AlignParser = line(fmap(
|
|
|
75
75
|
union([str(alignment)]),
|
|
76
76
|
([s]) => s.split('/').map(s => s.split(''))));
|
|
77
77
|
|
|
78
|
-
const delimiter = /^[-=<>]+(?:\/[-=^v]*)?(?=[^\S\n]*\n)|^[#:](?:(?!:\D|0)\d*:(?!0)\d*)
|
|
78
|
+
const delimiter = /^[-=<>]+(?:\/[-=^v]*)?(?=[^\S\n]*\n)|^[#:](?:(?!:\D|0)\d*:(?!0)\d*)?(?:!+[+]?)?(?=\s)/;
|
|
79
79
|
|
|
80
80
|
const head: CellParser.HeadParser = creation(1, false, block(fmap(open(
|
|
81
|
-
str(/^#(?:(?!:\D|0)\d*:(?!0)\d*)
|
|
81
|
+
str(/^#(?:(?!:\D|0)\d*:(?!0)\d*)?(?:!+[+]?)?(?=\s)/),
|
|
82
82
|
rewrite(
|
|
83
83
|
inits([
|
|
84
84
|
anyline,
|
|
@@ -90,7 +90,7 @@ const head: CellParser.HeadParser = creation(1, false, block(fmap(open(
|
|
|
90
90
|
false));
|
|
91
91
|
|
|
92
92
|
const data: CellParser.DataParser = creation(1, false, block(fmap(open(
|
|
93
|
-
str(/^:(?:(?!:\D|0)\d*:(?!0)\d*)
|
|
93
|
+
str(/^:(?:(?!:\D|0)\d*:(?!0)\d*)?(?:!+[+]?)?(?=\s)/),
|
|
94
94
|
rewrite(
|
|
95
95
|
inits([
|
|
96
96
|
anyline,
|
|
@@ -110,28 +110,40 @@ const dataline: CellParser.DatalineParser = creation(1, false, line(
|
|
|
110
110
|
]))));
|
|
111
111
|
|
|
112
112
|
function attributes(source: string) {
|
|
113
|
-
let [, rowspan = undefined, colspan = undefined, highlight = undefined
|
|
113
|
+
let [, rowspan = undefined, colspan = undefined, highlight = undefined, extension = undefined] =
|
|
114
|
+
source.match(/^[#:](?:(\d+)?:(\d+)?)?(?:(!+)([+]?))?$/) ?? [];
|
|
114
115
|
assert(rowspan?.[0] !== '0');
|
|
115
116
|
assert(colspan?.[0] !== '0');
|
|
116
117
|
rowspan === '1' ? rowspan = undefined : undefined;
|
|
117
118
|
colspan === '1' ? colspan = undefined : undefined;
|
|
118
119
|
rowspan &&= `${max(0, min(+rowspan, 65534))}`;
|
|
119
120
|
colspan &&= `${max(0, min(+colspan, 1000))}`;
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|| source[0] === '
|
|
121
|
+
extension ||= undefined;
|
|
122
|
+
const level = highlight?.length ?? 0;
|
|
123
|
+
const validH = !highlight
|
|
124
|
+
|| source[0] === '#' && level <= 6
|
|
125
|
+
|| source[0] === ':' && level <= 6;
|
|
126
|
+
const validE = source[0] === '#' || extension !== '+';
|
|
127
|
+
const valid = validH && validE;
|
|
124
128
|
return {
|
|
125
129
|
class: valid ? highlight && 'highlight' : 'invalid',
|
|
126
130
|
rowspan,
|
|
127
131
|
colspan,
|
|
128
|
-
...
|
|
129
|
-
|
|
130
|
-
:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
...
|
|
133
|
+
!validH && {
|
|
134
|
+
'data-invalid-syntax': 'table',
|
|
135
|
+
'data-invalid-type': 'syntax',
|
|
136
|
+
'data-invalid-message': 'Too much highlight level',
|
|
137
|
+
} ||
|
|
138
|
+
!validE && {
|
|
139
|
+
'data-invalid-syntax': 'table',
|
|
140
|
+
'data-invalid-type': 'syntax',
|
|
141
|
+
'data-invalid-message': 'Extensible cells are only head cells',
|
|
142
|
+
} ||
|
|
143
|
+
{
|
|
144
|
+
'data-highlight-level': level > 1 ? `${level}` : undefined,
|
|
145
|
+
'data-highlight-extension': extension,
|
|
146
|
+
},
|
|
135
147
|
};
|
|
136
148
|
}
|
|
137
149
|
|
|
@@ -143,7 +155,8 @@ function format(rows: Tree<RowParser>[]): HTMLTableSectionElement[] {
|
|
|
143
155
|
const valigns: ('middle' | 'top' | 'bottom' | '')[] = [];
|
|
144
156
|
let target = thead;
|
|
145
157
|
let ranges: Record<number, Record<number, HTMLTableCellElement>> = {};
|
|
146
|
-
let
|
|
158
|
+
let verticalHighlightExtensions = 0n;
|
|
159
|
+
let verticalHighlightLevels: string[] = [];
|
|
147
160
|
ROW:
|
|
148
161
|
for (let i = 0; i < rows.length; ++i) {
|
|
149
162
|
// Copy to make them retryable.
|
|
@@ -215,9 +228,11 @@ function format(rows: Tree<RowParser>[]): HTMLTableSectionElement[] {
|
|
|
215
228
|
const row = html('tr');
|
|
216
229
|
let heads = 0n;
|
|
217
230
|
let highlights = 0n;
|
|
231
|
+
let highlightExtensions = 0n;
|
|
232
|
+
let highlightLevels: string[] = [];
|
|
218
233
|
let hasDataCell = false;
|
|
219
|
-
let
|
|
220
|
-
let
|
|
234
|
+
let lHeadCellIndex: bigint;
|
|
235
|
+
let rHeadCellIndex: bigint;
|
|
221
236
|
for (let j = 0; j < cells.length; ++j) {
|
|
222
237
|
const jn = BigInt(j);
|
|
223
238
|
const isVirtual = !!ranges[i]?.[j];
|
|
@@ -225,14 +240,16 @@ function format(rows: Tree<RowParser>[]): HTMLTableSectionElement[] {
|
|
|
225
240
|
? splice(cells, j, 0, undefined) && ranges[i][j]
|
|
226
241
|
: cells[j];
|
|
227
242
|
const isHeadCell = cell.tagName === 'TH';
|
|
228
|
-
heads |=
|
|
229
|
-
highlights |=
|
|
243
|
+
heads |= isHeadCell ? 1n << jn : 0n;
|
|
244
|
+
highlights |= cell.className === 'highlight' ? 1n << jn : 0n;
|
|
245
|
+
highlightExtensions |= cell.getAttribute('data-highlight-extension') ? 1n << jn : 0n;
|
|
246
|
+
highlightLevels[j] = cell.getAttribute('data-highlight-level') ?? '1';
|
|
230
247
|
hasDataCell ||= !isHeadCell;
|
|
231
248
|
if (isHeadCell && !hasDataCell) {
|
|
232
|
-
|
|
249
|
+
lHeadCellIndex = jn;
|
|
233
250
|
}
|
|
234
251
|
if (isHeadCell && hasDataCell) {
|
|
235
|
-
|
|
252
|
+
rHeadCellIndex ??= jn;
|
|
236
253
|
}
|
|
237
254
|
const rowSpan = cell.rowSpan;
|
|
238
255
|
assert(rowSpan > 0);
|
|
@@ -249,6 +266,8 @@ function format(rows: Tree<RowParser>[]): HTMLTableSectionElement[] {
|
|
|
249
266
|
splice(cells, j + 1, 0, ...Array(colSpan - 1));
|
|
250
267
|
heads |= heads & 1n << jn && ~(~0n << BigInt(colSpan)) << jn;
|
|
251
268
|
highlights |= highlights & 1n << jn && ~(~0n << BigInt(colSpan)) << jn;
|
|
269
|
+
highlightExtensions |= highlightExtensions & 1n << jn && ~(~0n << BigInt(colSpan)) << jn;
|
|
270
|
+
splice(highlightLevels, j + 1, 0, ...Array(colSpan - 1));
|
|
252
271
|
j += colSpan - 1;
|
|
253
272
|
}
|
|
254
273
|
if (target === thead) {
|
|
@@ -285,22 +304,39 @@ function format(rows: Tree<RowParser>[]): HTMLTableSectionElement[] {
|
|
|
285
304
|
target.appendChild(row);
|
|
286
305
|
switch (target) {
|
|
287
306
|
case thead:
|
|
288
|
-
|
|
307
|
+
verticalHighlightExtensions = highlightExtensions;
|
|
308
|
+
verticalHighlightLevels = highlightLevels;
|
|
289
309
|
continue;
|
|
290
310
|
case tbody:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
const tHighlights =
|
|
294
|
-
const horizontalHighlights =
|
|
295
|
-
const
|
|
296
|
-
const
|
|
311
|
+
lHeadCellIndex ??= -1n;
|
|
312
|
+
rHeadCellIndex ??= -1n;
|
|
313
|
+
const tHighlights = verticalHighlightExtensions;
|
|
314
|
+
const horizontalHighlights = highlightExtensions;
|
|
315
|
+
const horizontalHighlightLevels = highlightLevels;
|
|
316
|
+
const lHighlight = ~lHeadCellIndex && horizontalHighlights & 1n << lHeadCellIndex;
|
|
317
|
+
const rHighlight = ~rHeadCellIndex && horizontalHighlights & 1n << rHeadCellIndex;
|
|
297
318
|
for (let i = 0, m = 1n; i < cells.length; ++i, m <<= 1n) {
|
|
298
319
|
const cell = cells[i];
|
|
299
320
|
if (!cell) continue;
|
|
300
321
|
if (heads & m) continue;
|
|
301
322
|
assert(cell.tagName === 'TD');
|
|
302
|
-
|
|
303
|
-
|
|
323
|
+
switch (m) {
|
|
324
|
+
case highlights & m:
|
|
325
|
+
assert(cell.className === 'highlight');
|
|
326
|
+
assert(horizontalHighlightLevels[i]);
|
|
327
|
+
(lHighlight || rHighlight) && cell.setAttribute('data-highlight-level', horizontalHighlightLevels[i]);
|
|
328
|
+
break;
|
|
329
|
+
case lHighlight && m:
|
|
330
|
+
case rHighlight && m:
|
|
331
|
+
cell.classList.add('highlight');
|
|
332
|
+
break;
|
|
333
|
+
case tHighlights & m:
|
|
334
|
+
cell.classList.add('highlight');
|
|
335
|
+
+verticalHighlightLevels[i] > 1 && cell.setAttribute('data-highlight-level', verticalHighlightLevels[i]);
|
|
336
|
+
break;
|
|
337
|
+
default:
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
304
340
|
assert(!+cell.setAttribute('highlight', [
|
|
305
341
|
'',
|
|
306
342
|
'c',
|
|
@@ -13,7 +13,7 @@ export const url: AutolinkParser.UrlParser = lazy(() => validate(['http://', 'ht
|
|
|
13
13
|
url => `{ ${url} }`,
|
|
14
14
|
union([unsafelink])))));
|
|
15
15
|
|
|
16
|
-
export const lineurl: AutolinkParser.UrlParser.LineUrlParser = open(
|
|
16
|
+
export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => open(
|
|
17
17
|
linebreak,
|
|
18
18
|
tails([
|
|
19
19
|
str('!'),
|
|
@@ -22,7 +22,7 @@ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = open(
|
|
|
22
22
|
convert(
|
|
23
23
|
url => `{ ${url} }`,
|
|
24
24
|
unsafelink)),
|
|
25
|
-
]));
|
|
25
|
+
])));
|
|
26
26
|
|
|
27
27
|
const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => creation(precedence(2, union([
|
|
28
28
|
surround('(', some(union([bracket, unescsource]), ')'), ')', true),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AutolinkParser } from '../inline';
|
|
2
|
-
import { union, some, syntax, constraint, validate, focus, fmap } from '../../combinator';
|
|
2
|
+
import { union, some, syntax, constraint, validate, focus, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { url, lineurl } from './autolink/url';
|
|
4
4
|
import { email } from './autolink/email';
|
|
5
5
|
import { channel } from './autolink/channel';
|
|
@@ -11,7 +11,7 @@ import { str } from '../source';
|
|
|
11
11
|
import { Syntax, State } from '../context';
|
|
12
12
|
import { stringify } from '../util';
|
|
13
13
|
|
|
14
|
-
export const autolink: AutolinkParser =
|
|
14
|
+
export const autolink: AutolinkParser = lazy(() =>
|
|
15
15
|
validate(/^(?:[@#>0-9a-z\r\n]|\S[#>])/i,
|
|
16
16
|
constraint(State.autolink, false,
|
|
17
17
|
syntax(Syntax.autolink, 1, 1, ~State.shortcut,
|
|
@@ -44,4 +44,4 @@ export const autolink: AutolinkParser =
|
|
|
44
44
|
anchor,
|
|
45
45
|
])),
|
|
46
46
|
ns => ns.length === 1 ? ns : [stringify(ns)]),
|
|
47
|
-
]))));
|
|
47
|
+
])))));
|