securemark 0.297.2 → 0.297.4
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 +59 -48
- package/package.json +1 -1
- package/src/parser/api/parse.test.ts +3 -3
- package/src/parser/inline/autolink/url.ts +6 -6
- package/src/parser/inline/extension/indexee.ts +16 -6
- package/src/parser/inline/media.ts +4 -4
- package/src/parser/inline/template.ts +5 -6
- package/src/parser/processor/note.test.ts +57 -40
- package/src/parser/processor/note.ts +57 -45
- package/src/renderer/render.ts +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.297.
|
|
1
|
+
/*! securemark v0.297.4 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"));
|
|
@@ -6632,7 +6632,7 @@ const combinator_1 = __webpack_require__(3484);
|
|
|
6632
6632
|
const inline_1 = __webpack_require__(7973);
|
|
6633
6633
|
const link_1 = __webpack_require__(3628);
|
|
6634
6634
|
const source_1 = __webpack_require__(8745);
|
|
6635
|
-
exports.url = (0, combinator_1.lazy)(() => (0, combinator_1.rewrite)((0, combinator_1.open)(/(?<![0-9A-Za-z][.+-]?|[@#])https?:\/\/(?=[\x21-\x7E])/y, (0, combinator_1.precedence)(0, (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(source_1.unescsource, /(?<![-+*=~^_,.;:!?]|\/{3})(?:[-+*=~^_,.;:!?]|\/{3,}(?!\/))*(?=[\\$"`\[\](){}<>()[]{}|]|[^\x21-\x7E]|$)/y), (0, combinator_1.precedence)(1,
|
|
6635
|
+
exports.url = (0, combinator_1.lazy)(() => (0, combinator_1.rewrite)((0, combinator_1.open)(/(?<![0-9A-Za-z][.+-]?|[@#])https?:\/\/(?=[\x21-\x7E])/y, (0, combinator_1.precedence)(0, (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(source_1.unescsource, /(?<![-+*=~^_,.;:!?]|\/{3})(?:[-+*=~^_,.;:!?]|\/{3,}(?!\/))*(?=[\\$"`\[\](){}<>()[]{}|]|[^\x21-\x7E]|$)/y), (0, combinator_1.precedence)(1, bracket)]), [[/[^\x21-\x7E]|\$/y, 9]])), false, [3 | 8 /* Backtrack.unescapable */]), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, (0, combinator_1.state)(1 /* State.autolink */, ({
|
|
6636
6636
|
context
|
|
6637
6637
|
}) => new parser_1.List([new parser_1.Node((0, link_1.parse)(new parser_1.List(), new parser_1.List([new parser_1.Node(context.source)]), context))]))), (0, combinator_1.open)((0, source_1.str)(/[^:]+/y), (0, combinator_1.some)(inline_1.inline))])));
|
|
6638
6638
|
exports.lineurl = (0, combinator_1.lazy)(() => (0, combinator_1.focus)(/(?<=^|[\r\n])!?https?:\/\/\S+(?=[^\S\n]*(?=$|\n))/y, (0, combinator_1.tails)([(0, source_1.str)('!'), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, (0, combinator_1.state)(1 /* State.autolink */, ({
|
|
@@ -6645,7 +6645,7 @@ exports.lineurl = (0, combinator_1.lazy)(() => (0, combinator_1.focus)(/(?<=^|[\
|
|
|
6645
6645
|
context.position -= source[0] === '!' ? 1 : 0;
|
|
6646
6646
|
return new parser_1.List([new parser_1.Node((0, link_1.parse)(new parser_1.List(), new parser_1.List([new parser_1.Node(source.slice(position))]), context))]);
|
|
6647
6647
|
})), (0, source_1.str)(/[^:]+/y)])])));
|
|
6648
|
-
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')')), (0, source_1.str)(')'), true, [3 | 8 /* Backtrack.unescapable */]
|
|
6648
|
+
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')')), (0, source_1.str)(')'), true, [3 | 8 /* Backtrack.unescapable */]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ']')), (0, source_1.str)(']'), true, [3 | 8 /* Backtrack.unescapable */]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), '}')), (0, source_1.str)('}'), true, [3 | 8 /* Backtrack.unescapable */]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)(source_1.unescsource, '"'))), (0, source_1.str)('"'), true, [3 | 8 /* Backtrack.unescapable */])]));
|
|
6649
6649
|
|
|
6650
6650
|
/***/ },
|
|
6651
6651
|
|
|
@@ -7129,7 +7129,7 @@ function baseR(n, r) {
|
|
|
7129
7129
|
return acc;
|
|
7130
7130
|
}
|
|
7131
7131
|
function signature(target) {
|
|
7132
|
-
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, :is(.annotation, .reference) > a, .checkbox, ul, ol, .label[data-label]'),
|
|
7132
|
+
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, :is(.annotation, .reference) > a, .checkbox, ul, ol, .label[data-label]'), i = es.length; i--;) {
|
|
7133
7133
|
const el = es[i];
|
|
7134
7134
|
switch (el.className) {
|
|
7135
7135
|
case 'math':
|
|
@@ -7138,10 +7138,15 @@ function signature(target) {
|
|
|
7138
7138
|
case 'label':
|
|
7139
7139
|
el.replaceWith(`[$${el.getAttribute('data-label').replace('$', '')}]`);
|
|
7140
7140
|
continue;
|
|
7141
|
-
case 'checkbox':
|
|
7142
|
-
case 'remark':
|
|
7143
7141
|
case 'annotation':
|
|
7142
|
+
el.replaceWith(`((${el.textContent}))`);
|
|
7143
|
+
continue;
|
|
7144
7144
|
case 'reference':
|
|
7145
|
+
const abbr = el.getAttribute('data-abbr');
|
|
7146
|
+
el.replaceWith(`[[${abbr ? `^${abbr}` : el.textContent}]]`);
|
|
7147
|
+
continue;
|
|
7148
|
+
case 'checkbox':
|
|
7149
|
+
case 'remark':
|
|
7145
7150
|
el.remove();
|
|
7146
7151
|
continue;
|
|
7147
7152
|
}
|
|
@@ -7165,16 +7170,21 @@ function signature(target) {
|
|
|
7165
7170
|
}
|
|
7166
7171
|
exports.signature = signature;
|
|
7167
7172
|
function text(target) {
|
|
7168
|
-
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, :is(.annotation, .reference) > a, .checkbox, ul, ol'),
|
|
7173
|
+
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, :is(.annotation, .reference) > a, .checkbox, ul, ol'), i = es.length; i--;) {
|
|
7169
7174
|
const el = es[i];
|
|
7170
7175
|
switch (el.className) {
|
|
7171
7176
|
case 'math':
|
|
7172
7177
|
el.replaceWith(el.getAttribute('data-src'));
|
|
7173
7178
|
continue;
|
|
7174
|
-
case 'checkbox':
|
|
7175
|
-
case 'remark':
|
|
7176
7179
|
case 'annotation':
|
|
7180
|
+
el.replaceWith(`((${el.textContent}))`);
|
|
7181
|
+
continue;
|
|
7177
7182
|
case 'reference':
|
|
7183
|
+
const abbr = el.getAttribute('data-abbr');
|
|
7184
|
+
el.replaceWith(`[[${abbr ? `^${abbr}` : el.textContent}]]`);
|
|
7185
|
+
continue;
|
|
7186
|
+
case 'checkbox':
|
|
7187
|
+
case 'remark':
|
|
7178
7188
|
el.remove();
|
|
7179
7189
|
continue;
|
|
7180
7190
|
}
|
|
@@ -7781,7 +7791,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* S
|
|
|
7781
7791
|
target: '_blank'
|
|
7782
7792
|
}, [el]))]);
|
|
7783
7793
|
}))));
|
|
7784
|
-
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ')')), (0, source_1.str)(')'), true, [
|
|
7794
|
+
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ')')), (0, source_1.str)(')'), true, [], undefined, () => new parser_1.List()), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']')), (0, source_1.str)(']'), true, [], undefined, () => new parser_1.List()), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), '}')), (0, source_1.str)('}'), true, [], undefined, () => new parser_1.List()), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, source_1.txt]), '"'))), (0, source_1.str)('"'), true, [], undefined, () => new parser_1.List())]));
|
|
7785
7795
|
const option = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, combinator_1.open)(/ /y, (0, source_1.str)(/[1-9][0-9]*/y)), (0, source_1.str)(/[x:]/y), (0, source_1.str)(/[1-9][0-9]*(?=[ }])/y), false, [], ([[{
|
|
7786
7796
|
value: a
|
|
7787
7797
|
}], [{
|
|
@@ -8105,7 +8115,7 @@ exports.template = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, s
|
|
|
8105
8115
|
class: 'invalid',
|
|
8106
8116
|
...(0, util_1.invalid)('template', 'syntax', `Missing the closing symbol "}}"`)
|
|
8107
8117
|
}, context.source.slice(context.position - context.range, context.position)))])));
|
|
8108
|
-
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), ')')), (0, source_1.str)(')'), true, [
|
|
8118
|
+
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), ')')), (0, source_1.str)(')'), true, [], undefined, ([as, bs]) => bs && as.import(bs)), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), ']')), (0, source_1.str)(']'), true, [], undefined, ([as, bs]) => bs && as.import(bs)), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), '}')), (0, source_1.str)('}'), true, [], undefined, ([as, bs]) => bs && as.import(bs)), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)(source_1.escsource, /["\n]/y, [['"', 2], ['\n', 3]]))), (0, source_1.str)('"'), true, [], undefined, ([as, bs]) => bs && as.import(bs))]));
|
|
8109
8119
|
|
|
8110
8120
|
/***/ },
|
|
8111
8121
|
|
|
@@ -8271,25 +8281,33 @@ function capitalize(label) {
|
|
|
8271
8281
|
Object.defineProperty(exports, "__esModule", ({
|
|
8272
8282
|
value: true
|
|
8273
8283
|
}));
|
|
8274
|
-
exports.
|
|
8284
|
+
exports.note = void 0;
|
|
8275
8285
|
const indexee_1 = __webpack_require__(7610);
|
|
8276
8286
|
const util_1 = __webpack_require__(4992);
|
|
8277
8287
|
const memoize_1 = __webpack_require__(6925);
|
|
8278
8288
|
const dom_1 = __webpack_require__(394);
|
|
8279
8289
|
function* note(target, notes, opts = {}, bottom = null) {
|
|
8280
|
-
|
|
8281
|
-
|
|
8290
|
+
const referenceRefMemory = referenceRefsMemoryCaller(target);
|
|
8291
|
+
const annotationRefMemory = annotationRefsMemoryCaller(target);
|
|
8292
|
+
for (const memory of [referenceRefMemory, annotationRefMemory]) {
|
|
8293
|
+
for (const [ref, {
|
|
8294
|
+
content
|
|
8295
|
+
}] of memory) {
|
|
8296
|
+
ref.replaceChildren(content);
|
|
8297
|
+
}
|
|
8298
|
+
memory.clear();
|
|
8299
|
+
}
|
|
8300
|
+
yield* reference(referenceRefMemory, target, notes?.references, opts, bottom);
|
|
8301
|
+
yield* annotation(annotationRefMemory, target, notes?.annotations, opts, bottom);
|
|
8282
8302
|
}
|
|
8283
8303
|
exports.note = note;
|
|
8284
|
-
|
|
8285
|
-
|
|
8286
|
-
|
|
8287
|
-
|
|
8288
|
-
function build(syntax,
|
|
8289
|
-
splitter &&= `${splitter}, .${
|
|
8290
|
-
|
|
8291
|
-
return function* (target, note, opts = {}, bottom = null) {
|
|
8292
|
-
const refMemory = refMemoryCaller(target);
|
|
8304
|
+
const annotationRefsMemoryCaller = (0, memoize_1.memoize)(target => new Map() ?? target, new WeakMap());
|
|
8305
|
+
const referenceRefsMemoryCaller = (0, memoize_1.memoize)(target => new Map() ?? target, new WeakMap());
|
|
8306
|
+
const annotation = build('annotation', 'annotations', '.annotation:not(:is(.annotations, .references) .annotation, .disabled)', n => `*${n}`, 'h1, h2, h3, h4, h5, h6, aside.aside, hr');
|
|
8307
|
+
const reference = build('reference', 'references', '.reference:not(:is(.annotations, .references) .reference, .disabled)', (n, abbr) => `[${abbr || n}]`);
|
|
8308
|
+
function build(syntax, list, query, marker, splitter = '') {
|
|
8309
|
+
splitter &&= `${splitter}, .${list}`;
|
|
8310
|
+
return function* (memory, target, note, opts = {}, bottom = null) {
|
|
8293
8311
|
const refInfoCaller = (0, memoize_1.memoize)(ref => {
|
|
8294
8312
|
const content = ref.firstElementChild;
|
|
8295
8313
|
const abbr = ref.getAttribute('data-abbr') ?? '';
|
|
@@ -8302,15 +8320,9 @@ function build(syntax, plural, marker, splitter = '') {
|
|
|
8302
8320
|
abbr,
|
|
8303
8321
|
text: txt
|
|
8304
8322
|
};
|
|
8305
|
-
},
|
|
8306
|
-
for (const [ref, {
|
|
8307
|
-
content
|
|
8308
|
-
}] of refMemory) {
|
|
8309
|
-
ref.replaceChildren(content);
|
|
8310
|
-
}
|
|
8311
|
-
refMemory.clear();
|
|
8323
|
+
}, memory);
|
|
8312
8324
|
const defs = new Map();
|
|
8313
|
-
const refs = target.querySelectorAll(
|
|
8325
|
+
const refs = target.querySelectorAll(query);
|
|
8314
8326
|
const identifierInfoCaller = (0, memoize_1.memoize)(identifier => ({
|
|
8315
8327
|
defIndex: 0,
|
|
8316
8328
|
defSubindex: 0,
|
|
@@ -8326,18 +8338,19 @@ function build(syntax, plural, marker, splitter = '') {
|
|
|
8326
8338
|
let refIndex = 0;
|
|
8327
8339
|
for (let len = refs.length, i = 0; i < len; ++i) {
|
|
8328
8340
|
const ref = refs[i];
|
|
8329
|
-
if (splitter) for (let
|
|
8341
|
+
if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
|
|
8342
|
+
const pos = splitter?.compareDocumentPosition(ref) ?? 0;
|
|
8343
|
+
if (pos & (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_DISCONNECTED)) break;
|
|
8330
8344
|
if (~iSplitters << 32 - 8 === 0) yield;
|
|
8331
|
-
if (
|
|
8332
|
-
|
|
8333
|
-
el.remove();
|
|
8345
|
+
if (splitter.classList.contains(list) && defs.size === 0) {
|
|
8346
|
+
splitter.remove();
|
|
8334
8347
|
continue;
|
|
8335
8348
|
}
|
|
8336
8349
|
if (defs.size > 0) {
|
|
8337
8350
|
total += defs.size;
|
|
8338
|
-
const note =
|
|
8339
|
-
class:
|
|
8340
|
-
}),
|
|
8351
|
+
const note = splitter.classList.contains(list) ? splitter : target.insertBefore((0, dom_1.html)('ol', {
|
|
8352
|
+
class: list
|
|
8353
|
+
}), splitter);
|
|
8341
8354
|
yield* proc(defs, note);
|
|
8342
8355
|
}
|
|
8343
8356
|
}
|
|
@@ -8399,17 +8412,15 @@ function build(syntax, plural, marker, splitter = '') {
|
|
|
8399
8412
|
}, `^${++refIndex}`));
|
|
8400
8413
|
}
|
|
8401
8414
|
if (note || defs.size > 0) {
|
|
8402
|
-
const
|
|
8403
|
-
note
|
|
8404
|
-
class:
|
|
8405
|
-
}),
|
|
8406
|
-
yield* proc(defs, note);
|
|
8415
|
+
const splitter = splitters[iSplitters++];
|
|
8416
|
+
yield* proc(defs, note ?? (splitter?.classList.contains(list) ? splitter : target.insertBefore((0, dom_1.html)('ol', {
|
|
8417
|
+
class: list
|
|
8418
|
+
}), splitter ?? bottom)));
|
|
8407
8419
|
}
|
|
8408
|
-
if (splitter) for (let
|
|
8420
|
+
if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
|
|
8409
8421
|
if (~iSplitters << 32 - 8 === 0) yield;
|
|
8410
|
-
if (
|
|
8411
|
-
|
|
8412
|
-
el.remove();
|
|
8422
|
+
if (splitter.classList.contains(list)) {
|
|
8423
|
+
splitter.remove();
|
|
8413
8424
|
}
|
|
8414
8425
|
}
|
|
8415
8426
|
};
|
|
@@ -9345,7 +9356,7 @@ const math_1 = __webpack_require__(3165);
|
|
|
9345
9356
|
const media_1 = __webpack_require__(3567);
|
|
9346
9357
|
const memoize_1 = __webpack_require__(6925);
|
|
9347
9358
|
const query_1 = __webpack_require__(2282);
|
|
9348
|
-
const selector = '
|
|
9359
|
+
const selector = ':not(.invalid):is(.media:is(img:not([src])[data-src], a > :not(img).media), pre.code, .math)';
|
|
9349
9360
|
const extend = (0, memoize_1.reduce)(opts => ({
|
|
9350
9361
|
code: code_1.code,
|
|
9351
9362
|
math: math_1.math,
|
package/package.json
CHANGED
|
@@ -216,12 +216,12 @@ describe('Unit: parser/api/parse', () => {
|
|
|
216
216
|
[...parse('$-a\n$$\n$$\n\n(($-a[[^B]]))[[^B|$-a]]', { notes }).children].map(el => el.outerHTML),
|
|
217
217
|
[
|
|
218
218
|
'<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>',
|
|
219
|
-
'<p><sup class="annotation" id="annotation::ref:[$-a]:1" title="(1)"><a href="#annotation::def:[$-a]:1">*1</a></sup><sup class="reference" data-abbr="B" id="reference::ref:B:
|
|
220
|
-
'<ol class="annotations"><li id="annotation::def:[$-a]:1" data-marker="*1"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="B" id="reference::ref:B:
|
|
219
|
+
'<p><sup class="annotation" id="annotation::ref:[$-a][[^B]]:1" title="(1)[[^B]]"><a href="#annotation::def:[$-a][[^B]]:1">*1</a></sup><sup class="reference" data-abbr="B" id="reference::ref:B:2" title="(1)"><a href="#reference::def:B">[B]</a></sup></p>',
|
|
220
|
+
'<ol class="annotations"><li id="annotation::def:[$-a][[^B]]:1" data-marker="*1"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="B" id="reference::ref:B:1" title="(1)"><a href="#reference::def:B">[B]</a></sup></span><sup><a href="#annotation::ref:[$-a][[^B]]:1">^1</a></sup></li></ol>',
|
|
221
221
|
]);
|
|
222
222
|
assert.deepStrictEqual(
|
|
223
223
|
notes.references.outerHTML,
|
|
224
|
-
'<ol><li id="reference::def:B"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><sup><a href="#reference::ref:B:1"
|
|
224
|
+
'<ol><li id="reference::def:B"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><sup><a href="#reference::ref:B:1">^1</a><a href="#reference::ref:B:2" title="(1)">^2</a></sup></li></ol>');
|
|
225
225
|
assert.deepStrictEqual(
|
|
226
226
|
[...parse([
|
|
227
227
|
'[[^A 1|b]]',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
2
|
import { State, Recursion, Backtrack } from '../../context';
|
|
3
3
|
import { List, Node } from '../../../combinator/data/parser';
|
|
4
|
-
import { union, tails, some, recursion, precedence, state, constraint,
|
|
4
|
+
import { union, tails, some, recursion, precedence, state, constraint, focus, rewrite, surround, open, lazy } from '../../../combinator';
|
|
5
5
|
import { inline } from '../../inline';
|
|
6
6
|
import { parse } from '../link';
|
|
7
7
|
import { unescsource, str } from '../../source';
|
|
@@ -11,7 +11,7 @@ export const url: AutolinkParser.UrlParser = lazy(() => rewrite(
|
|
|
11
11
|
/(?<![0-9A-Za-z][.+-]?|[@#])https?:\/\/(?=[\x21-\x7E])/y,
|
|
12
12
|
precedence(0, some(union([
|
|
13
13
|
some(unescsource, /(?<![-+*=~^_,.;:!?]|\/{3})(?:[-+*=~^_,.;:!?]|\/{3,}(?!\/))*(?=[\\$"`\[\](){}<>()[]{}|]|[^\x21-\x7E]|$)/y),
|
|
14
|
-
precedence(1,
|
|
14
|
+
precedence(1, bracket),
|
|
15
15
|
]), [[/[^\x21-\x7E]|\$/y, 9]])),
|
|
16
16
|
false,
|
|
17
17
|
[3 | Backtrack.unescapable]),
|
|
@@ -42,11 +42,11 @@ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => focus(
|
|
|
42
42
|
|
|
43
43
|
const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => union([
|
|
44
44
|
surround(str('('), recursion(Recursion.terminal, some(union([bracket, unescsource]), ')')), str(')'),
|
|
45
|
-
true, [3 | Backtrack.unescapable]
|
|
45
|
+
true, [3 | Backtrack.unescapable]),
|
|
46
46
|
surround(str('['), recursion(Recursion.terminal, some(union([bracket, unescsource]), ']')), str(']'),
|
|
47
|
-
true, [3 | Backtrack.unescapable]
|
|
47
|
+
true, [3 | Backtrack.unescapable]),
|
|
48
48
|
surround(str('{'), recursion(Recursion.terminal, some(union([bracket, unescsource]), '}')), str('}'),
|
|
49
|
-
true, [3 | Backtrack.unescapable]
|
|
49
|
+
true, [3 | Backtrack.unescapable]),
|
|
50
50
|
surround(str('"'), precedence(2, recursion(Recursion.terminal, some(unescsource, '"'))), str('"'),
|
|
51
|
-
true, [3 | Backtrack.unescapable]
|
|
51
|
+
true, [3 | Backtrack.unescapable]),
|
|
52
52
|
]));
|
|
@@ -110,7 +110,7 @@ export function signature(target: Element | DocumentFragment): string {
|
|
|
110
110
|
assert(!target.parentNode);
|
|
111
111
|
assert(!target.querySelector('br:not(:has(+ :is(ul, ol)))') || target.nodeName === 'MARK');
|
|
112
112
|
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, :is(.annotation, .reference) > a, .checkbox, ul, ol, .label[data-label]'),
|
|
113
|
-
|
|
113
|
+
i = es.length; i--;) {
|
|
114
114
|
const el = es[i];
|
|
115
115
|
switch (el.className) {
|
|
116
116
|
case 'math':
|
|
@@ -119,10 +119,15 @@ export function signature(target: Element | DocumentFragment): string {
|
|
|
119
119
|
case 'label':
|
|
120
120
|
el.replaceWith(`[$${el.getAttribute('data-label')!.replace('$', '')}]`);
|
|
121
121
|
continue;
|
|
122
|
-
case 'checkbox':
|
|
123
|
-
case 'remark':
|
|
124
122
|
case 'annotation':
|
|
123
|
+
el.replaceWith(`((${el.textContent}))`);
|
|
124
|
+
continue;
|
|
125
125
|
case 'reference':
|
|
126
|
+
const abbr = el.getAttribute('data-abbr');
|
|
127
|
+
el.replaceWith(`[[${abbr ? `^${abbr}` : el.textContent}]]`);
|
|
128
|
+
continue;
|
|
129
|
+
case 'checkbox':
|
|
130
|
+
case 'remark':
|
|
126
131
|
el.remove();
|
|
127
132
|
continue;
|
|
128
133
|
}
|
|
@@ -149,16 +154,21 @@ export function text(target: Element | DocumentFragment): string {
|
|
|
149
154
|
assert(!target.parentNode);
|
|
150
155
|
assert(!target.querySelector('br:not(:has(+ :is(ul, ol)))'));
|
|
151
156
|
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, :is(.annotation, .reference) > a, .checkbox, ul, ol'),
|
|
152
|
-
|
|
157
|
+
i = es.length; i--;) {
|
|
153
158
|
const el = es[i];
|
|
154
159
|
switch (el.className) {
|
|
155
160
|
case 'math':
|
|
156
161
|
el.replaceWith(el.getAttribute('data-src')!);
|
|
157
162
|
continue;
|
|
158
|
-
case 'checkbox':
|
|
159
|
-
case 'remark':
|
|
160
163
|
case 'annotation':
|
|
164
|
+
el.replaceWith(`((${el.textContent}))`);
|
|
165
|
+
continue;
|
|
161
166
|
case 'reference':
|
|
167
|
+
const abbr = el.getAttribute('data-abbr');
|
|
168
|
+
el.replaceWith(`[[${abbr ? `^${abbr}` : el.textContent}]]`);
|
|
169
|
+
continue;
|
|
170
|
+
case 'checkbox':
|
|
171
|
+
case 'remark':
|
|
162
172
|
el.remove();
|
|
163
173
|
continue;
|
|
164
174
|
}
|
|
@@ -114,13 +114,13 @@ export const media: MediaParser = lazy(() => constraint(State.media, open(
|
|
|
114
114
|
|
|
115
115
|
const bracket: MediaParser.TextParser.BracketParser = lazy(() => union([
|
|
116
116
|
surround(str('('), recursion(Recursion.terminal, some(union([unsafehtmlentity, bracket, txt]), ')')), str(')'),
|
|
117
|
-
true, [
|
|
117
|
+
true, [], undefined, () => new List()),
|
|
118
118
|
surround(str('['), recursion(Recursion.terminal, some(union([unsafehtmlentity, bracket, txt]), ']')), str(']'),
|
|
119
|
-
true, [
|
|
119
|
+
true, [], undefined, () => new List()),
|
|
120
120
|
surround(str('{'), recursion(Recursion.terminal, some(union([unsafehtmlentity, bracket, txt]), '}')), str('}'),
|
|
121
|
-
true, [
|
|
121
|
+
true, [], undefined, () => new List()),
|
|
122
122
|
surround(str('"'), precedence(2, recursion(Recursion.terminal, some(union([unsafehtmlentity, txt]), '"'))), str('"'),
|
|
123
|
-
true, [
|
|
123
|
+
true, [], undefined, () => new List()),
|
|
124
124
|
]));
|
|
125
125
|
|
|
126
126
|
const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TemplateParser } from '../inline';
|
|
2
|
-
import { Recursion
|
|
2
|
+
import { Recursion } from '../context';
|
|
3
3
|
import { List, Node } from '../../combinator/data/parser';
|
|
4
4
|
import { union, some, recursion, precedence, surround, lazy } from '../../combinator';
|
|
5
5
|
import { escsource, str } from '../source';
|
|
@@ -27,17 +27,16 @@ export const template: TemplateParser = lazy(() => surround(
|
|
|
27
27
|
|
|
28
28
|
const bracket: TemplateParser.BracketParser = lazy(() => union([
|
|
29
29
|
surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'),
|
|
30
|
-
true, [
|
|
30
|
+
true, [], undefined, ([as, bs]) => bs && as.import(bs as List<Node<string>>)),
|
|
31
31
|
surround(str('['), recursion(Recursion.terminal, some(union([bracket, escsource]), ']')), str(']'),
|
|
32
|
-
true, [
|
|
32
|
+
true, [], undefined, ([as, bs]) => bs && as.import(bs as List<Node<string>>)),
|
|
33
33
|
surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'),
|
|
34
|
-
true, [
|
|
34
|
+
true, [], undefined, ([as, bs]) => bs && as.import(bs as List<Node<string>>)),
|
|
35
35
|
surround(
|
|
36
36
|
str('"'),
|
|
37
37
|
precedence(2, recursion(Recursion.terminal, some(escsource, /["\n]/y, [['"', 2], ['\n', 3]]))),
|
|
38
38
|
str('"'),
|
|
39
|
-
true,
|
|
40
|
-
[3 | Backtrack.escapable],
|
|
39
|
+
true, [],
|
|
41
40
|
undefined,
|
|
42
41
|
([as, bs]) => bs && as.import(bs as List<Node<string>>)),
|
|
43
42
|
]));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { note
|
|
1
|
+
import { note } from './note';
|
|
2
2
|
import { parse as parse_ } from '../../parser';
|
|
3
3
|
import { html } from 'typed-dom/dom';
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
8
8
|
describe('annotation', () => {
|
|
9
9
|
it('empty', () => {
|
|
10
10
|
const target = parse('');
|
|
11
|
-
[...
|
|
11
|
+
[...note(target)];
|
|
12
12
|
assert.deepStrictEqual(
|
|
13
13
|
[...target.children].map(el => el.outerHTML),
|
|
14
14
|
[]);
|
|
@@ -17,7 +17,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
17
17
|
it('1', () => {
|
|
18
18
|
const target = parse('((a b))');
|
|
19
19
|
for (let i = 0; i < 3; ++i) {
|
|
20
|
-
assert.deepStrictEqual([...
|
|
20
|
+
assert.deepStrictEqual([...note(target)].length, i === 0 ? 2 : 3);
|
|
21
21
|
assert.deepStrictEqual(
|
|
22
22
|
[...target.children].map(el => el.outerHTML),
|
|
23
23
|
[
|
|
@@ -39,7 +39,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
39
39
|
it('2', () => {
|
|
40
40
|
const target = parse('((1))((12345678901234567890))');
|
|
41
41
|
for (let i = 0; i < 3; ++i) {
|
|
42
|
-
assert.deepStrictEqual([...
|
|
42
|
+
assert.deepStrictEqual([...note(target)].length, i === 0 ? 4 : 6);
|
|
43
43
|
assert.deepStrictEqual(
|
|
44
44
|
[...target.children].map(el => el.outerHTML),
|
|
45
45
|
[
|
|
@@ -68,7 +68,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
68
68
|
it('unify', () => {
|
|
69
69
|
const target = parse('((1))((2))((3))((2))((4))');
|
|
70
70
|
for (let i = 0; i < 3; ++i) {
|
|
71
|
-
[...
|
|
71
|
+
[...note(target)];
|
|
72
72
|
assert.deepStrictEqual(
|
|
73
73
|
[...target.children].map(el => el.outerHTML),
|
|
74
74
|
[
|
|
@@ -121,7 +121,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
121
121
|
'((4))',
|
|
122
122
|
].join('\n\n')).children);
|
|
123
123
|
for (let i = 0; i < 3; ++i) {
|
|
124
|
-
[...
|
|
124
|
+
[...note(target)];
|
|
125
125
|
assert.deepStrictEqual(
|
|
126
126
|
[...target.children].map(el => el.outerHTML),
|
|
127
127
|
[
|
|
@@ -202,7 +202,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
202
202
|
it('id', () => {
|
|
203
203
|
const target = parse('((a b))');
|
|
204
204
|
for (let i = 0; i < 3; ++i) {
|
|
205
|
-
assert.deepStrictEqual([...
|
|
205
|
+
assert.deepStrictEqual([...note(target, undefined, { id: '0' })].length, i === 0 ? 2 : 3);
|
|
206
206
|
assert.deepStrictEqual(
|
|
207
207
|
[...target.children].map(el => el.outerHTML),
|
|
208
208
|
[
|
|
@@ -222,37 +222,39 @@ describe('Unit: parser/processor/note', () => {
|
|
|
222
222
|
});
|
|
223
223
|
|
|
224
224
|
it('nest', () => {
|
|
225
|
-
const target = parse('((a((b((c))))))((a))((b))');
|
|
225
|
+
const target = parse('((a((b((c))))))((a))((b))((c))');
|
|
226
226
|
for (let i = 0; i < 3; ++i) {
|
|
227
|
-
[...
|
|
227
|
+
[...note(target)];
|
|
228
228
|
assert.deepStrictEqual(
|
|
229
229
|
[...target.children].map(el => el.outerHTML),
|
|
230
230
|
[
|
|
231
231
|
html('p', [
|
|
232
|
+
html('sup', { class: 'annotation', id: 'annotation::ref:a((b((c)))):1', title: 'a((b((c))))' }, [
|
|
233
|
+
html('a', { href: '#annotation::def:a((b((c)))):1' }, '*1')
|
|
234
|
+
]),
|
|
232
235
|
html('sup', { class: 'annotation', id: 'annotation::ref:a:1', title: 'a' }, [
|
|
233
|
-
html('a', { href: '#annotation::def:a:1' }, '*
|
|
236
|
+
html('a', { href: '#annotation::def:a:1' }, '*4')
|
|
234
237
|
]),
|
|
235
|
-
html('sup', { class: 'annotation', id: 'annotation::ref:
|
|
236
|
-
html('a', { href: '#annotation::def:
|
|
238
|
+
html('sup', { class: 'annotation', id: 'annotation::ref:b:1', title: 'b' }, [
|
|
239
|
+
html('a', { href: '#annotation::def:b:1' }, '*5')
|
|
237
240
|
]),
|
|
238
|
-
html('sup', { class: 'annotation', id: 'annotation::ref:
|
|
239
|
-
html('a', { href: '#annotation::def:
|
|
241
|
+
html('sup', { class: 'annotation', id: 'annotation::ref:c:2', title: 'c' }, [
|
|
242
|
+
html('a', { href: '#annotation::def:c:1' }, '*3')
|
|
240
243
|
]),
|
|
241
244
|
]).outerHTML,
|
|
242
245
|
html('ol', { class: 'annotations' }, [
|
|
243
|
-
html('li', { id: 'annotation::def:a:1', 'data-marker': '*1' }, [
|
|
246
|
+
html('li', { id: 'annotation::def:a((b((c)))):1', 'data-marker': '*1' }, [
|
|
244
247
|
html('span', [
|
|
245
248
|
'a',
|
|
246
|
-
html('sup', { class: 'annotation', id: 'annotation::ref:b:1', title: 'b' }, [
|
|
247
|
-
html('a', { href: '#annotation::def:b:1' }, '*2')
|
|
249
|
+
html('sup', { class: 'annotation', id: 'annotation::ref:b((c)):1', title: 'b((c))' }, [
|
|
250
|
+
html('a', { href: '#annotation::def:b((c)):1' }, '*2')
|
|
248
251
|
]),
|
|
249
252
|
]),
|
|
250
253
|
html('sup', [
|
|
251
|
-
html('a', { href: '#annotation::ref:a:1' }, '^1'),
|
|
252
|
-
html('a', { href: '#annotation::ref:a:2' }, '^4'),
|
|
254
|
+
html('a', { href: '#annotation::ref:a((b((c)))):1' }, '^1'),
|
|
253
255
|
])
|
|
254
256
|
]),
|
|
255
|
-
html('li', { id: 'annotation::def:b:1', 'data-marker': '*2' }, [
|
|
257
|
+
html('li', { id: 'annotation::def:b((c)):1', 'data-marker': '*2' }, [
|
|
256
258
|
html('span', [
|
|
257
259
|
'b',
|
|
258
260
|
html('sup', { class: 'annotation', id: 'annotation::ref:c:1', title: 'c' }, [
|
|
@@ -260,8 +262,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
260
262
|
]),
|
|
261
263
|
]),
|
|
262
264
|
html('sup', [
|
|
263
|
-
html('a', { href: '#annotation::ref:b:1' }, '^2'),
|
|
264
|
-
html('a', { href: '#annotation::ref:b:2' }, '^5'),
|
|
265
|
+
html('a', { href: '#annotation::ref:b((c)):1' }, '^2'),
|
|
265
266
|
])
|
|
266
267
|
]),
|
|
267
268
|
html('li', { id: 'annotation::def:c:1', 'data-marker': '*3' }, [
|
|
@@ -270,6 +271,23 @@ describe('Unit: parser/processor/note', () => {
|
|
|
270
271
|
]),
|
|
271
272
|
html('sup', [
|
|
272
273
|
html('a', { href: '#annotation::ref:c:1' }, '^3'),
|
|
274
|
+
html('a', { href: '#annotation::ref:c:2' }, '^6'),
|
|
275
|
+
])
|
|
276
|
+
]),
|
|
277
|
+
html('li', { id: 'annotation::def:a:1', 'data-marker': '*4' }, [
|
|
278
|
+
html('span', [
|
|
279
|
+
'a',
|
|
280
|
+
]),
|
|
281
|
+
html('sup', [
|
|
282
|
+
html('a', { href: '#annotation::ref:a:1' }, '^4'),
|
|
283
|
+
])
|
|
284
|
+
]),
|
|
285
|
+
html('li', { id: 'annotation::def:b:1', 'data-marker': '*5' }, [
|
|
286
|
+
html('span', [
|
|
287
|
+
'b',
|
|
288
|
+
]),
|
|
289
|
+
html('sup', [
|
|
290
|
+
html('a', { href: '#annotation::ref:b:1' }, '^5'),
|
|
273
291
|
])
|
|
274
292
|
]),
|
|
275
293
|
]).outerHTML,
|
|
@@ -282,9 +300,9 @@ describe('Unit: parser/processor/note', () => {
|
|
|
282
300
|
describe('reference', () => {
|
|
283
301
|
it('1', () => {
|
|
284
302
|
const target = parse('[[a b]]');
|
|
285
|
-
const
|
|
303
|
+
const notes = { references: html('ol') };
|
|
286
304
|
for (let i = 0; i < 3; ++i) {
|
|
287
|
-
[...
|
|
305
|
+
[...note(target, notes)];
|
|
288
306
|
assert.deepStrictEqual(
|
|
289
307
|
[...target.children].map(el => el.outerHTML),
|
|
290
308
|
[
|
|
@@ -295,7 +313,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
295
313
|
]).outerHTML,
|
|
296
314
|
]);
|
|
297
315
|
assert.deepStrictEqual(
|
|
298
|
-
[
|
|
316
|
+
[notes.references.outerHTML],
|
|
299
317
|
[
|
|
300
318
|
html('ol', [
|
|
301
319
|
html('li', { id: 'reference::def:a_b' }, [
|
|
@@ -309,9 +327,9 @@ describe('Unit: parser/processor/note', () => {
|
|
|
309
327
|
|
|
310
328
|
it('abbr', () => {
|
|
311
329
|
const target = parse('[[^A 1]][[^A 1|b]][[^A 1]]');
|
|
312
|
-
const
|
|
330
|
+
const notes = { references: html('ol') };
|
|
313
331
|
for (let i = 0; i < 3; ++i) {
|
|
314
|
-
[...
|
|
332
|
+
[...note(target, notes)];
|
|
315
333
|
assert.deepStrictEqual(
|
|
316
334
|
[...target.children].map(el => el.outerHTML),
|
|
317
335
|
[
|
|
@@ -328,7 +346,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
328
346
|
]).outerHTML,
|
|
329
347
|
]);
|
|
330
348
|
assert.deepStrictEqual(
|
|
331
|
-
[
|
|
349
|
+
[notes.references.outerHTML],
|
|
332
350
|
[
|
|
333
351
|
html('ol', [
|
|
334
352
|
html('li', { id: 'reference::def:A_1' }, [
|
|
@@ -346,42 +364,41 @@ describe('Unit: parser/processor/note', () => {
|
|
|
346
364
|
|
|
347
365
|
it('nest', () => {
|
|
348
366
|
const target = parse('((a[[^B]]))[[^B|c]]');
|
|
349
|
-
const
|
|
367
|
+
const notes = { references: html('ol') };
|
|
350
368
|
for (let i = 0; i < 3; ++i) {
|
|
351
|
-
[...
|
|
352
|
-
[...reference(target, note)];
|
|
369
|
+
[...note(target, notes)];
|
|
353
370
|
assert.deepStrictEqual(
|
|
354
371
|
[...target.children].map(el => el.outerHTML),
|
|
355
372
|
[
|
|
356
373
|
html('p', [
|
|
357
|
-
html('sup', { class: 'annotation', id: 'annotation::ref:a:1', title: 'a' }, [
|
|
358
|
-
html('a', { href: '#annotation::def:a:1' }, '*1')
|
|
374
|
+
html('sup', { class: 'annotation', id: 'annotation::ref:a[[^B]]:1', title: 'a[[^B]]' }, [
|
|
375
|
+
html('a', { href: '#annotation::def:a[[^B]]:1' }, '*1')
|
|
359
376
|
]),
|
|
360
|
-
html('sup', { class: 'reference', 'data-abbr': 'B', id: 'reference::ref:B:
|
|
377
|
+
html('sup', { class: 'reference', 'data-abbr': 'B', id: 'reference::ref:B:2', title: 'c' }, [
|
|
361
378
|
html('a', { href: '#reference::def:B' }, '[B]')
|
|
362
379
|
]),
|
|
363
380
|
]).outerHTML,
|
|
364
381
|
html('ol', { class: 'annotations' }, [
|
|
365
|
-
html('li', { id: 'annotation::def:a:1', 'data-marker': '*1' }, [
|
|
382
|
+
html('li', { id: 'annotation::def:a[[^B]]:1', 'data-marker': '*1' }, [
|
|
366
383
|
html('span', [
|
|
367
384
|
'a',
|
|
368
|
-
html('sup', { class: 'reference', 'data-abbr': 'B', id: 'reference::ref:B:
|
|
385
|
+
html('sup', { class: 'reference', 'data-abbr': 'B', id: 'reference::ref:B:1', title: 'c' }, [
|
|
369
386
|
html('a', { href: '#reference::def:B' }, '[B]')
|
|
370
387
|
]),
|
|
371
388
|
]),
|
|
372
|
-
html('sup', [html('a', { href: '#annotation::ref:a:1' }, '^1')])
|
|
389
|
+
html('sup', [html('a', { href: '#annotation::ref:a[[^B]]:1' }, '^1')])
|
|
373
390
|
]),
|
|
374
391
|
]).outerHTML,
|
|
375
392
|
]);
|
|
376
393
|
assert.deepStrictEqual(
|
|
377
|
-
[
|
|
394
|
+
[notes.references.outerHTML],
|
|
378
395
|
[
|
|
379
396
|
html('ol', [
|
|
380
397
|
html('li', { id: 'reference::def:B' }, [
|
|
381
398
|
html('span', 'c'),
|
|
382
399
|
html('sup', [
|
|
383
|
-
html('a', { href: '#reference::ref:B:1'
|
|
384
|
-
html('a', { href: '#reference::ref:B:2' }, '^2'),
|
|
400
|
+
html('a', { href: '#reference::ref:B:1' }, '^1'),
|
|
401
|
+
html('a', { href: '#reference::ref:B:2', title: 'c' }, '^2'),
|
|
385
402
|
]),
|
|
386
403
|
]),
|
|
387
404
|
]).outerHTML,
|
|
@@ -12,45 +12,66 @@ export function* note(
|
|
|
12
12
|
opts: { readonly id?: string; } = {},
|
|
13
13
|
bottom: Node | null = null,
|
|
14
14
|
): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const referenceRefMemory = referenceRefsMemoryCaller(target);
|
|
16
|
+
const annotationRefMemory = annotationRefsMemoryCaller(target);
|
|
17
|
+
for (const memory of [referenceRefMemory, annotationRefMemory]) {
|
|
18
|
+
for (const [ref, { content }] of memory) {
|
|
19
|
+
ref.replaceChildren(content);
|
|
20
|
+
}
|
|
21
|
+
memory.clear();
|
|
22
|
+
}
|
|
23
|
+
yield* reference(referenceRefMemory, target, notes?.references, opts, bottom);
|
|
24
|
+
yield* annotation(annotationRefMemory, target, notes?.annotations, opts, bottom);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface RefMemory {
|
|
28
|
+
readonly content: Element;
|
|
29
|
+
readonly identifier: string;
|
|
30
|
+
readonly abbr: string;
|
|
31
|
+
readonly text: string;
|
|
17
32
|
}
|
|
18
33
|
|
|
19
|
-
|
|
34
|
+
const annotationRefsMemoryCaller = memoize((target: Node) =>
|
|
35
|
+
new Map<HTMLElement, RefMemory>() ?? target,
|
|
36
|
+
new WeakMap());
|
|
37
|
+
|
|
38
|
+
const referenceRefsMemoryCaller = memoize((target: Node) =>
|
|
39
|
+
new Map<HTMLElement, {
|
|
40
|
+
readonly content: Element;
|
|
41
|
+
readonly identifier: string;
|
|
42
|
+
readonly abbr: string;
|
|
43
|
+
readonly text: string;
|
|
44
|
+
}>() ?? target,
|
|
45
|
+
new WeakMap());
|
|
46
|
+
|
|
47
|
+
const annotation = build(
|
|
20
48
|
'annotation',
|
|
21
49
|
'annotations',
|
|
50
|
+
'.annotation:not(:is(.annotations, .references) .annotation, .disabled)',
|
|
22
51
|
n => `*${n}`,
|
|
23
52
|
'h1, h2, h3, h4, h5, h6, aside.aside, hr');
|
|
24
|
-
|
|
53
|
+
const reference = build(
|
|
25
54
|
'reference',
|
|
26
55
|
'references',
|
|
56
|
+
'.reference:not(:is(.annotations, .references) .reference, .disabled)',
|
|
27
57
|
(n, abbr) => `[${abbr || n}]`);
|
|
28
58
|
|
|
29
|
-
// Referenceを含むAnnotationの重複排除は両構文が互いに処理済みであることを必要とするため
|
|
30
|
-
// 構文ごとに各1回の処理では不可能
|
|
31
59
|
function build(
|
|
32
60
|
syntax: string,
|
|
33
|
-
|
|
61
|
+
list: string,
|
|
62
|
+
query: string,
|
|
34
63
|
marker: (index: number, abbr: string) => string,
|
|
35
64
|
splitter: string = '',
|
|
36
65
|
) {
|
|
37
66
|
assert(syntax.match(/^[a-z]+$/));
|
|
38
|
-
splitter &&= `${splitter}, .${
|
|
39
|
-
const refMemoryCaller = memoize((target: Node) =>
|
|
40
|
-
new Map<HTMLElement, {
|
|
41
|
-
readonly content: Element;
|
|
42
|
-
readonly identifier: string;
|
|
43
|
-
readonly abbr: string;
|
|
44
|
-
readonly text: string;
|
|
45
|
-
}>() ?? target,
|
|
46
|
-
new WeakMap());
|
|
67
|
+
splitter &&= `${splitter}, .${list}`;
|
|
47
68
|
return function* (
|
|
69
|
+
memory: Map<HTMLElement, RefMemory>,
|
|
48
70
|
target: ParentNode & Node,
|
|
49
71
|
note?: HTMLOListElement,
|
|
50
72
|
opts: { readonly id?: string } = {},
|
|
51
73
|
bottom: Node | null = null,
|
|
52
74
|
): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
|
|
53
|
-
const refMemory = refMemoryCaller(target);
|
|
54
75
|
const refInfoCaller = memoize((ref: HTMLElement) => {
|
|
55
76
|
const content = ref.firstElementChild!;
|
|
56
77
|
const abbr = ref.getAttribute('data-abbr') ?? '';
|
|
@@ -72,13 +93,9 @@ function build(
|
|
|
72
93
|
abbr,
|
|
73
94
|
text: txt,
|
|
74
95
|
};
|
|
75
|
-
},
|
|
76
|
-
for (const [ref, { content }] of refMemory) {
|
|
77
|
-
ref.replaceChildren(content);
|
|
78
|
-
}
|
|
79
|
-
refMemory.clear();
|
|
96
|
+
}, memory);
|
|
80
97
|
const defs = new Map<string, HTMLLIElement>();
|
|
81
|
-
const refs = target.querySelectorAll<HTMLElement>(
|
|
98
|
+
const refs = target.querySelectorAll<HTMLElement>(query);
|
|
82
99
|
const identifierInfoCaller = memoize((identifier: string) => ({
|
|
83
100
|
defIndex: 0,
|
|
84
101
|
defSubindex: 0,
|
|
@@ -94,23 +111,21 @@ function build(
|
|
|
94
111
|
let refIndex = 0;
|
|
95
112
|
for (let len = refs.length, i = 0; i < len; ++i) {
|
|
96
113
|
const ref = refs[i];
|
|
97
|
-
if (splitter) for (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
el?.compareDocumentPosition(ref) & Node.DOCUMENT_POSITION_FOLLOWING;
|
|
101
|
-
++iSplitters) {
|
|
114
|
+
if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
|
|
115
|
+
const pos = splitter?.compareDocumentPosition(ref) ?? 0;
|
|
116
|
+
if (pos & (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_DISCONNECTED)) break;
|
|
102
117
|
if (~iSplitters << 32 - 8 === 0) yield;
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
el.remove();
|
|
118
|
+
if (splitter.classList.contains(list) && defs.size === 0) {
|
|
119
|
+
assert(splitter.matches(`.${list}`));
|
|
120
|
+
splitter.remove();
|
|
107
121
|
continue;
|
|
108
122
|
}
|
|
109
123
|
if (defs.size > 0) {
|
|
110
124
|
total += defs.size;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
125
|
+
assert(splitter.parentNode);
|
|
126
|
+
const note = splitter.classList.contains(list)
|
|
127
|
+
? splitter as HTMLOListElement
|
|
128
|
+
: target.insertBefore(html('ol', { class: list }), splitter);
|
|
114
129
|
assert(note.parentNode);
|
|
115
130
|
yield* proc(defs, note);
|
|
116
131
|
assert(defs.size === 0);
|
|
@@ -183,19 +198,16 @@ function build(
|
|
|
183
198
|
`^${++refIndex}`));
|
|
184
199
|
}
|
|
185
200
|
if (note || defs.size > 0) {
|
|
186
|
-
const
|
|
187
|
-
note
|
|
188
|
-
?
|
|
189
|
-
: target.insertBefore(html('ol', { class:
|
|
190
|
-
yield* proc(defs, note);
|
|
201
|
+
const splitter = splitters[iSplitters++];
|
|
202
|
+
yield* proc(defs, note ?? (splitter?.classList.contains(list)
|
|
203
|
+
? splitter as HTMLOListElement
|
|
204
|
+
: target.insertBefore(html('ol', { class: list }), splitter ?? bottom)));
|
|
191
205
|
assert(defs.size === 0);
|
|
192
206
|
}
|
|
193
|
-
if (splitter) for (let
|
|
207
|
+
if (splitter) for (let splitter; splitter = splitters[iSplitters]; ++iSplitters) {
|
|
194
208
|
if (~iSplitters << 32 - 8 === 0) yield;
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
assert(el.matches(`.${plural}`));
|
|
198
|
-
el.remove();
|
|
209
|
+
if (splitter.classList.contains(list)) {
|
|
210
|
+
splitter.remove();
|
|
199
211
|
}
|
|
200
212
|
}
|
|
201
213
|
}
|
package/src/renderer/render.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { media } from './render/media';
|
|
|
5
5
|
import { reduce } from 'spica/memoize';
|
|
6
6
|
import { querySelectorAllWith } from 'typed-dom/query';
|
|
7
7
|
|
|
8
|
-
const selector = '
|
|
8
|
+
const selector = ':not(.invalid):is(.media:is(img:not([src])[data-src], a > :not(img).media), pre.code, .math)';
|
|
9
9
|
|
|
10
10
|
const extend = reduce((opts: RenderingOptions): RenderingOptions =>
|
|
11
11
|
({ code, math, media: {}, ...opts }));
|