securemark 0.247.1 → 0.248.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 +12 -0
- package/design.md +7 -4
- package/dist/index.js +22 -94
- package/markdown.d.ts +0 -7
- package/package.json +1 -1
- package/src/combinator/control/manipulation/indent.ts +1 -2
- package/src/parser/inline/annotation.ts +1 -1
- package/src/parser/inline/deletion.ts +2 -2
- package/src/parser/inline/extension/index.ts +1 -2
- package/src/parser/inline/extension/label.ts +1 -2
- package/src/parser/inline/html.test.ts +3 -3
- package/src/parser/inline/html.ts +16 -82
- package/src/parser/inline/insertion.ts +2 -2
- package/src/parser/inline/math.test.ts +3 -3
- package/src/parser/inline/math.ts +2 -2
- package/src/parser/inline/media.ts +3 -3
- package/src/parser/inline/reference.ts +1 -1
- package/src/parser/inline/ruby.ts +4 -4
- package/src/parser/inline.test.ts +1 -0
- package/src/parser/processor/figure.ts +18 -19
- package/src/parser/util.ts +2 -2
package/CHANGELOG.md
CHANGED
package/design.md
CHANGED
|
@@ -278,8 +278,11 @@ CodeMirrorが素では速いがVimModeでは数万文字程度でも耐え難く
|
|
|
278
278
|
|
|
279
279
|
### バックトラック
|
|
280
280
|
|
|
281
|
-
SecuremarkのAnnotation
|
|
282
|
-
|
|
281
|
+
SecuremarkのAnnotation構文に典型的であるように文脈を変更する構文とその文脈に依存し変更される他の構文が存在する場合文脈の相違から解析結果を再利用不能な(`αA'β | αAB`)バックトラックが生じる。ここで解析中に文脈依存構文に遭遇した時、現在の文脈での解析を継続する場合はバックトラックが再帰的に生じ線形時間で解析できず、現在の文脈での解析を中止し直前の文脈を継続または新たな文脈を開始する場合は線形時間で解析できる。
|
|
282
|
+
CommonMarkはLink構文から明らかなように後者の解析方法により線形時間で解析できる言語であるがこれは同時に文脈依存構文の正当な入れ子表現すら解析できず文脈依存構文の存在する数に応じて指数関数的に構文の壊れやすさの増す脆く拡張性の低い言語であることを意味する。
|
|
283
|
+
従って線形時間で解析可能な文法に制約されるCommonMarkには文脈依存構文を入れ子表現の広範な制限ならびに構文の可読性および開始記号の信頼性の指数関数的な低下と引き換えにしか追加できないという拡張性の限界が存在する。
|
|
284
|
+
対してSecuremarkは線形時間で解析不能な前者の解析方法を採用し解析時間と解析範囲の局限により線形時間で解析不能な入力の影響を局限することでこの制限を回避している。
|
|
285
|
+
ただし実際には文脈依存構文の入れ子表現はほとんどがリンクの入れ子不可制約として正当に制限されており開始記号の文字列(終端記号)としての正当な使用も稀と思われるため実用上差異が生じることはほとんどないと思われる。
|
|
283
286
|
|
|
284
287
|
### 標準化
|
|
285
288
|
|
|
@@ -296,5 +299,5 @@ MarkdownはGFMのように最初から高機能で完成度の高い拡張不要
|
|
|
296
299
|
|
|
297
300
|
### Data URI
|
|
298
301
|
|
|
299
|
-
Data URI
|
|
300
|
-
|
|
302
|
+
Data URIは保存および転送容量削減ならびにユーザーおよび管理者双方の集約的管理のためサポートしない。
|
|
303
|
+
特に規制および公開レベルの媒体別設定の実現のためテキストとメディアの分離が必須となる。
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.
|
|
1
|
+
/*! securemark v0.248.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("DOMPurify"), require("Prism"));
|
|
@@ -2254,11 +2254,9 @@ const surround_1 = __webpack_require__(7130);
|
|
|
2254
2254
|
|
|
2255
2255
|
const memoize_1 = __webpack_require__(1808);
|
|
2256
2256
|
|
|
2257
|
-
const array_1 = __webpack_require__(8112);
|
|
2258
|
-
|
|
2259
2257
|
function indent(parser, separation = false) {
|
|
2260
2258
|
return (0, bind_1.bind)((0, block_1.block)((0, match_1.match)(/^(?=(([ \t])\2*))/, (0, memoize_1.memoize)(([, indent]) => (0, some_1.some)((0, line_1.line)((0, surround_1.open)(indent, source => [[unline(source)], '']))), ([, indent]) => indent.length * 2 + +(indent[0] === ' '), [])), separation), (nodes, rest, context) => {
|
|
2261
|
-
const result = parser(
|
|
2259
|
+
const result = parser(nodes.join('\n'), context);
|
|
2262
2260
|
return result && (0, parser_1.exec)(result) === '' ? [(0, parser_1.eval)(result), rest] : global_1.undefined;
|
|
2263
2261
|
});
|
|
2264
2262
|
}
|
|
@@ -5367,7 +5365,6 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0,
|
|
|
5367
5365
|
|
|
5368
5366
|
}
|
|
5369
5367
|
},
|
|
5370
|
-
state: global_1.undefined,
|
|
5371
5368
|
delimiters: global_1.undefined
|
|
5372
5369
|
}, (0, util_1.trimSpaceStart)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, ')', /^\\?\n/)]))))), '))'), ns => [(0, dom_1.html)('sup', {
|
|
5373
5370
|
class: 'annotation'
|
|
@@ -5754,7 +5751,7 @@ const dom_1 = __webpack_require__(3252);
|
|
|
5754
5751
|
|
|
5755
5752
|
const array_1 = __webpack_require__(8112);
|
|
5756
5753
|
|
|
5757
|
-
exports.deletion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('~~'), (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n
|
|
5754
|
+
exports.deletion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('~~'), (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n/, '~~')), (0, combinator_1.open)(/^\n/, (0, combinator_1.some)(inline_1.inline, '~'), true)])), (0, source_1.str)('~~'), false, ([, bs], rest) => [[(0, dom_1.html)('del', (0, dom_1.defrag)(bs))], rest], ([as, bs], rest) => [(0, array_1.unshift)(as, bs), rest])));
|
|
5758
5755
|
|
|
5759
5756
|
/***/ }),
|
|
5760
5757
|
|
|
@@ -5915,8 +5912,6 @@ const util_1 = __webpack_require__(9437);
|
|
|
5915
5912
|
|
|
5916
5913
|
const dom_1 = __webpack_require__(3252);
|
|
5917
5914
|
|
|
5918
|
-
const array_1 = __webpack_require__(8112);
|
|
5919
|
-
|
|
5920
5915
|
exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[#', ']', '\n', (0, combinator_1.fmap)((0, indexee_1.indexee)((0, combinator_1.fmap)((0, combinator_1.surround)('[#', (0, combinator_1.guard)(context => context.syntax?.inline?.index ?? true, (0, util_1.startTight)((0, combinator_1.context)({
|
|
5921
5916
|
syntax: {
|
|
5922
5917
|
inline: {
|
|
@@ -5936,7 +5931,7 @@ exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combi
|
|
|
5936
5931
|
}, el.childNodes)]))));
|
|
5937
5932
|
const signature = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.open)('|#', (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']'))), ns => [(0, dom_1.html)('span', {
|
|
5938
5933
|
class: 'indexer',
|
|
5939
|
-
'data-index': (0, indexee_1.identity)(
|
|
5934
|
+
'data-index': (0, indexee_1.identity)(ns.join('')).slice(6)
|
|
5940
5935
|
})])));
|
|
5941
5936
|
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']'), (0, source_1.str)(']'), true), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), '}'), (0, source_1.str)('}'), true), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.some)(source_1.txt, '"'), (0, source_1.str)('"'), true)])));
|
|
5942
5937
|
|
|
@@ -6076,8 +6071,6 @@ const source_1 = __webpack_require__(6743);
|
|
|
6076
6071
|
|
|
6077
6072
|
const dom_1 = __webpack_require__(3252);
|
|
6078
6073
|
|
|
6079
|
-
const array_1 = __webpack_require__(8112);
|
|
6080
|
-
|
|
6081
6074
|
const body = (0, source_1.str)(/^\$[A-Za-z]*(?:(?:-[A-Za-z][0-9A-Za-z]*)+|-(?:(?:0|[1-9][0-9]*)\.)*(?:0|[1-9][0-9]*)(?![0-9A-Za-z]))/);
|
|
6082
6075
|
exports.segment = (0, combinator_1.clear)((0, combinator_1.validate)(['[$', '$'], (0, combinator_1.union)([(0, combinator_1.surround)('[', body, ']'), body])));
|
|
6083
6076
|
exports.label = (0, combinator_1.creator)((0, combinator_1.validate)(['[$', '$'], (0, combinator_1.fmap)((0, combinator_1.guard)(context => context.syntax?.inline?.label ?? true, (0, combinator_1.union)([(0, combinator_1.surround)('[', body, ']'), body])), ([text]) => [(0, dom_1.html)('a', {
|
|
@@ -6106,7 +6099,7 @@ function increment(number, position) {
|
|
|
6106
6099
|
ms[i] = i < ns.length ? i + 1 < position ? +ns[i] : +ns[i] + 1 : i + 1 < position ? 0 : 1;
|
|
6107
6100
|
}
|
|
6108
6101
|
|
|
6109
|
-
return
|
|
6102
|
+
return ms.join('.');
|
|
6110
6103
|
}
|
|
6111
6104
|
|
|
6112
6105
|
/***/ }),
|
|
@@ -6184,77 +6177,13 @@ const attrspec = {
|
|
|
6184
6177
|
};
|
|
6185
6178
|
Object.setPrototypeOf(attrspec, null);
|
|
6186
6179
|
Object.values(attrspec).forEach(o => Object.setPrototypeOf(o, null));
|
|
6187
|
-
exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('<', (0, combinator_1.validate)(/^<[a-z]+(?=[^\S\n]|>)/, (0, combinator_1.union)([(0, combinator_1.match)(/^(?=<(wbr)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)(`<${tag}`, (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), /^\s*>/, true, ([, bs = []], rest) => [[(0, dom_1.html)(tag, attributes('html', [], attrspec[tag], bs))], rest]), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^(?=<(sup|sub|small)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.
|
|
6188
|
-
switch (tag) {
|
|
6189
|
-
case 'sup':
|
|
6190
|
-
case 'sub':
|
|
6191
|
-
return {
|
|
6192
|
-
state: {
|
|
6193
|
-
in: {
|
|
6194
|
-
supsub: true
|
|
6195
|
-
}
|
|
6196
|
-
},
|
|
6197
|
-
syntax: {
|
|
6198
|
-
inline: {
|
|
6199
|
-
annotation: false,
|
|
6200
|
-
reference: false,
|
|
6201
|
-
media: false
|
|
6202
|
-
}
|
|
6203
|
-
}
|
|
6204
|
-
};
|
|
6205
|
-
|
|
6206
|
-
case 'small':
|
|
6207
|
-
return {
|
|
6208
|
-
state: {
|
|
6209
|
-
in: {
|
|
6210
|
-
small: true
|
|
6211
|
-
}
|
|
6212
|
-
},
|
|
6213
|
-
syntax: {
|
|
6214
|
-
inline: {
|
|
6215
|
-
media: false
|
|
6216
|
-
}
|
|
6217
|
-
}
|
|
6218
|
-
};
|
|
6219
|
-
|
|
6220
|
-
default:
|
|
6221
|
-
return {};
|
|
6222
|
-
}
|
|
6223
|
-
})(), (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n?/, `</${tag}>`)), (0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, '</'), true)]), `</${tag}>`)), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest, context) => [[elem(tag, as, (0, dom_1.defrag)(bs), cs, context)], rest])), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^(?=<(bdo|bdi)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${tag}`, `</${tag}>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n?/, `</${tag}>`)), (0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, '</'), true)]), `</${tag}>`), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest, context) => [[elem(tag, as, (0, dom_1.defrag)(bs), cs, context)], rest], ([as, bs], rest) => as.length === 1 ? [(0, array_1.unshift)(as, bs), rest] : global_1.undefined)), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${tag}`, `</${tag}>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n?/, `</${tag}>`)), (0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, '</'), true)]), `</${tag}>`), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest, context) => [[elem(tag, as, (0, dom_1.defrag)(bs), cs, context)], rest], ([as, bs], rest) => as.length === 1 ? [(0, array_1.unshift)(as, bs), rest] : global_1.undefined)), ([, tag]) => tag, new cache_1.Cache(10000)))])))));
|
|
6180
|
+
exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('<', (0, combinator_1.validate)(/^<[a-z]+(?=[^\S\n]|>)/, (0, combinator_1.union)([(0, combinator_1.match)(/^(?=<(wbr)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)(`<${tag}`, (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), /^\s*>/, true, ([, bs = []], rest) => [[(0, dom_1.html)(tag, attributes('html', [], attrspec[tag], bs))], rest]), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n/, `</${tag}>`)), (0, combinator_1.open)(/^\n/, (0, combinator_1.some)(inline_1.inline, `</${tag}>`), true)]), `</${tag}>`), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, (0, dom_1.defrag)(bs), cs)], rest]), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n/, `</${tag}>`)), (0, combinator_1.open)(/^\n/, (0, combinator_1.some)(inline_1.inline, `</${tag}>`), true)]), `</${tag}>`), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, (0, dom_1.defrag)(bs), cs)], rest]), ([, tag]) => tag, new cache_1.Cache(10000)))])))));
|
|
6224
6181
|
exports.attribute = (0, combinator_1.union)([(0, source_1.str)(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|>)/)]);
|
|
6225
6182
|
|
|
6226
|
-
function elem(tag, as, bs, cs
|
|
6183
|
+
function elem(tag, as, bs, cs) {
|
|
6227
6184
|
if (!tags.includes(tag)) return invalid('tag', `Invalid HTML tag <${tag}>`, as, bs, cs);
|
|
6228
|
-
|
|
6229
|
-
switch (tag) {
|
|
6230
|
-
case 'sup':
|
|
6231
|
-
case 'sub':
|
|
6232
|
-
switch (true) {
|
|
6233
|
-
case context.state?.in?.supsub:
|
|
6234
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup> or <sub> HTML tag`, as, bs, cs);
|
|
6235
|
-
}
|
|
6236
|
-
|
|
6237
|
-
break;
|
|
6238
|
-
|
|
6239
|
-
case 'small':
|
|
6240
|
-
switch (true) {
|
|
6241
|
-
case context.state?.in?.supsub:
|
|
6242
|
-
case context.state?.in?.small:
|
|
6243
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup>, <sub>, or <small> HTML tag`, as, bs, cs);
|
|
6244
|
-
}
|
|
6245
|
-
|
|
6246
|
-
break;
|
|
6247
|
-
}
|
|
6248
|
-
|
|
6249
6185
|
const attrs = attributes('html', [], attrspec[tag], as.slice(1, -1));
|
|
6250
|
-
|
|
6251
|
-
switch (true) {
|
|
6252
|
-
case 'data-invalid-syntax' in attrs:
|
|
6253
|
-
return invalid('attribute', 'Invalid HTML attribute', as, bs, cs);
|
|
6254
|
-
|
|
6255
|
-
default:
|
|
6256
|
-
return (0, dom_1.html)(tag, attrs, bs);
|
|
6257
|
-
}
|
|
6186
|
+
return 'data-invalid-syntax' in attrs ? invalid('attribute', 'Invalid HTML attribute', as, bs, cs) : (0, dom_1.html)(tag, attrs, bs);
|
|
6258
6187
|
}
|
|
6259
6188
|
|
|
6260
6189
|
function invalid(type, message, as, bs, cs) {
|
|
@@ -6285,7 +6214,7 @@ function attributes(syntax, classes, spec, params) {
|
|
|
6285
6214
|
invalid ||= !!spec && !requiredAttributes(spec).every(name => name in attrs);
|
|
6286
6215
|
|
|
6287
6216
|
if (invalid) {
|
|
6288
|
-
attrs['class'] = (
|
|
6217
|
+
attrs['class'] = (classes.includes('invalid') ? classes : (0, array_1.unshift)(classes, ['invalid'])).join(' ');
|
|
6289
6218
|
attrs['data-invalid-syntax'] = syntax;
|
|
6290
6219
|
attrs['data-invalid-type'] = 'argument';
|
|
6291
6220
|
attrs['data-invalid-message'] = 'Invalid argument';
|
|
@@ -6356,7 +6285,7 @@ const dom_1 = __webpack_require__(3252);
|
|
|
6356
6285
|
|
|
6357
6286
|
const array_1 = __webpack_require__(8112);
|
|
6358
6287
|
|
|
6359
|
-
exports.insertion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('++'), (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n
|
|
6288
|
+
exports.insertion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('++'), (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, util_1.blank)(/\n/, '++')), (0, combinator_1.open)(/^\n/, (0, combinator_1.some)(inline_1.inline, '+'), true)])), (0, source_1.str)('++'), false, ([, bs], rest) => [[(0, dom_1.html)('ins', (0, dom_1.defrag)(bs))], rest], ([as, bs], rest) => [(0, array_1.unshift)(as, bs), rest])));
|
|
6360
6289
|
|
|
6361
6290
|
/***/ }),
|
|
6362
6291
|
|
|
@@ -6546,7 +6475,7 @@ const dom_1 = __webpack_require__(3252);
|
|
|
6546
6475
|
|
|
6547
6476
|
const syntax = /^(?:[ "([](?!\$)|\\{(?!\$)|\\[\\}$]?|^`|`(?!`)|[!#%&')\x2A-\x5A\]^_\x61-\x7A|~])+/;
|
|
6548
6477
|
const forbiddenCommand = /\\(?:begin|tiny|huge|large)(?![a-z])/i;
|
|
6549
|
-
exports.math = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('$', (0, combinator_1.rewrite)((0, combinator_1.union)([(0, combinator_1.surround)('$', bracket, '$'), (0, combinator_1.surround)(/^\$(
|
|
6478
|
+
exports.math = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('$', (0, combinator_1.rewrite)((0, combinator_1.union)([(0, combinator_1.surround)('$', bracket, '$'), (0, combinator_1.surround)(/^\$(?![\s{}])/, (0, combinator_1.some)((0, combinator_1.union)([bracket, quote, (0, source_1.str)(syntax)])), /^\$(?![0-9A-Za-z])/)]), (source, {
|
|
6550
6479
|
caches: {
|
|
6551
6480
|
math: cache
|
|
6552
6481
|
} = {}
|
|
@@ -6562,7 +6491,7 @@ exports.math = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combin
|
|
|
6562
6491
|
'data-invalid-message': `"${source.match(forbiddenCommand)[0]}" command is forbidden`
|
|
6563
6492
|
}, source)], '']))));
|
|
6564
6493
|
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)('{', (0, combinator_1.some)((0, combinator_1.union)([bracket, (0, combinator_1.some)(source_1.escsource, /^(?:[{}$]|\\?\n)/)])), '}', true)));
|
|
6565
|
-
const quote = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)('``', (0, combinator_1.some)((0, combinator_1.union)([quote, bracket, (0, combinator_1.focus)(/^(?:\\[\\{}$]|`(?!`)|[^`{}"$\n])
|
|
6494
|
+
const quote = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)('``', (0, combinator_1.some)((0, combinator_1.union)([quote, bracket, (0, combinator_1.focus)(/^(?:\\[\\{}$]|`(?!`)|[^`{}"$\n\P{ASCII}])*/u, (0, source_1.str)(syntax))])), /^"?/, true)));
|
|
6566
6495
|
|
|
6567
6496
|
/***/ }),
|
|
6568
6497
|
|
|
@@ -6602,7 +6531,7 @@ const optspec = {
|
|
|
6602
6531
|
rel: global_1.undefined
|
|
6603
6532
|
};
|
|
6604
6533
|
Object.setPrototypeOf(optspec, null);
|
|
6605
|
-
exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.validate)(['![', '!{'], '}', '\n', (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.open)('!', (0, combinator_1.guard)(context => context.syntax?.inline?.media ?? true, (0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)(/^\[(?!\s*\\\s)/, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']', /^\\?\n/), ']', true)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), /^[^\S\n]*}/))]))), ([as, bs]) => bs ? [[
|
|
6534
|
+
exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.validate)(['![', '!{'], '}', '\n', (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.open)('!', (0, combinator_1.guard)(context => context.syntax?.inline?.media ?? true, (0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)(/^\[(?!\s*\\\s)/, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']', /^\\?\n/), ']', true)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), /^[^\S\n]*}/))]))), ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
|
|
6606
6535
|
const INSECURE_URI = params.shift();
|
|
6607
6536
|
const url = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, context.host ?? global_1.location, context.url ?? context.host ?? global_1.location), context.host?.href || global_1.location.href);
|
|
6608
6537
|
let cache;
|
|
@@ -6617,7 +6546,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, c
|
|
|
6617
6546
|
if (context.syntax?.inline?.link === false || cache && cache.tagName !== 'IMG') return [[el], rest];
|
|
6618
6547
|
return (0, combinator_1.fmap)(link_1.link, ([link]) => [(0, dom_1.define)(link, {
|
|
6619
6548
|
target: '_blank'
|
|
6620
|
-
}, [el])])(`{ ${INSECURE_URI}${
|
|
6549
|
+
}, [el])])(`{ ${INSECURE_URI}${params.join('')} }${rest}`, context);
|
|
6621
6550
|
}))));
|
|
6622
6551
|
const bracket = (0, combinator_1.lazy)(() => (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, global_1.undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (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, global_1.undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (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, global_1.undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, source_1.txt]), '"'), (0, source_1.str)('"'), true)]));
|
|
6623
6552
|
const option = (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]);
|
|
@@ -6700,7 +6629,6 @@ exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, c
|
|
|
6700
6629
|
|
|
6701
6630
|
}
|
|
6702
6631
|
},
|
|
6703
|
-
state: global_1.undefined,
|
|
6704
6632
|
delimiters: global_1.undefined
|
|
6705
6633
|
}, (0, combinator_1.subsequence)([abbr, (0, combinator_1.focus)(/^\^[^\S\n]*/, source => [['', source], '']), (0, util_1.trimSpaceStart)((0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/))])))), ']]'), ns => [(0, dom_1.html)('sup', attributes(ns), (0, util_1.trimNodeEnd)((0, dom_1.defrag)(ns)))]))));
|
|
6706
6634
|
const abbr = (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.verify)((0, combinator_1.surround)('^', (0, combinator_1.union)([(0, source_1.str)(/^(?![0-9]+\s?[|\]])[0-9A-Za-z]+(?:(?:-|(?=\W)(?!'\d)'?(?!\.\d)\.?(?!,\S),? ?)[0-9A-Za-z]+)*(?:-|'?\.?,? ?)?/)]), /^\|?(?=]])|^\|[^\S\n]*/), (_, rest, context) => (0, util_1.isStartLoose)(rest, context)), ([source]) => [(0, dom_1.html)('abbr', source)]));
|
|
@@ -6760,7 +6688,7 @@ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combin
|
|
|
6760
6688
|
return [[(0, dom_1.html)('ruby', attributes(texts, rubies), (0, dom_1.defrag)((0, array_1.push)([...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')])), []), tail)))], rest];
|
|
6761
6689
|
|
|
6762
6690
|
default:
|
|
6763
|
-
return [[(0, dom_1.html)('ruby', attributes(texts, rubies), (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)([
|
|
6691
|
+
return [[(0, dom_1.html)('ruby', attributes(texts, rubies), (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)([texts.join(' ')], [(0, dom_1.html)('rp', '('), (0, dom_1.html)('rt', rubies.join(' ').trim()), (0, dom_1.html)('rp', ')')]), tail)))], rest];
|
|
6764
6692
|
}
|
|
6765
6693
|
}))));
|
|
6766
6694
|
const text = (0, combinator_1.creator)((source, context) => {
|
|
@@ -6797,7 +6725,7 @@ const text = (0, combinator_1.creator)((source, context) => {
|
|
|
6797
6725
|
}
|
|
6798
6726
|
}
|
|
6799
6727
|
|
|
6800
|
-
return
|
|
6728
|
+
return acc.join('').trimStart() ? [[acc], ''] : global_1.undefined;
|
|
6801
6729
|
});
|
|
6802
6730
|
|
|
6803
6731
|
function attributes(texts, rubies) {
|
|
@@ -7092,16 +7020,16 @@ function* figure(target, footnotes, opts = {}) {
|
|
|
7092
7020
|
}
|
|
7093
7021
|
|
|
7094
7022
|
const group = label.split('-', 1)[0];
|
|
7095
|
-
let number = (0, label_1.number)(label, numbers.has(group) && !(0, label_1.isFixed)(label) ?
|
|
7023
|
+
let number = (0, label_1.number)(label, numbers.has(group) && !(0, label_1.isFixed)(label) ? numbers.get(group).split('.').slice(0, bases.length).join('.') : base);
|
|
7096
7024
|
|
|
7097
7025
|
if (number.endsWith('.0')) {
|
|
7098
7026
|
if (group !== '$' || tagName === 'FIGURE' && def.firstChild) continue;
|
|
7099
7027
|
|
|
7100
7028
|
if (number.startsWith('0.')) {
|
|
7101
|
-
number =
|
|
7029
|
+
number = index.slice(0).reduce((ns, _, i, xs) => {
|
|
7102
7030
|
i === ns.length ? xs.length = i : ns[i] = +ns[i] > +xs[i] ? ns[i] : +ns[i] === 0 ? xs[i] : `${+xs[i] + 1}`;
|
|
7103
7031
|
return ns;
|
|
7104
|
-
}, number.split('.'))
|
|
7032
|
+
}, number.split('.')).join('.');
|
|
7105
7033
|
}
|
|
7106
7034
|
|
|
7107
7035
|
base = number;
|
|
@@ -7180,7 +7108,7 @@ const messages = {
|
|
|
7180
7108
|
|
|
7181
7109
|
function increment(bases, el) {
|
|
7182
7110
|
const index = (+el.tagName[1] - 1 || 1) - 1;
|
|
7183
|
-
return index + 1 < bases.length ?
|
|
7111
|
+
return index + 1 < bases.length ? bases.slice(0, index + 2).map((v, i) => {
|
|
7184
7112
|
switch (true) {
|
|
7185
7113
|
case i < index:
|
|
7186
7114
|
return v;
|
|
@@ -7191,7 +7119,7 @@ function increment(bases, el) {
|
|
|
7191
7119
|
default:
|
|
7192
7120
|
return 0;
|
|
7193
7121
|
}
|
|
7194
|
-
})
|
|
7122
|
+
}).join('.') : '';
|
|
7195
7123
|
}
|
|
7196
7124
|
|
|
7197
7125
|
function capitalize(label) {
|
|
@@ -7779,7 +7707,7 @@ const memoize_1 = __webpack_require__(1808);
|
|
|
7779
7707
|
const array_1 = __webpack_require__(8112);
|
|
7780
7708
|
|
|
7781
7709
|
function blank(prefix, suffix) {
|
|
7782
|
-
return new RegExp(String.raw
|
|
7710
|
+
return new RegExp(String.raw`^(?:${prefix && prefix.source}(?:\\\s|[^\S\n]|\n|&(?:${normalize_1.invisibleHTMLEntityNames.join('|')});|<wbr>)*)?${typeof suffix === 'string' ? suffix.replace(/[*+()\[\]]/g, '\\$&') : suffix.source}`);
|
|
7783
7711
|
}
|
|
7784
7712
|
|
|
7785
7713
|
exports.blank = blank;
|
package/markdown.d.ts
CHANGED
|
@@ -28,12 +28,6 @@ export namespace MarkdownParser {
|
|
|
28
28
|
readonly autolink?: boolean;
|
|
29
29
|
};
|
|
30
30
|
};
|
|
31
|
-
readonly state?: {
|
|
32
|
-
readonly in?: {
|
|
33
|
-
readonly supsub?: boolean;
|
|
34
|
-
readonly small?: boolean;
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
31
|
readonly caches?: {
|
|
38
32
|
readonly code?: Collection<string, HTMLElement>;
|
|
39
33
|
readonly math?: Collection<string, HTMLElement>;
|
|
@@ -987,7 +981,6 @@ export namespace MarkdownParser {
|
|
|
987
981
|
HTMLParser.OpenTagParser,
|
|
988
982
|
HTMLParser.TagParser,
|
|
989
983
|
HTMLParser.TagParser,
|
|
990
|
-
HTMLParser.TagParser,
|
|
991
984
|
]> {
|
|
992
985
|
}
|
|
993
986
|
export namespace HTMLParser {
|
package/package.json
CHANGED
|
@@ -7,7 +7,6 @@ import { bind } from '../monad/bind';
|
|
|
7
7
|
import { match } from './match';
|
|
8
8
|
import { open } from './surround';
|
|
9
9
|
import { memoize } from 'spica/memoize';
|
|
10
|
-
import { join } from 'spica/array';
|
|
11
10
|
|
|
12
11
|
export function indent<P extends Parser<unknown>>(parser: P, separation?: boolean): P;
|
|
13
12
|
export function indent<T>(parser: Parser<T>, separation = false): Parser<T> {
|
|
@@ -19,7 +18,7 @@ export function indent<T>(parser: Parser<T>, separation = false): Parser<T> {
|
|
|
19
18
|
some(line(open(indent, source => [[unline(source)], '']))),
|
|
20
19
|
([, indent]) => indent.length * 2 + +(indent[0] === ' '), [])), separation),
|
|
21
20
|
(nodes, rest, context) => {
|
|
22
|
-
const result = parser(join(
|
|
21
|
+
const result = parser(nodes.join('\n'), context);
|
|
23
22
|
return result && exec(result) === ''
|
|
24
23
|
? [eval(result), rest]
|
|
25
24
|
: undefined;
|
|
@@ -19,7 +19,7 @@ export const annotation: AnnotationParser = lazy(() => creator(validate('((', ')
|
|
|
19
19
|
//label: true,
|
|
20
20
|
//link: true,
|
|
21
21
|
//autolink: true,
|
|
22
|
-
}},
|
|
22
|
+
}}, delimiters: undefined },
|
|
23
23
|
trimSpaceStart(union([some(inline, ')', /^\\?\n/)]))))),
|
|
24
24
|
'))'),
|
|
25
25
|
ns => [html('sup', { class: 'annotation' }, trimNodeEnd(defrag(ns)))]))));
|
|
@@ -9,8 +9,8 @@ import { unshift } from 'spica/array';
|
|
|
9
9
|
export const deletion: DeletionParser = lazy(() => creator(surround(
|
|
10
10
|
str('~~'),
|
|
11
11
|
some(union([
|
|
12
|
-
some(inline, blank(/\n
|
|
13
|
-
open(/^\n
|
|
12
|
+
some(inline, blank(/\n/, '~~')),
|
|
13
|
+
open(/^\n/, some(inline, '~'), true),
|
|
14
14
|
])),
|
|
15
15
|
str('~~'), false,
|
|
16
16
|
([, bs], rest) => [[html('del', defrag(bs))], rest],
|
|
@@ -6,7 +6,6 @@ import { indexee, identity } from './indexee';
|
|
|
6
6
|
import { txt, str, stropt } from '../../source';
|
|
7
7
|
import { startTight, trimNodeEnd } from '../../util';
|
|
8
8
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
9
|
-
import { join } from 'spica/array';
|
|
10
9
|
|
|
11
10
|
import IndexParser = ExtensionParser.IndexParser;
|
|
12
11
|
|
|
@@ -44,7 +43,7 @@ const signature: IndexParser.SignatureParser = lazy(() => creator(fmap(open(
|
|
|
44
43
|
'|#',
|
|
45
44
|
startTight(some(union([bracket, txt]), ']'))),
|
|
46
45
|
ns => [
|
|
47
|
-
html('span', { class: 'indexer', 'data-index': identity(join(
|
|
46
|
+
html('span', { class: 'indexer', 'data-index': identity(ns.join('')).slice(6) }),
|
|
48
47
|
])));
|
|
49
48
|
|
|
50
49
|
const bracket: IndexParser.SignatureParser.BracketParser = lazy(() => creator(union([
|
|
@@ -3,7 +3,6 @@ import { ExtensionParser } from '../../inline';
|
|
|
3
3
|
import { union, validate, guard, creator, surround, clear, fmap } from '../../../combinator';
|
|
4
4
|
import { str } from '../../source';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
|
-
import { join } from 'spica/array';
|
|
7
6
|
|
|
8
7
|
const body = str(/^\$[A-Za-z]*(?:(?:-[A-Za-z][0-9A-Za-z]*)+|-(?:(?:0|[1-9][0-9]*)\.)*(?:0|[1-9][0-9]*)(?![0-9A-Za-z]))/);
|
|
9
8
|
|
|
@@ -48,5 +47,5 @@ function increment(number: string, position: number): string {
|
|
|
48
47
|
? 0
|
|
49
48
|
: 1;
|
|
50
49
|
}
|
|
51
|
-
return join(
|
|
50
|
+
return ms.join('.');
|
|
52
51
|
}
|
|
@@ -41,7 +41,7 @@ describe('Unit: parser/inline/html', () => {
|
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('</small>')), undefined);
|
|
42
42
|
assert.deepStrictEqual(inspect(parser('<small/>')), undefined);
|
|
43
43
|
assert.deepStrictEqual(inspect(parser('<b><b><b>a</b></b></b>')), [['<span class="invalid"><b><span class="invalid"><b><span class="invalid"><b>a</b></span></b></span></b></span>'], '']);
|
|
44
|
-
assert.deepStrictEqual(inspect(parser('<small><small><small>a</small></small></small>')), [['<small><
|
|
44
|
+
assert.deepStrictEqual(inspect(parser('<small><small><small>a</small></small></small>')), [['<small><small><small>a</small></small></small>'], '']);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('<x a="*b*"')), undefined);
|
|
46
46
|
assert.deepStrictEqual(inspect(parser('<x a="*b*">')), undefined);
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('<x a="*b*">c')), undefined);
|
|
@@ -72,8 +72,8 @@ describe('Unit: parser/inline/html', () => {
|
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
it('nest', () => {
|
|
75
|
-
assert.deepStrictEqual(inspect(parser('<small><small>a</small></small>')), [['<small><
|
|
76
|
-
assert.deepStrictEqual(inspect(parser('<small>a<small>b</small>c</small>')), [['<small>a<
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('<small><small>a</small></small>')), [['<small><small>a</small></small>'], '']);
|
|
76
|
+
assert.deepStrictEqual(inspect(parser('<small>a<small>b</small>c</small>')), [['<small>a<small>b</small>c</small>'], '']);
|
|
77
77
|
assert.deepStrictEqual(inspect(parser('<small>`a`</small>')), [['<small><code data-src="`a`">a</code></small>'], '']);
|
|
78
78
|
});
|
|
79
79
|
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { isFrozen, ObjectEntries } from 'spica/alias';
|
|
3
|
-
import { MarkdownParser } from '../../../markdown';
|
|
4
3
|
import { HTMLParser } from '../inline';
|
|
5
|
-
import { union, some, validate,
|
|
4
|
+
import { union, some, validate, creator, surround, open, match, lazy } from '../../combinator';
|
|
6
5
|
import { inline } from '../inline';
|
|
7
6
|
import { str } from '../source';
|
|
8
7
|
import { startLoose, blank } from '../util';
|
|
9
8
|
import { html as h, defrag } from 'typed-dom/dom';
|
|
10
9
|
import { memoize } from 'spica/memoize';
|
|
11
10
|
import { Cache } from 'spica/cache';
|
|
12
|
-
import { unshift, push, splice
|
|
11
|
+
import { unshift, push, splice } from 'spica/array';
|
|
13
12
|
|
|
14
13
|
const tags = Object.freeze(['wbr', 'sup', 'sub', 'small', 'bdo', 'bdi']);
|
|
15
14
|
const attrspec = {
|
|
@@ -31,78 +30,32 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
|
|
|
31
30
|
[[h(tag as 'span', attributes('html', [], attrspec[tag], bs))], rest]),
|
|
32
31
|
([, tag]) => tags.indexOf(tag), [])),
|
|
33
32
|
match(
|
|
34
|
-
/^(?=<(sup|sub|small)(?=[^\S\n]|>))/,
|
|
33
|
+
/^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/,
|
|
35
34
|
memoize(
|
|
36
35
|
([, tag]) =>
|
|
37
|
-
validate(`<${tag}`, `</${tag}>`,
|
|
38
|
-
surround<HTMLParser.TagParser, string>(surround(
|
|
39
|
-
str(`<${tag}`), some(attribute), str(/^\s*>/), true),
|
|
40
|
-
startLoose(
|
|
41
|
-
context((() => {
|
|
42
|
-
switch (tag) {
|
|
43
|
-
case 'sup':
|
|
44
|
-
case 'sub':
|
|
45
|
-
return {
|
|
46
|
-
state: { in: { supsub: true } },
|
|
47
|
-
syntax: { inline: {
|
|
48
|
-
annotation: false,
|
|
49
|
-
reference: false,
|
|
50
|
-
media: false,
|
|
51
|
-
}},
|
|
52
|
-
};
|
|
53
|
-
case 'small':
|
|
54
|
-
return {
|
|
55
|
-
state: { in: { small: true } },
|
|
56
|
-
syntax: { inline: {
|
|
57
|
-
media: false,
|
|
58
|
-
}},
|
|
59
|
-
};
|
|
60
|
-
default:
|
|
61
|
-
assert(false);
|
|
62
|
-
return {};
|
|
63
|
-
}
|
|
64
|
-
})(),
|
|
65
|
-
some(union([
|
|
66
|
-
some(inline, blank(/\n?/, `</${tag}>`)),
|
|
67
|
-
open(/^\n?/, some(inline, '</'), true),
|
|
68
|
-
]), `</${tag}>`)), `</${tag}>`),
|
|
69
|
-
str(`</${tag}>`), false,
|
|
70
|
-
([as, bs, cs], rest, context) =>
|
|
71
|
-
[[elem(tag, as, defrag(bs), cs, context)], rest])),
|
|
72
|
-
([, tag]) => tags.indexOf(tag), [])),
|
|
73
|
-
match(
|
|
74
|
-
/^(?=<(bdo|bdi)(?=[^\S\n]|>))/,
|
|
75
|
-
memoize(
|
|
76
|
-
([, tag]) =>
|
|
77
|
-
validate(`<${tag}`, `</${tag}>`,
|
|
78
36
|
surround<HTMLParser.TagParser, string>(surround(
|
|
79
37
|
str(`<${tag}`), some(attribute), str(/^\s*>/), true),
|
|
80
38
|
startLoose(some(union([
|
|
81
|
-
some(inline, blank(/\n
|
|
82
|
-
open(/^\n
|
|
39
|
+
some(inline, blank(/\n/, `</${tag}>`)),
|
|
40
|
+
open(/^\n/, some(inline, `</${tag}>`), true),
|
|
83
41
|
]), `</${tag}>`), `</${tag}>`),
|
|
84
42
|
str(`</${tag}>`), false,
|
|
85
|
-
([as, bs, cs], rest
|
|
86
|
-
[[elem(tag, as, defrag(bs), cs
|
|
87
|
-
([as, bs], rest) =>
|
|
88
|
-
as.length === 1 ? [unshift(as, bs), rest] : undefined)),
|
|
43
|
+
([as, bs, cs], rest) =>
|
|
44
|
+
[[elem(tag, as, defrag(bs), cs)], rest]),
|
|
89
45
|
([, tag]) => tags.indexOf(tag), [])),
|
|
90
46
|
match(
|
|
91
47
|
/^(?=<([a-z]+)(?=[^\S\n]|>))/,
|
|
92
48
|
memoize(
|
|
93
49
|
([, tag]) =>
|
|
94
|
-
validate(`<${tag}`, `</${tag}>`,
|
|
95
50
|
surround<HTMLParser.TagParser, string>(surround(
|
|
96
51
|
str(`<${tag}`), some(attribute), str(/^\s*>/), true),
|
|
97
52
|
startLoose(some(union([
|
|
98
|
-
some(inline, blank(/\n
|
|
99
|
-
open(/^\n
|
|
53
|
+
some(inline, blank(/\n/, `</${tag}>`)),
|
|
54
|
+
open(/^\n/, some(inline, `</${tag}>`), true),
|
|
100
55
|
]), `</${tag}>`), `</${tag}>`),
|
|
101
56
|
str(`</${tag}>`), false,
|
|
102
|
-
([as, bs, cs], rest
|
|
103
|
-
[[elem(tag, as, defrag(bs), cs
|
|
104
|
-
([as, bs], rest) =>
|
|
105
|
-
as.length === 1 ? [unshift(as, bs), rest] : undefined)),
|
|
57
|
+
([as, bs, cs], rest) =>
|
|
58
|
+
[[elem(tag, as, defrag(bs), cs)], rest]),
|
|
106
59
|
([, tag]) => tag,
|
|
107
60
|
new Cache(10000))),
|
|
108
61
|
])))));
|
|
@@ -111,35 +64,16 @@ export const attribute: HTMLParser.TagParser.AttributeParser = union([
|
|
|
111
64
|
str(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|>)/),
|
|
112
65
|
]);
|
|
113
66
|
|
|
114
|
-
function elem(tag: string, as: string[], bs: (HTMLElement | string)[], cs: string[]
|
|
67
|
+
function elem(tag: string, as: string[], bs: (HTMLElement | string)[], cs: string[]): HTMLElement {
|
|
115
68
|
assert(as.length > 0);
|
|
116
69
|
assert(as[0][0] === '<' && as[as.length - 1].slice(-1) === '>');
|
|
117
70
|
assert(bs.length === defrag(bs).length);
|
|
118
71
|
assert(cs.length === 1);
|
|
119
72
|
if (!tags.includes(tag)) return invalid('tag', `Invalid HTML tag <${tag}>`, as, bs, cs);
|
|
120
|
-
switch (tag) {
|
|
121
|
-
case 'sup':
|
|
122
|
-
case 'sub':
|
|
123
|
-
switch (true) {
|
|
124
|
-
case context.state?.in?.supsub:
|
|
125
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup> or <sub> HTML tag`, as, bs, cs);
|
|
126
|
-
}
|
|
127
|
-
break;
|
|
128
|
-
case 'small':
|
|
129
|
-
switch (true) {
|
|
130
|
-
case context.state?.in?.supsub:
|
|
131
|
-
case context.state?.in?.small:
|
|
132
|
-
return invalid('nest', `<${tag}> HTML tag cannot be used in <sup>, <sub>, or <small> HTML tag`, as, bs, cs);
|
|
133
|
-
}
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
73
|
const attrs = attributes('html', [], attrspec[tag], as.slice(1, -1));
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
default:
|
|
141
|
-
return h(tag as 'span', attrs, bs);
|
|
142
|
-
}
|
|
74
|
+
return 'data-invalid-syntax' in attrs
|
|
75
|
+
? invalid('attribute', 'Invalid HTML attribute', as, bs, cs)
|
|
76
|
+
: h(tag as 'span', attrs, bs);
|
|
143
77
|
}
|
|
144
78
|
function invalid(type: string, message: string, as: (HTMLElement | string)[], bs: (HTMLElement | string)[], cs: (HTMLElement | string)[]): HTMLElement {
|
|
145
79
|
return h('span', {
|
|
@@ -182,7 +116,7 @@ export function attributes(
|
|
|
182
116
|
}
|
|
183
117
|
invalid ||= !!spec && !requiredAttributes(spec).every(name => name in attrs);
|
|
184
118
|
if (invalid) {
|
|
185
|
-
attrs['class'] =
|
|
119
|
+
attrs['class'] = (classes.includes('invalid') ? classes : unshift(classes, ['invalid'])).join(' ');
|
|
186
120
|
attrs['data-invalid-syntax'] = syntax;
|
|
187
121
|
attrs['data-invalid-type'] = 'argument';
|
|
188
122
|
attrs['data-invalid-message'] = 'Invalid argument';
|
|
@@ -9,8 +9,8 @@ import { unshift } from 'spica/array';
|
|
|
9
9
|
export const insertion: InsertionParser = lazy(() => creator(surround(
|
|
10
10
|
str('++'),
|
|
11
11
|
some(union([
|
|
12
|
-
some(inline, blank(/\n
|
|
13
|
-
open(/^\n
|
|
12
|
+
some(inline, blank(/\n/, '++')),
|
|
13
|
+
open(/^\n/, some(inline, '+'), true),
|
|
14
14
|
])),
|
|
15
15
|
str('++'), false,
|
|
16
16
|
([, bs], rest) => [[html('ins', defrag(bs))], rest],
|
|
@@ -54,6 +54,9 @@ describe('Unit: parser/inline/math', () => {
|
|
|
54
54
|
assert.deepStrictEqual(inspect(parser('${a} $')), undefined);
|
|
55
55
|
assert.deepStrictEqual(inspect(parser('${a{b}$')), undefined);
|
|
56
56
|
assert.deepStrictEqual(inspect(parser('${a}b}$')), undefined);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('${a}b$')), undefined);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('${a}b{c}$')), undefined);
|
|
59
|
+
assert.deepStrictEqual(inspect(parser('${a}{b}$')), undefined);
|
|
57
60
|
assert.deepStrictEqual(inspect(parser('${$}$')), undefined);
|
|
58
61
|
assert.deepStrictEqual(inspect(parser('${\\}$')), undefined);
|
|
59
62
|
assert.deepStrictEqual(inspect(parser('${\n}$')), undefined);
|
|
@@ -128,9 +131,6 @@ describe('Unit: parser/inline/math', () => {
|
|
|
128
131
|
assert.deepStrictEqual(inspect(parser('${\\a}$')), [['<span class="math" translate="no" data-src="${\\a}$">${\\a}$</span>'], '']);
|
|
129
132
|
assert.deepStrictEqual(inspect(parser('${\\$}$')), [['<span class="math" translate="no" data-src="${\\$}$">${\\$}$</span>'], '']);
|
|
130
133
|
assert.deepStrictEqual(inspect(parser('${\\\\}$')), [['<span class="math" translate="no" data-src="${\\\\}$">${\\\\}$</span>'], '']);
|
|
131
|
-
assert.deepStrictEqual(inspect(parser('${a}b$')), [['<span class="math" translate="no" data-src="${a}b$">${a}b$</span>'], '']);
|
|
132
|
-
assert.deepStrictEqual(inspect(parser('${a}b{c}$')), [['<span class="math" translate="no" data-src="${a}b{c}$">${a}b{c}$</span>'], '']);
|
|
133
|
-
assert.deepStrictEqual(inspect(parser('${a}{b}$')), [['<span class="math" translate="no" data-src="${a}{b}$">${a}{b}$</span>'], '']);
|
|
134
134
|
assert.deepStrictEqual(inspect(parser('${あ}$')), [['<span class="math" translate="no" data-src="${あ}$">${あ}$</span>'], '']);
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -10,7 +10,7 @@ export const math: MathParser = lazy(() => creator(validate('$', rewrite(
|
|
|
10
10
|
union([
|
|
11
11
|
surround('$', bracket, '$'),
|
|
12
12
|
surround(
|
|
13
|
-
/^\$(
|
|
13
|
+
/^\$(?![\s{}])/,
|
|
14
14
|
some(union([
|
|
15
15
|
bracket,
|
|
16
16
|
quote,
|
|
@@ -47,7 +47,7 @@ const quote: MathParser.QuoteParser = lazy(() => creator(surround(
|
|
|
47
47
|
some(union([
|
|
48
48
|
quote,
|
|
49
49
|
bracket,
|
|
50
|
-
focus(/^(?:\\[\\{}$]|`(?!`)|[^`{}"$\n])
|
|
50
|
+
focus(/^(?:\\[\\{}$]|`(?!`)|[^`{}"$\n\P{ASCII}])*/u, str(syntax)),
|
|
51
51
|
])),
|
|
52
52
|
/^"?/,
|
|
53
53
|
true)));
|
|
@@ -7,7 +7,7 @@ import { unsafehtmlentity } from './htmlentity';
|
|
|
7
7
|
import { txt, str } from '../source';
|
|
8
8
|
import { html, define } from 'typed-dom/dom';
|
|
9
9
|
import { ReadonlyURL } from 'spica/url';
|
|
10
|
-
import { unshift, push
|
|
10
|
+
import { unshift, push } from 'spica/array';
|
|
11
11
|
|
|
12
12
|
const optspec = {
|
|
13
13
|
'width': [],
|
|
@@ -28,7 +28,7 @@ export const media: MediaParser = lazy(() => creator(10, validate(['![', '!{'],
|
|
|
28
28
|
true)),
|
|
29
29
|
dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]*}/)),
|
|
30
30
|
]))),
|
|
31
|
-
([as, bs]) => bs ? [[join(
|
|
31
|
+
([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]),
|
|
32
32
|
([[text]]) => text === '' || text.trim() !== ''),
|
|
33
33
|
([[text], params], rest, context) => {
|
|
34
34
|
assert(text === text.trim());
|
|
@@ -52,7 +52,7 @@ export const media: MediaParser = lazy(() => creator(10, validate(['![', '!{'],
|
|
|
52
52
|
return fmap(
|
|
53
53
|
link as MediaParser,
|
|
54
54
|
([link]) => [define(link, { target: '_blank' }, [el])])
|
|
55
|
-
(`{ ${INSECURE_URI}${join(
|
|
55
|
+
(`{ ${INSECURE_URI}${params.join('')} }${rest}`, context);
|
|
56
56
|
}))));
|
|
57
57
|
|
|
58
58
|
const bracket: MediaParser.TextParser.BracketParser = lazy(() => union([
|
|
@@ -19,7 +19,7 @@ export const reference: ReferenceParser = lazy(() => creator(validate('[[', ']]'
|
|
|
19
19
|
//label: true,
|
|
20
20
|
//link: true,
|
|
21
21
|
//autolink: true,
|
|
22
|
-
}},
|
|
22
|
+
}}, delimiters: undefined },
|
|
23
23
|
subsequence([
|
|
24
24
|
abbr,
|
|
25
25
|
focus(/^\^[^\S\n]*/, source => [['', source], '']),
|
|
@@ -6,7 +6,7 @@ import { unsafehtmlentity } from './htmlentity';
|
|
|
6
6
|
import { text as txt } from '../source';
|
|
7
7
|
import { isStartTightNodes } from '../util';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
|
-
import { unshift, push
|
|
9
|
+
import { unshift, push } from 'spica/array';
|
|
10
10
|
|
|
11
11
|
export const ruby: RubyParser = lazy(() => creator(validate('[', ')', '\n', bind(verify(
|
|
12
12
|
sequence([
|
|
@@ -39,8 +39,8 @@ export const ruby: RubyParser = lazy(() => creator(validate('[', ')', '\n', bind
|
|
|
39
39
|
default:
|
|
40
40
|
assert(rubies.length > 0);
|
|
41
41
|
return [[html('ruby', attributes(texts, rubies), defrag(push(unshift(
|
|
42
|
-
[join(
|
|
43
|
-
[html('rp', '('), html('rt', join(
|
|
42
|
+
[texts.join(' ')],
|
|
43
|
+
[html('rp', '('), html('rt', rubies.join(' ').trim()), html('rp', ')')]), tail)))
|
|
44
44
|
], rest];
|
|
45
45
|
}
|
|
46
46
|
}))));
|
|
@@ -74,7 +74,7 @@ const text: RubyParser.TextParser = creator((source, context) => {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
return join(
|
|
77
|
+
return acc.join('').trimStart()
|
|
78
78
|
? [[acc], '']
|
|
79
79
|
: undefined;
|
|
80
80
|
});
|
|
@@ -157,6 +157,7 @@ describe('Unit: parser/inline', () => {
|
|
|
157
157
|
assert.deepStrictEqual(inspect(parser('<http://host>')), [['<', '<a href="http://host" target="_blank">http://host</a>', '>'], '']);
|
|
158
158
|
assert.deepStrictEqual(inspect(parser('<<small>a<</small>')), [['<', '<small>a<</small>'], '']);
|
|
159
159
|
assert.deepStrictEqual(inspect(parser('<sup><sub>a</sub>')), [['<', 'sup', '>', '<sub>a</sub>'], '']);
|
|
160
|
+
assert.deepStrictEqual(inspect(parser('*<small>*`</small>`')), [['<em><small></em>', '<code data-src="`</small>`"></small></code>'], '']);
|
|
160
161
|
assert.deepStrictEqual(inspect(parser('[~http://host')), [['[', '~', '<a href="http://host" target="_blank">http://host</a>'], '']);
|
|
161
162
|
assert.deepStrictEqual(inspect(parser('[~a@b')), [['[', '~', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
|
|
162
163
|
assert.deepStrictEqual(inspect(parser('[~~a~~]')), [['[', '<del>a</del>', ']'], '']);
|
|
@@ -2,7 +2,7 @@ import { Infinity, Set, Map } from 'spica/global';
|
|
|
2
2
|
import { number as calculate, isFixed } from '../inline/extension/label';
|
|
3
3
|
import { define } from 'typed-dom/dom';
|
|
4
4
|
import { MultiMap } from 'spica/multimap';
|
|
5
|
-
import { push
|
|
5
|
+
import { push } from 'spica/array';
|
|
6
6
|
|
|
7
7
|
export function* figure(
|
|
8
8
|
target: ParentNode & Node,
|
|
@@ -85,7 +85,7 @@ export function* figure(
|
|
|
85
85
|
let number = calculate(
|
|
86
86
|
label,
|
|
87
87
|
numbers.has(group) && !isFixed(label)
|
|
88
|
-
?
|
|
88
|
+
? numbers.get(group)!.split('.').slice(0, bases.length).join('.')
|
|
89
89
|
: base);
|
|
90
90
|
assert(def.matches('figure') || number.endsWith('.0'));
|
|
91
91
|
if (number.endsWith('.0')) {
|
|
@@ -94,19 +94,18 @@ export function* figure(
|
|
|
94
94
|
if (group !== '$' || tagName === 'FIGURE' && def.firstChild) continue;
|
|
95
95
|
if (number.startsWith('0.')) {
|
|
96
96
|
assert(number.endsWith('.0'));
|
|
97
|
-
number =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
'.');
|
|
97
|
+
number = index.slice(0)
|
|
98
|
+
.reduce((ns, _, i, xs) => {
|
|
99
|
+
i === ns.length
|
|
100
|
+
? xs.length = i
|
|
101
|
+
: ns[i] = +ns[i] > +xs[i]
|
|
102
|
+
? ns[i]
|
|
103
|
+
: +ns[i] === 0
|
|
104
|
+
? xs[i]
|
|
105
|
+
: `${+xs[i] + 1}`;
|
|
106
|
+
return ns;
|
|
107
|
+
}, number.split('.'))
|
|
108
|
+
.join('.');
|
|
110
109
|
}
|
|
111
110
|
base = number;
|
|
112
111
|
bases = index = base.split('.');
|
|
@@ -184,8 +183,8 @@ function increment(bases: readonly string[], el: HTMLHeadingElement): string {
|
|
|
184
183
|
const index = (+el.tagName[1] - 1 || 1) - 1;
|
|
185
184
|
assert(index >= 0);
|
|
186
185
|
return index + 1 < bases.length
|
|
187
|
-
?
|
|
188
|
-
|
|
186
|
+
? bases.slice(0, index + 2)
|
|
187
|
+
.map((v, i) => {
|
|
189
188
|
switch (true) {
|
|
190
189
|
case i < index:
|
|
191
190
|
return v;
|
|
@@ -194,8 +193,8 @@ function increment(bases: readonly string[], el: HTMLHeadingElement): string {
|
|
|
194
193
|
default:
|
|
195
194
|
return 0;
|
|
196
195
|
}
|
|
197
|
-
})
|
|
198
|
-
'.')
|
|
196
|
+
})
|
|
197
|
+
.join('.')
|
|
199
198
|
: '';
|
|
200
199
|
}
|
|
201
200
|
|
package/src/parser/util.ts
CHANGED
|
@@ -10,9 +10,9 @@ import { push } from 'spica/array';
|
|
|
10
10
|
|
|
11
11
|
export function blank(prefix: '' | RegExp, suffix: string | RegExp): RegExp {
|
|
12
12
|
return new RegExp(String.raw
|
|
13
|
-
|
|
13
|
+
`^(?:${
|
|
14
14
|
prefix && prefix.source
|
|
15
|
-
}(?:\\\s|[^\S\n]
|
|
15
|
+
}(?:\\\s|[^\S\n]|\n|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)*)?${
|
|
16
16
|
typeof suffix === 'string' ? suffix.replace(/[*+()\[\]]/g, '\\$&') : suffix.source
|
|
17
17
|
}`);
|
|
18
18
|
}
|