securemark 0.290.0 → 0.290.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +60 -79
- package/markdown.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinator/control/manipulation/surround.ts +3 -3
- package/src/parser/api/parse.test.ts +2 -2
- package/src/parser/inline/code.ts +1 -1
- package/src/parser/inline/extension/index.ts +8 -7
- package/src/parser/inline/htmlentity.ts +6 -6
- package/src/parser/inline/link.ts +1 -2
- package/src/parser/inline/media.test.ts +1 -1
- package/src/parser/inline/media.ts +11 -11
- package/src/parser/inline/ruby.test.ts +2 -2
- package/src/parser/inline/ruby.ts +32 -35
- package/src/parser/inline/template.ts +12 -3
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.290.
|
|
1
|
+
/*! securemark v0.290.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
|
|
2
2
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
3
3
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
4
4
|
module.exports = factory(require("Prism"), require("DOMPurify"));
|
|
@@ -2997,8 +2997,8 @@ function close(parser, closer, optional, backtracks) {
|
|
|
2997
2997
|
}
|
|
2998
2998
|
exports.close = close;
|
|
2999
2999
|
const statesize = 2;
|
|
3000
|
-
function getBacktrack(context, backtracks, source, length) {
|
|
3001
|
-
for (const backtrack of backtracks) {
|
|
3000
|
+
function getBacktrack(context, backtracks, source, length = 1) {
|
|
3001
|
+
if (length > 0) for (const backtrack of backtracks) {
|
|
3002
3002
|
if (backtrack & 1) {
|
|
3003
3003
|
const {
|
|
3004
3004
|
backtracks = {},
|
|
@@ -3016,7 +3016,7 @@ function getBacktrack(context, backtracks, source, length) {
|
|
|
3016
3016
|
}
|
|
3017
3017
|
exports.getBacktrack = getBacktrack;
|
|
3018
3018
|
function setBacktrack(context, backtracks, position, length = 1) {
|
|
3019
|
-
for (const backtrack of backtracks) {
|
|
3019
|
+
if (length > 0) for (const backtrack of backtracks) {
|
|
3020
3020
|
if (backtrack & 2) {
|
|
3021
3021
|
const {
|
|
3022
3022
|
backtracks = {},
|
|
@@ -5480,22 +5480,6 @@ function format(list) {
|
|
|
5480
5480
|
|
|
5481
5481
|
/***/ },
|
|
5482
5482
|
|
|
5483
|
-
/***/ 8669
|
|
5484
|
-
(__unused_webpack_module, exports) {
|
|
5485
|
-
|
|
5486
|
-
"use strict";
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
Object.defineProperty(exports, "__esModule", ({
|
|
5490
|
-
value: true
|
|
5491
|
-
}));
|
|
5492
|
-
exports.CmdRegExp = void 0;
|
|
5493
|
-
exports.CmdRegExp = {
|
|
5494
|
-
Error: /\x07/g
|
|
5495
|
-
};
|
|
5496
|
-
|
|
5497
|
-
/***/ },
|
|
5498
|
-
|
|
5499
5483
|
/***/ 3009
|
|
5500
5484
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
5501
5485
|
|
|
@@ -5965,7 +5949,7 @@ const dom_1 = __webpack_require__(394);
|
|
|
5965
5949
|
exports.code = (0, combinator_1.validate)(({
|
|
5966
5950
|
source,
|
|
5967
5951
|
context
|
|
5968
|
-
}) => source[0] === '`' && !(0, combinator_1.getBacktrack)(context, [1 | 8 /* Backtrack.bracket */], source
|
|
5952
|
+
}) => source[0] === '`' && !(0, combinator_1.getBacktrack)(context, [1 | 8 /* Backtrack.bracket */], source), (0, combinator_1.match)(/^(`+)(?!`)([^\n]*?)(?:((?<!`)\1(?!`))|$|\n)/, ([whole,, body, closer]) => ({
|
|
5969
5953
|
source,
|
|
5970
5954
|
context
|
|
5971
5955
|
}) => closer ? [[(0, dom_1.html)('code', {
|
|
@@ -6136,18 +6120,19 @@ exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(32 /*
|
|
|
6136
6120
|
class: 'index',
|
|
6137
6121
|
href: el.id ? `#${el.id}` : undefined
|
|
6138
6122
|
})])));
|
|
6139
|
-
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/^\|(?!\\?\s)/), (0, visibility_1.tightStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']')), /^(?=])/, false, (
|
|
6140
|
-
|
|
6141
|
-
|
|
6123
|
+
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/^\|(?!\\?\s)/), (0, visibility_1.tightStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']')), /^(?=])/, false, (_, rest, context) => {
|
|
6124
|
+
//context.offset ??= 0;
|
|
6125
|
+
//context.offset += rest.length;
|
|
6142
6126
|
const sig = (0, parser_1.eval)(parser({
|
|
6143
|
-
source: recent[1],
|
|
6144
|
-
context
|
|
6127
|
+
source: context.recent[1],
|
|
6128
|
+
context
|
|
6145
6129
|
}), []).join('');
|
|
6146
|
-
|
|
6130
|
+
//context.offset -= rest.length;
|
|
6131
|
+
const index = (0, indexee_1.identity)('index', undefined, sig)?.slice(7);
|
|
6147
6132
|
return index ? [[(0, dom_1.html)('span', {
|
|
6148
6133
|
class: 'indexer',
|
|
6149
6134
|
'data-index': index
|
|
6150
|
-
})], rest] :
|
|
6135
|
+
})], rest] : undefined;
|
|
6151
6136
|
}, ([as, bs], rest) => [(0, array_1.unshift)(as, bs), rest])));
|
|
6152
6137
|
function dataindex(ns) {
|
|
6153
6138
|
if (ns.length === 0) return;
|
|
@@ -6477,13 +6462,15 @@ exports.htmlentity = exports.unsafehtmlentity = void 0;
|
|
|
6477
6462
|
const combinator_1 = __webpack_require__(3484);
|
|
6478
6463
|
const util_1 = __webpack_require__(4992);
|
|
6479
6464
|
const dom_1 = __webpack_require__(394);
|
|
6480
|
-
exports.unsafehtmlentity = (0, combinator_1.validate)('&', (0, combinator_1.focus)(/^&[0-9A-Za-z]{1,99};/,
|
|
6465
|
+
exports.unsafehtmlentity = (0, combinator_1.validate)('&', (0, combinator_1.focus)(/^&[0-9A-Za-z]{1,99};/,
|
|
6466
|
+
//({ source }) => [[parser(source) ?? `${Command.Error}${source}`], '']));
|
|
6467
|
+
({
|
|
6481
6468
|
source
|
|
6482
|
-
}) => [[parser(source) ??
|
|
6483
|
-
exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([text]) => [text[0]
|
|
6469
|
+
}) => [[parser(source) ?? source], '']));
|
|
6470
|
+
exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([text]) => [text.length === 1 || text[0] !== '&' ? text : (0, dom_1.html)('span', {
|
|
6484
6471
|
class: 'invalid',
|
|
6485
6472
|
...(0, util_1.invalid)('htmlentity', 'syntax', 'Invalid HTML entity')
|
|
6486
|
-
}, text
|
|
6473
|
+
}, text)]);
|
|
6487
6474
|
const parser = (el => entity => {
|
|
6488
6475
|
if (entity === '
') return ' ';
|
|
6489
6476
|
el.innerHTML = entity;
|
|
@@ -6545,7 +6532,7 @@ exports.italic = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('///',
|
|
|
6545
6532
|
Object.defineProperty(exports, "__esModule", ({
|
|
6546
6533
|
value: true
|
|
6547
6534
|
}));
|
|
6548
|
-
exports.resolve = exports.option = exports.uri = exports.unsafelink = exports.linemedialink = exports.medialink = exports.textlink = void 0;
|
|
6535
|
+
exports.decode = exports.resolve = exports.option = exports.uri = exports.unsafelink = exports.linemedialink = exports.medialink = exports.textlink = void 0;
|
|
6549
6536
|
const combinator_1 = __webpack_require__(3484);
|
|
6550
6537
|
const inline_1 = __webpack_require__(7973);
|
|
6551
6538
|
const html_1 = __webpack_require__(5013);
|
|
@@ -6653,7 +6640,6 @@ function resolve(uri, host, source) {
|
|
|
6653
6640
|
}
|
|
6654
6641
|
exports.resolve = resolve;
|
|
6655
6642
|
function decode(uri) {
|
|
6656
|
-
if (!uri.includes('%')) return uri;
|
|
6657
6643
|
const origin = uri.match(/^[a-z](?:[-.](?=[0-9a-z])|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i)?.[0] ?? '';
|
|
6658
6644
|
try {
|
|
6659
6645
|
let path = decodeURI(uri.slice(origin.length));
|
|
@@ -6665,6 +6651,7 @@ function decode(uri) {
|
|
|
6665
6651
|
return uri.replace(/\s+/g, encodeURI);
|
|
6666
6652
|
}
|
|
6667
6653
|
}
|
|
6654
|
+
exports.decode = decode;
|
|
6668
6655
|
|
|
6669
6656
|
/***/ },
|
|
6670
6657
|
|
|
@@ -6744,7 +6731,6 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
6744
6731
|
value: true
|
|
6745
6732
|
}));
|
|
6746
6733
|
exports.linemedia = exports.media = void 0;
|
|
6747
|
-
const context_1 = __webpack_require__(8669);
|
|
6748
6734
|
const combinator_1 = __webpack_require__(3484);
|
|
6749
6735
|
const link_1 = __webpack_require__(3628);
|
|
6750
6736
|
const html_1 = __webpack_require__(5013);
|
|
@@ -6764,7 +6750,7 @@ Object.setPrototypeOf(optspec, null);
|
|
|
6764
6750
|
exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* State.media */, false, (0, combinator_1.validate)(['![', '!{'], (0, combinator_1.creation)(10, (0, combinator_1.open)('!', (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.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']')), ']', true, ([, ns = []], rest, context) => context.linebreak === undefined ? [ns, rest] : undefined, undefined, [3 | 4 /* Backtrack.escbracket */])), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), /^[^\S\n]*}/, false, undefined, undefined, [3 | 64 /* Backtrack.link */]))]), ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
|
|
6765
6751
|
const INSECURE_URI = params.shift();
|
|
6766
6752
|
// altが空だとエラーが見えないため埋める。
|
|
6767
|
-
text ||= INSECURE_URI;
|
|
6753
|
+
text ||= (0, link_1.decode)(INSECURE_URI);
|
|
6768
6754
|
let uri;
|
|
6769
6755
|
try {
|
|
6770
6756
|
uri = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, context.host ?? location, context.url ?? context.host ?? location), context.host?.href || location.href);
|
|
@@ -6775,7 +6761,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* S
|
|
|
6775
6761
|
'data-src': uri?.source
|
|
6776
6762
|
});
|
|
6777
6763
|
el.setAttribute('alt', text);
|
|
6778
|
-
if (!sanitize(el, uri
|
|
6764
|
+
if (!sanitize(el, uri)) return [[el], rest];
|
|
6779
6765
|
(0, dom_1.define)(el, (0, html_1.attributes)('media', (0, array_1.push)([], el.classList), optspec, params));
|
|
6780
6766
|
// Awaiting the generic support for attr().
|
|
6781
6767
|
if (el.hasAttribute('aspect-ratio')) {
|
|
@@ -6794,10 +6780,10 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* S
|
|
|
6794
6780
|
exports.linemedia = (0, combinator_1.surround)(source_1.linebreak, (0, combinator_1.union)([exports.media]), /^(?=[^\S\n]*(?:$|\n))/);
|
|
6795
6781
|
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true, undefined, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']'), (0, source_1.str)(']'), true, undefined, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), '}'), (0, source_1.str)('}'), true, undefined, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, source_1.txt]), '"')), (0, source_1.str)('"'), true, undefined, () => [[], ''], [3 | 4 /* Backtrack.escbracket */])])));
|
|
6796
6782
|
const option = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+[1-9][0-9]*x[1-9][0-9]*(?=[^\S\n]|})/), ([opt]) => [` width="${opt.slice(1).split('x')[0]}"`, ` height="${opt.slice(1).split('x')[1]}"`]), (0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+[1-9][0-9]*:[1-9][0-9]*(?=[^\S\n]|})/), ([opt]) => [` aspect-ratio="${opt.slice(1).split(':').join('/')}"`]), link_1.option]));
|
|
6797
|
-
function sanitize(target, uri
|
|
6783
|
+
function sanitize(target, uri) {
|
|
6798
6784
|
let type;
|
|
6799
6785
|
let message;
|
|
6800
|
-
|
|
6786
|
+
switch (uri?.protocol) {
|
|
6801
6787
|
case undefined:
|
|
6802
6788
|
type = 'argument';
|
|
6803
6789
|
message = 'Invalid URI';
|
|
@@ -6811,11 +6797,12 @@ function sanitize(target, uri, alt) {
|
|
|
6811
6797
|
default:
|
|
6812
6798
|
type = 'argument';
|
|
6813
6799
|
message = 'Invalid protocol';
|
|
6814
|
-
} else {
|
|
6815
|
-
target.setAttribute('alt', alt.replace(context_1.CmdRegExp.Error, ''));
|
|
6816
|
-
type = 'argument';
|
|
6817
|
-
message = `Invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)[0]}"`;
|
|
6818
6800
|
}
|
|
6801
|
+
//else {
|
|
6802
|
+
// target.setAttribute('alt', alt.replace(CmdRegExp.Error, ''));
|
|
6803
|
+
// type = 'argument';
|
|
6804
|
+
// message = `Invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`;
|
|
6805
|
+
//}
|
|
6819
6806
|
(0, dom_1.define)(target, {
|
|
6820
6807
|
'data-src': null,
|
|
6821
6808
|
class: 'invalid',
|
|
@@ -6908,47 +6895,37 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
6908
6895
|
value: true
|
|
6909
6896
|
}));
|
|
6910
6897
|
exports.ruby = void 0;
|
|
6911
|
-
const context_1 = __webpack_require__(8669);
|
|
6912
6898
|
const parser_1 = __webpack_require__(605);
|
|
6913
6899
|
const combinator_1 = __webpack_require__(3484);
|
|
6914
6900
|
const htmlentity_1 = __webpack_require__(470);
|
|
6915
6901
|
const source_1 = __webpack_require__(8745);
|
|
6916
6902
|
const visibility_1 = __webpack_require__(6364);
|
|
6917
|
-
const util_1 = __webpack_require__(4992);
|
|
6918
6903
|
const array_1 = __webpack_require__(6876);
|
|
6919
6904
|
const dom_1 = __webpack_require__(394);
|
|
6920
|
-
exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.bind)((0, combinator_1.inits)([(0, combinator_1.dup)((0, combinator_1.surround)('[',
|
|
6921
|
-
const ns = (0, parser_1.eval)(text({
|
|
6922
|
-
source,
|
|
6923
|
-
context
|
|
6924
|
-
}), [undefined])[0];
|
|
6905
|
+
exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.bind)((0, combinator_1.inits)([(0, combinator_1.dup)((0, combinator_1.surround)('[', rtext, ']', false, ([, ns], rest) => {
|
|
6925
6906
|
ns && ns.at(-1) === '' && ns.pop();
|
|
6926
|
-
return
|
|
6927
|
-
}, undefined, [3 | 32 /* Backtrack.ruby */ | 1, 64 /* Backtrack.link */, 1 | 8 /* Backtrack.bracket */])), (0, combinator_1.dup)((0, combinator_1.surround)('(',
|
|
6928
|
-
const ns = (0, parser_1.eval)(text({
|
|
6929
|
-
source,
|
|
6930
|
-
context
|
|
6931
|
-
}), [undefined])[0];
|
|
6932
|
-
return ns && [ns, rest];
|
|
6933
|
-
}, undefined, [3 | 32 /* Backtrack.ruby */ | 1, 64 /* Backtrack.link */, 1 | 8 /* Backtrack.bracket */]))]), ([texts, rubies], rest, context) => {
|
|
6907
|
+
return (0, visibility_1.isTightNodeStart)(ns) ? [ns, rest] : undefined;
|
|
6908
|
+
}, undefined, [3 | 32 /* Backtrack.ruby */ | 1, 64 /* Backtrack.link */, 1 | 8 /* Backtrack.bracket */])), (0, combinator_1.dup)((0, combinator_1.surround)('(', rtext, ')', false, undefined, undefined, [3 | 32 /* Backtrack.ruby */ | 1, 64 /* Backtrack.link */, 1 | 8 /* Backtrack.bracket */]))]), ([texts, rubies], rest, context) => {
|
|
6934
6909
|
if (rubies === undefined) {
|
|
6935
6910
|
return void (0, combinator_1.setBacktrack)(context, [2 | 32 /* Backtrack.ruby */], context.recent.reduce((a, b) => a + b.length, 0));
|
|
6936
6911
|
}
|
|
6937
6912
|
switch (true) {
|
|
6938
6913
|
case rubies.length <= texts.length:
|
|
6939
|
-
return [[(0, dom_1.html)('ruby',
|
|
6914
|
+
return [[(0, dom_1.html)('ruby', (0, dom_1.defrag)(texts.reduce((acc, _, i) => (0, array_1.push)(acc, (0, array_1.unshift)([texts[i]], i < rubies.length && rubies[i] ? [(0, dom_1.html)('rp', '('), (0, dom_1.html)('rt', rubies[i]), (0, dom_1.html)('rp', ')')] : [(0, dom_1.html)('rt')])), [])))], rest];
|
|
6940
6915
|
case texts.length === 1 && [...texts[0]].length >= rubies.length:
|
|
6941
|
-
return [[(0, dom_1.html)('ruby',
|
|
6916
|
+
return [[(0, dom_1.html)('ruby', (0, dom_1.defrag)([...texts[0]].reduce((acc, _, i, texts) => (0, array_1.push)(acc, (0, array_1.unshift)([texts[i]], i < rubies.length && rubies[i] ? [(0, dom_1.html)('rp', '('), (0, dom_1.html)('rt', rubies[i]), (0, dom_1.html)('rp', ')')] : [(0, dom_1.html)('rt')])), [])))], rest];
|
|
6942
6917
|
default:
|
|
6943
|
-
return [[(0, dom_1.html)('ruby',
|
|
6918
|
+
return [[(0, dom_1.html)('ruby', (0, dom_1.defrag)((0, array_1.unshift)([texts.join(' ')], [(0, dom_1.html)('rp', '('), (0, dom_1.html)('rt', rubies.join(' ').trim()), (0, dom_1.html)('rp', ')')])))], rest];
|
|
6944
6919
|
}
|
|
6945
6920
|
}));
|
|
6946
|
-
const
|
|
6921
|
+
const rtext = ({
|
|
6947
6922
|
source,
|
|
6948
6923
|
context
|
|
6949
6924
|
}) => {
|
|
6950
6925
|
const acc = [''];
|
|
6926
|
+
let state = false;
|
|
6951
6927
|
while (source !== '') {
|
|
6928
|
+
if (!/^(?:\\[^\n]|[^\\[\](){}<>"\n])/.test(source)) break;
|
|
6952
6929
|
switch (source[0]) {
|
|
6953
6930
|
// @ts-expect-error
|
|
6954
6931
|
case '&':
|
|
@@ -6960,6 +6937,7 @@ const text = ({
|
|
|
6960
6937
|
if (result) {
|
|
6961
6938
|
acc[acc.length - 1] += (0, parser_1.eval)(result)[0];
|
|
6962
6939
|
source = (0, parser_1.exec)(result, source.slice(1));
|
|
6940
|
+
state ||= acc.at(-1).trimStart() !== '';
|
|
6963
6941
|
continue;
|
|
6964
6942
|
}
|
|
6965
6943
|
// fallthrough
|
|
@@ -6977,26 +6955,27 @@ const text = ({
|
|
|
6977
6955
|
});
|
|
6978
6956
|
acc[acc.length - 1] += (0, parser_1.eval)(result)[0] ?? source.slice(0, source.length - (0, parser_1.exec)(result).length);
|
|
6979
6957
|
source = (0, parser_1.exec)(result);
|
|
6958
|
+
state ||= acc.at(-1).trimStart() !== '';
|
|
6980
6959
|
continue;
|
|
6981
6960
|
}
|
|
6982
6961
|
}
|
|
6983
6962
|
}
|
|
6984
|
-
return
|
|
6963
|
+
return state ? [acc, source] : undefined;
|
|
6985
6964
|
};
|
|
6986
|
-
function attributes(texts, rubies) {
|
|
6987
|
-
let attrs;
|
|
6988
|
-
for (const ss of [texts, rubies]) {
|
|
6989
|
-
for (let i = 0; i < ss.length; ++i) {
|
|
6990
|
-
if (!ss[i].includes(
|
|
6991
|
-
ss[i] = ss[i].replace(
|
|
6992
|
-
attrs ??= {
|
|
6993
|
-
class: 'invalid',
|
|
6994
|
-
...
|
|
6995
|
-
};
|
|
6996
|
-
}
|
|
6997
|
-
}
|
|
6998
|
-
return attrs ?? {};
|
|
6999
|
-
}
|
|
6965
|
+
//function attributes(texts: string[], rubies: string[]): Record<string, string> {
|
|
6966
|
+
// let attrs: Record<string, string> | undefined;
|
|
6967
|
+
// for (const ss of [texts, rubies]) {
|
|
6968
|
+
// for (let i = 0; i < ss.length; ++i) {
|
|
6969
|
+
// if (!ss[i].includes(Command.Error)) continue;
|
|
6970
|
+
// ss[i] = ss[i].replace(CmdRegExp.Error, '');
|
|
6971
|
+
// attrs ??= {
|
|
6972
|
+
// class: 'invalid',
|
|
6973
|
+
// ...invalid('ruby', ss === texts ? 'content' : 'argument', 'Invalid HTML entity'),
|
|
6974
|
+
// };
|
|
6975
|
+
// }
|
|
6976
|
+
// }
|
|
6977
|
+
// return attrs ?? {};
|
|
6978
|
+
//}
|
|
7000
6979
|
|
|
7001
6980
|
/***/ },
|
|
7002
6981
|
|
|
@@ -7056,8 +7035,10 @@ const array_1 = __webpack_require__(6876);
|
|
|
7056
7035
|
const dom_1 = __webpack_require__(394);
|
|
7057
7036
|
exports.template = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.str)('{{'), (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), '}')), (0, source_1.str)('}}'), true, ([as, bs = [], cs], rest) => [[(0, dom_1.html)('span', {
|
|
7058
7037
|
class: 'template'
|
|
7059
|
-
}, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], undefined, [3 | 16 /* Backtrack.doublebracket */,
|
|
7060
|
-
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, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (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, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (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, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (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, '"'))), (0, source_1.str)('"'), true,
|
|
7038
|
+
}, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], undefined, [3 | 16 /* Backtrack.doublebracket */, 3 | 4 /* Backtrack.escbracket */]));
|
|
7039
|
+
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, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (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, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (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, () => [[], ''], [3 | 4 /* Backtrack.escbracket */]), (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, '"', [['"', 2, false]]))), (0, source_1.str)('"'), true, ([as, bs = [], cs], rest, {
|
|
7040
|
+
linebreak = 0
|
|
7041
|
+
}) => linebreak > rest.length ? [(0, array_1.unshift)(as, bs), cs[0] + rest] : [(0, array_1.push)((0, array_1.unshift)(as, bs), cs), rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [3 | 4 /* Backtrack.escbracket */])]));
|
|
7061
7042
|
|
|
7062
7043
|
/***/ },
|
|
7063
7044
|
|
package/markdown.d.ts
CHANGED
|
@@ -951,7 +951,7 @@ export namespace MarkdownParser {
|
|
|
951
951
|
export namespace RubyParser {
|
|
952
952
|
export interface TextParser extends
|
|
953
953
|
Inline<'ruby/text'>,
|
|
954
|
-
Parser<string
|
|
954
|
+
Parser<string, Context, []> {
|
|
955
955
|
}
|
|
956
956
|
}
|
|
957
957
|
export interface HTMLParser extends
|
package/package.json
CHANGED
|
@@ -123,9 +123,9 @@ export function getBacktrack(
|
|
|
123
123
|
context: Ctx,
|
|
124
124
|
backtracks: readonly number[],
|
|
125
125
|
source: string,
|
|
126
|
-
length: number,
|
|
126
|
+
length: number = 1,
|
|
127
127
|
): boolean {
|
|
128
|
-
for (const backtrack of backtracks) {
|
|
128
|
+
if (length > 0) for (const backtrack of backtracks) {
|
|
129
129
|
if (backtrack & 1) {
|
|
130
130
|
const { backtracks = {}, offset = 0 } = context;
|
|
131
131
|
for (let i = 0; i < length; ++i) {
|
|
@@ -145,7 +145,7 @@ export function setBacktrack(
|
|
|
145
145
|
position: number,
|
|
146
146
|
length: number = 1,
|
|
147
147
|
): void {
|
|
148
|
-
for (const backtrack of backtracks) {
|
|
148
|
+
if (length > 0) for (const backtrack of backtracks) {
|
|
149
149
|
if (backtrack & 2) {
|
|
150
150
|
const { backtracks = {}, offset = 0 } = context;
|
|
151
151
|
for (let i = 0; i < length; ++i) {
|
|
@@ -351,7 +351,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
351
351
|
it('backtrack', function () {
|
|
352
352
|
this.timeout(5000);
|
|
353
353
|
// 8n = template + link + annotation/reference + link + code + url + ruby + text
|
|
354
|
-
const source = `${'.'.repeat(
|
|
354
|
+
const source = `${'.'.repeat(0 + 0)}{{{((([[[\`http://[${'.'.repeat(12493)}`;
|
|
355
355
|
assert.deepStrictEqual(
|
|
356
356
|
[...parse(source).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
357
357
|
[`<p>${source}</p>`]);
|
|
@@ -359,7 +359,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
359
359
|
|
|
360
360
|
it('backtrack error', function () {
|
|
361
361
|
this.timeout(5000);
|
|
362
|
-
const source = `${'.'.repeat(
|
|
362
|
+
const source = `${'.'.repeat(0 + 1)}{{{((([[[\`http://[${'.'.repeat(12493)}`;
|
|
363
363
|
assert.deepStrictEqual(
|
|
364
364
|
[...parse(source).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
365
365
|
[
|
|
@@ -6,7 +6,7 @@ import { html } from 'typed-dom/dom';
|
|
|
6
6
|
export const code: CodeParser = validate(
|
|
7
7
|
({ source, context }) =>
|
|
8
8
|
source[0] === '`' &&
|
|
9
|
-
!getBacktrack(context, [1 | Backtrack.bracket], source
|
|
9
|
+
!getBacktrack(context, [1 | Backtrack.bracket], source),
|
|
10
10
|
match(
|
|
11
11
|
/^(`+)(?!`)([^\n]*?)(?:((?<!`)\1(?!`))|$|\n)/,
|
|
12
12
|
([whole, , body, closer]) => ({ source, context }) =>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
-
import { State, Backtrack
|
|
2
|
+
import { State, Backtrack } from '../../context';
|
|
3
3
|
import { eval } from '../../../combinator/data/parser';
|
|
4
4
|
import { union, inits, some, precedence, state, constraint, validate, surround, lazy, fmap } from '../../../combinator';
|
|
5
5
|
import { inline } from '../../inline';
|
|
@@ -43,14 +43,15 @@ export const signature: IndexParser.SignatureParser = lazy(() => validate('|', s
|
|
|
43
43
|
tightStart(some(union([inline]), ']')),
|
|
44
44
|
/^(?=])/,
|
|
45
45
|
false,
|
|
46
|
-
(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
(_, rest, context) => {
|
|
47
|
+
//context.offset ??= 0;
|
|
48
|
+
//context.offset += rest.length;
|
|
49
|
+
const sig = eval(parser({ source: context.recent![1], context }), []).join('');
|
|
50
|
+
//context.offset -= rest.length;
|
|
51
|
+
const index = identity('index', undefined, sig)?.slice(7);
|
|
51
52
|
return index
|
|
52
53
|
? [[html('span', { class: 'indexer', 'data-index': index })], rest]
|
|
53
|
-
:
|
|
54
|
+
: undefined;
|
|
54
55
|
},
|
|
55
56
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
56
57
|
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { HTMLEntityParser, UnsafeHTMLEntityParser } from '../inline';
|
|
2
|
-
import { Command } from '../context';
|
|
3
2
|
import { union, validate, focus, fmap } from '../../combinator';
|
|
4
3
|
import { invalid } from '../util';
|
|
5
4
|
import { html } from 'typed-dom/dom';
|
|
6
5
|
|
|
7
6
|
export const unsafehtmlentity: UnsafeHTMLEntityParser = validate('&', focus(
|
|
8
7
|
/^&[0-9A-Za-z]{1,99};/,
|
|
9
|
-
({ source }) => [[parser(source) ?? `${Command.Error}${source}`], '']));
|
|
8
|
+
//({ source }) => [[parser(source) ?? `${Command.Error}${source}`], '']));
|
|
9
|
+
({ source }) => [[parser(source) ?? source], '']));
|
|
10
10
|
|
|
11
11
|
export const htmlentity: HTMLEntityParser = fmap(
|
|
12
12
|
union([unsafehtmlentity]),
|
|
13
13
|
([text]) => [
|
|
14
|
-
text[0]
|
|
15
|
-
?
|
|
14
|
+
text.length === 1 || text[0] !== '&'
|
|
15
|
+
? text
|
|
16
|
+
: html('span', {
|
|
16
17
|
class: 'invalid',
|
|
17
18
|
...invalid('htmlentity', 'syntax', 'Invalid HTML entity'),
|
|
18
|
-
|
|
19
|
-
: text,
|
|
19
|
+
}, text)
|
|
20
20
|
]);
|
|
21
21
|
|
|
22
22
|
const parser = (el => (entity: string): string | undefined => {
|
|
@@ -226,8 +226,7 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
function decode(uri: string): string {
|
|
230
|
-
if (!uri.includes('%')) return uri;
|
|
229
|
+
export function decode(uri: string): string {
|
|
231
230
|
const origin = uri.match(/^[a-z](?:[-.](?=[0-9a-z])|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i)?.[0] ?? '';
|
|
232
231
|
try {
|
|
233
232
|
let path = decodeURI(uri.slice(origin.length));
|
|
@@ -43,7 +43,7 @@ describe('Unit: parser/inline/media', () => {
|
|
|
43
43
|
assert.deepStrictEqual(inspect(parser('![\\ ]{b}')), undefined);
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('![\\\n]{b}')), undefined);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('![	]{b}')), undefined);
|
|
46
|
-
assert.deepStrictEqual(inspect(parser('![&a;]{b}')), [['<img class="
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('![&a;]{b}')), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="&a;"></a>'], '']);
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('![[]{b}')), undefined);
|
|
48
48
|
assert.deepStrictEqual(inspect(parser('![]]{b}')), undefined);
|
|
49
49
|
assert.deepStrictEqual(inspect(parser('![a]{}')), undefined);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MediaParser } from '../inline';
|
|
2
|
-
import { State, Recursion, Backtrack
|
|
2
|
+
import { State, Recursion, Backtrack } from '../context';
|
|
3
3
|
import { union, inits, tails, some, creation, recursion, precedence, constraint, validate, verify, surround, open, dup, lazy, fmap, bind } from '../../combinator';
|
|
4
|
-
import { unsafelink, uri, option as linkoption, resolve } from './link';
|
|
4
|
+
import { unsafelink, uri, option as linkoption, resolve, decode } from './link';
|
|
5
5
|
import { attributes } from './html';
|
|
6
6
|
import { unsafehtmlentity } from './htmlentity';
|
|
7
7
|
import { txt, linebreak, str } from '../source';
|
|
@@ -51,7 +51,7 @@ export const media: MediaParser = lazy(() => constraint(State.media, false, vali
|
|
|
51
51
|
assert(INSECURE_URI === INSECURE_URI.trim());
|
|
52
52
|
assert(!INSECURE_URI.match(/\s/));
|
|
53
53
|
// altが空だとエラーが見えないため埋める。
|
|
54
|
-
text ||= INSECURE_URI;
|
|
54
|
+
text ||= decode(INSECURE_URI);
|
|
55
55
|
let uri: ReadonlyURL | undefined;
|
|
56
56
|
try {
|
|
57
57
|
uri = new ReadonlyURL(
|
|
@@ -66,7 +66,7 @@ export const media: MediaParser = lazy(() => constraint(State.media, false, vali
|
|
|
66
66
|
|| html('img', { class: 'media', 'data-src': uri?.source });
|
|
67
67
|
assert(!el.matches('.invalid'));
|
|
68
68
|
el.setAttribute('alt', text);
|
|
69
|
-
if (!sanitize(el, uri
|
|
69
|
+
if (!sanitize(el, uri)) return [[el], rest];
|
|
70
70
|
assert(!el.matches('.invalid'));
|
|
71
71
|
define(el, attributes('media', push([], el.classList), optspec, params));
|
|
72
72
|
assert(el.matches('img') || !el.matches('.invalid'));
|
|
@@ -104,12 +104,12 @@ const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
|
104
104
|
linkoption,
|
|
105
105
|
]));
|
|
106
106
|
|
|
107
|
-
function sanitize(target: HTMLElement, uri: ReadonlyURL | undefined
|
|
107
|
+
function sanitize(target: HTMLElement, uri: ReadonlyURL | undefined): boolean {
|
|
108
108
|
assert(target.tagName === 'IMG');
|
|
109
109
|
assert(!target.matches('.invalid'));
|
|
110
110
|
let type: string;
|
|
111
111
|
let message: string;
|
|
112
|
-
|
|
112
|
+
switch (uri?.protocol) {
|
|
113
113
|
case undefined:
|
|
114
114
|
type = 'argument';
|
|
115
115
|
message = 'Invalid URI';
|
|
@@ -125,11 +125,11 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL | undefined, alt: string
|
|
|
125
125
|
type = 'argument';
|
|
126
126
|
message = 'Invalid protocol';
|
|
127
127
|
}
|
|
128
|
-
else {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
128
|
+
//else {
|
|
129
|
+
// target.setAttribute('alt', alt.replace(CmdRegExp.Error, ''));
|
|
130
|
+
// type = 'argument';
|
|
131
|
+
// message = `Invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`;
|
|
132
|
+
//}
|
|
133
133
|
define(target, {
|
|
134
134
|
'data-src': null,
|
|
135
135
|
class: 'invalid',
|
|
@@ -15,8 +15,8 @@ describe('Unit: parser/inline/ruby', () => {
|
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('[ a](b)')), undefined);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('[	a](b)')), undefined);
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('[	 a](b)')), undefined);
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('[&a;](b)')), [['<ruby
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('[a](&a;)')), [['<ruby
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('[&a;](b)')), [['<ruby>&a;<rp>(</rp><rt>b</rt><rp>)</rp></ruby>'], '']);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('[a](&a;)')), [['<ruby>a<rp>(</rp><rt>&a;</rt><rp>)</rp></ruby>'], '']);
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('[<wbr>](a)')), undefined);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('[a](<wbr>)')), undefined);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('[a]()')), undefined);
|
|
@@ -1,34 +1,27 @@
|
|
|
1
1
|
import { RubyParser } from '../inline';
|
|
2
|
-
import { Backtrack
|
|
2
|
+
import { Backtrack } from '../context';
|
|
3
3
|
import { eval, exec } from '../../combinator/data/parser';
|
|
4
4
|
import { inits, surround, setBacktrack, dup, lazy, bind } from '../../combinator';
|
|
5
5
|
import { unsafehtmlentity } from './htmlentity';
|
|
6
|
-
import { text
|
|
6
|
+
import { text } from '../source';
|
|
7
7
|
import { isTightNodeStart } from '../visibility';
|
|
8
|
-
import { invalid } from '../util';
|
|
9
8
|
import { unshift, push } from 'spica/array';
|
|
10
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
11
10
|
|
|
12
11
|
export const ruby: RubyParser = lazy(() => bind(
|
|
13
12
|
inits([
|
|
14
13
|
dup(surround(
|
|
15
|
-
'[',
|
|
14
|
+
'[', rtext, ']',
|
|
16
15
|
false,
|
|
17
|
-
([,
|
|
18
|
-
const ns = eval(text({ source, context }), [undefined])[0];
|
|
16
|
+
([, ns], rest) => {
|
|
19
17
|
ns && ns.at(-1) === '' && ns.pop();
|
|
20
|
-
return
|
|
18
|
+
return isTightNodeStart(ns) ? [ns, rest] : undefined;
|
|
21
19
|
},
|
|
22
20
|
undefined,
|
|
23
21
|
[3 | Backtrack.ruby | 1, Backtrack.link, 1 | Backtrack.bracket])),
|
|
24
22
|
dup(surround(
|
|
25
|
-
'(',
|
|
26
|
-
false,
|
|
27
|
-
([, [source]], rest, context) => {
|
|
28
|
-
const ns = eval(text({ source, context }), [undefined])[0];
|
|
29
|
-
return ns && [ns, rest];
|
|
30
|
-
},
|
|
31
|
-
undefined,
|
|
23
|
+
'(', rtext, ')',
|
|
24
|
+
false, undefined, undefined,
|
|
32
25
|
[3 | Backtrack.ruby | 1, Backtrack.link, 1 | Backtrack.bracket])),
|
|
33
26
|
]),
|
|
34
27
|
([texts, rubies], rest, context) => {
|
|
@@ -38,7 +31,7 @@ export const ruby: RubyParser = lazy(() => bind(
|
|
|
38
31
|
switch (true) {
|
|
39
32
|
case rubies.length <= texts.length:
|
|
40
33
|
return [[
|
|
41
|
-
html('ruby',
|
|
34
|
+
html('ruby', defrag(texts
|
|
42
35
|
.reduce((acc, _, i) =>
|
|
43
36
|
push(acc, unshift(
|
|
44
37
|
[texts[i]],
|
|
@@ -49,7 +42,7 @@ export const ruby: RubyParser = lazy(() => bind(
|
|
|
49
42
|
], rest];
|
|
50
43
|
case texts.length === 1 && [...texts[0]].length >= rubies.length:
|
|
51
44
|
return [[
|
|
52
|
-
html('ruby',
|
|
45
|
+
html('ruby', defrag([...texts[0]]
|
|
53
46
|
.reduce((acc, _, i, texts) =>
|
|
54
47
|
push(acc, unshift(
|
|
55
48
|
[texts[i]],
|
|
@@ -61,16 +54,18 @@ export const ruby: RubyParser = lazy(() => bind(
|
|
|
61
54
|
default:
|
|
62
55
|
assert(rubies.length > 0);
|
|
63
56
|
return [[
|
|
64
|
-
html('ruby',
|
|
57
|
+
html('ruby', defrag(unshift(
|
|
65
58
|
[texts.join(' ')],
|
|
66
59
|
[html('rp', '('), html('rt', rubies.join(' ').trim()), html('rp', ')')]))),
|
|
67
60
|
], rest];
|
|
68
61
|
}
|
|
69
62
|
}));
|
|
70
63
|
|
|
71
|
-
const
|
|
64
|
+
const rtext: RubyParser.TextParser = ({ source, context }) => {
|
|
72
65
|
const acc = [''];
|
|
66
|
+
let state = false;
|
|
73
67
|
while (source !== '') {
|
|
68
|
+
if (!/^(?:\\[^\n]|[^\\[\](){}<>"\n])/.test(source)) break;
|
|
74
69
|
assert(source[0] !== '\n');
|
|
75
70
|
switch (source[0]) {
|
|
76
71
|
// @ts-expect-error
|
|
@@ -79,6 +74,7 @@ const text: RubyParser.TextParser = ({ source, context }) => {
|
|
|
79
74
|
if (result) {
|
|
80
75
|
acc[acc.length - 1] += eval(result)[0];
|
|
81
76
|
source = exec(result, source.slice(1));
|
|
77
|
+
state ||= acc.at(-1)!.trimStart() !== '';
|
|
82
78
|
continue;
|
|
83
79
|
}
|
|
84
80
|
// fallthrough
|
|
@@ -89,30 +85,31 @@ const text: RubyParser.TextParser = ({ source, context }) => {
|
|
|
89
85
|
source = source.slice(1);
|
|
90
86
|
continue;
|
|
91
87
|
}
|
|
92
|
-
const result =
|
|
88
|
+
const result = text({ source, context })!;
|
|
93
89
|
assert(result);
|
|
94
90
|
acc[acc.length - 1] += eval(result)[0] ?? source.slice(0, source.length - exec(result).length);
|
|
95
91
|
source = exec(result);
|
|
92
|
+
state ||= acc.at(-1)!.trimStart() !== '';
|
|
96
93
|
continue;
|
|
97
94
|
}
|
|
98
95
|
}
|
|
99
96
|
}
|
|
100
|
-
return
|
|
101
|
-
? [
|
|
97
|
+
return state
|
|
98
|
+
? [acc, source]
|
|
102
99
|
: undefined;
|
|
103
100
|
};
|
|
104
101
|
|
|
105
|
-
function attributes(texts: string[], rubies: string[]): Record<string, string> {
|
|
106
|
-
let attrs: Record<string, string> | undefined;
|
|
107
|
-
for (const ss of [texts, rubies]) {
|
|
108
|
-
for (let i = 0; i < ss.length; ++i) {
|
|
109
|
-
if (!ss[i].includes(Command.Error)) continue;
|
|
110
|
-
ss[i] = ss[i].replace(CmdRegExp.Error, '');
|
|
111
|
-
attrs ??= {
|
|
112
|
-
class: 'invalid',
|
|
113
|
-
...invalid('ruby', ss === texts ? 'content' : 'argument', 'Invalid HTML entity'),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return attrs ?? {};
|
|
118
|
-
}
|
|
102
|
+
//function attributes(texts: string[], rubies: string[]): Record<string, string> {
|
|
103
|
+
// let attrs: Record<string, string> | undefined;
|
|
104
|
+
// for (const ss of [texts, rubies]) {
|
|
105
|
+
// for (let i = 0; i < ss.length; ++i) {
|
|
106
|
+
// if (!ss[i].includes(Command.Error)) continue;
|
|
107
|
+
// ss[i] = ss[i].replace(CmdRegExp.Error, '');
|
|
108
|
+
// attrs ??= {
|
|
109
|
+
// class: 'invalid',
|
|
110
|
+
// ...invalid('ruby', ss === texts ? 'content' : 'argument', 'Invalid HTML entity'),
|
|
111
|
+
// };
|
|
112
|
+
// }
|
|
113
|
+
// }
|
|
114
|
+
// return attrs ?? {};
|
|
115
|
+
//}
|
|
@@ -14,7 +14,7 @@ export const template: TemplateParser = lazy(() => surround(
|
|
|
14
14
|
([as, bs = [], cs], rest) =>
|
|
15
15
|
[[html('span', { class: 'template' }, defrag(push(unshift(as, bs), cs)))], rest],
|
|
16
16
|
undefined,
|
|
17
|
-
[3 | Backtrack.doublebracket,
|
|
17
|
+
[3 | Backtrack.doublebracket, 3 | Backtrack.escbracket]));
|
|
18
18
|
|
|
19
19
|
const bracket: TemplateParser.BracketParser = lazy(() => union([
|
|
20
20
|
surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'), true,
|
|
@@ -23,6 +23,15 @@ const bracket: TemplateParser.BracketParser = lazy(() => union([
|
|
|
23
23
|
undefined, () => [[], ''], [3 | Backtrack.escbracket]),
|
|
24
24
|
surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'), true,
|
|
25
25
|
undefined, () => [[], ''], [3 | Backtrack.escbracket]),
|
|
26
|
-
surround(
|
|
27
|
-
|
|
26
|
+
surround(
|
|
27
|
+
str('"'),
|
|
28
|
+
precedence(2, recursion(Recursion.terminal, some(escsource, '"', [['"', 2, false]]))),
|
|
29
|
+
str('"'),
|
|
30
|
+
true,
|
|
31
|
+
([as, bs = [], cs], rest, { linebreak = 0 }) =>
|
|
32
|
+
linebreak > rest.length
|
|
33
|
+
? [unshift(as, bs), cs[0] + rest]
|
|
34
|
+
: [push(unshift(as, bs), cs), rest],
|
|
35
|
+
([as, bs = []], rest) => [unshift(as, bs), rest],
|
|
36
|
+
[3 | Backtrack.escbracket]),
|
|
28
37
|
]));
|