securemark 0.260.3 → 0.260.6
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 +12 -0
- package/dist/index.js +242 -138
- package/markdown.d.ts +2 -2
- package/package.json +5 -5
- package/src/combinator/data/parser/context/memo.ts +7 -3
- package/src/combinator/data/parser/context.ts +25 -16
- package/src/combinator/data/parser.ts +0 -1
- package/src/parser/api/bind.ts +2 -1
- package/src/parser/api/parse.ts +2 -1
- package/src/parser/block/reply/cite.test.ts +5 -0
- package/src/parser/block/reply/cite.ts +5 -4
- package/src/parser/context.ts +8 -7
- package/src/parser/inline/autolink.ts +1 -1
- package/src/parser/inline/extension/index.ts +1 -1
- package/src/parser/inline/extension/placeholder.ts +1 -1
- package/src/parser/inline/link.test.ts +2 -0
- package/src/parser/inline/link.ts +5 -5
- package/src/parser/inline/media.ts +2 -2
- package/src/parser/inline/ruby.ts +10 -6
- package/src/parser/inline/template.ts +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.260.
|
|
1
|
+
/*! securemark v0.260.6 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("DOMPurify"), require("Prism"));
|
|
@@ -64,9 +64,9 @@ __exportStar(__webpack_require__(256), exports);
|
|
|
64
64
|
Object.defineProperty(exports, "__esModule", ({
|
|
65
65
|
value: true
|
|
66
66
|
}));
|
|
67
|
-
exports.ObjectSetPrototypeOf = exports.ObjectGetPrototypeOf = exports.ObjectCreate = exports.ObjectAssign = exports.toString = exports.isEnumerable = exports.isPrototypeOf = exports.hasOwnProperty = exports.isArray = exports.sign = exports.round = exports.random = exports.min = exports.max = exports.floor = exports.ceil = exports.abs = exports.parseInt = exports.parseFloat = exports.isSafeInteger = exports.isNaN = exports.isInteger = exports.isFinite = exports[NaN] = void 0;
|
|
67
|
+
exports.ObjectSetPrototypeOf = exports.ObjectGetPrototypeOf = exports.ObjectCreate = exports.ObjectAssign = exports.toString = exports.isEnumerable = exports.isPrototypeOf = exports.hasOwnProperty = exports.isArray = exports.sqrt = exports.log = exports.tan = exports.cos = exports.sign = exports.round = exports.random = exports.min = exports.max = exports.floor = exports.ceil = exports.abs = exports.parseInt = exports.parseFloat = exports.isSafeInteger = exports.isNaN = exports.isInteger = exports.isFinite = exports[NaN] = void 0;
|
|
68
68
|
exports[NaN] = Number.NaN, exports.isFinite = Number.isFinite, exports.isInteger = Number.isInteger, exports.isNaN = Number.isNaN, exports.isSafeInteger = Number.isSafeInteger, exports.parseFloat = Number.parseFloat, exports.parseInt = Number.parseInt;
|
|
69
|
-
exports.abs = Math.abs, exports.ceil = Math.ceil, exports.floor = Math.floor, exports.max = Math.max, exports.min = Math.min, exports.random = Math.random, exports.round = Math.round, exports.sign = Math.sign;
|
|
69
|
+
exports.abs = Math.abs, exports.ceil = Math.ceil, exports.floor = Math.floor, exports.max = Math.max, exports.min = Math.min, exports.random = Math.random, exports.round = Math.round, exports.sign = Math.sign, exports.cos = Math.cos, exports.tan = Math.tan, exports.log = Math.log, exports.sqrt = Math.sqrt;
|
|
70
70
|
exports.isArray = Array.isArray;
|
|
71
71
|
exports.hasOwnProperty = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
|
|
72
72
|
exports.isPrototypeOf = Object.prototype.isPrototypeOf.call.bind(Object.prototype.isPrototypeOf);
|
|
@@ -356,6 +356,8 @@ exports.Cache = void 0;
|
|
|
356
356
|
|
|
357
357
|
const global_1 = __webpack_require__(4128);
|
|
358
358
|
|
|
359
|
+
const alias_1 = __webpack_require__(5406);
|
|
360
|
+
|
|
359
361
|
const clock_1 = __webpack_require__(7681);
|
|
360
362
|
|
|
361
363
|
const invlist_1 = __webpack_require__(7452);
|
|
@@ -364,20 +366,23 @@ const heap_1 = __webpack_require__(818);
|
|
|
364
366
|
|
|
365
367
|
const assign_1 = __webpack_require__(4401);
|
|
366
368
|
|
|
367
|
-
const tuple_1 = __webpack_require__(5341);
|
|
368
|
-
|
|
369
369
|
class Cache {
|
|
370
370
|
constructor(capacity, opts = {}) {
|
|
371
371
|
this.settings = {
|
|
372
|
+
window: 0,
|
|
372
373
|
capacity: 0,
|
|
373
374
|
space: global_1.Infinity,
|
|
374
375
|
age: global_1.Infinity,
|
|
375
376
|
earlyExpiring: false,
|
|
376
|
-
limit: 950,
|
|
377
377
|
capture: {
|
|
378
378
|
delete: true,
|
|
379
379
|
clear: true
|
|
380
|
-
}
|
|
380
|
+
},
|
|
381
|
+
resolution: 1,
|
|
382
|
+
offset: 0,
|
|
383
|
+
block: 20,
|
|
384
|
+
sweep: 10,
|
|
385
|
+
limit: 950
|
|
381
386
|
};
|
|
382
387
|
this.overlap = 0;
|
|
383
388
|
this.SIZE = 0;
|
|
@@ -387,31 +392,8 @@ class Cache {
|
|
|
387
392
|
LFU: new invlist_1.List()
|
|
388
393
|
};
|
|
389
394
|
this.expiries = new heap_1.Heap((a, b) => a.value.expiry - b.value.expiry);
|
|
390
|
-
this.
|
|
391
|
-
|
|
392
|
-
LFU: (0, tuple_1.tuple)(0, 0),
|
|
393
|
-
|
|
394
|
-
slide() {
|
|
395
|
-
const {
|
|
396
|
-
LRU,
|
|
397
|
-
LFU
|
|
398
|
-
} = this;
|
|
399
|
-
LRU[1] = LRU[0];
|
|
400
|
-
LRU[0] = 0;
|
|
401
|
-
LFU[1] = LFU[0];
|
|
402
|
-
LFU[0] = 0;
|
|
403
|
-
},
|
|
404
|
-
|
|
405
|
-
clear() {
|
|
406
|
-
const {
|
|
407
|
-
LRU,
|
|
408
|
-
LFU
|
|
409
|
-
} = this;
|
|
410
|
-
LRU[0] = LRU[1] = 0;
|
|
411
|
-
LFU[0] = LFU[1] = 0;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
};
|
|
395
|
+
this.misses = 0;
|
|
396
|
+
this.sweep = 0;
|
|
415
397
|
this.ratio = 500;
|
|
416
398
|
|
|
417
399
|
if (typeof capacity === 'object') {
|
|
@@ -419,15 +401,19 @@ class Cache {
|
|
|
419
401
|
capacity = opts.capacity ?? 0;
|
|
420
402
|
}
|
|
421
403
|
|
|
422
|
-
(0, assign_1.extend)(this.settings, opts, {
|
|
404
|
+
const settings = (0, assign_1.extend)(this.settings, opts, {
|
|
423
405
|
capacity
|
|
424
406
|
});
|
|
425
|
-
this.capacity =
|
|
407
|
+
this.capacity = settings.capacity;
|
|
426
408
|
if (this.capacity >= 1 === false) throw new Error(`Spica: Cache: Capacity must be 1 or more.`);
|
|
427
|
-
this.
|
|
428
|
-
this.
|
|
429
|
-
this.
|
|
430
|
-
this.
|
|
409
|
+
this.window = settings.window || this.capacity;
|
|
410
|
+
if (this.window * 1000 < this.capacity) throw new Error(`Spica: Cache: Window must be 0.1% of capacity or more.`);
|
|
411
|
+
this.space = settings.space;
|
|
412
|
+
this.block = settings.block;
|
|
413
|
+
this.limit = settings.limit;
|
|
414
|
+
this.earlyExpiring = settings.earlyExpiring;
|
|
415
|
+
this.disposer = settings.disposer;
|
|
416
|
+
this.stats = new Stats(this.window, settings.resolution, settings.offset);
|
|
431
417
|
}
|
|
432
418
|
|
|
433
419
|
get length() {
|
|
@@ -452,7 +438,7 @@ class Cache {
|
|
|
452
438
|
|
|
453
439
|
ensure(margin, skip) {
|
|
454
440
|
let size = skip?.value.size ?? 0;
|
|
455
|
-
if (margin - size <= 0) return;
|
|
441
|
+
if (margin - size <= 0) return true;
|
|
456
442
|
const {
|
|
457
443
|
LRU,
|
|
458
444
|
LFU
|
|
@@ -474,7 +460,6 @@ class Cache {
|
|
|
474
460
|
target = LFU.last !== skip ? LFU.last : LFU.length >= 2 ? LFU.last.prev : skip;
|
|
475
461
|
|
|
476
462
|
if (target !== skip) {
|
|
477
|
-
if (this.ratio > 500) break;
|
|
478
463
|
LRU.unshiftNode(target);
|
|
479
464
|
++this.overlap;
|
|
480
465
|
}
|
|
@@ -482,6 +467,18 @@ class Cache {
|
|
|
482
467
|
// fallthrough
|
|
483
468
|
|
|
484
469
|
default:
|
|
470
|
+
if (this.misses * 100 > LRU.length * this.block) {
|
|
471
|
+
this.sweep ||= LRU.length * this.settings.sweep / 100 + 1 | 0;
|
|
472
|
+
|
|
473
|
+
if (this.sweep > 0) {
|
|
474
|
+
LRU.head = LRU.head.next.next;
|
|
475
|
+
--this.sweep;
|
|
476
|
+
this.sweep ||= -(0, alias_1.round)(LRU.length * this.settings.sweep / 100 * 99 / 100);
|
|
477
|
+
} else {
|
|
478
|
+
++this.sweep;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
485
482
|
target = LRU.last !== skip ? LRU.last : LRU.length >= 2 ? LRU.last.prev : LFU.last;
|
|
486
483
|
}
|
|
487
484
|
|
|
@@ -489,6 +486,8 @@ class Cache {
|
|
|
489
486
|
skip = skip?.list && skip;
|
|
490
487
|
size = skip?.value.size ?? 0;
|
|
491
488
|
}
|
|
489
|
+
|
|
490
|
+
return !!skip?.list;
|
|
492
491
|
}
|
|
493
492
|
|
|
494
493
|
put(key, value, {
|
|
@@ -503,10 +502,9 @@ class Cache {
|
|
|
503
502
|
const expiry = age === global_1.Infinity ? global_1.Infinity : (0, clock_1.now)() + age;
|
|
504
503
|
const node = this.memory.get(key);
|
|
505
504
|
|
|
506
|
-
if (node) {
|
|
505
|
+
if (node && this.ensure(size, node)) {
|
|
507
506
|
const val = node.value.value;
|
|
508
507
|
const index = node.value;
|
|
509
|
-
this.ensure(size, node);
|
|
510
508
|
this.SIZE += size - index.size;
|
|
511
509
|
index.size = size;
|
|
512
510
|
index.expiry = expiry;
|
|
@@ -550,10 +548,16 @@ class Cache {
|
|
|
550
548
|
|
|
551
549
|
get(key) {
|
|
552
550
|
const node = this.memory.get(key);
|
|
553
|
-
|
|
551
|
+
|
|
552
|
+
if (!node) {
|
|
553
|
+
++this.misses;
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
|
|
554
557
|
const expiry = node.value.expiry;
|
|
555
558
|
|
|
556
559
|
if (expiry !== global_1.Infinity && expiry < (0, clock_1.now)()) {
|
|
560
|
+
++this.misses;
|
|
557
561
|
this.evict(node, true);
|
|
558
562
|
return;
|
|
559
563
|
} // Optimization for memoize.
|
|
@@ -561,7 +565,9 @@ class Cache {
|
|
|
561
565
|
|
|
562
566
|
if (this.capacity > 3 && node === node.list.head) return node.value.value;
|
|
563
567
|
this.access(node);
|
|
564
|
-
this.
|
|
568
|
+
this.adjust();
|
|
569
|
+
this.misses &&= 0;
|
|
570
|
+
this.sweep = 0;
|
|
565
571
|
return node.value.value;
|
|
566
572
|
}
|
|
567
573
|
|
|
@@ -588,6 +594,8 @@ class Cache {
|
|
|
588
594
|
}
|
|
589
595
|
|
|
590
596
|
clear() {
|
|
597
|
+
this.misses = 0;
|
|
598
|
+
this.sweep = 0;
|
|
591
599
|
this.overlap = 0;
|
|
592
600
|
this.SIZE = 0;
|
|
593
601
|
this.ratio = 500;
|
|
@@ -620,31 +628,26 @@ class Cache {
|
|
|
620
628
|
return;
|
|
621
629
|
}
|
|
622
630
|
|
|
623
|
-
|
|
624
|
-
const {
|
|
625
|
-
LRU,
|
|
626
|
-
LFU
|
|
627
|
-
} = this.stats;
|
|
631
|
+
adjust() {
|
|
628
632
|
const {
|
|
629
633
|
capacity,
|
|
630
634
|
ratio,
|
|
631
635
|
limit,
|
|
636
|
+
stats,
|
|
632
637
|
indexes
|
|
633
638
|
} = this;
|
|
634
|
-
|
|
635
|
-
const total = LRU[0] + LFU[0];
|
|
636
|
-
total === window && this.stats.slide();
|
|
637
|
-
if (total * 1000 % capacity || !LRU[1] || !LFU[1]) return;
|
|
639
|
+
if (stats.subtotal() * 1000 % capacity || !stats.full()) return;
|
|
638
640
|
const lenR = indexes.LRU.length;
|
|
639
641
|
const lenF = indexes.LFU.length;
|
|
640
|
-
const
|
|
641
|
-
const
|
|
642
|
-
const rateR0 =
|
|
643
|
-
const rateF0 =
|
|
644
|
-
const rateF1 =
|
|
642
|
+
const lenO = this.overlap;
|
|
643
|
+
const leverage = (lenF + lenO) * 1000 / (lenR + lenF) | 0;
|
|
644
|
+
const rateR0 = stats.rateLRU() * leverage;
|
|
645
|
+
const rateF0 = stats.rateLFU() * (1000 - leverage);
|
|
646
|
+
const rateF1 = stats.offset && stats.rateLFU(true) * (1000 - leverage); // 操作頻度を超えてキャッシュ比率を増減させても余剰比率の消化が追いつかず無駄
|
|
645
647
|
// LRUの下限設定ではLRU拡大の要否を迅速に判定できないためLFUのヒット率低下の検出で代替する
|
|
646
648
|
|
|
647
|
-
if (ratio > 0 && (rateR0 > rateF0 || rateF0 < rateF1 *
|
|
649
|
+
if (ratio > 0 && (rateR0 > rateF0 || stats.offset && rateF0 * 100 < rateF1 * (100 - stats.offset))) {
|
|
650
|
+
//rateR0 <= rateF0 && rateF0 * 100 < rateF1 * (100 - stats.offset) && console.debug(0);
|
|
648
651
|
if (lenR >= capacity * (1000 - ratio) / 1000) {
|
|
649
652
|
//ratio % 100 || ratio === 1000 || console.debug('-', ratio, LRU, LFU);
|
|
650
653
|
--this.ratio;
|
|
@@ -682,13 +685,100 @@ class Cache {
|
|
|
682
685
|
|
|
683
686
|
exports.Cache = Cache;
|
|
684
687
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
688
|
+
class Stats {
|
|
689
|
+
constructor(window, resolution, offset) {
|
|
690
|
+
this.window = window;
|
|
691
|
+
this.resolution = resolution;
|
|
692
|
+
this.offset = offset;
|
|
693
|
+
this.max = (0, alias_1.ceil)(this.resolution * (100 + this.offset) / 100) + 1;
|
|
694
|
+
this.LRU = [0];
|
|
695
|
+
this.LFU = [0];
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
get length() {
|
|
699
|
+
return this.LRU.length;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
full() {
|
|
703
|
+
return this.length === this.max;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
rateLRU(offset = false) {
|
|
707
|
+
return rate(this.window, this.LRU, this.LFU, +offset && this.offset);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
rateLFU(offset = false) {
|
|
711
|
+
return rate(this.window, this.LFU, this.LRU, +offset && this.offset);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
subtotal() {
|
|
715
|
+
const {
|
|
716
|
+
LRU,
|
|
717
|
+
LFU,
|
|
718
|
+
window,
|
|
719
|
+
resolution,
|
|
720
|
+
offset
|
|
721
|
+
} = this;
|
|
722
|
+
|
|
723
|
+
if (offset && LRU[0] + LFU[0] >= window * offset / 100) {
|
|
724
|
+
if (this.length === 1) {
|
|
725
|
+
this.slide();
|
|
726
|
+
} else {
|
|
727
|
+
LRU[1] += LRU[0];
|
|
728
|
+
LFU[1] += LFU[0];
|
|
729
|
+
LRU[0] = 0;
|
|
730
|
+
LFU[0] = 0;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
const subtotal = LRU[+offset && 1] + LFU[+offset && 1] || 0;
|
|
735
|
+
subtotal >= window / resolution && this.slide();
|
|
736
|
+
return LRU[0] + LFU[0];
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
slide() {
|
|
740
|
+
const {
|
|
741
|
+
LRU,
|
|
742
|
+
LFU,
|
|
743
|
+
max
|
|
744
|
+
} = this;
|
|
745
|
+
|
|
746
|
+
if (LRU.length === max) {
|
|
747
|
+
LRU.pop();
|
|
748
|
+
LFU.pop();
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
LRU.unshift(0);
|
|
752
|
+
LFU.unshift(0);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
clear() {
|
|
756
|
+
this.LRU = [0];
|
|
757
|
+
this.LFU = [0];
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
function rate(window, hits1, hits2, offset) {
|
|
763
|
+
let total = 0;
|
|
764
|
+
let hits = 0;
|
|
765
|
+
let ratio = 100;
|
|
766
|
+
|
|
767
|
+
for (let i = 0, len = hits1.length; i < len; ++i) {
|
|
768
|
+
const subtotal = hits1[i] + hits2[i];
|
|
769
|
+
if (subtotal === 0) continue;
|
|
770
|
+
offset = i + 1 === len ? 0 : offset;
|
|
771
|
+
const subratio = (0, alias_1.min)(subtotal * 100 / window, ratio) - offset;
|
|
772
|
+
offset = offset && subratio < 0 ? -subratio : 0;
|
|
773
|
+
if (subratio <= 0) continue;
|
|
774
|
+
const rate = window * subratio / subtotal;
|
|
775
|
+
total += subtotal * rate;
|
|
776
|
+
hits += hits1[i] * rate;
|
|
777
|
+
ratio -= subratio;
|
|
778
|
+
if (ratio <= 0) break;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
return hits * 10000 / total | 0;
|
|
692
782
|
}
|
|
693
783
|
|
|
694
784
|
/***/ }),
|
|
@@ -1671,25 +1761,6 @@ function random(len) {
|
|
|
1671
1761
|
|
|
1672
1762
|
/***/ }),
|
|
1673
1763
|
|
|
1674
|
-
/***/ 5341:
|
|
1675
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
1676
|
-
|
|
1677
|
-
"use strict";
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
Object.defineProperty(exports, "__esModule", ({
|
|
1681
|
-
value: true
|
|
1682
|
-
}));
|
|
1683
|
-
exports.tuple = void 0;
|
|
1684
|
-
|
|
1685
|
-
function tuple(...as) {
|
|
1686
|
-
return as;
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
exports.tuple = tuple;
|
|
1690
|
-
|
|
1691
|
-
/***/ }),
|
|
1692
|
-
|
|
1693
1764
|
/***/ 5177:
|
|
1694
1765
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1695
1766
|
|
|
@@ -2888,12 +2959,16 @@ const parser_1 = __webpack_require__(6728);
|
|
|
2888
2959
|
const memo_1 = __webpack_require__(1090);
|
|
2889
2960
|
|
|
2890
2961
|
function reset(base, parser) {
|
|
2962
|
+
if (!('memo' in base)) {
|
|
2963
|
+
base.memo = global_1.undefined;
|
|
2964
|
+
}
|
|
2965
|
+
|
|
2891
2966
|
const changes = global_1.Object.entries(base);
|
|
2892
2967
|
const values = (0, global_1.Array)(changes.length);
|
|
2893
2968
|
return ({
|
|
2894
2969
|
source,
|
|
2895
2970
|
context
|
|
2896
|
-
}) => apply(parser, source, (0, alias_1.ObjectCreate)(context), changes, values);
|
|
2971
|
+
}) => apply(parser, source, (0, alias_1.ObjectCreate)(context), changes, values, true);
|
|
2897
2972
|
}
|
|
2898
2973
|
|
|
2899
2974
|
exports.reset = reset;
|
|
@@ -2909,18 +2984,25 @@ function context(base, parser) {
|
|
|
2909
2984
|
|
|
2910
2985
|
exports.context = context;
|
|
2911
2986
|
|
|
2912
|
-
function apply(parser, source, context, changes, values) {
|
|
2987
|
+
function apply(parser, source, context, changes, values, reset = false) {
|
|
2913
2988
|
if (context) for (let i = 0; i < changes.length; ++i) {
|
|
2914
2989
|
const change = changes[i];
|
|
2915
2990
|
const prop = change[0];
|
|
2916
2991
|
|
|
2917
2992
|
switch (prop) {
|
|
2918
2993
|
case 'resources':
|
|
2919
|
-
if (
|
|
2920
|
-
|
|
2994
|
+
if (!reset) break;
|
|
2995
|
+
if (prop in context && !(0, alias_1.hasOwnProperty)(context, prop)) break;
|
|
2921
2996
|
context[prop] = (0, alias_1.ObjectCreate)(change[1]);
|
|
2922
2997
|
break;
|
|
2923
2998
|
|
|
2999
|
+
case 'memo':
|
|
3000
|
+
if (!reset) break;
|
|
3001
|
+
context.memo = new memo_1.Memo({
|
|
3002
|
+
targets: context.memo?.targets
|
|
3003
|
+
});
|
|
3004
|
+
break;
|
|
3005
|
+
|
|
2924
3006
|
default:
|
|
2925
3007
|
values[i] = context[prop];
|
|
2926
3008
|
context[prop] = change[1];
|
|
@@ -2935,8 +3017,11 @@ function apply(parser, source, context, changes, values) {
|
|
|
2935
3017
|
const prop = change[0];
|
|
2936
3018
|
|
|
2937
3019
|
switch (prop) {
|
|
2938
|
-
case 'resources':
|
|
2939
|
-
|
|
3020
|
+
case 'resources': // @ts-expect-error
|
|
3021
|
+
|
|
3022
|
+
case 'memo':
|
|
3023
|
+
if (!reset) break;
|
|
3024
|
+
// fallthrough
|
|
2940
3025
|
|
|
2941
3026
|
default:
|
|
2942
3027
|
context[prop] = values[i];
|
|
@@ -2953,26 +3038,25 @@ function syntax(syntax, prec, cost, state, parser) {
|
|
|
2953
3038
|
}) => {
|
|
2954
3039
|
if (source === '') return;
|
|
2955
3040
|
const memo = context.memo ??= new memo_1.Memo();
|
|
2956
|
-
context.memorable ??= ~0;
|
|
2957
3041
|
context.offset ??= 0;
|
|
2958
3042
|
const position = source.length + context.offset;
|
|
2959
|
-
const
|
|
2960
|
-
const
|
|
2961
|
-
const cache = syntax && memo.get(position, syntax,
|
|
3043
|
+
const stateOuter = context.state ?? 0;
|
|
3044
|
+
const stateInner = context.state = stateOuter | state;
|
|
3045
|
+
const cache = syntax && stateInner & memo.targets && memo.get(position, syntax, stateInner);
|
|
2962
3046
|
const result = cache ? cache.length === 0 ? global_1.undefined : [cache[0], source.slice(cache[1])] : parser({
|
|
2963
3047
|
source,
|
|
2964
3048
|
context
|
|
2965
3049
|
});
|
|
2966
3050
|
|
|
2967
|
-
if (syntax &&
|
|
2968
|
-
cache ?? memo.set(position, syntax,
|
|
3051
|
+
if (syntax && stateOuter & memo.targets) {
|
|
3052
|
+
cache ?? memo.set(position, syntax, stateInner, (0, parser_1.eval)(result), source.length - (0, parser_1.exec)(result, '').length);
|
|
2969
3053
|
}
|
|
2970
3054
|
|
|
2971
|
-
if (result && !
|
|
3055
|
+
if (result && !stateOuter && memo.length >= position + 2) {
|
|
2972
3056
|
memo.clear(position + 2);
|
|
2973
3057
|
}
|
|
2974
3058
|
|
|
2975
|
-
context.state =
|
|
3059
|
+
context.state = stateOuter;
|
|
2976
3060
|
return result;
|
|
2977
3061
|
}));
|
|
2978
3062
|
}
|
|
@@ -3200,8 +3284,11 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
3200
3284
|
exports.Memo = void 0;
|
|
3201
3285
|
|
|
3202
3286
|
class Memo {
|
|
3203
|
-
constructor(
|
|
3287
|
+
constructor({
|
|
3288
|
+
targets = ~0
|
|
3289
|
+
} = {}) {
|
|
3204
3290
|
this.memory = [];
|
|
3291
|
+
this.targets = targets;
|
|
3205
3292
|
}
|
|
3206
3293
|
|
|
3207
3294
|
get length() {
|
|
@@ -3209,14 +3296,14 @@ class Memo {
|
|
|
3209
3296
|
}
|
|
3210
3297
|
|
|
3211
3298
|
get(position, syntax, state) {
|
|
3212
|
-
//console.log('get', position
|
|
3299
|
+
//console.log('get', position, syntax, state, this.memory[position - 1]?.[`${syntax}:${state}`]);;
|
|
3213
3300
|
const cache = this.memory[position - 1]?.[`${syntax}:${state}`];
|
|
3214
3301
|
return cache?.length === 2 ? [cache[0].slice(), cache[1]] : cache;
|
|
3215
3302
|
}
|
|
3216
3303
|
|
|
3217
3304
|
set(position, syntax, state, nodes, offset) {
|
|
3218
3305
|
const record = this.memory[position - 1] ??= {};
|
|
3219
|
-
record[`${syntax}:${state}`] = nodes ? [nodes.slice(), offset] : []; //console.log('set', position
|
|
3306
|
+
record[`${syntax}:${state}`] = nodes ? [nodes.slice(), offset] : []; //console.log('set', position, syntax, state, record[`${syntax}:${state}`]);
|
|
3220
3307
|
}
|
|
3221
3308
|
|
|
3222
3309
|
clear(position) {
|
|
@@ -3224,7 +3311,7 @@ class Memo {
|
|
|
3224
3311
|
|
|
3225
3312
|
for (let i = position, len = memory.length; i < len; ++i) {
|
|
3226
3313
|
memory.pop();
|
|
3227
|
-
} //console.log('clear', position +
|
|
3314
|
+
} //console.log('clear', position + 1);
|
|
3228
3315
|
|
|
3229
3316
|
}
|
|
3230
3317
|
|
|
@@ -3595,6 +3682,8 @@ const global_1 = __webpack_require__(4128);
|
|
|
3595
3682
|
|
|
3596
3683
|
const parser_1 = __webpack_require__(6728);
|
|
3597
3684
|
|
|
3685
|
+
const memo_1 = __webpack_require__(1090);
|
|
3686
|
+
|
|
3598
3687
|
const segment_1 = __webpack_require__(9002);
|
|
3599
3688
|
|
|
3600
3689
|
const header_1 = __webpack_require__(5702);
|
|
@@ -3616,9 +3705,11 @@ const array_1 = __webpack_require__(8112);
|
|
|
3616
3705
|
function bind(target, settings) {
|
|
3617
3706
|
let context = { ...settings,
|
|
3618
3707
|
host: settings.host ?? new url_1.ReadonlyURL(global_1.location.pathname, global_1.location.origin),
|
|
3619
|
-
|
|
3620
|
-
|
|
3708
|
+
memo: new memo_1.Memo({
|
|
3709
|
+
targets: 236
|
|
3710
|
+
/* State.backtrackers */
|
|
3621
3711
|
|
|
3712
|
+
})
|
|
3622
3713
|
};
|
|
3623
3714
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
3624
3715
|
const blocks = [];
|
|
@@ -3958,6 +4049,8 @@ const global_1 = __webpack_require__(4128);
|
|
|
3958
4049
|
|
|
3959
4050
|
const parser_1 = __webpack_require__(6728);
|
|
3960
4051
|
|
|
4052
|
+
const memo_1 = __webpack_require__(1090);
|
|
4053
|
+
|
|
3961
4054
|
const segment_1 = __webpack_require__(9002);
|
|
3962
4055
|
|
|
3963
4056
|
const header_1 = __webpack_require__(5702);
|
|
@@ -3988,9 +4081,11 @@ function parse(source, opts = {}, context) {
|
|
|
3988
4081
|
...(context?.resources && {
|
|
3989
4082
|
resources: context.resources
|
|
3990
4083
|
}),
|
|
3991
|
-
|
|
3992
|
-
|
|
4084
|
+
memo: new memo_1.Memo({
|
|
4085
|
+
targets: 236
|
|
4086
|
+
/* State.backtrackers */
|
|
3993
4087
|
|
|
4088
|
+
})
|
|
3994
4089
|
};
|
|
3995
4090
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
3996
4091
|
const node = (0, dom_1.frag)();
|
|
@@ -5478,15 +5573,16 @@ const source_1 = __webpack_require__(6743);
|
|
|
5478
5573
|
|
|
5479
5574
|
const dom_1 = __webpack_require__(3252);
|
|
5480
5575
|
|
|
5481
|
-
exports.cite = (0, combinator_1.creation)(1, false, (0, combinator_1.line)((0, combinator_1.fmap)((0, combinator_1.validate)('>>', (0, combinator_1.reverse)((0, combinator_1.tails)([(0, source_1.str)(/^>*(?=>>[^>\s]
|
|
5576
|
+
exports.cite = (0, combinator_1.creation)(1, false, (0, combinator_1.line)((0, combinator_1.fmap)((0, combinator_1.validate)('>>', (0, combinator_1.reverse)((0, combinator_1.tails)([(0, source_1.str)(/^>*(?=>>[^>\s]+\s*$)/), (0, combinator_1.union)([anchor_1.anchor, // Subject page representation.
|
|
5482
5577
|
// リンクの実装は後で検討
|
|
5483
|
-
(0, combinator_1.focus)(/^>>\.
|
|
5578
|
+
(0, combinator_1.focus)(/^>>\.(?=\s*$)/, () => [[(0, dom_1.html)('a', {
|
|
5484
5579
|
class: 'anchor'
|
|
5485
|
-
}, '>>.')], '']), (0, combinator_1.focus)(/^>>#\S*
|
|
5580
|
+
}, '>>.')], '']), (0, combinator_1.focus)(/^>>#\S*(?=\s*$)/, ({
|
|
5486
5581
|
source
|
|
5487
5582
|
}) => [[(0, dom_1.html)('a', {
|
|
5488
5583
|
class: 'anchor'
|
|
5489
|
-
}, source)], '']),
|
|
5584
|
+
}, source)], '']), // Support all domains, but don't support IP(v6) addresses.
|
|
5585
|
+
(0, combinator_1.focus)(/^>>https?:\/\/[^\p{C}\p{S}\p{P}\s]\S*(?=\s*$)/u, ({
|
|
5490
5586
|
source
|
|
5491
5587
|
}) => [[(0, dom_1.html)('a', {
|
|
5492
5588
|
class: 'anchor',
|
|
@@ -5948,8 +6044,8 @@ exports.autolink = (0, combinator_1.fmap)((0, combinator_1.validate)(/^(?:[@#>0-
|
|
|
5948
6044
|
/* State.autolink */
|
|
5949
6045
|
, false, (0, combinator_1.syntax)(2
|
|
5950
6046
|
/* Syntax.autolink */
|
|
5951
|
-
, 1, 1,
|
|
5952
|
-
/* State.
|
|
6047
|
+
, 1, 1, ~1
|
|
6048
|
+
/* State.shortcut */
|
|
5953
6049
|
, (0, combinator_1.some)((0, combinator_1.union)([url_1.url, email_1.email, // Escape unmatched email-like strings.
|
|
5954
6050
|
(0, source_1.str)(/^[0-9a-z]+(?:[.+_-][0-9a-z]+)*(?:@(?:[0-9a-z]+(?:[.-][0-9a-z]+)*)?)*/i), channel_1.channel, account_1.account, // Escape unmatched account-like strings.
|
|
5955
6051
|
(0, source_1.str)(/^@+[0-9a-z]*(?:-[0-9a-z]+)*/i), // Escape invalid leading characters.
|
|
@@ -6502,10 +6598,12 @@ const dom_1 = __webpack_require__(3252);
|
|
|
6502
6598
|
|
|
6503
6599
|
exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[#', (0, combinator_1.fmap)((0, indexee_1.indexee)((0, combinator_1.surround)('[#', (0, combinator_1.constraint)(32
|
|
6504
6600
|
/* State.index */
|
|
6505
|
-
, false, (0, combinator_1.syntax)(
|
|
6601
|
+
, false, (0, combinator_1.syntax)(2048
|
|
6506
6602
|
/* Syntax.index */
|
|
6507
|
-
, 2, 1,
|
|
6508
|
-
/* State.
|
|
6603
|
+
, 2, 1, 250
|
|
6604
|
+
/* State.linkers */
|
|
6605
|
+
| 4
|
|
6606
|
+
/* State.media */
|
|
6509
6607
|
, (0, visibility_1.startTight)((0, combinator_1.open)((0, source_1.stropt)(/^\|?/), (0, visibility_1.trimBlankEnd)((0, combinator_1.some)((0, combinator_1.union)([signature, inline_1.inline]), ']', [[/^\\?\n/, 9], [']', 2]])), true)))), ']', false, ([, ns], rest) => [[(0, dom_1.html)('a', (0, dom_1.defrag)(ns))], rest])), ([el]) => [(0, dom_1.define)(el, {
|
|
6510
6608
|
id: el.id ? null : global_1.undefined,
|
|
6511
6609
|
class: 'index',
|
|
@@ -6707,8 +6805,8 @@ const array_1 = __webpack_require__(8112); // Don't use the symbols already used
|
|
|
6707
6805
|
// All syntax surrounded by square brackets shouldn't contain line breaks.
|
|
6708
6806
|
|
|
6709
6807
|
|
|
6710
|
-
exports.placeholder = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['[:', '[^'], (0, combinator_1.surround)((0, source_1.str)(/^\[[:^]/), (0, combinator_1.syntax)(
|
|
6711
|
-
/* Syntax.
|
|
6808
|
+
exports.placeholder = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['[:', '[^'], (0, combinator_1.surround)((0, source_1.str)(/^\[[:^]/), (0, combinator_1.syntax)(1024
|
|
6809
|
+
/* Syntax.placeholder */
|
|
6712
6810
|
, 2, 1, 0
|
|
6713
6811
|
/* State.none */
|
|
6714
6812
|
, (0, visibility_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[/^\\?\n/, 9], [']', 2]]))), (0, source_1.str)(']'), false, ([as, bs], rest) => [[(0, dom_1.html)('span', {
|
|
@@ -6928,8 +7026,10 @@ const textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8
|
|
|
6928
7026
|
/* State.link */
|
|
6929
7027
|
, false, (0, combinator_1.syntax)(256
|
|
6930
7028
|
/* Syntax.link */
|
|
6931
|
-
, 2, 10,
|
|
6932
|
-
/* State.
|
|
7029
|
+
, 2, 10, 250
|
|
7030
|
+
/* State.linkers */
|
|
7031
|
+
| 4
|
|
7032
|
+
/* State.media */
|
|
6933
7033
|
, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[/^\\?\n/, 9], [']', 2]]), ']', true)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => {
|
|
6934
7034
|
return parse(content, params, rest, context);
|
|
6935
7035
|
}))));
|
|
@@ -6939,10 +7039,8 @@ const medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8
|
|
|
6939
7039
|
/* State.media */
|
|
6940
7040
|
, false, (0, combinator_1.syntax)(256
|
|
6941
7041
|
/* Syntax.link */
|
|
6942
|
-
, 2, 10,
|
|
6943
|
-
/* State.
|
|
6944
|
-
^ 4
|
|
6945
|
-
/* State.media */
|
|
7042
|
+
, 2, 10, 250
|
|
7043
|
+
/* State.linkers */
|
|
6946
7044
|
, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => parse(content, params, rest, context)))));
|
|
6947
7045
|
exports.unsafelink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(10, (0, combinator_1.precedence)(2, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([source_1.unescsource]), ']'), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => parse(content, params, rest, context)))));
|
|
6948
7046
|
exports.uri = (0, combinator_1.union)([(0, combinator_1.open)(/^[^\S\n]+/, (0, source_1.str)(/^\S+/)), (0, source_1.str)(/^[^\s{}]+/)]);
|
|
@@ -6958,7 +7056,7 @@ function parse(content, params, rest, context) {
|
|
|
6958
7056
|
content = (0, dom_1.defrag)(content);
|
|
6959
7057
|
|
|
6960
7058
|
for (let source = (0, util_1.stringify)(content); source;) {
|
|
6961
|
-
if (/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)
|
|
7059
|
+
if (/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(source)) return;
|
|
6962
7060
|
const result = autolink({
|
|
6963
7061
|
source,
|
|
6964
7062
|
context
|
|
@@ -7044,12 +7142,12 @@ exports.resolve = resolve;
|
|
|
7044
7142
|
|
|
7045
7143
|
function decode(uri) {
|
|
7046
7144
|
if (!uri.includes('%')) return uri;
|
|
7047
|
-
const origin = uri.match(/^[a-z](?:[-.](?=\w)|[0-9a-z])
|
|
7145
|
+
const origin = uri.match(/^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i)?.[0] ?? '';
|
|
7048
7146
|
|
|
7049
7147
|
try {
|
|
7050
7148
|
let path = (0, global_1.decodeURI)(uri.slice(origin.length));
|
|
7051
7149
|
|
|
7052
|
-
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])
|
|
7150
|
+
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(path)) {
|
|
7053
7151
|
path = uri.slice(origin.length);
|
|
7054
7152
|
}
|
|
7055
7153
|
|
|
@@ -7172,8 +7270,8 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['![', '
|
|
|
7172
7270
|
/* State.media */
|
|
7173
7271
|
, false, (0, combinator_1.syntax)(64
|
|
7174
7272
|
/* Syntax.media */
|
|
7175
|
-
, 2, 10,
|
|
7176
|
-
/* State.
|
|
7273
|
+
, 2, 10, ~8
|
|
7274
|
+
/* State.link */
|
|
7177
7275
|
, (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']', [[/^\\?\n/, 9]]), ']', true)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), /^[^\S\n]*}/))]), ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
|
|
7178
7276
|
const INSECURE_URI = params.shift();
|
|
7179
7277
|
const url = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, context.host ?? global_1.location, context.url ?? context.host ?? global_1.location), context.host?.href || global_1.location.href);
|
|
@@ -7195,7 +7293,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['![', '
|
|
|
7195
7293
|
if (context.state & 8
|
|
7196
7294
|
/* State.link */
|
|
7197
7295
|
) return [[el], rest];
|
|
7198
|
-
if (cache && cache.tagName !== 'IMG') return (0, combinator_1.creation)(10,
|
|
7296
|
+
if (cache && cache.tagName !== 'IMG') return (0, combinator_1.creation)(10, _ => [[el], rest])({
|
|
7199
7297
|
source: '!',
|
|
7200
7298
|
context
|
|
7201
7299
|
});
|
|
@@ -7279,7 +7377,7 @@ const dom_1 = __webpack_require__(3252);
|
|
|
7279
7377
|
|
|
7280
7378
|
exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.surround)('[[', (0, combinator_1.constraint)(64
|
|
7281
7379
|
/* State.reference */
|
|
7282
|
-
, false, (0, combinator_1.syntax)(
|
|
7380
|
+
, false, (0, combinator_1.syntax)(8192
|
|
7283
7381
|
/* Syntax.reference */
|
|
7284
7382
|
, 6, 1, 128
|
|
7285
7383
|
/* State.annotation */
|
|
@@ -7335,11 +7433,17 @@ const dom_1 = __webpack_require__(3252);
|
|
|
7335
7433
|
|
|
7336
7434
|
const array_1 = __webpack_require__(8112);
|
|
7337
7435
|
|
|
7338
|
-
exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[', (0, combinator_1.syntax)(
|
|
7339
|
-
/* Syntax.
|
|
7340
|
-
, 2, 1,
|
|
7341
|
-
/* State.
|
|
7342
|
-
, (0, combinator_1.fmap)((0, combinator_1.verify)((0, combinator_1.sequence)([(0, combinator_1.surround)('[', (0,
|
|
7436
|
+
exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[', (0, combinator_1.syntax)(512
|
|
7437
|
+
/* Syntax.ruby */
|
|
7438
|
+
, 2, 1, -1
|
|
7439
|
+
/* State.all */
|
|
7440
|
+
, (0, combinator_1.fmap)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.sequence)([(0, combinator_1.surround)('[', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']'), (0, combinator_1.surround)('(', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')')]), ([texts, rubies], _, context) => [(0, parser_1.eval)(text({
|
|
7441
|
+
source: texts,
|
|
7442
|
+
context
|
|
7443
|
+
}), [])[0] ?? '', (0, parser_1.eval)(text({
|
|
7444
|
+
source: rubies,
|
|
7445
|
+
context
|
|
7446
|
+
}), [])[0] ?? '']), ([texts, rubies]) => texts && rubies && (0, visibility_1.isStartTightNodes)(texts)), ([texts, rubies]) => {
|
|
7343
7447
|
texts[texts.length - 1] === '' && texts.pop();
|
|
7344
7448
|
|
|
7345
7449
|
switch (true) {
|
|
@@ -7499,8 +7603,8 @@ const array_1 = __webpack_require__(8112);
|
|
|
7499
7603
|
|
|
7500
7604
|
exports.template = (0, combinator_1.lazy)(() => (0, combinator_1.surround)('{{', (0, combinator_1.syntax)(0
|
|
7501
7605
|
/* Syntax.none */
|
|
7502
|
-
, 2, 1,
|
|
7503
|
-
/* State.
|
|
7606
|
+
, 2, 1, -1
|
|
7607
|
+
/* State.all */
|
|
7504
7608
|
, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), '}')), '}}', true, ([, ns = []], rest) => [[(0, dom_1.html)('span', {
|
|
7505
7609
|
class: 'template'
|
|
7506
7610
|
}, `{{${ns.join('').replace(/\x1B/g, '')}}}`)], rest]));
|
package/markdown.d.ts
CHANGED
|
@@ -829,8 +829,8 @@ export namespace MarkdownParser {
|
|
|
829
829
|
// [AB](a b)
|
|
830
830
|
Inline<'ruby'>,
|
|
831
831
|
Parser<HTMLElement, Context, [
|
|
832
|
-
|
|
833
|
-
|
|
832
|
+
SourceParser.StrParser,
|
|
833
|
+
SourceParser.StrParser,
|
|
834
834
|
]> {
|
|
835
835
|
}
|
|
836
836
|
export namespace RubyParser {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securemark",
|
|
3
|
-
"version": "0.260.
|
|
3
|
+
"version": "0.260.6",
|
|
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",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@types/mocha": "9.1.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.31.0",
|
|
38
38
|
"babel-loader": "^8.2.5",
|
|
39
39
|
"babel-plugin-unassert": "^3.2.0",
|
|
40
40
|
"concurrently": "^7.3.0",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"karma-mocha": "^2.0.1",
|
|
50
50
|
"karma-power-assert": "^1.0.0",
|
|
51
51
|
"mocha": "^10.0.0",
|
|
52
|
-
"npm-check-updates": "^
|
|
52
|
+
"npm-check-updates": "^16.0.3",
|
|
53
53
|
"semver": "^7.3.7",
|
|
54
|
-
"spica": "0.0.
|
|
54
|
+
"spica": "0.0.591",
|
|
55
55
|
"ts-loader": "^9.3.1",
|
|
56
56
|
"typed-dom": "^0.0.301",
|
|
57
57
|
"typescript": "4.7.4",
|
|
58
|
-
"webpack": "^5.
|
|
58
|
+
"webpack": "^5.74.0",
|
|
59
59
|
"webpack-cli": "^4.10.0",
|
|
60
60
|
"webpack-merge": "^5.8.0"
|
|
61
61
|
},
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export class Memo {
|
|
2
|
+
constructor({ targets = ~0 } = {}) {
|
|
3
|
+
this.targets = targets;
|
|
4
|
+
}
|
|
5
|
+
public readonly targets: number;
|
|
2
6
|
private readonly memory: Record<string, readonly [any[], number] | readonly []>[/* pos */] = [];
|
|
3
7
|
public get length(): number {
|
|
4
8
|
return this.memory.length;
|
|
@@ -8,7 +12,7 @@ export class Memo {
|
|
|
8
12
|
syntax: number,
|
|
9
13
|
state: number,
|
|
10
14
|
): readonly [any[], number] | readonly [] | undefined {
|
|
11
|
-
//console.log('get', position
|
|
15
|
+
//console.log('get', position, syntax, state, this.memory[position - 1]?.[`${syntax}:${state}`]);;
|
|
12
16
|
const cache = this.memory[position - 1]?.[`${syntax}:${state}`];
|
|
13
17
|
return cache?.length === 2
|
|
14
18
|
? [cache[0].slice(), cache[1]]
|
|
@@ -26,13 +30,13 @@ export class Memo {
|
|
|
26
30
|
record[`${syntax}:${state}`] = nodes
|
|
27
31
|
? [nodes.slice(), offset]
|
|
28
32
|
: [];
|
|
29
|
-
//console.log('set', position
|
|
33
|
+
//console.log('set', position, syntax, state, record[`${syntax}:${state}`]);
|
|
30
34
|
}
|
|
31
35
|
public clear(position: number): void {
|
|
32
36
|
const memory = this.memory;
|
|
33
37
|
for (let i = position, len = memory.length; i < len; ++i) {
|
|
34
38
|
memory.pop();
|
|
35
39
|
}
|
|
36
|
-
//console.log('clear', position +
|
|
40
|
+
//console.log('clear', position + 1);
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -5,12 +5,15 @@ import { Memo } from './context/memo';
|
|
|
5
5
|
|
|
6
6
|
export function reset<P extends Parser<unknown>>(base: Context<P>, parser: P): P;
|
|
7
7
|
export function reset<T>(base: Ctx, parser: Parser<T>): Parser<T> {
|
|
8
|
+
if (!('memo' in base)) {
|
|
9
|
+
base.memo = undefined;
|
|
10
|
+
}
|
|
8
11
|
assert(Object.getPrototypeOf(base) === Object.prototype);
|
|
9
12
|
assert(Object.freeze(base));
|
|
10
13
|
const changes = Object.entries(base);
|
|
11
14
|
const values = Array(changes.length);
|
|
12
15
|
return ({ source, context }) =>
|
|
13
|
-
apply(parser, source, ObjectCreate(context), changes, values);
|
|
16
|
+
apply(parser, source, ObjectCreate(context), changes, values, true);
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export function context<P extends Parser<unknown>>(base: Context<P>, parser: P): P;
|
|
@@ -23,18 +26,22 @@ export function context<T>(base: Ctx, parser: Parser<T>): Parser<T> {
|
|
|
23
26
|
apply(parser, source, context, changes, values);
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
function apply<P extends Parser<unknown>>(parser: P, source: string, context: Context<P>, changes: [string, any][], values: any[]): Result<Tree<P>>;
|
|
27
|
-
function apply<T>(parser: Parser<T>, source: string, context: Ctx, changes: [string, any][], values: any[]): Result<T> {
|
|
29
|
+
function apply<P extends Parser<unknown>>(parser: P, source: string, context: Context<P>, changes: [string, any][], values: any[], reset?: boolean): Result<Tree<P>>;
|
|
30
|
+
function apply<T>(parser: Parser<T>, source: string, context: Ctx, changes: [string, any][], values: any[], reset = false): Result<T> {
|
|
28
31
|
if (context) for (let i = 0; i < changes.length; ++i) {
|
|
29
32
|
const change = changes[i];
|
|
30
33
|
const prop = change[0];
|
|
31
34
|
switch (prop) {
|
|
32
35
|
case 'resources':
|
|
36
|
+
if (!reset) break;
|
|
33
37
|
assert(typeof change[1] === 'object');
|
|
34
38
|
assert(context[prop] || !(prop in context));
|
|
35
39
|
if (prop in context && !hasOwnProperty(context, prop)) break;
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
context[prop as string] = ObjectCreate(change[1]);
|
|
41
|
+
break;
|
|
42
|
+
case 'memo':
|
|
43
|
+
if (!reset) break;
|
|
44
|
+
context.memo = new Memo({ targets: context.memo?.targets });
|
|
38
45
|
break;
|
|
39
46
|
default:
|
|
40
47
|
values[i] = context[prop];
|
|
@@ -47,7 +54,10 @@ function apply<T>(parser: Parser<T>, source: string, context: Ctx, changes: [str
|
|
|
47
54
|
const prop = change[0];
|
|
48
55
|
switch (prop) {
|
|
49
56
|
case 'resources':
|
|
50
|
-
|
|
57
|
+
// @ts-expect-error
|
|
58
|
+
case 'memo':
|
|
59
|
+
if (!reset) break;
|
|
60
|
+
// fallthrough
|
|
51
61
|
default:
|
|
52
62
|
context[prop] = values[i];
|
|
53
63
|
values[i] = undefined;
|
|
@@ -61,26 +71,25 @@ export function syntax<T>(syntax: number, prec: number, cost: number, state: num
|
|
|
61
71
|
return creation(cost, precedence(prec, ({ source, context }) => {
|
|
62
72
|
if (source === '') return;
|
|
63
73
|
const memo = context.memo ??= new Memo();
|
|
64
|
-
context.memorable ??= ~0;
|
|
65
74
|
context.offset ??= 0;
|
|
66
75
|
const position = source.length + context.offset!;
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
const cache = syntax && memo.get(position, syntax,
|
|
76
|
+
const stateOuter = context.state ?? 0;
|
|
77
|
+
const stateInner = context.state = stateOuter | state;
|
|
78
|
+
const cache = syntax && stateInner & memo.targets && memo.get(position, syntax, stateInner);
|
|
70
79
|
const result: Result<T> = cache
|
|
71
80
|
? cache.length === 0
|
|
72
81
|
? undefined
|
|
73
82
|
: [cache[0], source.slice(cache[1])]
|
|
74
83
|
: parser!({ source, context });
|
|
75
|
-
if (syntax &&
|
|
76
|
-
cache ?? memo.set(position, syntax,
|
|
77
|
-
assert.deepStrictEqual(cache && cache, cache && memo.get(position, syntax,
|
|
84
|
+
if (syntax && stateOuter & memo.targets) {
|
|
85
|
+
cache ?? memo.set(position, syntax, stateInner, eval(result), source.length - exec(result, '').length);
|
|
86
|
+
assert.deepStrictEqual(cache && cache, cache && memo.get(position, syntax, stateInner));
|
|
78
87
|
}
|
|
79
|
-
if (result && !
|
|
80
|
-
assert(!(
|
|
88
|
+
if (result && !stateOuter && memo.length! >= position + 2) {
|
|
89
|
+
assert(!(stateOuter & memo.targets));
|
|
81
90
|
memo.clear(position + 2);
|
|
82
91
|
}
|
|
83
|
-
context.state =
|
|
92
|
+
context.state = stateOuter;
|
|
84
93
|
return result;
|
|
85
94
|
}));
|
|
86
95
|
}
|
package/src/parser/api/bind.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { undefined, location } from 'spica/global';
|
|
|
2
2
|
import { ParserSettings, Progress } from '../../..';
|
|
3
3
|
import { MarkdownParser } from '../../../markdown';
|
|
4
4
|
import { eval } from '../../combinator/data/parser';
|
|
5
|
+
import { Memo } from '../../combinator/data/parser/context/memo';
|
|
5
6
|
import { segment, validate, MAX_INPUT_SIZE } from '../segment';
|
|
6
7
|
import { header } from '../header';
|
|
7
8
|
import { block } from '../block';
|
|
@@ -24,7 +25,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
24
25
|
let context: MarkdownParser.Context = {
|
|
25
26
|
...settings,
|
|
26
27
|
host: settings.host ?? new ReadonlyURL(location.pathname, location.origin),
|
|
27
|
-
|
|
28
|
+
memo: new Memo({ targets: State.backtrackers }),
|
|
28
29
|
};
|
|
29
30
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
30
31
|
assert(!settings.id);
|
package/src/parser/api/parse.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { location } from 'spica/global';
|
|
|
2
2
|
import { ParserOptions } from '../../..';
|
|
3
3
|
import { MarkdownParser } from '../../../markdown';
|
|
4
4
|
import { eval } from '../../combinator/data/parser';
|
|
5
|
+
import { Memo } from '../../combinator/data/parser/context/memo';
|
|
5
6
|
import { segment, validate, MAX_SEGMENT_SIZE } from '../segment';
|
|
6
7
|
import { header } from '../header';
|
|
7
8
|
import { block } from '../block';
|
|
@@ -30,7 +31,7 @@ export function parse(source: string, opts: Options = {}, context?: MarkdownPars
|
|
|
30
31
|
...context?.resources && {
|
|
31
32
|
resources: context.resources,
|
|
32
33
|
},
|
|
33
|
-
|
|
34
|
+
memo: new Memo({ targets: State.backtrackers }),
|
|
34
35
|
};
|
|
35
36
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
36
37
|
const node = frag();
|
|
@@ -39,11 +39,16 @@ describe('Unit: parser/block/reply/cite', () => {
|
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('>>>0\n>>')), [['<span class="cite">>><a class="anchor" href="?at=0" data-depth="2">>0</a></span>', '<br>'], '>>']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('>>>0\n>>1')), [['<span class="cite">>><a class="anchor" href="?at=0" data-depth="2">>0</a></span>', '<br>', '<span class="cite">><a class="anchor" href="?at=1" data-depth="1">>1</a></span>', '<br>'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('>>.')), [['<span class="cite">><a class="anchor" data-depth="1">>.</a></span>', '<br>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('>>. ')), [['<span class="cite">><a class="anchor" data-depth="1">>.</a></span>', '<br>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('>>.\n')), [['<span class="cite">><a class="anchor" data-depth="1">>.</a></span>', '<br>'], '']);
|
|
42
44
|
assert.deepStrictEqual(inspect(parser('>>#')), [['<span class="cite">><a class="anchor" data-depth="1">>#</a></span>', '<br>'], '']);
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('>>#\n')), [['<span class="cite">><a class="anchor" data-depth="1">>#</a></span>', '<br>'], '']);
|
|
43
46
|
assert.deepStrictEqual(inspect(parser('>>#a')), [['<span class="cite">><a class="anchor" data-depth="1">>#a</a></span>', '<br>'], '']);
|
|
44
47
|
assert.deepStrictEqual(inspect(parser('>>#index:a')), [['<span class="cite">><a class="anchor" data-depth="1">>#index:a</a></span>', '<br>'], '']);
|
|
45
48
|
assert.deepStrictEqual(inspect(parser('>>#:~:text=a')), [['<span class="cite">><a class="anchor" data-depth="1">>#:~:text=a</a></span>', '<br>'], '']);
|
|
46
49
|
assert.deepStrictEqual(inspect(parser('>>http://host')), [['<span class="cite">><a class="anchor" href="http://host" target="_blank" data-depth="1">>http://host</a></span>', '<br>'], '']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('>>http://host ')), [['<span class="cite">><a class="anchor" href="http://host" target="_blank" data-depth="1">>http://host</a></span>', '<br>'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('>>http://host\n')), [['<span class="cite">><a class="anchor" href="http://host" target="_blank" data-depth="1">>http://host</a></span>', '<br>'], '']);
|
|
47
52
|
assert.deepStrictEqual(inspect(parser('>>https://host')), [['<span class="cite">><a class="anchor" href="https://host" target="_blank" data-depth="1">>https://host</a></span>', '<br>'], '']);
|
|
48
53
|
});
|
|
49
54
|
|
|
@@ -7,14 +7,15 @@ import { html, define, defrag } from 'typed-dom/dom';
|
|
|
7
7
|
export const cite: ReplyParser.CiteParser = creation(1, false, line(fmap(validate(
|
|
8
8
|
'>>',
|
|
9
9
|
reverse(tails([
|
|
10
|
-
str(/^>*(?=>>[^>\s]
|
|
10
|
+
str(/^>*(?=>>[^>\s]+\s*$)/),
|
|
11
11
|
union([
|
|
12
12
|
anchor,
|
|
13
13
|
// Subject page representation.
|
|
14
14
|
// リンクの実装は後で検討
|
|
15
|
-
focus(/^>>\.
|
|
16
|
-
focus(/^>>#\S*
|
|
17
|
-
|
|
15
|
+
focus(/^>>\.(?=\s*$)/, () => [[html('a', { class: 'anchor' }, '>>.')], '']),
|
|
16
|
+
focus(/^>>#\S*(?=\s*$)/, ({ source }) => [[html('a', { class: 'anchor' }, source)], '']),
|
|
17
|
+
// Support all domains, but don't support IP(v6) addresses.
|
|
18
|
+
focus(/^>>https?:\/\/[^\p{C}\p{S}\p{P}\s]\S*(?=\s*$)/u, ({ source }) => [[html('a', { class: 'anchor', href: source.slice(2).trimEnd(), target: '_blank' }, source)], '']),
|
|
18
19
|
]),
|
|
19
20
|
]))),
|
|
20
21
|
([el, quotes = '']: [HTMLElement, string?]) => [
|
package/src/parser/context.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export const enum Syntax {
|
|
2
|
-
reference = 1 <<
|
|
3
|
-
comment = 1 <<
|
|
4
|
-
index = 1 <<
|
|
5
|
-
placeholder = 1 <<
|
|
2
|
+
reference = 1 << 13,
|
|
3
|
+
comment = 1 << 12,
|
|
4
|
+
index = 1 << 11,
|
|
5
|
+
placeholder = 1 << 10,
|
|
6
|
+
ruby = 1 << 9,
|
|
6
7
|
link = 1 << 8,
|
|
7
8
|
bracket = 1 << 7,
|
|
8
9
|
media = 1 << 6,
|
|
@@ -25,15 +26,15 @@ export const enum State {
|
|
|
25
26
|
autolink = 1 << 1,
|
|
26
27
|
shortcut = 1 << 0,
|
|
27
28
|
none = 0,
|
|
28
|
-
|
|
29
|
+
all = ~0,
|
|
30
|
+
linkers = 0
|
|
29
31
|
| State.annotation
|
|
30
32
|
| State.reference
|
|
31
33
|
| State.index
|
|
32
34
|
| State.label
|
|
33
35
|
| State.link
|
|
34
|
-
| State.media
|
|
35
36
|
| State.autolink,
|
|
36
|
-
|
|
37
|
+
backtrackers = 0
|
|
37
38
|
| State.annotation
|
|
38
39
|
| State.reference
|
|
39
40
|
| State.index
|
|
@@ -14,7 +14,7 @@ import { stringify } from '../util';
|
|
|
14
14
|
export const autolink: AutolinkParser = fmap(
|
|
15
15
|
validate(/^(?:[@#>0-9a-z]|\S[#>])/i,
|
|
16
16
|
constraint(State.autolink, false,
|
|
17
|
-
syntax(Syntax.autolink, 1, 1, State.
|
|
17
|
+
syntax(Syntax.autolink, 1, 1, ~State.shortcut,
|
|
18
18
|
some(union([
|
|
19
19
|
url,
|
|
20
20
|
email,
|
|
@@ -13,7 +13,7 @@ import IndexParser = ExtensionParser.IndexParser;
|
|
|
13
13
|
export const index: IndexParser = lazy(() => validate('[#', fmap(indexee(surround(
|
|
14
14
|
'[#',
|
|
15
15
|
constraint(State.index, false,
|
|
16
|
-
syntax(Syntax.index, 2, 1, State.
|
|
16
|
+
syntax(Syntax.index, 2, 1, State.linkers | State.media,
|
|
17
17
|
startTight(
|
|
18
18
|
open(stropt(/^\|?/), trimBlankEnd(some(union([
|
|
19
19
|
signature,
|
|
@@ -13,7 +13,7 @@ import { unshift } from 'spica/array';
|
|
|
13
13
|
|
|
14
14
|
export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => validate(['[:', '[^'], surround(
|
|
15
15
|
str(/^\[[:^]/),
|
|
16
|
-
syntax(Syntax.
|
|
16
|
+
syntax(Syntax.placeholder, 2, 1, State.none,
|
|
17
17
|
startTight(some(union([inline]), ']', [[/^\\?\n/, 9], [']', 2]]))),
|
|
18
18
|
str(']'), false,
|
|
19
19
|
([as, bs], rest) => [[
|
|
@@ -29,6 +29,8 @@ describe('Unit: parser/inline/link', () => {
|
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('{http://a%C3%A1}')), [['<a class="url" href="http://a%C3%A1" target="_blank">http://a%C3%A1</a>'], '']);
|
|
30
30
|
assert.deepStrictEqual(inspect(parser('[http://á]{http://evil}')), undefined);
|
|
31
31
|
assert.deepStrictEqual(inspect(parser('[xxx://á]{http://evil}')), undefined);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('[mailto:á]{http://evil}')), undefined);
|
|
33
|
+
assert.deepStrictEqual(inspect(parser('[file:///]{http://evil}')), undefined);
|
|
32
34
|
assert.deepStrictEqual(inspect(parser('[.http://á]{http://evil}')), undefined);
|
|
33
35
|
assert.deepStrictEqual(inspect(parser('[0987654321]{tel:1234567890}')), undefined);
|
|
34
36
|
assert.deepStrictEqual(inspect(parser('[1234567890-]{tel:1234567890}')), undefined);
|
|
@@ -25,7 +25,7 @@ export const link: LinkParser = lazy(() => validate(['[', '{'], union([
|
|
|
25
25
|
|
|
26
26
|
const textlink: LinkParser.TextLinkParser = lazy(() =>
|
|
27
27
|
constraint(State.link, false,
|
|
28
|
-
syntax(Syntax.link, 2, 10, State.
|
|
28
|
+
syntax(Syntax.link, 2, 10, State.linkers | State.media,
|
|
29
29
|
bind(reverse(tails([
|
|
30
30
|
dup(surround(
|
|
31
31
|
'[',
|
|
@@ -41,7 +41,7 @@ const textlink: LinkParser.TextLinkParser = lazy(() =>
|
|
|
41
41
|
|
|
42
42
|
const medialink: LinkParser.MediaLinkParser = lazy(() =>
|
|
43
43
|
constraint(State.link | State.media, false,
|
|
44
|
-
syntax(Syntax.link, 2, 10, State.
|
|
44
|
+
syntax(Syntax.link, 2, 10, State.linkers,
|
|
45
45
|
bind(reverse(sequence([
|
|
46
46
|
dup(surround(
|
|
47
47
|
'[',
|
|
@@ -88,7 +88,7 @@ function parse(
|
|
|
88
88
|
if (content.length !== 0 && trimNode(content).length === 0) return;
|
|
89
89
|
content = defrag(content);
|
|
90
90
|
for (let source = stringify(content); source;) {
|
|
91
|
-
if (/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)
|
|
91
|
+
if (/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(source)) return;
|
|
92
92
|
const result = autolink({ source, context });
|
|
93
93
|
if (typeof eval(result, [])[0] === 'object') return;
|
|
94
94
|
source = exec(result, '');
|
|
@@ -202,10 +202,10 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
202
202
|
|
|
203
203
|
function decode(uri: string): string {
|
|
204
204
|
if (!uri.includes('%')) return uri;
|
|
205
|
-
const origin = uri.match(/^[a-z](?:[-.](?=\w)|[0-9a-z])
|
|
205
|
+
const origin = uri.match(/^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i)?.[0] ?? '';
|
|
206
206
|
try {
|
|
207
207
|
let path = decodeURI(uri.slice(origin.length));
|
|
208
|
-
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])
|
|
208
|
+
if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(path)) {
|
|
209
209
|
path = uri.slice(origin.length);
|
|
210
210
|
}
|
|
211
211
|
uri = origin + path;
|
|
@@ -21,7 +21,7 @@ Object.setPrototypeOf(optspec, null);
|
|
|
21
21
|
export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
|
|
22
22
|
'!',
|
|
23
23
|
constraint(State.media, false,
|
|
24
|
-
syntax(Syntax.media, 2, 10, State.
|
|
24
|
+
syntax(Syntax.media, 2, 10, ~State.link,
|
|
25
25
|
bind(verify(fmap(tails([
|
|
26
26
|
dup(surround(
|
|
27
27
|
'[',
|
|
@@ -55,7 +55,7 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
|
|
|
55
55
|
el.style.aspectRatio = el.getAttribute('aspect-ratio')!;
|
|
56
56
|
}
|
|
57
57
|
if (context.state! & State.link) return [[el], rest];
|
|
58
|
-
if (cache && cache.tagName !== 'IMG') return creation(10,
|
|
58
|
+
if (cache && cache.tagName !== 'IMG') return creation(10, _ => [[el!], rest])({ source: '!', context });
|
|
59
59
|
return fmap(
|
|
60
60
|
unsafelink as MediaParser,
|
|
61
61
|
([link]) => [define(link, { class: null, target: '_blank' }, [el])])
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { RubyParser } from '../inline';
|
|
3
3
|
import { eval, exec } from '../../combinator/data/parser';
|
|
4
|
-
import { sequence, syntax, creation, validate, verify,
|
|
4
|
+
import { sequence, syntax, creation, validate, verify, surround, lazy, fmap } from '../../combinator';
|
|
5
5
|
import { unsafehtmlentity } from './htmlentity';
|
|
6
|
-
import { text as txt } from '../source';
|
|
6
|
+
import { text as txt, str } from '../source';
|
|
7
7
|
import { Syntax, State } from '../context';
|
|
8
8
|
import { isStartTightNodes } from '../visibility';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
import { unshift, push } from 'spica/array';
|
|
11
11
|
|
|
12
|
-
export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.
|
|
12
|
+
export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.ruby, 2, 1, State.all, fmap(verify(fmap(
|
|
13
13
|
sequence([
|
|
14
|
-
surround('[',
|
|
15
|
-
surround('(',
|
|
14
|
+
surround('[', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']'),
|
|
15
|
+
surround('(', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')'),
|
|
16
16
|
]),
|
|
17
|
-
([texts]) =>
|
|
17
|
+
([texts, rubies], _, context) => [
|
|
18
|
+
eval(text({ source: texts, context }), [])[0] ?? '',
|
|
19
|
+
eval(text({ source: rubies, context }), [])[0] ?? '',
|
|
20
|
+
]),
|
|
21
|
+
([texts, rubies]) => texts && rubies && isStartTightNodes(texts)),
|
|
18
22
|
([texts, rubies]) => {
|
|
19
23
|
texts[texts.length - 1] === '' && texts.pop();
|
|
20
24
|
switch (true) {
|
|
@@ -7,7 +7,7 @@ import { html } from 'typed-dom/dom';
|
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
9
9
|
export const template: TemplateParser = lazy(() => surround(
|
|
10
|
-
'{{', syntax(Syntax.none, 2, 1, State.
|
|
10
|
+
'{{', syntax(Syntax.none, 2, 1, State.all, some(union([bracket, escsource]), '}')), '}}', true,
|
|
11
11
|
([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('').replace(/\x1B/g, '')}}}`)], rest]));
|
|
12
12
|
|
|
13
13
|
const bracket: TemplateParser.BracketParser = lazy(() => creation(union([
|