securemark 0.281.1 → 0.281.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/CHANGELOG.md +4 -0
- package/dist/index.js +22 -28
- package/package.json +1 -1
- package/src/parser/block/extension/aside.ts +3 -3
- package/src/parser/block/olist.ts +1 -1
- package/src/parser/block/ulist.ts +1 -1
- package/src/parser/inline/extension/index.test.ts +6 -2
- package/src/parser/inline/extension/index.ts +1 -1
- package/src/parser/inline/extension/indexee.ts +34 -49
- package/src/parser/inline/extension/indexer.test.ts +2 -0
- package/src/parser/inline/mark.test.ts +1 -1
- package/src/parser/inline/mark.ts +1 -1
- package/src/parser/processor/note.ts +3 -3
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.281.
|
|
1
|
+
/*! securemark v0.281.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
|
|
2
2
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
3
3
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
4
4
|
module.exports = factory(require("Prism"), require("DOMPurify"));
|
|
@@ -4437,7 +4437,7 @@ exports.aside = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, co
|
|
|
4437
4437
|
'data-invalid-message': 'Missing the title at the first line'
|
|
4438
4438
|
}, `${opener}${body}${closer}`)];
|
|
4439
4439
|
return [(0, dom_1.html)('aside', {
|
|
4440
|
-
id: (0, indexee_1.identity)(context.id,
|
|
4440
|
+
id: (0, indexee_1.identity)('index', context.id, heading),
|
|
4441
4441
|
class: 'aside'
|
|
4442
4442
|
}, [document, (0, dom_1.html)('h2', 'References'), references])];
|
|
4443
4443
|
})));
|
|
@@ -5199,7 +5199,7 @@ exports.olist = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combina
|
|
|
5199
5199
|
exports.olist_ = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.union)([(0, combinator_1.match)(openers['.'], (0, memoize_1.memoize)(ms => list(type(ms[1]), '.'), ms => idx(ms[1]), [])), (0, combinator_1.match)(openers['('], (0, memoize_1.memoize)(ms => list(type(ms[1]), '('), ms => idx(ms[1]), []))])));
|
|
5200
5200
|
const list = (type, form) => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.creation)(1, false, (0, combinator_1.union)([(0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.fallback)((0, combinator_1.inits)([(0, combinator_1.line)((0, combinator_1.open)(heads[form], (0, combinator_1.subsequence)([ulist_1.checkbox, (0, combinator_1.trim)((0, visibility_1.visualize)((0, util_1.lineable)((0, visibility_1.trimBlank)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))))]), true)), (0, combinator_1.indent)((0, combinator_1.union)([ulist_1.ulist_, exports.olist_, ilist_1.ilist_]))]), ulist_1.invalid), ns => [(0, dom_1.html)('li', {
|
|
5201
5201
|
'data-marker': ns.shift() || undefined
|
|
5202
|
-
}, (0, dom_1.defrag)((0, ulist_1.fillFirstLine)(ns)))])
|
|
5202
|
+
}, (0, dom_1.defrag)((0, ulist_1.fillFirstLine)(ns)))]))]))), es => [format((0, dom_1.html)('ol', es), type, form)]);
|
|
5203
5203
|
const heads = {
|
|
5204
5204
|
'.': (0, combinator_1.focus)(openers['.'], ({
|
|
5205
5205
|
source
|
|
@@ -5523,7 +5523,7 @@ const visibility_1 = __webpack_require__(6364);
|
|
|
5523
5523
|
const array_1 = __webpack_require__(6876);
|
|
5524
5524
|
const dom_1 = __webpack_require__(394);
|
|
5525
5525
|
exports.ulist = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.validate)(/^-(?=[^\S\n]|\n[^\S\n]*\S)/, exports.ulist_)));
|
|
5526
|
-
exports.ulist_ = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.validate)(/^-(?=$|\s)/, (0, combinator_1.some)((0, combinator_1.creation)(1, false, (0, combinator_1.union)([(0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.fallback)((0, combinator_1.inits)([(0, combinator_1.line)((0, combinator_1.open)(/^-(?:$|\s)/, (0, combinator_1.subsequence)([exports.checkbox, (0, combinator_1.trim)((0, visibility_1.visualize)((0, util_1.lineable)((0, visibility_1.trimBlank)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))))]), true)), (0, combinator_1.indent)((0, combinator_1.union)([exports.ulist_, olist_1.olist_, ilist_1.ilist_]))]), exports.invalid), ns => [(0, dom_1.html)('li', (0, dom_1.defrag)(fillFirstLine(ns)))])
|
|
5526
|
+
exports.ulist_ = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.validate)(/^-(?=$|\s)/, (0, combinator_1.some)((0, combinator_1.creation)(1, false, (0, combinator_1.union)([(0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.fallback)((0, combinator_1.inits)([(0, combinator_1.line)((0, combinator_1.open)(/^-(?:$|\s)/, (0, combinator_1.subsequence)([exports.checkbox, (0, combinator_1.trim)((0, visibility_1.visualize)((0, util_1.lineable)((0, visibility_1.trimBlank)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))))]), true)), (0, combinator_1.indent)((0, combinator_1.union)([exports.ulist_, olist_1.olist_, ilist_1.ilist_]))]), exports.invalid), ns => [(0, dom_1.html)('li', (0, dom_1.defrag)(fillFirstLine(ns)))]))])))), es => [format((0, dom_1.html)('ul', es))])));
|
|
5527
5527
|
exports.checkbox = (0, combinator_1.creation)(1, false, (0, combinator_1.focus)(/^\[[xX ]\](?=$|\s)/, ({
|
|
5528
5528
|
source
|
|
5529
5529
|
}) => [[(0, dom_1.html)('span', {
|
|
@@ -6057,7 +6057,7 @@ exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[#', (0
|
|
|
6057
6057
|
})]))));
|
|
6058
6058
|
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.creation)((0, combinator_1.fmap)((0, combinator_1.open)('|', (0, visibility_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']'))), ns => [(0, dom_1.html)('span', {
|
|
6059
6059
|
class: 'indexer',
|
|
6060
|
-
'data-index': (0, indexee_1.identity)(undefined, ns.join('')).slice(7)
|
|
6060
|
+
'data-index': (0, indexee_1.identity)('index', undefined, ns.join('')).slice(7)
|
|
6061
6061
|
})]))));
|
|
6062
6062
|
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']'), (0, source_1.str)(']'), true), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), '}'), (0, source_1.str)('}'), true), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(3, (0, combinator_1.some)(source_1.txt, '"')), (0, source_1.str)('"'), true)])));
|
|
6063
6063
|
|
|
@@ -6072,15 +6072,15 @@ const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, comb
|
|
|
6072
6072
|
Object.defineProperty(exports, "__esModule", ({
|
|
6073
6073
|
value: true
|
|
6074
6074
|
}));
|
|
6075
|
-
exports.text = exports.signature = exports.
|
|
6075
|
+
exports.text = exports.signature = exports.identity = exports.indexee = void 0;
|
|
6076
6076
|
const combinator_1 = __webpack_require__(3484);
|
|
6077
6077
|
const memoize_1 = __webpack_require__(6925);
|
|
6078
6078
|
const dom_1 = __webpack_require__(394);
|
|
6079
|
-
function indexee(parser
|
|
6079
|
+
function indexee(parser) {
|
|
6080
6080
|
return (0, combinator_1.fmap)(parser, ([el], _, {
|
|
6081
6081
|
id
|
|
6082
6082
|
}) => [(0, dom_1.define)(el, {
|
|
6083
|
-
id: identity(id,
|
|
6083
|
+
id: identity('index', id, el)
|
|
6084
6084
|
})]);
|
|
6085
6085
|
}
|
|
6086
6086
|
exports.indexee = indexee;
|
|
@@ -6088,20 +6088,23 @@ const MAX = 60;
|
|
|
6088
6088
|
const ELLIPSIS = '...';
|
|
6089
6089
|
const PART = (MAX - ELLIPSIS.length) / 2 | 0;
|
|
6090
6090
|
const REM = MAX - PART * 2 - ELLIPSIS.length;
|
|
6091
|
-
function identity(id, text
|
|
6091
|
+
function identity(type, id, text) {
|
|
6092
6092
|
if (id === '') return undefined;
|
|
6093
|
+
if (typeof text !== 'string') {
|
|
6094
|
+
const index = text.querySelector(':scope > .indexer')?.getAttribute('data-index');
|
|
6095
|
+
if (index === '' && text.tagName === 'LI') return undefined;
|
|
6096
|
+
return index ? `${type}:${id ?? ''}:${index}` : identity(type, id, signature(text));
|
|
6097
|
+
}
|
|
6093
6098
|
text = text.trim();
|
|
6094
6099
|
if (text === '') return undefined;
|
|
6095
6100
|
const str = text.replace(/\s/g, '_');
|
|
6096
6101
|
const cs = [...str];
|
|
6097
|
-
if (
|
|
6098
|
-
|
|
6099
|
-
case 'index':
|
|
6100
|
-
case 'mark':
|
|
6101
|
-
const s1 = cs.slice(0, PART + REM).join('');
|
|
6102
|
-
const s2 = cs.slice(-PART).join('');
|
|
6103
|
-
return `${type}:${id ?? ''}:${s1}${ELLIPSIS}${s2}=${hash(text).toString(36)}`;
|
|
6102
|
+
if (type === '' || cs.length <= MAX) {
|
|
6103
|
+
return `${type}:${id ?? ''}:${str}${/_|[^\S ]/.test(text) ? `=${hash(text)}` : ''}`;
|
|
6104
6104
|
}
|
|
6105
|
+
const s1 = cs.slice(0, PART + REM).join('');
|
|
6106
|
+
const s2 = cs.slice(-PART).join('');
|
|
6107
|
+
return `${type}:${id ?? ''}:${s1}${ELLIPSIS}${s2}=${hash(text)}`;
|
|
6105
6108
|
}
|
|
6106
6109
|
exports.identity = identity;
|
|
6107
6110
|
function hash(source) {
|
|
@@ -6112,17 +6115,8 @@ function hash(source) {
|
|
|
6112
6115
|
x ^= x >>> 17;
|
|
6113
6116
|
x ^= x << 15;
|
|
6114
6117
|
}
|
|
6115
|
-
return x >>> 0;
|
|
6116
|
-
}
|
|
6117
|
-
function index(source, optional = false) {
|
|
6118
|
-
if (!source.firstChild) return '';
|
|
6119
|
-
const indexer = source.querySelector(':scope > .indexer');
|
|
6120
|
-
const text = indexer?.getAttribute('data-index');
|
|
6121
|
-
if (text === '' && optional) return '';
|
|
6122
|
-
if (text) return [...text].length <= MAX ? text : text.replace(/=\w{1,7}$/, '');
|
|
6123
|
-
return signature(source);
|
|
6118
|
+
return (x >>> 0).toString(36);
|
|
6124
6119
|
}
|
|
6125
|
-
exports.index = index;
|
|
6126
6120
|
function signature(source) {
|
|
6127
6121
|
const target = source.cloneNode(true);
|
|
6128
6122
|
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .label[data-label], .remark, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'), len = es.length, i = 0; i < len; ++i) {
|
|
@@ -6539,7 +6533,7 @@ exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, combi
|
|
|
6539
6533
|
}) => {
|
|
6540
6534
|
const el = (0, dom_1.html)('mark', (0, dom_1.defrag)(bs));
|
|
6541
6535
|
return [[(0, dom_1.define)(el, {
|
|
6542
|
-
id: (0, indexee_1.identity)(id, (0, indexee_1.signature)(el)
|
|
6536
|
+
id: (0, indexee_1.identity)('mark', id, (0, indexee_1.signature)(el))
|
|
6543
6537
|
}), el.id && (0, dom_1.html)('a', {
|
|
6544
6538
|
href: `#${el.id}`
|
|
6545
6539
|
})], rest];
|
|
@@ -7054,7 +7048,7 @@ function build(syntax, marker, splitter = '') {
|
|
|
7054
7048
|
const content = ref.firstElementChild;
|
|
7055
7049
|
content.replaceWith(content.cloneNode());
|
|
7056
7050
|
const abbr = ref.getAttribute('data-abbr') ?? '';
|
|
7057
|
-
const identifier = abbr ? (0, indexee_1.identity)(undefined, abbr.match(/^(?:\S+ )+?(?:(?:January|February|March|April|May|June|August|September|October|November|December) \d{1,2}(?:-\d{0,2})?, \d{1,4}(?:-\d{0,4})?[a-z]?|n\.d\.)(?=,|$)/)?.[0] ?? abbr.match(/^[^,\s]+(?:,? [^,\s]+)*?(?: \d{1,4}(?:-\d{0,4})?[a-z]?(?=,|$)|(?=,(?: [a-z]+\.?)? [0-9]))/)?.[0] ?? abbr
|
|
7051
|
+
const identifier = abbr ? (0, indexee_1.identity)('', undefined, abbr.match(/^(?:\S+ )+?(?:(?:January|February|March|April|May|June|August|September|October|November|December) \d{1,2}(?:-\d{0,2})?, \d{1,4}(?:-\d{0,4})?[a-z]?|n\.d\.)(?=,|$)/)?.[0] ?? abbr.match(/^[^,\s]+(?:,? [^,\s]+)*?(?: \d{1,4}(?:-\d{0,4})?[a-z]?(?=,|$)|(?=,(?: [a-z]+\.?)? [0-9]))/)?.[0] ?? abbr)?.slice(2) || '' : (0, indexee_1.identity)('mark', undefined, (0, indexee_1.signature)(content))?.slice(6) || '';
|
|
7058
7052
|
return {
|
|
7059
7053
|
content,
|
|
7060
7054
|
identifier,
|
package/package.json
CHANGED
|
@@ -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 } 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('index', context.id, heading));
|
|
38
38
|
return [
|
|
39
|
-
html('aside', { id: identity(context.id,
|
|
39
|
+
html('aside', { id: identity('index', context.id, heading), class: 'aside' }, [
|
|
40
40
|
document,
|
|
41
41
|
html('h2', 'References'),
|
|
42
42
|
references,
|
|
@@ -39,7 +39,7 @@ const list = (type: string, form: string): OListParser.ListParser => fmap(
|
|
|
39
39
|
indent(union([ulist_, olist_, ilist_])),
|
|
40
40
|
]),
|
|
41
41
|
invalid),
|
|
42
|
-
ns => [html('li', { 'data-marker': ns.shift() as string || undefined }, defrag(fillFirstLine(ns)))])
|
|
42
|
+
ns => [html('li', { 'data-marker': ns.shift() as string || undefined }, defrag(fillFirstLine(ns)))])),
|
|
43
43
|
]))),
|
|
44
44
|
es => [format(html('ol', es), type, form)]);
|
|
45
45
|
|
|
@@ -26,7 +26,7 @@ export const ulist_: UListParser = lazy(() => block(fmap(validate(
|
|
|
26
26
|
indent(union([ulist_, olist_, ilist_])),
|
|
27
27
|
]),
|
|
28
28
|
invalid),
|
|
29
|
-
ns => [html('li', defrag(fillFirstLine(ns)))])
|
|
29
|
+
ns => [html('li', defrag(fillFirstLine(ns)))])),
|
|
30
30
|
])))),
|
|
31
31
|
es => [format(html('ul', es))])));
|
|
32
32
|
|
|
@@ -44,13 +44,15 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('[#a]')), [['<a class="index" href="#index::a">a</a>'], '']);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index::a">a</a>'], '']);
|
|
46
46
|
assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index::a">a</a>'], '']);
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index::a_b">a b</a>'], '']);
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index::a__b">a b</a>'], '']);
|
|
49
47
|
assert.deepStrictEqual(inspect(parser('[#a \\ ]')), [['<a class="index" href="#index::a">a</a>'], '']);
|
|
50
48
|
assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index::a">a</a>'], '']);
|
|
51
49
|
assert.deepStrictEqual(inspect(parser('[#a <wbr>]')), [['<a class="index" href="#index::a">a</a>'], '']);
|
|
52
50
|
assert.deepStrictEqual(inspect(parser('[#a [% b %]]')), [['<a class="index" href="#index::a">a <span class="remark"><input type="checkbox"><span>[% b %]</span></span></a>'], '']);
|
|
53
51
|
assert.deepStrictEqual(inspect(parser('[#a\\ ]')), [['<a class="index" href="#index::a">a</a>'], '']);
|
|
52
|
+
assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index::a_b">a b</a>'], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index::a__b">a b</a>'], '']);
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('[#a\tb]')), [['<a class="index" href="#index::a_b=1eu1tj4">a\tb</a>'], '']);
|
|
55
|
+
assert.deepStrictEqual(inspect(parser('[#a_b]')), [['<a class="index" href="#index::a_b=10dxc9b">a_b</a>'], '']);
|
|
54
56
|
assert.deepStrictEqual(inspect(parser('[#a\\ b]')), [['<a class="index" href="#index::a_b">a b</a>'], '']);
|
|
55
57
|
assert.deepStrictEqual(inspect(parser('[#[]]')), [['<a class="index" href="#index::[]">[]</a>'], '']);
|
|
56
58
|
assert.deepStrictEqual(inspect(parser('[#\\]]')), [['<a class="index" href="#index::]">]</a>'], '']);
|
|
@@ -85,6 +87,8 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
85
87
|
assert.deepStrictEqual(inspect(parser('[#a|*b*]')), [['<a class="index" href="#index::*b*">a<span class="indexer" data-index="*b*"></span></a>'], '']);
|
|
86
88
|
assert.deepStrictEqual(inspect(parser('[#a|b c]')), [['<a class="index" href="#index::b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
|
|
87
89
|
assert.deepStrictEqual(inspect(parser('[#a|b c]')), [['<a class="index" href="#index::b__c">a<span class="indexer" data-index="b__c"></span></a>'], '']);
|
|
90
|
+
assert.deepStrictEqual(inspect(parser('[#a|b\tc]')), [['<a class="index" href="#index::b_c=3p5wqt">a<span class="indexer" data-index="b_c=3p5wqt"></span></a>'], '']);
|
|
91
|
+
assert.deepStrictEqual(inspect(parser('[#a|b_c]')), [['<a class="index" href="#index::b_c=fvw9e2">a<span class="indexer" data-index="b_c=fvw9e2"></span></a>'], '']);
|
|
88
92
|
assert.deepStrictEqual(inspect(parser('[#a|[]]')), [['<a class="index" href="#index::[]">a<span class="indexer" data-index="[]"></span></a>'], '']);
|
|
89
93
|
assert.deepStrictEqual(inspect(parser('[#a|©]')), [['<a class="index" href="#index::&copy;">a<span class="indexer" data-index="&copy;"></span></a>'], '']);
|
|
90
94
|
assert.deepStrictEqual(inspect(parser('[#a |b]')), [['<a class="index" href="#index::b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
@@ -34,7 +34,7 @@ export const signature: IndexParser.SignatureParser = lazy(() => validate('|', c
|
|
|
34
34
|
'|',
|
|
35
35
|
startTight(some(union([bracket, txt]), ']'))),
|
|
36
36
|
ns => [
|
|
37
|
-
html('span', { class: 'indexer', 'data-index': identity(undefined, ns.join(''))!.slice(7) }),
|
|
37
|
+
html('span', { class: 'indexer', 'data-index': identity('index', undefined, ns.join(''))!.slice(7) }),
|
|
38
38
|
]))));
|
|
39
39
|
|
|
40
40
|
const bracket: IndexParser.SignatureParser.BracketParser = lazy(() => creation(union([
|
|
@@ -4,9 +4,9 @@ import { fmap } from '../../../combinator';
|
|
|
4
4
|
import { reduce } from 'spica/memoize';
|
|
5
5
|
import { define } from 'typed-dom/dom';
|
|
6
6
|
|
|
7
|
-
export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parser: P
|
|
8
|
-
export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context
|
|
9
|
-
return fmap(parser, ([el], _, { id }) => [define(el, { id: identity(id,
|
|
7
|
+
export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parser: P): P;
|
|
8
|
+
export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context>): Parser<HTMLElement> {
|
|
9
|
+
return fmap(parser, ([el], _, { id }) => [define(el, { id: identity('index', id, el) })]);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const MAX = 60;
|
|
@@ -14,44 +14,50 @@ const ELLIPSIS = '...';
|
|
|
14
14
|
const PART = (MAX - ELLIPSIS.length) / 2 | 0;
|
|
15
15
|
const REM = MAX - PART * 2 - ELLIPSIS.length;
|
|
16
16
|
export function identity(
|
|
17
|
+
type: 'index' | 'mark' | '',
|
|
17
18
|
id: string | undefined,
|
|
18
|
-
text: string,
|
|
19
|
-
type: 'index' | 'mark' | '' = 'index',
|
|
19
|
+
text: string | HTMLElement,
|
|
20
20
|
): string | undefined {
|
|
21
21
|
assert(id?.match(/^[0-9a-z/-]*$/i) ?? true);
|
|
22
|
-
assert(!text.includes('\n'));
|
|
23
22
|
if (id === '') return undefined;
|
|
23
|
+
if (typeof text !== 'string') {
|
|
24
|
+
const index = text.querySelector(':scope > .indexer')?.getAttribute('data-index');
|
|
25
|
+
if (index === '' && text.tagName === 'LI') return undefined;
|
|
26
|
+
return index
|
|
27
|
+
? `${type}:${id ?? ''}:${index}`
|
|
28
|
+
: identity(type, id, signature(text));
|
|
29
|
+
}
|
|
24
30
|
text = text.trim();
|
|
25
31
|
if (text === '') return undefined;
|
|
26
32
|
const str = text.replace(/\s/g, '_');
|
|
27
33
|
const cs = [...str];
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
case 'index':
|
|
31
|
-
case 'mark':
|
|
32
|
-
const s1 = cs.slice(0, PART + REM).join('');
|
|
33
|
-
const s2 = cs.slice(-PART).join('');
|
|
34
|
-
assert([...`${s1}${ELLIPSIS}${s2}`].length === MAX);
|
|
35
|
-
return `${type}:${id ?? ''}:${s1}${ELLIPSIS}${s2}=${hash(text).toString(36)}`;
|
|
34
|
+
if (type === '' || cs.length <= MAX) {
|
|
35
|
+
return `${type}:${id ?? ''}:${str}${/_|[^\S ]/.test(text) ? `=${hash(text)}` : ''}`;
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
const s1 = cs.slice(0, PART + REM).join('');
|
|
38
|
+
const s2 = cs.slice(-PART).join('');
|
|
39
|
+
assert([...`${s1}${ELLIPSIS}${s2}`].length === MAX);
|
|
40
|
+
return `${type}:${id ?? ''}:${s1}${ELLIPSIS}${s2}=${hash(text)}`;
|
|
38
41
|
}
|
|
39
42
|
assert.deepStrictEqual(
|
|
40
|
-
identity(undefined,
|
|
43
|
+
identity('index', undefined, ' 0 '),
|
|
44
|
+
identity('index', undefined, ' 0 '.trim()));
|
|
45
|
+
assert.notDeepStrictEqual(
|
|
46
|
+
identity('index', undefined, '0 0'),
|
|
47
|
+
identity('index', undefined, '0_0'));
|
|
48
|
+
assert.notDeepStrictEqual(
|
|
49
|
+
identity('index', undefined, '0 0'),
|
|
50
|
+
identity('index', undefined, '0\t0'));
|
|
51
|
+
assert.deepStrictEqual(
|
|
52
|
+
identity('index', undefined, `${'0'.repeat(MAX - 1)}1`)!.slice(7),
|
|
41
53
|
`${'0'.repeat(MAX - 1)}1`);
|
|
42
54
|
assert.deepStrictEqual(
|
|
43
|
-
identity(undefined, `0${'1'.repeat(MAX / 2)}${'2'.repeat(MAX / 2)}3`)!.slice(7),
|
|
55
|
+
identity('index', undefined, `0${'1'.repeat(MAX / 2)}${'2'.repeat(MAX / 2)}3`)!.slice(7),
|
|
44
56
|
`0${'1'.repeat(PART + REM - 1)}${ELLIPSIS}${'2'.repeat(PART - 1)}3=mhy513`);
|
|
45
57
|
assert.deepStrictEqual(
|
|
46
|
-
identity(undefined, `0${'1'.repeat(MAX * 2)}${'2'.repeat(MAX * 2)}3`)!.slice(7),
|
|
58
|
+
identity('index', undefined, `0${'1'.repeat(MAX * 2)}${'2'.repeat(MAX * 2)}3`)!.slice(7),
|
|
47
59
|
`0${'1'.repeat(PART + REM - 1)}${ELLIPSIS}${'2'.repeat(PART - 1)}3=12jqtiv`);
|
|
48
|
-
|
|
49
|
-
identity(undefined, ` ${'0 '.repeat(MAX)}`)!.slice(7),
|
|
50
|
-
identity(undefined, ` ${'0 '.repeat(MAX)}`.trim())!.slice(7));
|
|
51
|
-
assert.notDeepStrictEqual(
|
|
52
|
-
identity(undefined, `${'0 '.repeat(MAX)}`)!.slice(7),
|
|
53
|
-
identity(undefined, `${'0_'.repeat(MAX)}`)!.slice(7));
|
|
54
|
-
function hash(source: string): number {
|
|
60
|
+
function hash(source: string): string {
|
|
55
61
|
let x = 0;
|
|
56
62
|
for (let i = 0; i < source.length; ++i) {
|
|
57
63
|
x ^= source.charCodeAt(i) << 1 | 1; // 16+1bit
|
|
@@ -59,33 +65,12 @@ function hash(source: string): number {
|
|
|
59
65
|
x ^= x >>> 17;
|
|
60
66
|
x ^= x << 15;
|
|
61
67
|
}
|
|
62
|
-
return x >>> 0;
|
|
68
|
+
return (x >>> 0).toString(36);
|
|
63
69
|
}
|
|
64
|
-
assert(hash('\x00') !== 0);
|
|
65
|
-
assert(hash('\x01') !== 0);
|
|
70
|
+
assert(hash('\x00') !== '0');
|
|
71
|
+
assert(hash('\x01') !== '0');
|
|
66
72
|
assert(hash('\x00') !== hash(String.fromCharCode(1 << 15)));
|
|
67
73
|
|
|
68
|
-
export function index(source: Element, optional = false): string {
|
|
69
|
-
assert(!source.matches('.indexer'));
|
|
70
|
-
assert(source.querySelectorAll(':scope > .indexer').length <= 1);
|
|
71
|
-
if (!source.firstChild) return '';
|
|
72
|
-
const indexer = source.querySelector(':scope > .indexer');
|
|
73
|
-
const text = indexer?.getAttribute('data-index');
|
|
74
|
-
if (text === '' && optional) return '';
|
|
75
|
-
if (text) return [...text].length <= MAX ? text : text.replace(/=\w{1,7}$/, '');
|
|
76
|
-
return signature(source);
|
|
77
|
-
}
|
|
78
|
-
assert.deepStrictEqual(
|
|
79
|
-
index(define(document.createElement('b'), [
|
|
80
|
-
define(document.createElement('b'), { class: 'indexer', 'data-index': '0'.repeat(MAX - 2) + '=0' })
|
|
81
|
-
])),
|
|
82
|
-
'0'.repeat(MAX - 2) + '=0');
|
|
83
|
-
assert.deepStrictEqual(
|
|
84
|
-
index(define(document.createElement('b'), [
|
|
85
|
-
define(document.createElement('b'), { class: 'indexer', 'data-index': '0'.repeat(MAX) + '=0' })
|
|
86
|
-
])),
|
|
87
|
-
'0'.repeat(MAX));
|
|
88
|
-
|
|
89
74
|
export function signature(source: Element | DocumentFragment): string {
|
|
90
75
|
assert(!navigator.userAgent.includes('Chrome') || !source.querySelector('br:not(:has(+ :is(ul, ol)))'));
|
|
91
76
|
const target = source.cloneNode(true) as typeof source;
|
|
@@ -25,6 +25,8 @@ describe('Unit: parser/inline/extension/indexer', () => {
|
|
|
25
25
|
assert.deepStrictEqual(inspect(parser(' [|a ]')), [['<span class="indexer" data-index="a"></span>'], '']);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser(' [|a b]')), [['<span class="indexer" data-index="a_b"></span>'], '']);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser(' [|a b]')), [['<span class="indexer" data-index="a__b"></span>'], '']);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser(' [|a\tb]')), [['<span class="indexer" data-index="a_b=1eu1tj4"></span>'], '']);
|
|
29
|
+
assert.deepStrictEqual(inspect(parser(' [|a_b]')), [['<span class="indexer" data-index="a_b=10dxc9b"></span>'], '']);
|
|
28
30
|
assert.deepStrictEqual(inspect(parser(' [|A]')), [['<span class="indexer" data-index="A"></span>'], '']);
|
|
29
31
|
assert.deepStrictEqual(inspect(parser(' [|*A*]')), [['<span class="indexer" data-index="*A*"></span>'], '']);
|
|
30
32
|
assert.deepStrictEqual(inspect(parser(' [|`A`]')), [['<span class="indexer" data-index="`A`"></span>'], '']);
|
|
@@ -38,7 +38,7 @@ describe('Unit: parser/inline/mark', () => {
|
|
|
38
38
|
it('nest', () => {
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('==a ==b====')), [['<mark id="mark::a_b">a <mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::a_b"></a>'], '']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('==a\\ ==b====')), [['<mark id="mark::a_b">a <mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::a_b"></a>'], '']);
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('==a	==b====')), [['<mark id="mark::a_b">a\t<mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::a_b"></a>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('==a	==b====')), [['<mark id="mark::a_b=1eu1tj4">a\t<mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::a_b=1eu1tj4"></a>'], '']);
|
|
42
42
|
assert.deepStrictEqual(inspect(parser('==a<wbr>==b====')), [['<mark id="mark::ab">a<wbr><mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::ab"></a>'], '']);
|
|
43
43
|
assert.deepStrictEqual(inspect(parser('==*==a==*==')), [['<mark id="mark::a"><em><mark id="mark::a">a</mark><a href="#mark::a"></a></em></mark>', '<a href="#mark::a"></a>'], '']);
|
|
44
44
|
});
|
|
@@ -20,7 +20,7 @@ export const mark: MarkParser = lazy(() => creation(surround(
|
|
|
20
20
|
([, bs], rest, { id }) => {
|
|
21
21
|
const el = html('mark', defrag(bs));
|
|
22
22
|
return [[
|
|
23
|
-
define(el, { id: identity(id, signature(el)
|
|
23
|
+
define(el, { id: identity('mark', id, signature(el)) }),
|
|
24
24
|
el.id && html('a', { href: `#${el.id}` }),
|
|
25
25
|
], rest];
|
|
26
26
|
},
|
|
@@ -39,14 +39,14 @@ function build(
|
|
|
39
39
|
const abbr = ref.getAttribute('data-abbr') ?? '';
|
|
40
40
|
const identifier = abbr
|
|
41
41
|
? identity(
|
|
42
|
+
'',
|
|
42
43
|
undefined,
|
|
43
44
|
(
|
|
44
45
|
abbr.match(/^(?:\S+ )+?(?:(?:January|February|March|April|May|June|August|September|October|November|December) \d{1,2}(?:-\d{0,2})?, \d{1,4}(?:-\d{0,4})?[a-z]?|n\.d\.)(?=,|$)/)?.[0] ??
|
|
45
46
|
abbr.match(/^[^,\s]+(?:,? [^,\s]+)*?(?: \d{1,4}(?:-\d{0,4})?[a-z]?(?=,|$)|(?=,(?: [a-z]+\.?)? [0-9]))/)?.[0] ??
|
|
46
47
|
abbr
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
: identity(undefined, signature(content), 'mark')?.slice(6) || '';
|
|
48
|
+
))?.slice(2) || ''
|
|
49
|
+
: identity('mark', undefined, signature(content))?.slice(6) || '';
|
|
50
50
|
return {
|
|
51
51
|
content,
|
|
52
52
|
identifier,
|