securemark 0.285.0 → 0.285.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/index.js +45 -35
- package/markdown.d.ts +3 -2
- package/package.json +1 -1
- package/src/combinator/control/constraint/contract.ts +4 -4
- package/src/combinator/control/manipulation/convert.ts +3 -3
- package/src/combinator/control/manipulation/indent.ts +3 -3
- package/src/combinator/control/manipulation/scope.ts +3 -3
- package/src/combinator/control/manipulation/surround.ts +25 -13
- package/src/combinator/data/parser/context.ts +1 -1
- package/src/combinator/data/parser/some.ts +1 -0
- package/src/combinator/data/parser.ts +2 -1
- package/src/parser/api/parse.test.ts +14 -14
- package/src/parser/context.ts +10 -5
- package/src/parser/inline/annotation.ts +2 -2
- package/src/parser/inline/autolink/url.ts +14 -7
- package/src/parser/inline/extension/index.ts +12 -8
- package/src/parser/inline/link.ts +2 -2
- package/src/parser/inline/media.ts +10 -6
- package/src/parser/inline/reference.ts +2 -2
- package/src/parser/inline/template.ts +7 -8
- package/src/parser/inline.test.ts +3 -0
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.285.
|
|
1
|
+
/*! securemark v0.285.1 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"));
|
|
@@ -996,14 +996,14 @@ function indent(opener, parser, separation = false) {
|
|
|
996
996
|
source
|
|
997
997
|
}) => [[source], '']))), ([indent]) => indent.length * 2 + +(indent[0] === ' '), {})), separation), (lines, rest, context) => {
|
|
998
998
|
const {
|
|
999
|
-
|
|
999
|
+
backtracks
|
|
1000
1000
|
} = context;
|
|
1001
|
-
context.
|
|
1001
|
+
context.backtracks = {};
|
|
1002
1002
|
const result = parser({
|
|
1003
1003
|
source: trimBlockEnd(lines.join('')),
|
|
1004
1004
|
context
|
|
1005
1005
|
});
|
|
1006
|
-
context.
|
|
1006
|
+
context.backtracks = backtracks;
|
|
1007
1007
|
return result && (0, parser_1.exec)(result) === '' ? [(0, parser_1.eval)(result), rest] : undefined;
|
|
1008
1008
|
});
|
|
1009
1009
|
}
|
|
@@ -1993,13 +1993,13 @@ const combinator_1 = __webpack_require__(3484);
|
|
|
1993
1993
|
const link_1 = __webpack_require__(3628);
|
|
1994
1994
|
const source_1 = __webpack_require__(8745);
|
|
1995
1995
|
const closer = /^[-+*=~^_,.;:!?]*(?=[\\"`|\[\](){}<>]|$)/;
|
|
1996
|
-
exports.url = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['http://', 'https://'], (0, combinator_1.rewrite)((0, combinator_1.open)(/^https?:\/\/(?=[\x21-\x7E])/, (0, combinator_1.focus)(/^[\x21-\x7E]+/, (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([bracket, (0, combinator_1.some)(source_1.unescsource, closer)]))))), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.state)(1 /* State.autolink */, (0, combinator_1.convert)(url => `{ ${url} }`, link_1.unsafelink))), ({
|
|
1996
|
+
exports.url = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['http://', 'https://'], (0, combinator_1.rewrite)((0, combinator_1.open)(/^https?:\/\/(?=[\x21-\x7E])/, (0, combinator_1.focus)(/^[\x21-\x7E]+/, (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.verify)((0, combinator_1.union)([bracket, (0, combinator_1.some)(source_1.unescsource, closer)]), ns => ns[0] !== "\u001B" /* Command.Escape */))))), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.state)(1 /* State.autolink */, (0, combinator_1.convert)(url => `{ ${url} }`, link_1.unsafelink))), ({
|
|
1997
1997
|
source
|
|
1998
1998
|
}) => [[source], '']]))));
|
|
1999
1999
|
exports.lineurl = (0, combinator_1.lazy)(() => (0, combinator_1.open)(source_1.linebreak, (0, combinator_1.focus)(/^!?https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/, (0, combinator_1.tails)([(0, source_1.str)('!'), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.state)(1 /* State.autolink */, (0, combinator_1.convert)(url => `{ ${url} }`, link_1.unsafelink))), ({
|
|
2000
2000
|
source
|
|
2001
2001
|
}) => [[source], '']])]))));
|
|
2002
|
-
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')'), (0, source_1.str)(')'), true, undefined,
|
|
2002
|
+
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')'), (0, source_1.str)(')'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 4 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ']'), (0, source_1.str)(']'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 4 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), '}'), (0, source_1.str)('}'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 4 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.some)(source_1.unescsource, '"')), (0, source_1.str)('"'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 4 /* Backtrack.url */)])));
|
|
2003
2003
|
|
|
2004
2004
|
/***/ },
|
|
2005
2005
|
|
|
@@ -3267,7 +3267,7 @@ const optspec = {
|
|
|
3267
3267
|
rel: ['nofollow']
|
|
3268
3268
|
};
|
|
3269
3269
|
Object.setPrototypeOf(optspec, null);
|
|
3270
|
-
exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */, false, (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.precedence)(1, (0, combinator_1.state)(251 /* State.linkers */ | 4 /* State.media */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [['\n', 9], [']', 1]])), ']', true, undefined, undefined, 1 | 8 /* Backtrack.bracket */)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/, false, undefined, undefined, 3 |
|
|
3270
|
+
exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */, false, (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.precedence)(1, (0, combinator_1.state)(251 /* State.linkers */ | 4 /* State.media */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [['\n', 9], [']', 1]])), ']', true, undefined, undefined, 1 | 12 /* Backtrack.linebracket */, 8 /* Backtrack.bracket */ | 1 /* BacktrackState.nobreak */)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/, false, undefined, undefined, 3 | 24 /* Backtrack.link */))])), ([params, content = []], rest, context) => {
|
|
3271
3271
|
if (content.length !== 0 && (0, visibility_1.trimBlankNodeEnd)(content).length === 0) return;
|
|
3272
3272
|
return [[parse((0, dom_1.defrag)(content), params, context)], rest];
|
|
3273
3273
|
}))))));
|
|
@@ -4343,7 +4343,7 @@ const visibility_1 = __webpack_require__(6364);
|
|
|
4343
4343
|
const dom_1 = __webpack_require__(394);
|
|
4344
4344
|
exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(128 /* State.annotation */, false, (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('((', (0, combinator_1.precedence)(1, (0, combinator_1.state)(128 /* State.annotation */ | 4 /* State.media */, (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ')', [['\n', 9], [')', 1]])))), '))', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('sup', {
|
|
4345
4345
|
class: 'annotation'
|
|
4346
|
-
}, [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, undefined, 1 | 8 /* Backtrack.bracket */))));
|
|
4346
|
+
}, [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, undefined, 1 | 12 /* Backtrack.linebracket */, 8 /* Backtrack.bracket */ | 1 /* BacktrackState.nobreak */))));
|
|
4347
4347
|
|
|
4348
4348
|
/***/ },
|
|
4349
4349
|
|
|
@@ -5009,12 +5009,11 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
5009
5009
|
exports.template = void 0;
|
|
5010
5010
|
const combinator_1 = __webpack_require__(3484);
|
|
5011
5011
|
const source_1 = __webpack_require__(8745);
|
|
5012
|
-
const array_1 = __webpack_require__(6876);
|
|
5013
5012
|
const dom_1 = __webpack_require__(394);
|
|
5014
|
-
exports.template = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('{{', (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), '}')), '}}', true, ([, ns = []], rest) => [[(0, dom_1.html)('span', {
|
|
5013
|
+
exports.template = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('{{', (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.verify)((0, combinator_1.union)([bracket, source_1.escsource]), ns => ns[0] !== "\u001B" /* Command.Escape */), '}')), '}}', true, ([, ns = []], rest) => [[(0, dom_1.html)('span', {
|
|
5015
5014
|
class: 'template'
|
|
5016
|
-
}, `{{${ns.join('')}}}`)], rest], undefined, 3 |
|
|
5017
|
-
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), ')'), (0, source_1.str)(')'), true, undefined, (
|
|
5015
|
+
}, `{{${ns.join('')}}}`)], rest], undefined, 3 | 32 /* Backtrack.template */)));
|
|
5016
|
+
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), ')'), (0, source_1.str)(')'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 32 /* Backtrack.template */), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), ']'), (0, source_1.str)(']'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 32 /* Backtrack.template */), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.escsource]), '}'), (0, source_1.str)('}'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 32 /* Backtrack.template */), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.some)(source_1.escsource, /^["\n]/)), (0, source_1.str)('"'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 32 /* Backtrack.template */)])));
|
|
5018
5017
|
|
|
5019
5018
|
/***/ },
|
|
5020
5019
|
|
|
@@ -5143,16 +5142,16 @@ const visibility_1 = __webpack_require__(6364);
|
|
|
5143
5142
|
const dom_1 = __webpack_require__(394);
|
|
5144
5143
|
exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(32 /* State.index */, false, (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, indexee_1.indexee)((0, combinator_1.surround)('[#', (0, combinator_1.precedence)(1, (0, combinator_1.state)(251 /* State.linkers */ | 4 /* State.media */, (0, visibility_1.tightStart)((0, combinator_1.some)((0, combinator_1.inits)([inline_1.inline, exports.signature]), ']', [['\n', 9], [']', 1]])))), ']', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('a', {
|
|
5145
5144
|
'data-index': dataindex(ns)
|
|
5146
|
-
}, (0, dom_1.defrag)(ns))], rest] : undefined, undefined, 1 | 8 /* Backtrack.bracket */)), ([el]) => [(0, dom_1.define)(el, {
|
|
5145
|
+
}, (0, dom_1.defrag)(ns))], rest] : undefined, undefined, 1 | 12 /* Backtrack.linebracket */, 8 /* Backtrack.bracket */ | 1 /* BacktrackState.nobreak */)), ([el]) => [(0, dom_1.define)(el, {
|
|
5147
5146
|
id: el.id ? null : undefined,
|
|
5148
5147
|
class: 'index',
|
|
5149
5148
|
href: el.id ? `#${el.id}` : undefined
|
|
5150
5149
|
})]))));
|
|
5151
|
-
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, combinator_1.open)(/^\|(?!\\?\s)/, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']')), ns => [(0, dom_1.html)('span', {
|
|
5150
|
+
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, combinator_1.open)(/^\|(?!\\?\s)/, (0, combinator_1.some)((0, combinator_1.verify)((0, combinator_1.union)([bracket, source_1.txt]), ns => ns[0] !== "\u001B" /* Command.Escape */), ']')), ns => [(0, dom_1.html)('span', {
|
|
5152
5151
|
class: 'indexer',
|
|
5153
5152
|
'data-index': (0, indexee_1.identity)('index', undefined, ns.join('')).slice(7)
|
|
5154
5153
|
})]))));
|
|
5155
|
-
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true, undefined,
|
|
5154
|
+
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 28 /* Backtrack.index */), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']'), (0, source_1.str)(']'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 28 /* Backtrack.index */), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), '}'), (0, source_1.str)('}'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 28 /* Backtrack.index */), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.some)(source_1.txt, '"')), (0, source_1.str)('"'), true, undefined, () => [["\u001B" /* Command.Escape */], ''], 3 | 28 /* Backtrack.index */)])));
|
|
5156
5155
|
function dataindex(ns) {
|
|
5157
5156
|
if (ns.length === 0) return;
|
|
5158
5157
|
for (let i = ns.length - 1; i >= 0; --i) {
|
|
@@ -5751,7 +5750,7 @@ function context(base, parser) {
|
|
|
5751
5750
|
exports.context = context;
|
|
5752
5751
|
function apply(parser, source, context, changes, values, reset = false) {
|
|
5753
5752
|
if (reset) {
|
|
5754
|
-
context.
|
|
5753
|
+
context.backtracks = {};
|
|
5755
5754
|
}
|
|
5756
5755
|
for (let i = 0; i < changes.length; ++i) {
|
|
5757
5756
|
const change = changes[i];
|
|
@@ -5896,7 +5895,7 @@ exports.clear = exports.close = exports.open = exports.surround = void 0;
|
|
|
5896
5895
|
const parser_1 = __webpack_require__(605);
|
|
5897
5896
|
const fmap_1 = __webpack_require__(2705);
|
|
5898
5897
|
const array_1 = __webpack_require__(6876);
|
|
5899
|
-
function surround(opener, parser, closer, optional = false, f, g,
|
|
5898
|
+
function surround(opener, parser, closer, optional = false, f, g, backtrack = 0, bstate = 0) {
|
|
5900
5899
|
switch (typeof opener) {
|
|
5901
5900
|
case 'string':
|
|
5902
5901
|
case 'object':
|
|
@@ -5920,22 +5919,30 @@ function surround(opener, parser, closer, optional = false, f, g, log = 0) {
|
|
|
5920
5919
|
if (res1 === undefined) return;
|
|
5921
5920
|
const rl = (0, parser_1.eval)(res1);
|
|
5922
5921
|
const mr_ = (0, parser_1.exec)(res1);
|
|
5923
|
-
if (
|
|
5922
|
+
if (backtrack & 1) {
|
|
5924
5923
|
const {
|
|
5925
|
-
|
|
5924
|
+
backtracks = {},
|
|
5925
|
+
backtrack: state = 0,
|
|
5926
5926
|
offset = 0
|
|
5927
5927
|
} = context;
|
|
5928
5928
|
for (let i = 0; i < source.length - mr_.length; ++i) {
|
|
5929
5929
|
if (source[i] !== source[0]) break;
|
|
5930
5930
|
const pos = source.length + offset - i - 1;
|
|
5931
|
-
if (!(pos in
|
|
5932
|
-
|
|
5931
|
+
if (!(pos in backtracks)) continue;
|
|
5932
|
+
// bracket only
|
|
5933
|
+
const shift = backtrack >>> 2 === state >>> 2 ? state & 3 : 0;
|
|
5934
|
+
if (backtracks[pos] & 1 << (backtrack >>> 2) + shift) return;
|
|
5933
5935
|
}
|
|
5934
5936
|
}
|
|
5937
|
+
const {
|
|
5938
|
+
backtrack: state = 0
|
|
5939
|
+
} = context;
|
|
5940
|
+
context.backtrack = state | bstate;
|
|
5935
5941
|
const res2 = mr_ !== '' ? parser({
|
|
5936
5942
|
source: mr_,
|
|
5937
5943
|
context
|
|
5938
5944
|
}) : undefined;
|
|
5945
|
+
context.backtrack = state;
|
|
5939
5946
|
const rm = (0, parser_1.eval)(res2);
|
|
5940
5947
|
const r_ = (0, parser_1.exec)(res2, mr_);
|
|
5941
5948
|
if (!rm && !optional) return;
|
|
@@ -5946,12 +5953,15 @@ function surround(opener, parser, closer, optional = false, f, g, log = 0) {
|
|
|
5946
5953
|
const rr = (0, parser_1.eval)(res3);
|
|
5947
5954
|
const rest = (0, parser_1.exec)(res3, r_);
|
|
5948
5955
|
if (rest.length === lmr_.length) return;
|
|
5949
|
-
if (
|
|
5956
|
+
if (backtrack & 2 && rr === undefined) {
|
|
5950
5957
|
const {
|
|
5951
|
-
|
|
5958
|
+
backtracks = {},
|
|
5959
|
+
backtrack: state = 0,
|
|
5952
5960
|
offset = 0
|
|
5953
5961
|
} = context;
|
|
5954
|
-
|
|
5962
|
+
// bracket only
|
|
5963
|
+
const shift = backtrack >>> 2 === state >>> 2 ? state & 3 : 0;
|
|
5964
|
+
backtracks[source.length + offset - 1] |= 1 << (backtrack >>> 2) + shift;
|
|
5955
5965
|
}
|
|
5956
5966
|
return rr ? f ? f([rl, rm, rr], rest, context) : [(0, array_1.push)((0, array_1.unshift)(rl, rm ?? []), rr), rest] : g ? g([rl, rm, mr_], rest, context) : undefined;
|
|
5957
5967
|
};
|
|
@@ -6483,14 +6493,14 @@ function convert(conv, parser, empty = false) {
|
|
|
6483
6493
|
if (src === '') return empty ? [[], ''] : undefined;
|
|
6484
6494
|
const sub = source.endsWith(src);
|
|
6485
6495
|
const {
|
|
6486
|
-
|
|
6496
|
+
backtracks
|
|
6487
6497
|
} = context;
|
|
6488
|
-
context.
|
|
6498
|
+
context.backtracks = sub ? backtracks : {};
|
|
6489
6499
|
const result = parser({
|
|
6490
6500
|
source: src,
|
|
6491
6501
|
context
|
|
6492
6502
|
});
|
|
6493
|
-
context.
|
|
6503
|
+
context.backtracks = backtracks;
|
|
6494
6504
|
return result;
|
|
6495
6505
|
};
|
|
6496
6506
|
}
|
|
@@ -7091,14 +7101,14 @@ const source_1 = __webpack_require__(8745);
|
|
|
7091
7101
|
const visibility_1 = __webpack_require__(6364);
|
|
7092
7102
|
const array_1 = __webpack_require__(6876);
|
|
7093
7103
|
const dom_1 = __webpack_require__(394);
|
|
7094
|
-
exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, combinator_1.sequence)([(0, combinator_1.bind)((0, combinator_1.surround)('[', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']', false, undefined, undefined, 3 |
|
|
7104
|
+
exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, combinator_1.sequence)([(0, combinator_1.bind)((0, combinator_1.surround)('[', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']', false, undefined, undefined, 3 | 20 /* Backtrack.ruby */), ([source], rest, context) => {
|
|
7095
7105
|
const ns = (0, parser_1.eval)(text({
|
|
7096
7106
|
source,
|
|
7097
7107
|
context
|
|
7098
7108
|
}), [undefined])[0];
|
|
7099
7109
|
ns && ns.at(-1) === '' && ns.pop();
|
|
7100
7110
|
return ns && (0, visibility_1.isTightNodeStart)(ns) ? [[ns], rest] : undefined;
|
|
7101
|
-
}), (0, combinator_1.bind)((0, combinator_1.surround)('(', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')', false, undefined, undefined, 3 |
|
|
7111
|
+
}), (0, combinator_1.bind)((0, combinator_1.surround)('(', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')', false, undefined, undefined, 3 | 20 /* Backtrack.ruby */), ([source], rest, context) => {
|
|
7102
7112
|
const ns = (0, parser_1.eval)(text({
|
|
7103
7113
|
source,
|
|
7104
7114
|
context
|
|
@@ -7252,7 +7262,7 @@ const optspec = {
|
|
|
7252
7262
|
rel: undefined
|
|
7253
7263
|
};
|
|
7254
7264
|
Object.setPrototypeOf(optspec, null);
|
|
7255
|
-
exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* State.media */, false, (0, combinator_1.validate)(['![', '!{'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (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]), ']', [['\n', 9]])), ']', true, undefined, undefined, 1 |
|
|
7265
|
+
exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* State.media */, false, (0, combinator_1.validate)(['![', '!{'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (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.verify)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ns => ns[0] !== "\u001B" /* Command.Escape */), ']', [['\n', 9]])), ']', true, undefined, undefined, 1 | 16 /* Backtrack.media */)), (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 | 24 /* Backtrack.link */))]), ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
|
|
7256
7266
|
const INSECURE_URI = params.shift();
|
|
7257
7267
|
const url = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, context.host ?? location, context.url ?? context.host ?? location), context.host?.href || location.href);
|
|
7258
7268
|
let cache;
|
|
@@ -7279,7 +7289,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* S
|
|
|
7279
7289
|
});
|
|
7280
7290
|
}))))));
|
|
7281
7291
|
exports.linemedia = (0, combinator_1.surround)(source_1.linebreak, (0, combinator_1.union)([exports.media]), /^(?=[^\S\n]*(?:$|\n))/);
|
|
7282
|
-
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 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, (
|
|
7292
|
+
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 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, () => [["\u001B" /* Command.Escape */], ''], 3 | 16 /* Backtrack.media */), (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, () => [["\u001B" /* Command.Escape */], ''], 3 | 16 /* Backtrack.media */), (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, () => [["\u001B" /* Command.Escape */], ''], 3 | 16 /* Backtrack.media */), (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, () => [["\u001B" /* Command.Escape */], ''], 3 | 16 /* Backtrack.media */)])));
|
|
7283
7293
|
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]));
|
|
7284
7294
|
function sanitize(target, uri, alt) {
|
|
7285
7295
|
switch (uri.protocol) {
|
|
@@ -7745,14 +7755,14 @@ function rewrite(scope, parser) {
|
|
|
7745
7755
|
} = input;
|
|
7746
7756
|
if (source === '') return;
|
|
7747
7757
|
const {
|
|
7748
|
-
|
|
7758
|
+
backtracks
|
|
7749
7759
|
} = context;
|
|
7750
|
-
context.
|
|
7760
|
+
context.backtracks = {};
|
|
7751
7761
|
//const { resources = { clock: 0 } } = context;
|
|
7752
7762
|
//const clock = resources.clock;
|
|
7753
7763
|
const res1 = scope(input);
|
|
7754
7764
|
//resources.clock = clock;
|
|
7755
|
-
context.
|
|
7765
|
+
context.backtracks = backtracks;
|
|
7756
7766
|
if (res1 === undefined || (0, parser_1.exec)(res1).length >= source.length) return;
|
|
7757
7767
|
const src = source.slice(0, source.length - (0, parser_1.exec)(res1).length);
|
|
7758
7768
|
const offset = source.length - src.length;
|
|
@@ -8841,7 +8851,7 @@ const inline_1 = __webpack_require__(7973);
|
|
|
8841
8851
|
const source_1 = __webpack_require__(8745);
|
|
8842
8852
|
const visibility_1 = __webpack_require__(6364);
|
|
8843
8853
|
const dom_1 = __webpack_require__(394);
|
|
8844
|
-
exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(64 /* State.reference */, false, (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('[[', (0, combinator_1.precedence)(1, (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 4 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [['\n', 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, undefined, 1 | 8 /* Backtrack.bracket */))));
|
|
8854
|
+
exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(64 /* State.reference */, false, (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('[[', (0, combinator_1.precedence)(1, (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 4 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [['\n', 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, undefined, 1 | 12 /* Backtrack.linebracket */, 8 /* Backtrack.bracket */ | 1 /* BacktrackState.nobreak */))));
|
|
8845
8855
|
// Chicago-Style
|
|
8846
8856
|
const abbr = (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('^', (0, combinator_1.union)([(0, source_1.str)(/^(?=[A-Z])(?:[0-9A-Za-z]'?|(?:[-.:]|\.?\??,? ?)(?!['\-.:?, ]))+/)]), /^\|?(?=]])|^\|[^\S\n]*/, true, ([, ns], rest) => ns ? [['\n', ns[0].trimEnd()], rest.replace(visibility_1.blank.start, '')] : [[''], `^${rest}`], ([,, rest]) => [[''], `^${rest}`]));
|
|
8847
8857
|
function attributes(ns) {
|
package/markdown.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Parser, Ctx } from './src/combinator/data/parser';
|
|
2
|
+
import { Command } from './src/parser/context';
|
|
2
3
|
import { Dict } from 'spica/dict';
|
|
3
4
|
|
|
4
5
|
declare abstract class Markdown<T> {
|
|
@@ -1196,8 +1197,8 @@ export namespace MarkdownParser {
|
|
|
1196
1197
|
}
|
|
1197
1198
|
export interface BracketParser extends
|
|
1198
1199
|
Inline<'url/bracket'>,
|
|
1199
|
-
Parser<string, Context, [
|
|
1200
|
-
Parser<string, Context, [
|
|
1200
|
+
Parser<string | Command.Escape, Context, [
|
|
1201
|
+
Parser<string | Command.Escape, Context, [
|
|
1201
1202
|
BracketParser,
|
|
1202
1203
|
SourceParser.UnescapableSourceParser,
|
|
1203
1204
|
]>,
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isArray } from 'spica/alias';
|
|
2
2
|
import { Parser, Input, Ctx, Tree, Context, eval, exec, check } from '../../data/parser';
|
|
3
3
|
|
|
4
|
-
//export function contract<P extends Parser<unknown>>(patterns: string | RegExp | (string | RegExp)[], parser: P, cond: (
|
|
5
|
-
//export function contract<T>(patterns: string | RegExp | (string | RegExp)[], parser: Parser<T>, cond: (
|
|
4
|
+
//export function contract<P extends Parser<unknown>>(patterns: string | RegExp | (string | RegExp)[], parser: P, cond: (nodes: readonly Data<P>[], rest: string) => boolean): P;
|
|
5
|
+
//export function contract<T>(patterns: string | RegExp | (string | RegExp)[], parser: Parser<T>, cond: (nodes: readonly T[], rest: string) => boolean): Parser<T> {
|
|
6
6
|
// return verify(validate(patterns, parser), cond);
|
|
7
7
|
//}
|
|
8
8
|
|
|
@@ -45,8 +45,8 @@ function guard<T>(f: (input: Input<Ctx>) => boolean, parser: Parser<T>): Parser<
|
|
|
45
45
|
: undefined;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export function verify<P extends Parser<unknown>>(parser: P, cond: (
|
|
49
|
-
export function verify<T>(parser: Parser<T>, cond: (
|
|
48
|
+
export function verify<P extends Parser<unknown>>(parser: P, cond: (nodes: readonly Tree<P>[], rest: string, context: Context<P>) => boolean): P;
|
|
49
|
+
export function verify<T>(parser: Parser<T>, cond: (nodes: readonly T[], rest: string, context: Ctx) => boolean): Parser<T> {
|
|
50
50
|
assert(parser);
|
|
51
51
|
return input => {
|
|
52
52
|
const { source, context } = input;
|
|
@@ -8,11 +8,11 @@ export function convert<T>(conv: (source: string, context: Ctx) => string, parse
|
|
|
8
8
|
const src = conv(source, context);
|
|
9
9
|
if (src === '') return empty ? [[], ''] : undefined;
|
|
10
10
|
const sub = source.endsWith(src);
|
|
11
|
-
const {
|
|
12
|
-
context.
|
|
11
|
+
const { backtracks } = context;
|
|
12
|
+
context.backtracks = sub ? backtracks : {};
|
|
13
13
|
const result = parser({ source: src, context });
|
|
14
14
|
assert(check(src, result));
|
|
15
|
-
context.
|
|
15
|
+
context.backtracks = backtracks;
|
|
16
16
|
return result;
|
|
17
17
|
};
|
|
18
18
|
}
|
|
@@ -20,10 +20,10 @@ export function indent<T>(opener: RegExp | Parser<T>, parser?: Parser<T> | boole
|
|
|
20
20
|
([indent]) => indent.length * 2 + +(indent[0] === ' '), {})), separation),
|
|
21
21
|
(lines, rest, context) => {
|
|
22
22
|
assert(parser = parser as Parser<T>);
|
|
23
|
-
const {
|
|
24
|
-
context.
|
|
23
|
+
const { backtracks } = context;
|
|
24
|
+
context.backtracks = {};
|
|
25
25
|
const result = parser({ source: trimBlockEnd(lines.join('')), context });
|
|
26
|
-
context.
|
|
26
|
+
context.backtracks = backtracks;
|
|
27
27
|
return result && exec(result) === ''
|
|
28
28
|
? [eval(result), rest]
|
|
29
29
|
: undefined;
|
|
@@ -35,14 +35,14 @@ export function rewrite<T>(scope: Parser<unknown>, parser: Parser<T>): Parser<T>
|
|
|
35
35
|
return input => {
|
|
36
36
|
const { source, context } = input;
|
|
37
37
|
if (source === '') return;
|
|
38
|
-
const {
|
|
39
|
-
context.
|
|
38
|
+
const { backtracks } = context;
|
|
39
|
+
context.backtracks = {};
|
|
40
40
|
//const { resources = { clock: 0 } } = context;
|
|
41
41
|
//const clock = resources.clock;
|
|
42
42
|
const res1 = scope(input);
|
|
43
43
|
assert(check(source, res1));
|
|
44
44
|
//resources.clock = clock;
|
|
45
|
-
context.
|
|
45
|
+
context.backtracks = backtracks;
|
|
46
46
|
if (res1 === undefined || exec(res1).length >= source.length) return;
|
|
47
47
|
const src = source.slice(0, source.length - exec(res1).length);
|
|
48
48
|
assert(src !== '');
|
|
@@ -7,35 +7,40 @@ export function surround<P extends Parser<unknown>, S = string>(
|
|
|
7
7
|
optional?: false,
|
|
8
8
|
f?: (rss: [S[], SubTree<P>[], S[]], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
9
9
|
g?: (rss: [S[], SubTree<P>[], string], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
10
|
-
|
|
10
|
+
backtrack?: number,
|
|
11
|
+
bstate?: number,
|
|
11
12
|
): P;
|
|
12
13
|
export function surround<P extends Parser<unknown>, S = string>(
|
|
13
14
|
opener: string | RegExp | Parser<S, Context<P>>, parser: IntermediateParser<P>, closer: string | RegExp | Parser<S, Context<P>>,
|
|
14
15
|
optional?: boolean,
|
|
15
16
|
f?: (rss: [S[], SubTree<P>[] | undefined, S[]], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
16
17
|
g?: (rss: [S[], SubTree<P>[] | undefined, string], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
17
|
-
|
|
18
|
+
backtrack?: number,
|
|
19
|
+
bstate?: number,
|
|
18
20
|
): P;
|
|
19
21
|
export function surround<P extends Parser<unknown>, S = string>(
|
|
20
22
|
opener: string | RegExp | Parser<S, Context<P>>, parser: P, closer: string | RegExp | Parser<S, Context<P>>,
|
|
21
23
|
optional?: false,
|
|
22
24
|
f?: (rss: [S[], Tree<P>[], S[]], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
23
25
|
g?: (rss: [S[], Tree<P>[], string], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
24
|
-
|
|
26
|
+
backtrack?: number,
|
|
27
|
+
bstate?: number,
|
|
25
28
|
): P;
|
|
26
29
|
export function surround<P extends Parser<unknown>, S = string>(
|
|
27
30
|
opener: string | RegExp | Parser<S, Context<P>>, parser: P, closer: string | RegExp | Parser<S, Context<P>>,
|
|
28
31
|
optional?: boolean,
|
|
29
32
|
f?: (rss: [S[], Tree<P>[] | undefined, S[]], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
30
33
|
g?: (rss: [S[], Tree<P>[] | undefined, string], rest: string, context: Context<P>) => Result<Tree<P>, Context<P>, SubParsers<P>>,
|
|
31
|
-
|
|
34
|
+
backtrack?: number,
|
|
35
|
+
bstate?: number,
|
|
32
36
|
): P;
|
|
33
37
|
export function surround<T>(
|
|
34
38
|
opener: string | RegExp | Parser<T>, parser: Parser<T>, closer: string | RegExp | Parser<T>,
|
|
35
39
|
optional: boolean = false,
|
|
36
40
|
f?: (rss: [T[], T[], T[]], rest: string, context: Ctx) => Result<T>,
|
|
37
41
|
g?: (rss: [T[], T[], string], rest: string, context: Ctx) => Result<T>,
|
|
38
|
-
|
|
42
|
+
backtrack: number = 0,
|
|
43
|
+
bstate: number = 0,
|
|
39
44
|
): Parser<T> {
|
|
40
45
|
switch (typeof opener) {
|
|
41
46
|
case 'string':
|
|
@@ -55,18 +60,23 @@ export function surround<T>(
|
|
|
55
60
|
if (res1 === undefined) return;
|
|
56
61
|
const rl = eval(res1);
|
|
57
62
|
const mr_ = exec(res1);
|
|
58
|
-
if (
|
|
59
|
-
const {
|
|
63
|
+
if (backtrack & 1) {
|
|
64
|
+
const { backtracks = {}, backtrack: state = 0, offset = 0 } = context;
|
|
60
65
|
for (let i = 0; i < source.length - mr_.length; ++i) {
|
|
61
66
|
if (source[i] !== source[0]) break;
|
|
62
67
|
const pos = source.length + offset - i - 1;
|
|
63
|
-
if (!(pos in
|
|
64
|
-
assert(
|
|
65
|
-
|
|
68
|
+
if (!(pos in backtracks)) continue;
|
|
69
|
+
assert(backtrack >>> 2);
|
|
70
|
+
// bracket only
|
|
71
|
+
const shift = backtrack >>> 2 === state >>> 2 ? state & 3 : 0;
|
|
72
|
+
if (backtracks[pos] & 1 << (backtrack >>> 2) + shift) return;
|
|
66
73
|
}
|
|
67
74
|
}
|
|
75
|
+
const { backtrack: state = 0 } = context;
|
|
76
|
+
context.backtrack = state | bstate;
|
|
68
77
|
const res2 = mr_ !== '' ? parser({ source: mr_, context }) : undefined;
|
|
69
78
|
assert(check(mr_, res2));
|
|
79
|
+
context.backtrack = state;
|
|
70
80
|
const rm = eval(res2);
|
|
71
81
|
const r_ = exec(res2, mr_);
|
|
72
82
|
if (!rm && !optional) return;
|
|
@@ -75,9 +85,11 @@ export function surround<T>(
|
|
|
75
85
|
const rr = eval(res3);
|
|
76
86
|
const rest = exec(res3, r_);
|
|
77
87
|
if (rest.length === lmr_.length) return;
|
|
78
|
-
if (
|
|
79
|
-
const {
|
|
80
|
-
|
|
88
|
+
if (backtrack & 2 && rr === undefined) {
|
|
89
|
+
const { backtracks = {}, backtrack: state = 0, offset = 0 } = context;
|
|
90
|
+
// bracket only
|
|
91
|
+
const shift = backtrack >>> 2 === state >>> 2 ? state & 3 : 0;
|
|
92
|
+
backtracks[source.length + offset - 1] |= 1 << (backtrack >>> 2) + shift;
|
|
81
93
|
}
|
|
82
94
|
return rr
|
|
83
95
|
? f
|
|
@@ -25,7 +25,7 @@ export function context<T>(base: Ctx, parser: Parser<T>): Parser<T> {
|
|
|
25
25
|
function apply<P extends Parser<unknown>>(parser: P, source: string, context: Context<P>, changes: readonly [string, unknown][], values: unknown[], reset?: boolean): Result<Tree<P>>;
|
|
26
26
|
function apply<T>(parser: Parser<T>, source: string, context: Ctx, changes: readonly [string, unknown][], values: unknown[], reset = false): Result<T> {
|
|
27
27
|
if (reset) {
|
|
28
|
-
context.
|
|
28
|
+
context.backtracks = {};
|
|
29
29
|
}
|
|
30
30
|
for (let i = 0; i < changes.length; ++i) {
|
|
31
31
|
const change = changes[i];
|
|
@@ -18,6 +18,7 @@ export function some<T>(parser: Parser<T>, end?: string | RegExp | number, delim
|
|
|
18
18
|
}));
|
|
19
19
|
return ({ source, context }) => {
|
|
20
20
|
if (source === '') return;
|
|
21
|
+
assert(context.backtracks ??= {});
|
|
21
22
|
let rest = source;
|
|
22
23
|
let nodes: T[] | undefined;
|
|
23
24
|
if (delims.length > 0) {
|
|
@@ -19,7 +19,8 @@ export interface Ctx {
|
|
|
19
19
|
precedence?: number;
|
|
20
20
|
delimiters?: Delimiters;
|
|
21
21
|
state?: number;
|
|
22
|
-
|
|
22
|
+
backtracks?: Record<number, number>;
|
|
23
|
+
backtrack?: number;
|
|
23
24
|
}
|
|
24
25
|
export type Tree<P extends Parser<unknown>> = P extends Parser<infer T> ? T : never;
|
|
25
26
|
export type SubParsers<P extends Parser<unknown>> = P extends Parser<unknown, Ctx, infer D> ? D : never;
|
|
@@ -297,26 +297,26 @@ describe('Unit: parser/api/parse', () => {
|
|
|
297
297
|
`<pre class="error" translate="no">${'{'.repeat(21)}a</pre>`,
|
|
298
298
|
]);
|
|
299
299
|
assert.deepStrictEqual(
|
|
300
|
-
[...parse(`${'('.repeat(
|
|
301
|
-
[`<p>${'('.repeat(
|
|
300
|
+
[...parse(`${'('.repeat(20)}a`).children].map(el => el.outerHTML),
|
|
301
|
+
[`<p>${'('.repeat(20)}a</p>`]);
|
|
302
302
|
assert.deepStrictEqual(
|
|
303
|
-
[...parse(`${'('.repeat(
|
|
303
|
+
[...parse(`${'('.repeat(21)}a`).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
304
304
|
[
|
|
305
305
|
'<h1 id="error:rnd" class="error">Error: Too much recursion</h1>',
|
|
306
|
-
`<pre class="error" translate="no">${'('.repeat(
|
|
306
|
+
`<pre class="error" translate="no">${'('.repeat(21)}a</pre>`,
|
|
307
307
|
]);
|
|
308
308
|
assert.deepStrictEqual(
|
|
309
|
-
[...parse(`${'['.repeat(
|
|
310
|
-
[`<p>${'['.repeat(
|
|
309
|
+
[...parse(`${'['.repeat(20)}a`).children].map(el => el.outerHTML),
|
|
310
|
+
[`<p>${'['.repeat(20)}a</p>`]);
|
|
311
311
|
assert.deepStrictEqual(
|
|
312
|
-
[...parse(`${'['.repeat(
|
|
312
|
+
[...parse(`${'['.repeat(21)}a`).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
313
313
|
[
|
|
314
314
|
'<h1 id="error:rnd" class="error">Error: Too much recursion</h1>',
|
|
315
|
-
`<pre class="error" translate="no">${'['.repeat(
|
|
315
|
+
`<pre class="error" translate="no">${'['.repeat(21)}a</pre>`,
|
|
316
316
|
]);
|
|
317
317
|
assert.deepStrictEqual(
|
|
318
|
-
[...parse(`${'['.repeat(
|
|
319
|
-
[`<p>${'['.repeat(
|
|
318
|
+
[...parse(`${'['.repeat(20)}\na`).children].map(el => el.outerHTML),
|
|
319
|
+
[`<p>${'['.repeat(20)}<br>a</p>`]);
|
|
320
320
|
});
|
|
321
321
|
|
|
322
322
|
it('recovery', () => {
|
|
@@ -351,17 +351,17 @@ describe('Unit: parser/api/parse', () => {
|
|
|
351
351
|
it('backtrack', function () {
|
|
352
352
|
this.timeout(5000);
|
|
353
353
|
assert.deepStrictEqual(
|
|
354
|
-
[...parse(`(({{${'['.repeat(
|
|
355
|
-
[`<p>(({{${'['.repeat(
|
|
354
|
+
[...parse(`(({{${'['.repeat(15)}http://[${'.'.repeat(1802)}`).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
355
|
+
[`<p>(({{${'['.repeat(15)}http://[${'.'.repeat(1802)}</p>`]);
|
|
356
356
|
});
|
|
357
357
|
|
|
358
358
|
it('backtrack error', function () {
|
|
359
359
|
this.timeout(5000);
|
|
360
360
|
assert.deepStrictEqual(
|
|
361
|
-
[...parse(`(({{${'['.repeat(
|
|
361
|
+
[...parse(`(({{${'['.repeat(15)}http://[${'.'.repeat(1803)}`).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
362
362
|
[
|
|
363
363
|
'<h1 id="error:rnd" class="error">Error: Too many creations</h1>',
|
|
364
|
-
`<pre class="error" translate="no">(({{${'['.repeat(
|
|
364
|
+
`<pre class="error" translate="no">(({{${'['.repeat(15)}http://[${'.'.repeat(1000 - 4 - 15 - 8 - 3)}...</pre>`,
|
|
365
365
|
]);
|
|
366
366
|
});
|
|
367
367
|
|
package/src/parser/context.ts
CHANGED
|
@@ -29,14 +29,19 @@ export const enum Recursion {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export const enum Backtrack {
|
|
32
|
-
template =
|
|
33
|
-
index =
|
|
34
|
-
link =
|
|
35
|
-
ruby =
|
|
36
|
-
media =
|
|
32
|
+
template = 8 << 2,
|
|
33
|
+
index = 7 << 2,
|
|
34
|
+
link = 6 << 2,
|
|
35
|
+
ruby = 5 << 2,
|
|
36
|
+
media = 4 << 2,
|
|
37
|
+
linebracket = 3 << 2,
|
|
37
38
|
bracket = 2 << 2,
|
|
38
39
|
url = 1 << 2,
|
|
39
40
|
}
|
|
41
|
+
export const enum BacktrackState {
|
|
42
|
+
nobreak = 1,
|
|
43
|
+
}
|
|
44
|
+
assert(Backtrack.linebracket === Backtrack.bracket + (BacktrackState.nobreak << 2));
|
|
40
45
|
|
|
41
46
|
export const enum Command {
|
|
42
47
|
Error = '\x07',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AnnotationParser } from '../inline';
|
|
2
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
2
|
+
import { State, Recursion, Backtrack, BacktrackState } from '../context';
|
|
3
3
|
import { union, some, creation, precedence, state, constraint, surround, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
|
|
@@ -15,4 +15,4 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
|
|
|
15
15
|
trimBlankNodeEnd(ns).length > 0
|
|
16
16
|
? [[html('sup', { class: 'annotation' }, [html('span', defrag(ns))])], rest]
|
|
17
17
|
: undefined,
|
|
18
|
-
undefined, 1 | Backtrack.bracket))));
|
|
18
|
+
undefined, 1 | Backtrack.linebracket, Backtrack.bracket | BacktrackState.nobreak))));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
|
-
import { State, Recursion, Backtrack } from '../../context';
|
|
3
|
-
import { union, tails, some, creation, precedence, state, constraint, validate, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
|
|
2
|
+
import { State, Recursion, Backtrack, Command } from '../../context';
|
|
3
|
+
import { union, tails, some, creation, precedence, state, constraint, validate, verify, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
|
|
4
4
|
import { unsafelink } from '../link';
|
|
5
5
|
import { linebreak, unescsource, str } from '../../source';
|
|
6
6
|
|
|
@@ -9,7 +9,10 @@ const closer = /^[-+*=~^_,.;:!?]*(?=[\\"`|\[\](){}<>]|$)/;
|
|
|
9
9
|
export const url: AutolinkParser.UrlParser = lazy(() => validate(['http://', 'https://'], rewrite(
|
|
10
10
|
open(
|
|
11
11
|
/^https?:\/\/(?=[\x21-\x7E])/,
|
|
12
|
-
focus(/^[\x21-\x7E]+/, precedence(1, some(union([
|
|
12
|
+
focus(/^[\x21-\x7E]+/, precedence(1, some(verify(union([
|
|
13
|
+
bracket,
|
|
14
|
+
some(unescsource, closer),
|
|
15
|
+
]), ns => ns[0] !== Command.Escape))))),
|
|
13
16
|
union([
|
|
14
17
|
constraint(State.autolink, false, state(State.autolink, convert(
|
|
15
18
|
url => `{ ${url} }`,
|
|
@@ -32,8 +35,12 @@ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => open(
|
|
|
32
35
|
]))));
|
|
33
36
|
|
|
34
37
|
const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
|
35
|
-
surround(str('('), some(union([bracket, unescsource]), ')'), str(')'), true,
|
|
36
|
-
|
|
37
|
-
surround(str('
|
|
38
|
-
|
|
38
|
+
surround(str('('), some(union([bracket, unescsource]), ')'), str(')'), true,
|
|
39
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.url),
|
|
40
|
+
surround(str('['), some(union([bracket, unescsource]), ']'), str(']'), true,
|
|
41
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.url),
|
|
42
|
+
surround(str('{'), some(union([bracket, unescsource]), '}'), str('}'), true,
|
|
43
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.url),
|
|
44
|
+
surround(str('"'), precedence(2, some(unescsource, '"')), str('"'), true,
|
|
45
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.url),
|
|
39
46
|
])));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
-
import { State, Recursion, Backtrack } from '../../context';
|
|
3
|
-
import { union, inits, some, creation, precedence, state, constraint, validate, surround, open, lazy, fmap } from '../../../combinator';
|
|
2
|
+
import { State, Recursion, Backtrack, BacktrackState, Command } from '../../context';
|
|
3
|
+
import { union, inits, some, creation, precedence, state, constraint, validate, verify, surround, open, lazy, fmap } from '../../../combinator';
|
|
4
4
|
import { inline } from '../../inline';
|
|
5
5
|
import { indexee, identity } from './indexee';
|
|
6
6
|
import { txt, str } from '../../source';
|
|
@@ -23,7 +23,7 @@ export const index: IndexParser = lazy(() => constraint(State.index, false, crea
|
|
|
23
23
|
trimBlankNodeEnd(ns).length > 0
|
|
24
24
|
? [[html('a', { 'data-index': dataindex(ns) }, defrag(ns))], rest]
|
|
25
25
|
: undefined,
|
|
26
|
-
undefined, 1 | Backtrack.bracket)),
|
|
26
|
+
undefined, 1 | Backtrack.linebracket, Backtrack.bracket | BacktrackState.nobreak)),
|
|
27
27
|
([el]: [HTMLAnchorElement]) => [
|
|
28
28
|
define(el,
|
|
29
29
|
{
|
|
@@ -35,16 +35,20 @@ export const index: IndexParser = lazy(() => constraint(State.index, false, crea
|
|
|
35
35
|
|
|
36
36
|
export const signature: IndexParser.SignatureParser = lazy(() => validate('|', creation(1, Recursion.ignore, fmap(open(
|
|
37
37
|
/^\|(?!\\?\s)/,
|
|
38
|
-
some(union([bracket, txt]), ']')),
|
|
38
|
+
some(verify(union([bracket, txt]), ns => ns[0] !== Command.Escape), ']')),
|
|
39
39
|
ns => [
|
|
40
40
|
html('span', { class: 'indexer', 'data-index': identity('index', undefined, ns.join(''))!.slice(7) }),
|
|
41
41
|
]))));
|
|
42
42
|
|
|
43
43
|
const bracket: IndexParser.SignatureParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
|
44
|
-
surround(str('('), some(union([bracket, txt]), ')'), str(')'), true,
|
|
45
|
-
|
|
46
|
-
surround(str('
|
|
47
|
-
|
|
44
|
+
surround(str('('), some(union([bracket, txt]), ')'), str(')'), true,
|
|
45
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
46
|
+
surround(str('['), some(union([bracket, txt]), ']'), str(']'), true,
|
|
47
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
48
|
+
surround(str('{'), some(union([bracket, txt]), '}'), str('}'), true,
|
|
49
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
50
|
+
surround(str('"'), precedence(2, some(txt, '"')), str('"'), true,
|
|
51
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
48
52
|
])));
|
|
49
53
|
|
|
50
54
|
export function dataindex(ns: readonly (string | HTMLElement)[]): string | undefined {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../../markdown';
|
|
2
2
|
import { LinkParser } from '../inline';
|
|
3
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
3
|
+
import { State, Recursion, Backtrack, BacktrackState } from '../context';
|
|
4
4
|
import { union, inits, tails, sequence, some, creation, precedence, state, constraint, validate, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
|
|
5
5
|
import { inline, media, shortmedia } from '../inline';
|
|
6
6
|
import { attributes } from './html';
|
|
@@ -22,7 +22,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
22
22
|
'[',
|
|
23
23
|
trimBlankStart(some(union([inline]), ']', [['\n', 9], [']', 1]])),
|
|
24
24
|
']',
|
|
25
|
-
true, undefined, undefined, 1 | Backtrack.bracket)),
|
|
25
|
+
true, undefined, undefined, 1 | Backtrack.linebracket, Backtrack.bracket | BacktrackState.nobreak)),
|
|
26
26
|
dup(surround(
|
|
27
27
|
/^{(?![{}])/,
|
|
28
28
|
inits([uri, some(option)]),
|
|
@@ -7,7 +7,7 @@ import { unsafehtmlentity } from './htmlentity';
|
|
|
7
7
|
import { txt, linebreak, str } from '../source';
|
|
8
8
|
import { markInvalid } from '../util';
|
|
9
9
|
import { ReadonlyURL } from 'spica/url';
|
|
10
|
-
import {
|
|
10
|
+
import { push } from 'spica/array';
|
|
11
11
|
import { html, define } from 'typed-dom/dom';
|
|
12
12
|
|
|
13
13
|
const optspec = {
|
|
@@ -23,7 +23,11 @@ export const media: MediaParser = lazy(() => constraint(State.media, false, vali
|
|
|
23
23
|
bind(verify(fmap(tails([
|
|
24
24
|
dup(surround(
|
|
25
25
|
'[',
|
|
26
|
-
precedence(1, some(union([
|
|
26
|
+
precedence(1, some(verify(union([
|
|
27
|
+
unsafehtmlentity,
|
|
28
|
+
bracket,
|
|
29
|
+
txt,
|
|
30
|
+
]), ns => ns[0] !== Command.Escape), ']', [['\n', 9]])),
|
|
27
31
|
']',
|
|
28
32
|
true, undefined, undefined, 1 | Backtrack.media)),
|
|
29
33
|
dup(surround(
|
|
@@ -71,13 +75,13 @@ export const linemedia: MediaParser.LineMediaParser = surround(
|
|
|
71
75
|
|
|
72
76
|
const bracket: MediaParser.TextParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
|
73
77
|
surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true,
|
|
74
|
-
undefined, (
|
|
78
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
75
79
|
surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true,
|
|
76
|
-
undefined, (
|
|
80
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
77
81
|
surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'), true,
|
|
78
|
-
undefined, (
|
|
82
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
79
83
|
surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'), true,
|
|
80
|
-
undefined,
|
|
84
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
81
85
|
])));
|
|
82
86
|
|
|
83
87
|
const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReferenceParser } from '../inline';
|
|
2
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
2
|
+
import { State, Recursion, Backtrack, BacktrackState } from '../context';
|
|
3
3
|
import { union, subsequence, some, creation, precedence, state, constraint, surround, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
@@ -19,7 +19,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
19
19
|
trimBlankNodeEnd(ns).length > 0
|
|
20
20
|
? [[html('sup', attributes(ns), [html('span', defrag(ns))])], rest]
|
|
21
21
|
: undefined,
|
|
22
|
-
undefined, 1 | Backtrack.bracket))));
|
|
22
|
+
undefined, 1 | Backtrack.linebracket, Backtrack.bracket | BacktrackState.nobreak))));
|
|
23
23
|
|
|
24
24
|
// Chicago-Style
|
|
25
25
|
const abbr: ReferenceParser.AbbrParser = creation(1, Recursion.ignore, surround(
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { TemplateParser } from '../inline';
|
|
2
|
-
import { Recursion, Backtrack } from '../context';
|
|
3
|
-
import { union, some, creation, precedence, surround, lazy } from '../../combinator';
|
|
2
|
+
import { Recursion, Backtrack, Command } from '../context';
|
|
3
|
+
import { union, some, creation, precedence, verify, surround, lazy } from '../../combinator';
|
|
4
4
|
import { escsource, str } from '../source';
|
|
5
|
-
import { unshift } from 'spica/array';
|
|
6
5
|
import { html } from 'typed-dom/dom';
|
|
7
6
|
|
|
8
7
|
export const template: TemplateParser = lazy(() => creation(1, Recursion.ignore, surround(
|
|
9
8
|
'{{',
|
|
10
|
-
precedence(1, some(union([bracket, escsource]), '}')),
|
|
9
|
+
precedence(1, some(verify(union([bracket, escsource]), ns => ns[0] !== Command.Escape), '}')),
|
|
11
10
|
'}}',
|
|
12
11
|
true,
|
|
13
12
|
([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('')}}}`)], rest],
|
|
@@ -15,11 +14,11 @@ export const template: TemplateParser = lazy(() => creation(1, Recursion.ignore,
|
|
|
15
14
|
|
|
16
15
|
const bracket: TemplateParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
|
17
16
|
surround(str('('), some(union([bracket, escsource]), ')'), str(')'), true,
|
|
18
|
-
undefined, (
|
|
17
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
19
18
|
surround(str('['), some(union([bracket, escsource]), ']'), str(']'), true,
|
|
20
|
-
undefined, (
|
|
19
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
21
20
|
surround(str('{'), some(union([bracket, escsource]), '}'), str('}'), true,
|
|
22
|
-
undefined, (
|
|
21
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
23
22
|
surround(str('"'), precedence(2, some(escsource, /^["\n]/)), str('"'), true,
|
|
24
|
-
undefined,
|
|
23
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
25
24
|
])));
|
|
@@ -126,6 +126,7 @@ describe('Unit: parser/inline', () => {
|
|
|
126
126
|
assert.deepStrictEqual(inspect(parser('((((a))))')), [['<sup class="annotation"><span><span class="paren">((a))</span></span></sup>'], '']);
|
|
127
127
|
assert.deepStrictEqual(inspect(parser('((${))}$')), [['(', '(', '<span class="math" translate="no" data-src="${))}$">${))}$</span>'], '']);
|
|
128
128
|
assert.deepStrictEqual(inspect(parser('((a\nb))')), [['<span class="paren">(<span class="paren">(a<br>b)</span>)</span>'], '']);
|
|
129
|
+
assert.deepStrictEqual(inspect(parser('(((a\nb)))')), [['<span class="paren">(<span class="paren">(<span class="paren">(a<br>b)</span>)</span>)</span>'], '']);
|
|
129
130
|
assert.deepStrictEqual(inspect(parser('"((""))')), [['"', '(', '(', '"', '"', ')', ')'], '']);
|
|
130
131
|
assert.deepStrictEqual(inspect(parser('[[[a]]')), [['[', '<sup class="reference"><span>a</span></sup>'], '']);
|
|
131
132
|
assert.deepStrictEqual(inspect(parser('[[[[a]]')), [['[', '[', '<sup class="reference"><span>a</span></sup>'], '']);
|
|
@@ -135,6 +136,8 @@ describe('Unit: parser/inline', () => {
|
|
|
135
136
|
assert.deepStrictEqual(inspect(parser('[[[a]{b}]]')), [['<sup class="reference"><span><a class="link" href="b">a</a></span></sup>'], '']);
|
|
136
137
|
assert.deepStrictEqual(inspect(parser('[(([a]{#}))]{#}')), [['<a class="link" href="#"><span class="paren">(<span class="paren">([a]{#})</span>)</span></a>'], '']);
|
|
137
138
|
assert.deepStrictEqual(inspect(parser('[[${]]}$')), [['[', '[', '<span class="math" translate="no" data-src="${]]}$">${]]}$</span>'], '']);
|
|
139
|
+
assert.deepStrictEqual(inspect(parser('[[a\nb]]')), [['[', '[', 'a', '<br>', 'b', ']', ']'], '']);
|
|
140
|
+
assert.deepStrictEqual(inspect(parser('[[[a\nb]]]')), [['[', '[', '[', 'a', '<br>', 'b', ']', ']', ']'], '']);
|
|
138
141
|
assert.deepStrictEqual(inspect(parser('"[[""]]')), [['"', '[', '[', '"', '"', ']', ']'], '']);
|
|
139
142
|
assert.deepStrictEqual(inspect(parser('[==a==]{b}')), [['<a class="link" href="b">==a==</a>'], '']);
|
|
140
143
|
assert.deepStrictEqual(inspect(parser('[[a](b)]{c}')), [['<a class="link" href="c"><ruby>a<rp>(</rp><rt>b</rt><rp>)</rp></ruby></a>'], '']);
|