securemark 0.224.1 → 0.226.0
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 +16 -0
- package/design.md +5 -11
- package/dist/securemark.js +61 -46
- package/markdown.d.ts +1 -0
- package/package-lock.json +1 -1
- package/package.json +1 -1
- package/src/combinator/control/manipulation/scope.ts +1 -0
- package/src/parser/api/parse.test.ts +0 -3
- package/src/parser/inline/deletion.test.ts +0 -2
- package/src/parser/inline/deletion.ts +2 -2
- package/src/parser/inline/emphasis.test.ts +8 -5
- package/src/parser/inline/emphasis.ts +2 -2
- package/src/parser/inline/emstrong.ts +8 -8
- package/src/parser/inline/html.ts +3 -3
- package/src/parser/inline/insertion.test.ts +0 -2
- package/src/parser/inline/insertion.ts +2 -2
- package/src/parser/inline/mark.test.ts +6 -5
- package/src/parser/inline/mark.ts +2 -2
- package/src/parser/inline/math.test.ts +43 -33
- package/src/parser/inline/math.ts +5 -7
- package/src/parser/inline/ruby.ts +5 -5
- package/src/parser/inline/strong.test.ts +9 -7
- package/src/parser/inline/strong.ts +2 -2
- package/src/parser/inline.test.ts +4 -6
- package/src/parser/source/escapable.test.ts +9 -1
- package/src/parser/source/escapable.ts +7 -1
- package/src/parser/source/text.test.ts +2 -3
- package/src/parser/source/unescapable.test.ts +9 -0
- package/src/parser/util.ts +26 -41
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.226.0
|
|
4
|
+
|
|
5
|
+
- Improve math parser.
|
|
6
|
+
|
|
7
|
+
## 0.225.2
|
|
8
|
+
|
|
9
|
+
- Refactoring.
|
|
10
|
+
|
|
11
|
+
## 0.225.1
|
|
12
|
+
|
|
13
|
+
- Refactoring.
|
|
14
|
+
|
|
15
|
+
## 0.225.0
|
|
16
|
+
|
|
17
|
+
- Refine some parsers to disallow trailing whitespace.
|
|
18
|
+
|
|
3
19
|
## 0.224.1
|
|
4
20
|
|
|
5
21
|
- Refactoring.
|
package/design.md
CHANGED
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
|
|
70
70
|
### 自己完結性
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
ドキュメントはすべて初期(共通)構成の閲覧環境で閲覧できなければならない。
|
|
73
73
|
よって閲覧に拡張機能等の追加が必要となってはならない
|
|
74
74
|
|
|
75
75
|
ゆえにドキュメントはサードパーティツールなど自己完結性を損なうツールの使用をサポートしない。
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
|
|
140
140
|
オートリンクは原則としてコピー&ペーストによる引用等を経た際にその解釈が変わってはならない。
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
ゆえにハッシュタグ構文は構文が表示文字列と一致する構文であるオートリンク構文としてのみ構文化され、表示文字列からの構文の範囲の特定が不可能となる通常の構文を持たない。
|
|
143
143
|
|
|
144
144
|
### 自動附番
|
|
145
145
|
|
|
@@ -148,12 +148,6 @@
|
|
|
148
148
|
ゆえに参照箇所に実体を記述する注釈構文および識別に文字列を使用する図表構文を採用し、その表示方法は任意とする。
|
|
149
149
|
脚注構文は附番が手作業となり参照と実体の対応の管理が困難であるため不採用とし注釈構文により生成可能とする。
|
|
150
150
|
|
|
151
|
-
### 羅列的知識への非依存
|
|
152
|
-
|
|
153
|
-
構文はその使用のために羅列的知識を求めてはならない。
|
|
154
|
-
|
|
155
|
-
ゆえに構文はHTMLエンティティの参照の有効性を検査しない。
|
|
156
|
-
|
|
157
151
|
### テンプレート対応
|
|
158
152
|
|
|
159
153
|
ソーステキストは自身をテンプレートとして別のソーステキストを生成するための構文を使用できなければならない。
|
|
@@ -277,7 +271,7 @@ CodeMirrorが素では速いがVimModeでは数万文字程度でも耐え難く
|
|
|
277
271
|
### バックトラック
|
|
278
272
|
|
|
279
273
|
SecuremarkのAnnotation構文に典型的であるようにスコープの生成規則を変える構文が存在する場合文脈の相違から解析結果を再利用不能な(`αA'β | αAB`)バックトラックが再帰的に生じ、このような言語を線形時間で解析することは基本的に不可能であり直ちに文脈を確定する任意の構文または記号の前に文脈の差異が生じない(`αAβ | αAB`)場合のみ再利用可能なバックトラックにより線形時間で解析できると思われる。
|
|
280
|
-
このため線形時間で解析可能な文法に制約されるCommonMark
|
|
274
|
+
このため線形時間で解析可能な文法に制約されるCommonMarkがこの制約を破らずこのような文脈不確定文法を導入することは不可能であるという拡張性の限界が存在する。
|
|
281
275
|
|
|
282
276
|
### 標準化
|
|
283
277
|
|
|
@@ -285,8 +279,8 @@ Markdownのように自然言語と自身の文法を分離する汎用構造が
|
|
|
285
279
|
このためCommonMarkは拡張構文を標準化した次期標準仕様との互換性を確保する役には立たずその有用性は構文の拡張を考慮しない範囲での効率的な実装方法の例示およびテストケースの集積による個別実装の支援ならびにその結果としての限定的互換性にとどまる。
|
|
286
280
|
さらにCommonMarkは前述の解析時間の制約から拡張性が低く、高度な構文や機能の実装可能性を考慮していないことから拡張仕様において準拠すべき技術的正当性もない。
|
|
287
281
|
|
|
288
|
-
よってMarkdown
|
|
289
|
-
MarkdownはGFM
|
|
282
|
+
よってMarkdownの標準化は後方互換性確保が不可能であることから発展性がなくスナップショット以上の技術的意味を持たない。
|
|
283
|
+
MarkdownはGFMのように最初から高機能で完成度の高い拡張不要な独自実装のほうが標準としての互換性を確保でき、構文に曖昧さがない形式言語と異なりまず最小限の標準仕様を策定しのちに拡張していく通常の標準化方法が適さない特殊な言語である。
|
|
290
284
|
|
|
291
285
|
### トランスクルージョン
|
|
292
286
|
|
package/dist/securemark.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.
|
|
1
|
+
/*! securemark v0.226.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
|
|
2
2
|
require = function () {
|
|
3
3
|
function r(e, n, t) {
|
|
4
4
|
function o(i, f) {
|
|
@@ -6966,7 +6966,7 @@ require = function () {
|
|
|
6966
6966
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
6967
6967
|
const array_1 = _dereq_('spica/array');
|
|
6968
6968
|
exports.deletion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('~~'), (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '~~')]), (0, source_1.str)('~~'), false, ([, bs], rest) => [
|
|
6969
|
-
[(0, typed_dom_1.html)('del', (0, typed_dom_1.defrag)((0, util_1.
|
|
6969
|
+
[(0, typed_dom_1.html)('del', (0, typed_dom_1.defrag)((0, util_1.trimNodeEndBR)(bs)))],
|
|
6970
6970
|
rest
|
|
6971
6971
|
], ([as, bs], rest) => [
|
|
6972
6972
|
(0, array_1.unshift)(as, bs),
|
|
@@ -6998,7 +6998,7 @@ require = function () {
|
|
|
6998
6998
|
strong_1.strong,
|
|
6999
6999
|
(0, combinator_1.some)(inline_1.inline, '*')
|
|
7000
7000
|
]))), (0, source_1.str)('*'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
|
|
7001
|
-
[(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(
|
|
7001
|
+
[(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))],
|
|
7002
7002
|
rest
|
|
7003
7003
|
] : [
|
|
7004
7004
|
(0, array_1.unshift)(as, bs),
|
|
@@ -7039,41 +7039,41 @@ require = function () {
|
|
|
7039
7039
|
switch (cs[0]) {
|
|
7040
7040
|
case '*':
|
|
7041
7041
|
return (_a = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '**')]), (ds, rest) => rest.slice(0, 2) === '**' && (0, util_1.isEndTightNodes)(ds) ? [
|
|
7042
|
-
[(0, typed_dom_1.html)('strong', (0, array_1.unshift)([(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(
|
|
7042
|
+
[(0, typed_dom_1.html)('strong', (0, array_1.unshift)([(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))], (0, typed_dom_1.defrag)(ds)))],
|
|
7043
7043
|
rest.slice(2)
|
|
7044
7044
|
] : [
|
|
7045
7045
|
(0, array_1.unshift)([
|
|
7046
7046
|
'**',
|
|
7047
|
-
(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(
|
|
7047
|
+
(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
|
|
7048
7048
|
], ds),
|
|
7049
7049
|
rest
|
|
7050
7050
|
])(rest, context)) !== null && _a !== void 0 ? _a : [
|
|
7051
7051
|
[
|
|
7052
7052
|
'**',
|
|
7053
|
-
(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(
|
|
7053
|
+
(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
|
|
7054
7054
|
],
|
|
7055
7055
|
rest
|
|
7056
7056
|
];
|
|
7057
7057
|
case '**':
|
|
7058
7058
|
return (_b = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '*')]), (ds, rest) => rest.slice(0, 1) === '*' && (0, util_1.isEndTightNodes)(ds) ? [
|
|
7059
|
-
[(0, typed_dom_1.html)('em', (0, array_1.unshift)([(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(
|
|
7059
|
+
[(0, typed_dom_1.html)('em', (0, array_1.unshift)([(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))], (0, typed_dom_1.defrag)(ds)))],
|
|
7060
7060
|
rest.slice(1)
|
|
7061
7061
|
] : [
|
|
7062
7062
|
(0, array_1.unshift)([
|
|
7063
7063
|
'*',
|
|
7064
|
-
(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(
|
|
7064
|
+
(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))
|
|
7065
7065
|
], ds),
|
|
7066
7066
|
rest
|
|
7067
7067
|
])(rest, context)) !== null && _b !== void 0 ? _b : [
|
|
7068
7068
|
[
|
|
7069
7069
|
'*',
|
|
7070
|
-
(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(
|
|
7070
|
+
(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))
|
|
7071
7071
|
],
|
|
7072
7072
|
rest
|
|
7073
7073
|
];
|
|
7074
7074
|
case '***':
|
|
7075
7075
|
return [
|
|
7076
|
-
[(0, typed_dom_1.html)('em', [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(
|
|
7076
|
+
[(0, typed_dom_1.html)('em', [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))])],
|
|
7077
7077
|
rest
|
|
7078
7078
|
];
|
|
7079
7079
|
}
|
|
@@ -7441,11 +7441,11 @@ require = function () {
|
|
|
7441
7441
|
return {};
|
|
7442
7442
|
}
|
|
7443
7443
|
})(), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`)), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
|
|
7444
|
-
[elem(tag, as, (0, util_1.
|
|
7444
|
+
[elem(tag, as, (0, util_1.trimNodeEndBR)((0, typed_dom_1.defrag)(bs)), cs, context)],
|
|
7445
7445
|
rest
|
|
7446
7446
|
])), ([, tag]) => tag)),
|
|
7447
7447
|
(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)('>'), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest) => [
|
|
7448
|
-
[elem(tag, as, (0, util_1.
|
|
7448
|
+
[elem(tag, as, (0, util_1.trimNodeEndBR)((0, typed_dom_1.defrag)(bs)), cs, {})],
|
|
7449
7449
|
rest
|
|
7450
7450
|
], ([as, bs], rest) => as.length === 1 ? [
|
|
7451
7451
|
(0, array_1.unshift)(as, bs),
|
|
@@ -7561,7 +7561,7 @@ require = function () {
|
|
|
7561
7561
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
7562
7562
|
const array_1 = _dereq_('spica/array');
|
|
7563
7563
|
exports.insertion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('++'), (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '++')]), (0, source_1.str)('++'), false, ([, bs], rest) => [
|
|
7564
|
-
[(0, typed_dom_1.html)('ins', (0, typed_dom_1.defrag)((0, util_1.
|
|
7564
|
+
[(0, typed_dom_1.html)('ins', (0, typed_dom_1.defrag)((0, util_1.trimNodeEndBR)(bs)))],
|
|
7565
7565
|
rest
|
|
7566
7566
|
], ([as, bs], rest) => [
|
|
7567
7567
|
(0, array_1.unshift)(as, bs),
|
|
@@ -7733,7 +7733,7 @@ require = function () {
|
|
|
7733
7733
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
7734
7734
|
const array_1 = _dereq_('spica/array');
|
|
7735
7735
|
exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('=='), (0, util_1.startTight)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '==')])), (0, source_1.str)('=='), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
|
|
7736
|
-
[(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)(
|
|
7736
|
+
[(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)(bs))],
|
|
7737
7737
|
rest
|
|
7738
7738
|
] : [
|
|
7739
7739
|
(0, array_1.unshift)(as, bs),
|
|
@@ -7763,8 +7763,8 @@ require = function () {
|
|
|
7763
7763
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
7764
7764
|
const disallowedCommand = /\\(?:begin|tiny|huge|large)(?![0-9a-z])/i;
|
|
7765
7765
|
exports.math = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('$', '$', '\n', (0, combinator_1.rewrite)((0, combinator_1.union)([
|
|
7766
|
-
(0, combinator_1.surround)('$',
|
|
7767
|
-
(0, combinator_1.surround)('$',
|
|
7766
|
+
(0, combinator_1.surround)('$', (0, combinator_1.verify)((0, source_1.str)(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*(?:[\s,.!?()[\]{}]|[^\x00-\x7F])|-[\da-z]|[a-z]+-)(?:\\\$|[\x20-\x23\x25-\x7E])*/i), util_1.isEndTightNodes), /^\$(?![0-9a-z])/i),
|
|
7767
|
+
(0, combinator_1.surround)('$', bracket, '$')
|
|
7768
7768
|
]), (source, {
|
|
7769
7769
|
caches: {math: cache} = {}
|
|
7770
7770
|
}) => {
|
|
@@ -7786,7 +7786,7 @@ require = function () {
|
|
|
7786
7786
|
}))));
|
|
7787
7787
|
const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)('{', (0, combinator_1.some)((0, combinator_1.union)([
|
|
7788
7788
|
bracket,
|
|
7789
|
-
(0, combinator_1.some)(source_1.escsource, /^[{}]/)
|
|
7789
|
+
(0, combinator_1.some)(source_1.escsource, /^(?:[{}]|\\?\n)/)
|
|
7790
7790
|
])), '}', true)));
|
|
7791
7791
|
},
|
|
7792
7792
|
{
|
|
@@ -8051,11 +8051,6 @@ require = function () {
|
|
|
8051
8051
|
const acc = [''];
|
|
8052
8052
|
while (source !== '') {
|
|
8053
8053
|
switch (source[0]) {
|
|
8054
|
-
case ' ':
|
|
8055
|
-
case '\u3000':
|
|
8056
|
-
acc.push('');
|
|
8057
|
-
source = source.slice(1);
|
|
8058
|
-
continue;
|
|
8059
8054
|
case '&': {
|
|
8060
8055
|
const result = (0, htmlentity_1.htmlentity)(source, context);
|
|
8061
8056
|
acc[acc.length - 1] += (0, parser_1.eval)(result, [source[0]])[0];
|
|
@@ -8063,6 +8058,11 @@ require = function () {
|
|
|
8063
8058
|
continue;
|
|
8064
8059
|
}
|
|
8065
8060
|
default: {
|
|
8061
|
+
if (source[0].trimStart() === '') {
|
|
8062
|
+
acc.push('');
|
|
8063
|
+
source = source.slice(1);
|
|
8064
|
+
continue;
|
|
8065
|
+
}
|
|
8066
8066
|
const result = (0, source_1.text)(source, context);
|
|
8067
8067
|
acc[acc.length - 1] += (_a = (0, parser_1.eval)(result)[0]) !== null && _a !== void 0 ? _a : source.slice(0, source.length - (0, parser_1.exec)(result).length);
|
|
8068
8068
|
source = (0, parser_1.exec)(result);
|
|
@@ -8123,7 +8123,7 @@ require = function () {
|
|
|
8123
8123
|
(0, combinator_1.some)(inline_1.inline, '*'),
|
|
8124
8124
|
(0, source_1.str)('*')
|
|
8125
8125
|
]), '**')), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
|
|
8126
|
-
[(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(
|
|
8126
|
+
[(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))],
|
|
8127
8127
|
rest
|
|
8128
8128
|
] : [
|
|
8129
8129
|
(0, array_1.unshift)(as, bs),
|
|
@@ -8642,6 +8642,7 @@ require = function () {
|
|
|
8642
8642
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8643
8643
|
exports.escsource = void 0;
|
|
8644
8644
|
const combinator_1 = _dereq_('../../combinator');
|
|
8645
|
+
const text_1 = _dereq_('./text');
|
|
8645
8646
|
const separator = /[\s\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]/;
|
|
8646
8647
|
exports.escsource = (0, combinator_1.creator)(source => {
|
|
8647
8648
|
if (source === '')
|
|
@@ -8661,9 +8662,11 @@ require = function () {
|
|
|
8661
8662
|
source.slice(2)
|
|
8662
8663
|
];
|
|
8663
8664
|
default:
|
|
8665
|
+
const b = source[0] !== '\n' && source[0].trimStart() === '';
|
|
8666
|
+
const i = b ? source.search(text_1.nonWhitespace) : 1;
|
|
8664
8667
|
return [
|
|
8665
|
-
[source.slice(0,
|
|
8666
|
-
source.slice(
|
|
8668
|
+
[source.slice(0, i)],
|
|
8669
|
+
source.slice(i)
|
|
8667
8670
|
];
|
|
8668
8671
|
}
|
|
8669
8672
|
default:
|
|
@@ -8674,7 +8677,10 @@ require = function () {
|
|
|
8674
8677
|
}
|
|
8675
8678
|
});
|
|
8676
8679
|
},
|
|
8677
|
-
{
|
|
8680
|
+
{
|
|
8681
|
+
'../../combinator': 30,
|
|
8682
|
+
'./text': 135
|
|
8683
|
+
}
|
|
8678
8684
|
],
|
|
8679
8685
|
133: [
|
|
8680
8686
|
function (_dereq_, module, exports) {
|
|
@@ -8886,7 +8892,7 @@ require = function () {
|
|
|
8886
8892
|
function (_dereq_, module, exports) {
|
|
8887
8893
|
'use strict';
|
|
8888
8894
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8889
|
-
exports.stringify = exports.
|
|
8895
|
+
exports.stringify = exports.trimNodeEndBR = exports.trimNodeEnd = exports.trimNode = exports.isEndTightNodes = exports.isStartTightNodes = exports.startTight = exports.isStartLoose = exports.startLoose = exports.visualize = void 0;
|
|
8890
8896
|
const global_1 = _dereq_('spica/global');
|
|
8891
8897
|
const parser_1 = _dereq_('../combinator/data/parser');
|
|
8892
8898
|
const combinator_1 = _dereq_('../combinator');
|
|
@@ -9020,17 +9026,21 @@ require = function () {
|
|
|
9020
9026
|
function isEndTightNodes(nodes) {
|
|
9021
9027
|
if (nodes.length === 0)
|
|
9022
9028
|
return true;
|
|
9023
|
-
|
|
9024
|
-
|
|
9029
|
+
for (let i = nodes.length; i--;) {
|
|
9030
|
+
const node = nodes[i];
|
|
9031
|
+
if (typeof node === 'object' && node.className === 'comment')
|
|
9032
|
+
continue;
|
|
9033
|
+
return isVisible(node, -1);
|
|
9034
|
+
}
|
|
9035
|
+
return false;
|
|
9025
9036
|
}
|
|
9026
9037
|
exports.isEndTightNodes = isEndTightNodes;
|
|
9027
|
-
function isVisible(node,
|
|
9028
|
-
if (!node)
|
|
9029
|
-
return false;
|
|
9038
|
+
function isVisible(node, strpos) {
|
|
9030
9039
|
switch (typeof node) {
|
|
9031
9040
|
case 'string':
|
|
9032
|
-
const char =
|
|
9041
|
+
const char = node && strpos !== global_1.undefined ? node[strpos >= 0 ? strpos : node.length + strpos] : node;
|
|
9033
9042
|
switch (char) {
|
|
9043
|
+
case '':
|
|
9034
9044
|
case ' ':
|
|
9035
9045
|
case '\t':
|
|
9036
9046
|
case '\n':
|
|
@@ -9057,26 +9067,31 @@ require = function () {
|
|
|
9057
9067
|
}
|
|
9058
9068
|
exports.trimNode = trimNode;
|
|
9059
9069
|
function trimNodeStart(nodes) {
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9070
|
+
for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[0], 0);) {
|
|
9071
|
+
if (nodes.length === 1 && typeof node === 'object' && node.className === 'indexer')
|
|
9072
|
+
break;
|
|
9073
|
+
if (typeof node === 'object' && node.className === 'comment')
|
|
9074
|
+
break;
|
|
9075
|
+
if (typeof node === 'string') {
|
|
9076
|
+
const pos = node.length - node.trimStart().length;
|
|
9064
9077
|
if (pos > 0) {
|
|
9065
|
-
nodes[0] =
|
|
9078
|
+
nodes[0] = node.slice(pos);
|
|
9066
9079
|
break;
|
|
9067
9080
|
}
|
|
9068
9081
|
}
|
|
9069
|
-
nodes.
|
|
9082
|
+
nodes.shift();
|
|
9070
9083
|
}
|
|
9071
|
-
return
|
|
9084
|
+
return nodes;
|
|
9072
9085
|
}
|
|
9073
9086
|
function trimNodeEnd(nodes) {
|
|
9074
9087
|
const skip = nodes.length > 0 && typeof nodes[nodes.length - 1] === 'object' && nodes[nodes.length - 1]['className'] === 'indexer' ? [nodes.pop()] : [];
|
|
9075
|
-
for (let
|
|
9076
|
-
if (typeof
|
|
9077
|
-
|
|
9088
|
+
for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[nodes.length - 1], -1);) {
|
|
9089
|
+
if (typeof node === 'object' && node.className === 'comment')
|
|
9090
|
+
break;
|
|
9091
|
+
if (typeof node === 'string') {
|
|
9092
|
+
const pos = node.trimEnd().length;
|
|
9078
9093
|
if (pos > 0) {
|
|
9079
|
-
nodes[nodes.length - 1] =
|
|
9094
|
+
nodes[nodes.length - 1] = node.slice(0, pos);
|
|
9080
9095
|
break;
|
|
9081
9096
|
}
|
|
9082
9097
|
}
|
|
@@ -9085,13 +9100,13 @@ require = function () {
|
|
|
9085
9100
|
return (0, array_1.push)(nodes, skip);
|
|
9086
9101
|
}
|
|
9087
9102
|
exports.trimNodeEnd = trimNodeEnd;
|
|
9088
|
-
function
|
|
9103
|
+
function trimNodeEndBR(nodes) {
|
|
9089
9104
|
if (nodes.length === 0)
|
|
9090
9105
|
return nodes;
|
|
9091
9106
|
const node = nodes[nodes.length - 1];
|
|
9092
9107
|
return typeof node === 'object' && node.tagName === 'BR' ? (0, array_1.pop)(nodes)[0] : nodes;
|
|
9093
9108
|
}
|
|
9094
|
-
exports.
|
|
9109
|
+
exports.trimNodeEndBR = trimNodeEndBR;
|
|
9095
9110
|
function stringify(nodes) {
|
|
9096
9111
|
let acc = '';
|
|
9097
9112
|
for (let i = 0; i < nodes.length; ++i) {
|
package/markdown.d.ts
CHANGED
package/package-lock.json
CHANGED
package/package.json
CHANGED
|
@@ -23,6 +23,7 @@ export function focus<T>(scope: string | RegExp, parser: Parser<T>): Parser<T> {
|
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
//export function rewrite<T, C extends Ctx, D extends Parser<unknown, C>[]>(scope: Parser<unknown, C, D>, parser: Parser<T, C, never>): Parser<T, C, D>;
|
|
26
27
|
export function rewrite<P extends Parser<unknown>>(scope: Parser<unknown, Context<P>>, parser: P): P;
|
|
27
28
|
export function rewrite<T>(scope: Parser<unknown>, parser: Parser<T>): Parser<T> {
|
|
28
29
|
assert(scope);
|
|
@@ -60,9 +60,6 @@ describe('Unit: parser/api/parse', () => {
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
it('linebreak', () => {
|
|
63
|
-
assert.deepStrictEqual(
|
|
64
|
-
[...parse('*a\n*\nb').children].map(el => el.outerHTML),
|
|
65
|
-
['<p><em>a</em><br>b</p>']);
|
|
66
63
|
assert.deepStrictEqual(
|
|
67
64
|
[...parse('\\ ').children].map(el => el.outerHTML),
|
|
68
65
|
['<p>\\</p>']);
|
|
@@ -32,8 +32,6 @@ describe('Unit: parser/inline/deletion', () => {
|
|
|
32
32
|
assert.deepStrictEqual(inspect(parser('~~a\\\nb~~')), [['<del>a<span class="linebreak"> </span>b</del>'], '']);
|
|
33
33
|
assert.deepStrictEqual(inspect(parser('~~\\~~~')), [['<del>~</del>'], '']);
|
|
34
34
|
assert.deepStrictEqual(inspect(parser('~~a~~~')), [['<del>a</del>'], '~']);
|
|
35
|
-
assert.deepStrictEqual(inspect(parser('~~~a~~')), [['<del>~a</del>'], '']);
|
|
36
|
-
assert.deepStrictEqual(inspect(parser('~~~a~~~')), [['<del>~a</del>'], '~']);
|
|
37
35
|
});
|
|
38
36
|
|
|
39
37
|
it('nest', () => {
|
|
@@ -2,7 +2,7 @@ import { DeletionParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import {
|
|
5
|
+
import { trimNodeEndBR } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
@@ -10,5 +10,5 @@ export const deletion: DeletionParser = lazy(() => creator(surround(
|
|
|
10
10
|
str('~~'),
|
|
11
11
|
union([some(inline, '~~')]),
|
|
12
12
|
str('~~'), false,
|
|
13
|
-
([, bs], rest) => [[html('del', defrag(
|
|
13
|
+
([, bs], rest) => [[html('del', defrag(trimNodeEndBR(bs)))], rest],
|
|
14
14
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -9,9 +9,13 @@ describe('Unit: parser/inline/emphasis', () => {
|
|
|
9
9
|
it('invalid', () => {
|
|
10
10
|
assert.deepStrictEqual(inspect(parser('*')), undefined);
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('*a')), [['*', 'a'], '']);
|
|
12
|
-
assert.deepStrictEqual(inspect(parser('*a
|
|
12
|
+
assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' '], '*']);
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a', '<br>'], '*']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a', ' '], '*']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a', '<span class="linebreak"> </span>'], '*']);
|
|
13
16
|
assert.deepStrictEqual(inspect(parser('*a**b')), [['*', 'a', '**', 'b'], '']);
|
|
14
17
|
assert.deepStrictEqual(inspect(parser('*a**b*')), [['*', 'a', '**', 'b', '*'], '']);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('*a [# b #]*')), [['*', 'a', ' ', '<sup class="comment" title="b"></sup>'], '*']);
|
|
15
19
|
assert.deepStrictEqual(inspect(parser('* *')), undefined);
|
|
16
20
|
assert.deepStrictEqual(inspect(parser('* a*')), undefined);
|
|
17
21
|
assert.deepStrictEqual(inspect(parser('* a *')), undefined);
|
|
@@ -28,17 +32,16 @@ describe('Unit: parser/inline/emphasis', () => {
|
|
|
28
32
|
|
|
29
33
|
it('basic', () => {
|
|
30
34
|
assert.deepStrictEqual(inspect(parser('*a*')), [['<em>a</em>'], '']);
|
|
31
|
-
assert.deepStrictEqual(inspect(parser('*a *')), [['<em>a </em>'], '']);
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('*a\n*')), [['<em>a</em>'], '']);
|
|
33
|
-
assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['<em>a<span class="linebreak"> </span></em>'], '']);
|
|
34
35
|
assert.deepStrictEqual(inspect(parser('*ab*')), [['<em>ab</em>'], '']);
|
|
35
36
|
assert.deepStrictEqual(inspect(parser('*a\nb*')), [['<em>a<br>b</em>'], '']);
|
|
36
37
|
assert.deepStrictEqual(inspect(parser('*a\\\nb*')), [['<em>a<span class="linebreak"> </span>b</em>'], '']);
|
|
37
38
|
assert.deepStrictEqual(inspect(parser('*a**')), [['<em>a</em>'], '*']);
|
|
38
|
-
assert.deepStrictEqual(inspect(parser('*a**b**c*')), [['<em>a<strong>b</strong>c</em>'], '']);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
it('nest', () => {
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('*a**b**c*')), [['<em>a<strong>b</strong>c</em>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('*a**b**c*d')), [['<em>a<strong>b</strong>c</em>'], 'd']);
|
|
44
|
+
assert.deepStrictEqual(inspect(parser('*a[# b #]*')), [['<em>a<sup class="comment" title="b"></sup></em>'], '']);
|
|
42
45
|
assert.deepStrictEqual(inspect(parser('*`a`*')), [['<em><code data-src="`a`">a</code></em>'], '']);
|
|
43
46
|
assert.deepStrictEqual(inspect(parser('*<small>*')), [['<em><small></em>'], '']);
|
|
44
47
|
assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
|
|
@@ -3,7 +3,7 @@ import { union, some, creator, surround, close, lazy } from '../../combinator';
|
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { strong } from './strong';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import { startTight, isEndTightNodes
|
|
6
|
+
import { startTight, isEndTightNodes } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
|
|
@@ -13,6 +13,6 @@ export const emphasis: EmphasisParser = lazy(() => creator(surround(close(
|
|
|
13
13
|
str('*'), false,
|
|
14
14
|
([as, bs, cs], rest) =>
|
|
15
15
|
isEndTightNodes(bs)
|
|
16
|
-
? [[html('em', defrag(
|
|
16
|
+
? [[html('em', defrag(bs))], rest]
|
|
17
17
|
: [unshift(as, bs), cs[0] + rest],
|
|
18
18
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -2,7 +2,7 @@ import { EmStrongParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy, bind } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import { startTight, isEndTightNodes
|
|
5
|
+
import { startTight, isEndTightNodes } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
@@ -18,19 +18,19 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
|
18
18
|
union([some(inline, '**')]),
|
|
19
19
|
(ds, rest) =>
|
|
20
20
|
rest.slice(0, 2) === '**' && isEndTightNodes(ds)
|
|
21
|
-
? [[html('strong', unshift([html('em', defrag(
|
|
22
|
-
: [unshift(['**', html('em', defrag(
|
|
23
|
-
(rest, context) ?? [['**', html('em', defrag(
|
|
21
|
+
? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds)))], rest.slice(2)]
|
|
22
|
+
: [unshift(['**', html('em', defrag(bs))], ds), rest])
|
|
23
|
+
(rest, context) ?? [['**', html('em', defrag(bs))], rest];
|
|
24
24
|
case '**':
|
|
25
25
|
return bind<EmStrongParser>(
|
|
26
26
|
union([some(inline, '*')]),
|
|
27
27
|
(ds, rest) =>
|
|
28
28
|
rest.slice(0, 1) === '*' && isEndTightNodes(ds)
|
|
29
|
-
? [[html('em', unshift([html('strong', defrag(
|
|
30
|
-
: [unshift(['*', html('strong', defrag(
|
|
31
|
-
(rest, context) ?? [['*', html('strong', defrag(
|
|
29
|
+
? [[html('em', unshift([html('strong', defrag(bs))], defrag(ds)))], rest.slice(1)]
|
|
30
|
+
: [unshift(['*', html('strong', defrag(bs))], ds), rest])
|
|
31
|
+
(rest, context) ?? [['*', html('strong', defrag(bs))], rest];
|
|
32
32
|
case '***':
|
|
33
|
-
return [[html('em', [html('strong', defrag(
|
|
33
|
+
return [[html('em', [html('strong', defrag(bs))])], rest];
|
|
34
34
|
}
|
|
35
35
|
assert(false);
|
|
36
36
|
},
|
|
@@ -5,7 +5,7 @@ import { HTMLParser } from '../inline';
|
|
|
5
5
|
import { union, some, validate, context, creator, surround, match, lazy } from '../../combinator';
|
|
6
6
|
import { inline } from '../inline';
|
|
7
7
|
import { str } from '../source';
|
|
8
|
-
import { startLoose,
|
|
8
|
+
import { startLoose, trimNodeEndBR } from '../util';
|
|
9
9
|
import { html as h, defrag } from 'typed-dom';
|
|
10
10
|
import { memoize } from 'spica/memoize';
|
|
11
11
|
import { Cache } from 'spica/cache';
|
|
@@ -66,7 +66,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
66
66
|
some(union([inline]), `</${tag}>`)), `</${tag}>`),
|
|
67
67
|
str(`</${tag}>`), false,
|
|
68
68
|
([as, bs, cs], rest, context) =>
|
|
69
|
-
[[elem(tag, as,
|
|
69
|
+
[[elem(tag, as, trimNodeEndBR(defrag(bs)), cs, context)], rest])),
|
|
70
70
|
([, tag]) => tag)),
|
|
71
71
|
match(
|
|
72
72
|
/^(?=<([a-z]+)(?=[^\S\n]|>))/,
|
|
@@ -78,7 +78,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
78
78
|
startLoose(some(union([inline]), `</${tag}>`), `</${tag}>`),
|
|
79
79
|
str(`</${tag}>`), false,
|
|
80
80
|
([as, bs, cs], rest) =>
|
|
81
|
-
[[elem(tag, as,
|
|
81
|
+
[[elem(tag, as, trimNodeEndBR(defrag(bs)), cs, {})], rest],
|
|
82
82
|
([as, bs], rest) =>
|
|
83
83
|
as.length === 1
|
|
84
84
|
? [unshift(as, bs), rest]
|
|
@@ -32,8 +32,6 @@ describe('Unit: parser/inline/insertion', () => {
|
|
|
32
32
|
assert.deepStrictEqual(inspect(parser('++a\\\nb++')), [['<ins>a<span class="linebreak"> </span>b</ins>'], '']);
|
|
33
33
|
assert.deepStrictEqual(inspect(parser('++\\+++')), [['<ins>+</ins>'], '']);
|
|
34
34
|
assert.deepStrictEqual(inspect(parser('++a+++')), [['<ins>a</ins>'], '+']);
|
|
35
|
-
assert.deepStrictEqual(inspect(parser('+++a++')), [['<ins>+a</ins>'], '']);
|
|
36
|
-
assert.deepStrictEqual(inspect(parser('+++a+++')), [['<ins>+a</ins>'], '+']);
|
|
37
35
|
});
|
|
38
36
|
|
|
39
37
|
it('nest', () => {
|
|
@@ -2,7 +2,7 @@ import { InsertionParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import {
|
|
5
|
+
import { trimNodeEndBR } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
@@ -10,5 +10,5 @@ export const insertion: InsertionParser = lazy(() => creator(surround(
|
|
|
10
10
|
str('++'),
|
|
11
11
|
union([some(inline, '++')]),
|
|
12
12
|
str('++'), false,
|
|
13
|
-
([, bs], rest) => [[html('ins', defrag(
|
|
13
|
+
([, bs], rest) => [[html('ins', defrag(trimNodeEndBR(bs)))], rest],
|
|
14
14
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -12,7 +12,11 @@ describe('Unit: parser/inline/mark', () => {
|
|
|
12
12
|
assert.deepStrictEqual(inspect(parser('==')), undefined);
|
|
13
13
|
assert.deepStrictEqual(inspect(parser('==a')), [['==', 'a'], '']);
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('==a=')), [['==', 'a', '='], '']);
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('==a
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' '], '==']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('==a\n==')), [['==', 'a', '<br>'], '==']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('==a\\ ==')), [['==', 'a', ' '], '==']);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('==a\\\n==')), [['==', 'a', '<span class="linebreak"> </span>'], '==']);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('==a [# b #]==')), [['==', 'a', ' ', '<sup class="comment" title="b"></sup>'], '==']);
|
|
16
20
|
assert.deepStrictEqual(inspect(parser('== ==')), undefined);
|
|
17
21
|
assert.deepStrictEqual(inspect(parser('== a==')), undefined);
|
|
18
22
|
assert.deepStrictEqual(inspect(parser('== a ==')), undefined);
|
|
@@ -26,17 +30,14 @@ describe('Unit: parser/inline/mark', () => {
|
|
|
26
30
|
it('basic', () => {
|
|
27
31
|
assert.deepStrictEqual(inspect(parser('==a==')), [['<mark>a</mark>'], '']);
|
|
28
32
|
assert.deepStrictEqual(inspect(parser('==ab==')), [['<mark>ab</mark>'], '']);
|
|
29
|
-
assert.deepStrictEqual(inspect(parser('==a ==')), [['<mark>a </mark>'], '']);
|
|
30
|
-
assert.deepStrictEqual(inspect(parser('==a\n==')), [['<mark>a</mark>'], '']);
|
|
31
33
|
assert.deepStrictEqual(inspect(parser('==a\nb==')), [['<mark>a<br>b</mark>'], '']);
|
|
32
34
|
assert.deepStrictEqual(inspect(parser('==a\\\nb==')), [['<mark>a<span class="linebreak"> </span>b</mark>'], '']);
|
|
33
35
|
assert.deepStrictEqual(inspect(parser('==\\===')), [['<mark>=</mark>'], '']);
|
|
34
36
|
assert.deepStrictEqual(inspect(parser('==a===')), [['<mark>a</mark>'], '=']);
|
|
35
|
-
assert.deepStrictEqual(inspect(parser('===a==')), [['<mark>=a</mark>'], '']);
|
|
36
|
-
assert.deepStrictEqual(inspect(parser('===a===')), [['<mark>=a</mark>'], '=']);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('nest', () => {
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('==a[# b #]==')), [['<mark>a<sup class="comment" title="b"></sup></mark>'], '']);
|
|
40
41
|
assert.deepStrictEqual(inspect(parser('==*==a==*==')), [['<mark><em><mark>a</mark></em></mark>'], '']);
|
|
41
42
|
});
|
|
42
43
|
|
|
@@ -2,7 +2,7 @@ import { MarkParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import { startTight, isEndTightNodes
|
|
5
|
+
import { startTight, isEndTightNodes } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
@@ -12,6 +12,6 @@ export const mark: MarkParser = lazy(() => creator(surround(
|
|
|
12
12
|
str('=='), false,
|
|
13
13
|
([as, bs, cs], rest) =>
|
|
14
14
|
isEndTightNodes(bs)
|
|
15
|
-
? [[html('mark', defrag(
|
|
15
|
+
? [[html('mark', defrag(bs))], rest]
|
|
16
16
|
: [unshift(as, bs), cs[0] + rest],
|
|
17
17
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -11,31 +11,29 @@ describe('Unit: parser/inline/math', () => {
|
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('$')), undefined);
|
|
12
12
|
assert.deepStrictEqual(inspect(parser('$$')), undefined);
|
|
13
13
|
assert.deepStrictEqual(inspect(parser('$$$')), undefined);
|
|
14
|
-
assert.deepStrictEqual(inspect(parser('$0$')), undefined);
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('$0
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('$
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('$0
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('$0
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('$0
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('$0-
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('$0+
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('$0 $')), undefined);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('$0.$')), undefined);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('$1,000.99.$')), undefined);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('$0(a)$')), undefined);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('$0[a]$')), undefined);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('$0{a}$')), undefined);
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('$0 - $')), undefined);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('$0 + $')), undefined);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('$-0$')), undefined);
|
|
23
23
|
assert.deepStrictEqual(inspect(parser('$-0$-1')), undefined);
|
|
24
24
|
assert.deepStrictEqual(inspect(parser('$-a$')), undefined);
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('$-a$-b')), undefined);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser('$a $')), undefined);
|
|
26
27
|
assert.deepStrictEqual(inspect(parser('$a-b$')), undefined);
|
|
27
28
|
assert.deepStrictEqual(inspect(parser('$a-b$c-d')), undefined);
|
|
28
|
-
assert.deepStrictEqual(inspect(parser('$a+b$')), undefined);
|
|
29
|
-
assert.deepStrictEqual(inspect(parser('$a*b$')), undefined);
|
|
30
|
-
assert.deepStrictEqual(inspect(parser('$a/b$')), undefined);
|
|
31
|
-
assert.deepStrictEqual(inspect(parser('$a[b]$')), undefined);
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('$a{b}$')), undefined);
|
|
33
29
|
assert.deepStrictEqual(inspect(parser('$a$b')), undefined);
|
|
34
30
|
assert.deepStrictEqual(inspect(parser('$a$b$')), undefined);
|
|
35
31
|
assert.deepStrictEqual(inspect(parser('$ $')), undefined);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('$ a$')), undefined);
|
|
33
|
+
assert.deepStrictEqual(inspect(parser('$ a $')), undefined);
|
|
36
34
|
assert.deepStrictEqual(inspect(parser('$\n$')), undefined);
|
|
37
|
-
assert.deepStrictEqual(inspect(parser('$a
|
|
38
|
-
assert.deepStrictEqual(inspect(parser('$a
|
|
35
|
+
assert.deepStrictEqual(inspect(parser('$a\\$\nb$')), undefined);
|
|
36
|
+
assert.deepStrictEqual(inspect(parser('$a\\$\\\nb$')), undefined);
|
|
39
37
|
assert.deepStrictEqual(inspect(parser('${')), undefined);
|
|
40
38
|
assert.deepStrictEqual(inspect(parser('${a')), undefined);
|
|
41
39
|
assert.deepStrictEqual(inspect(parser('${$')), undefined);
|
|
@@ -47,8 +45,8 @@ describe('Unit: parser/inline/math', () => {
|
|
|
47
45
|
assert.deepStrictEqual(inspect(parser('${a}b}$')), undefined);
|
|
48
46
|
assert.deepStrictEqual(inspect(parser('${\\}$')), undefined);
|
|
49
47
|
assert.deepStrictEqual(inspect(parser('${\n}$')), undefined);
|
|
50
|
-
assert.deepStrictEqual(inspect(parser('${a
|
|
51
|
-
assert.deepStrictEqual(inspect(parser('${a
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('${a\\$\nb}$')), undefined);
|
|
49
|
+
assert.deepStrictEqual(inspect(parser('${a\\$\\\nb}$')), undefined);
|
|
52
50
|
assert.deepStrictEqual(inspect(parser('${\\begin}$')), [['<span class="invalid" translate="no">${\\begin}$</span>'], '']);
|
|
53
51
|
assert.deepStrictEqual(inspect(parser('${\\Huge}$')), [['<span class="invalid" translate="no">${\\Huge}$</span>'], '']);
|
|
54
52
|
assert.deepStrictEqual(inspect(parser('${a}b$')), undefined);
|
|
@@ -56,29 +54,26 @@ describe('Unit: parser/inline/math', () => {
|
|
|
56
54
|
});
|
|
57
55
|
|
|
58
56
|
it('basic', () => {
|
|
59
|
-
assert.deepStrictEqual(inspect(parser('$
|
|
60
|
-
assert.deepStrictEqual(inspect(parser('$
|
|
61
|
-
assert.deepStrictEqual(inspect(parser('$
|
|
62
|
-
assert.deepStrictEqual(inspect(parser('$
|
|
63
|
-
assert.deepStrictEqual(inspect(parser('$
|
|
64
|
-
assert.deepStrictEqual(inspect(parser('$
|
|
65
|
-
assert.deepStrictEqual(inspect(parser('${a b}$')), [['<span class="math" translate="no" data-src="${a b}$">${a b}$</span>'], '']);
|
|
66
|
-
assert.deepStrictEqual(inspect(parser('${a }$')), [['<span class="math" translate="no" data-src="${a }$">${a }$</span>'], '']);
|
|
67
|
-
assert.deepStrictEqual(inspect(parser('${ a}$')), [['<span class="math" translate="no" data-src="${ a}$">${ a}$</span>'], '']);
|
|
68
|
-
assert.deepStrictEqual(inspect(parser('${ a }$')), [['<span class="math" translate="no" data-src="${ a }$">${ a }$</span>'], '']);
|
|
69
|
-
assert.deepStrictEqual(inspect(parser('${$}$')), [['<span class="math" translate="no" data-src="${$}$">${$}$</span>'], '']);
|
|
70
|
-
assert.deepStrictEqual(inspect(parser('${\\a}$')), [['<span class="math" translate="no" data-src="${\\a}$">${\\a}$</span>'], '']);
|
|
71
|
-
assert.deepStrictEqual(inspect(parser('${\\$}$')), [['<span class="math" translate="no" data-src="${\\$}$">${\\$}$</span>'], '']);
|
|
72
|
-
assert.deepStrictEqual(inspect(parser('${\\\\}$')), [['<span class="math" translate="no" data-src="${\\\\}$">${\\\\}$</span>'], '']);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('$0$')), [['<span class="math" translate="no" data-src="$0$">$0$</span>'], '']);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('$0$$')), [['<span class="math" translate="no" data-src="$0$">$0$</span>'], '$']);
|
|
59
|
+
assert.deepStrictEqual(inspect(parser('$0-1$')), [['<span class="math" translate="no" data-src="$0-1$">$0-1$</span>'], '']);
|
|
60
|
+
assert.deepStrictEqual(inspect(parser('$0+1$')), [['<span class="math" translate="no" data-src="$0+1$">$0+1$</span>'], '']);
|
|
61
|
+
assert.deepStrictEqual(inspect(parser('$0*1$')), [['<span class="math" translate="no" data-src="$0*1$">$0*1$</span>'], '']);
|
|
62
|
+
assert.deepStrictEqual(inspect(parser('$0/1$')), [['<span class="math" translate="no" data-src="$0/1$">$0/1$</span>'], '']);
|
|
73
63
|
assert.deepStrictEqual(inspect(parser('$a$')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '']);
|
|
64
|
+
assert.deepStrictEqual(inspect(parser('$a$$')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '$']);
|
|
65
|
+
assert.deepStrictEqual(inspect(parser('$a -b$')), [['<span class="math" translate="no" data-src="$a -b$">$a -b$</span>'], '']);
|
|
66
|
+
assert.deepStrictEqual(inspect(parser('$a+b$')), [['<span class="math" translate="no" data-src="$a+b$">$a+b$</span>'], '']);
|
|
67
|
+
assert.deepStrictEqual(inspect(parser('$a*b$')), [['<span class="math" translate="no" data-src="$a*b$">$a*b$</span>'], '']);
|
|
68
|
+
assert.deepStrictEqual(inspect(parser('$a/b$')), [['<span class="math" translate="no" data-src="$a/b$">$a/b$</span>'], '']);
|
|
74
69
|
assert.deepStrictEqual(inspect(parser(`$a'$`)), [[`<span class="math" translate="no" data-src="$a'$">$a'$</span>`], '']);
|
|
75
70
|
assert.deepStrictEqual(inspect(parser(`$a''$`)), [[`<span class="math" translate="no" data-src="$a''$">$a''$</span>`], '']);
|
|
76
71
|
assert.deepStrictEqual(inspect(parser('$a$[A](a)')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '[A](a)']);
|
|
77
|
-
assert.deepStrictEqual(inspect(parser('$a$$')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '$']);
|
|
78
72
|
assert.deepStrictEqual(inspect(parser('$A$')), [['<span class="math" translate="no" data-src="$A$">$A$</span>'], '']);
|
|
79
73
|
assert.deepStrictEqual(inspect(parser('$\\$$')), [['<span class="math" translate="no" data-src="$\\$$">$\\$$</span>'], '']);
|
|
80
74
|
assert.deepStrictEqual(inspect(parser('$\\Pi$')), [['<span class="math" translate="no" data-src="$\\Pi$">$\\Pi$</span>'], '']);
|
|
81
|
-
assert.deepStrictEqual(inspect(parser('$\\
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('$\\ 0$')), [['<span class="math" translate="no" data-src="$\\ 0$">$\\ 0$</span>'], '']);
|
|
76
|
+
assert.deepStrictEqual(inspect(parser('$\\\\0$')), [['<span class="math" translate="no" data-src="$\\\\0$">$\\\\0$</span>'], '']);
|
|
82
77
|
assert.deepStrictEqual(inspect(parser('$|1|$')), [['<span class="math" translate="no" data-src="$|1|$">$|1|$</span>'], '']);
|
|
83
78
|
assert.deepStrictEqual(inspect(parser('$[0,1)$]')), [['<span class="math" translate="no" data-src="$[0,1)$">$[0,1)$</span>'], ']']);
|
|
84
79
|
assert.deepStrictEqual(inspect(parser('$(0, 1]$)')), [['<span class="math" translate="no" data-src="$(0, 1]$">$(0, 1]$</span>'], ')']);
|
|
@@ -90,6 +85,21 @@ describe('Unit: parser/inline/math', () => {
|
|
|
90
85
|
assert.deepStrictEqual(inspect(parser('$f(x)$')), [['<span class="math" translate="no" data-src="$f(x)$">$f(x)$</span>'], '']);
|
|
91
86
|
assert.deepStrictEqual(inspect(parser('$f: x \\to y$')), [['<span class="math" translate="no" data-src="$f: x \\to y$">$f: x \\to y$</span>'], '']);
|
|
92
87
|
assert.deepStrictEqual(inspect(parser('$k$-space')), [['<span class="math" translate="no" data-src="$k$">$k$</span>'], '-space']);
|
|
88
|
+
assert.deepStrictEqual(inspect(parser('${}$')), [['<span class="math" translate="no" data-src="${}$">${}$</span>'], '']);
|
|
89
|
+
assert.deepStrictEqual(inspect(parser('${ }$')), [['<span class="math" translate="no" data-src="${ }$">${ }$</span>'], '']);
|
|
90
|
+
assert.deepStrictEqual(inspect(parser('${a}$')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], '']);
|
|
91
|
+
assert.deepStrictEqual(inspect(parser('${a}$$')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], '$']);
|
|
92
|
+
assert.deepStrictEqual(inspect(parser('${a}$0')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], '0']);
|
|
93
|
+
assert.deepStrictEqual(inspect(parser('${a}$b')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], 'b']);
|
|
94
|
+
assert.deepStrictEqual(inspect(parser('${ab}$')), [['<span class="math" translate="no" data-src="${ab}$">${ab}$</span>'], '']);
|
|
95
|
+
assert.deepStrictEqual(inspect(parser('${a b}$')), [['<span class="math" translate="no" data-src="${a b}$">${a b}$</span>'], '']);
|
|
96
|
+
assert.deepStrictEqual(inspect(parser('${a }$')), [['<span class="math" translate="no" data-src="${a }$">${a }$</span>'], '']);
|
|
97
|
+
assert.deepStrictEqual(inspect(parser('${ a}$')), [['<span class="math" translate="no" data-src="${ a}$">${ a}$</span>'], '']);
|
|
98
|
+
assert.deepStrictEqual(inspect(parser('${ a }$')), [['<span class="math" translate="no" data-src="${ a }$">${ a }$</span>'], '']);
|
|
99
|
+
assert.deepStrictEqual(inspect(parser('${$}$')), [['<span class="math" translate="no" data-src="${$}$">${$}$</span>'], '']);
|
|
100
|
+
assert.deepStrictEqual(inspect(parser('${\\a}$')), [['<span class="math" translate="no" data-src="${\\a}$">${\\a}$</span>'], '']);
|
|
101
|
+
assert.deepStrictEqual(inspect(parser('${\\$}$')), [['<span class="math" translate="no" data-src="${\\$}$">${\\$}$</span>'], '']);
|
|
102
|
+
assert.deepStrictEqual(inspect(parser('${\\\\}$')), [['<span class="math" translate="no" data-src="${\\\\}$">${\\\\}$</span>'], '']);
|
|
93
103
|
});
|
|
94
104
|
|
|
95
105
|
it('nest', () => {
|
|
@@ -8,7 +8,6 @@ const disallowedCommand = /\\(?:begin|tiny|huge|large)(?![0-9a-z])/i;
|
|
|
8
8
|
|
|
9
9
|
export const math: MathParser = lazy(() => creator(validate('$', '$', '\n', rewrite(
|
|
10
10
|
union([
|
|
11
|
-
surround('$', bracket, '$'),
|
|
12
11
|
surround(
|
|
13
12
|
'$',
|
|
14
13
|
verify(
|
|
@@ -17,12 +16,11 @@ export const math: MathParser = lazy(() => creator(validate('$', '$', '\n', rewr
|
|
|
17
16
|
// $[A-z]*- : Label
|
|
18
17
|
// $[A-z]*(?!-) : Math
|
|
19
18
|
// $[\^_[({|] : Math
|
|
20
|
-
// $[#$%&] : Invalid first character in
|
|
21
|
-
|
|
22
|
-
// $[A-z]*\s?[!@#&*+~=`$[]{<] : Incomplete syntax in or around another syntax
|
|
23
|
-
str(/^(?=[\\^_[(|]|[A-Za-z][0-9A-Za-z]*'*[ ~]?(?:\$|([\\^_(|:=<>])(?!\1)))(?:\\\$|[\x20-\x23\x25-\x7E])*/),
|
|
19
|
+
// $[#$%&] : Invalid first character in Latex syntax
|
|
20
|
+
str(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*(?:[\s,.!?()[\]{}]|[^\x00-\x7F])|-[\da-z]|[a-z]+-)(?:\\\$|[\x20-\x23\x25-\x7E])*/i),
|
|
24
21
|
isEndTightNodes),
|
|
25
|
-
/^\$(?![0-
|
|
22
|
+
/^\$(?![0-9a-z])/i),
|
|
23
|
+
surround('$', bracket, '$'),
|
|
26
24
|
]),
|
|
27
25
|
(source, { caches: { math: cache } = {} }) => [[
|
|
28
26
|
cache?.get(source)?.cloneNode(true) ||
|
|
@@ -43,7 +41,7 @@ const bracket: MathParser.BracketParser = lazy(() => creator(surround(
|
|
|
43
41
|
'{',
|
|
44
42
|
some(union([
|
|
45
43
|
bracket,
|
|
46
|
-
some(escsource, /^[{}]/),
|
|
44
|
+
some(escsource, /^(?:[{}]|\\?\n)/),
|
|
47
45
|
])),
|
|
48
46
|
'}',
|
|
49
47
|
true)));
|
|
@@ -51,11 +51,6 @@ const text: RubyParser.TextParser = creator((source, context) => {
|
|
|
51
51
|
while (source !== '') {
|
|
52
52
|
assert(source[0] !== '\n');
|
|
53
53
|
switch (source[0]) {
|
|
54
|
-
case ' ':
|
|
55
|
-
case ' ':
|
|
56
|
-
acc.push('');
|
|
57
|
-
source = source.slice(1);
|
|
58
|
-
continue;
|
|
59
54
|
case '&': {
|
|
60
55
|
const result = htmlentity(source, context);
|
|
61
56
|
acc[acc.length - 1] += eval(result, [source[0]])[0];
|
|
@@ -63,6 +58,11 @@ const text: RubyParser.TextParser = creator((source, context) => {
|
|
|
63
58
|
continue;
|
|
64
59
|
}
|
|
65
60
|
default: {
|
|
61
|
+
if (source[0].trimStart() === '') {
|
|
62
|
+
acc.push('');
|
|
63
|
+
source = source.slice(1);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
66
|
const result = txt(source, context)!;
|
|
67
67
|
assert(result);
|
|
68
68
|
acc[acc.length - 1] += eval(result)[0] ?? source.slice(0, source.length - exec(result).length);
|
|
@@ -10,8 +10,12 @@ describe('Unit: parser/inline/strong', () => {
|
|
|
10
10
|
assert.deepStrictEqual(inspect(parser('**')), undefined);
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('**a')), [['**', 'a'], '']);
|
|
12
12
|
assert.deepStrictEqual(inspect(parser('**a*')), [['**', 'a', '*'], '']);
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('**a
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('**a **')), [['**', 'a', ' '], '**']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('**a\n**')), [['**', 'a', '<br>'], '**']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('**a\\ **')), [['**', 'a', ' '], '**']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['**', 'a', '<span class="linebreak"> </span>'], '**']);
|
|
14
17
|
assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('**a [# b #]**')), [['**', 'a', ' ', '<sup class="comment" title="b"></sup>'], '**']);
|
|
15
19
|
assert.deepStrictEqual(inspect(parser('** **')), undefined);
|
|
16
20
|
assert.deepStrictEqual(inspect(parser('** a**')), undefined);
|
|
17
21
|
assert.deepStrictEqual(inspect(parser('** a **')), undefined);
|
|
@@ -27,18 +31,16 @@ describe('Unit: parser/inline/strong', () => {
|
|
|
27
31
|
|
|
28
32
|
it('basic', () => {
|
|
29
33
|
assert.deepStrictEqual(inspect(parser('**a**')), [['<strong>a</strong>'], '']);
|
|
30
|
-
assert.deepStrictEqual(inspect(parser('**a **')), [['<strong>a </strong>'], '']);
|
|
31
|
-
assert.deepStrictEqual(inspect(parser('**a\n**')), [['<strong>a</strong>'], '']);
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['<strong>a<span class="linebreak"> </span></strong>'], '']);
|
|
33
34
|
assert.deepStrictEqual(inspect(parser('**ab**')), [['<strong>ab</strong>'], '']);
|
|
34
35
|
assert.deepStrictEqual(inspect(parser('**a\nb**')), [['<strong>a<br>b</strong>'], '']);
|
|
35
36
|
assert.deepStrictEqual(inspect(parser('**a\\\nb**')), [['<strong>a<span class="linebreak"> </span>b</strong>'], '']);
|
|
36
|
-
assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
|
|
37
|
-
assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
|
|
38
|
-
assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
|
|
39
37
|
});
|
|
40
38
|
|
|
41
39
|
it('nest', () => {
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('**a[# b #]**')), [['<strong>a<sup class="comment" title="b"></sup></strong>'], '']);
|
|
42
44
|
assert.deepStrictEqual(inspect(parser('**`a`**')), [['<strong><code data-src="`a`">a</code></strong>'], '']);
|
|
43
45
|
assert.deepStrictEqual(inspect(parser('**<small>**')), [['<strong><small></strong>'], '']);
|
|
44
46
|
assert.deepStrictEqual(inspect(parser('**(*a*)**')), [['<strong><span class="paren">(<em>a</em>)</span></strong>'], '']);
|
|
@@ -3,7 +3,7 @@ import { union, some, creator, surround, close, lazy } from '../../combinator';
|
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { emphasis } from './emphasis';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import { startTight, isEndTightNodes
|
|
6
|
+
import { startTight, isEndTightNodes } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
|
|
@@ -13,6 +13,6 @@ export const strong: StrongParser = lazy(() => creator(surround(close(
|
|
|
13
13
|
str('**'), false,
|
|
14
14
|
([as, bs, cs], rest) =>
|
|
15
15
|
isEndTightNodes(bs)
|
|
16
|
-
? [[html('strong', defrag(
|
|
16
|
+
? [[html('strong', defrag(bs))], rest]
|
|
17
17
|
: [unshift(as, bs), cs[0] + rest],
|
|
18
18
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -30,18 +30,16 @@ describe('Unit: parser/inline', () => {
|
|
|
30
30
|
assert.deepStrictEqual(inspect(parser('*a**b*c')), [['*', 'a', '**', 'b', '*', 'c'], '']);
|
|
31
31
|
assert.deepStrictEqual(inspect(parser('*a**b*c*')), [['*', 'a', '**', 'b', '<em>c</em>'], '']);
|
|
32
32
|
assert.deepStrictEqual(inspect(parser('*a**b**')), [['*', 'a', '<strong>b</strong>'], '']);
|
|
33
|
-
assert.deepStrictEqual(inspect(parser('*a
|
|
34
|
-
assert.deepStrictEqual(inspect(parser('*a
|
|
33
|
+
assert.deepStrictEqual(inspect(parser('*a **b***')), [['<em>a <strong>b</strong></em>'], '']);
|
|
34
|
+
assert.deepStrictEqual(inspect(parser('*a **b***c')), [['<em>a <strong>b</strong></em>', 'c'], '']);
|
|
35
35
|
assert.deepStrictEqual(inspect(parser('**a*')), [['**', 'a', '*'], '']);
|
|
36
36
|
assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('**a*b**c')), [['**', 'a', '*', 'b', '**', 'c'], '']);
|
|
38
|
-
assert.deepStrictEqual(inspect(parser('**a
|
|
39
|
-
assert.deepStrictEqual(inspect(parser('**a
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('**a *b***c')), [['<strong>a <em>b</em></strong>', 'c'], '']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('***a*b**')), [['<strong><em>a</em>b</strong>'], '']);
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('***a*b **')), [['**', '<em>a</em>', 'b', ' ', '**'], '']);
|
|
42
41
|
assert.deepStrictEqual(inspect(parser('***a* b**')), [['<strong><em>a</em> b</strong>'], '']);
|
|
43
42
|
assert.deepStrictEqual(inspect(parser('***a**b*')), [['<em><strong>a</strong>b</em>'], '']);
|
|
44
|
-
assert.deepStrictEqual(inspect(parser('***a**b *')), [['*', '<strong>a</strong>', 'b', ' ', '*'], '']);
|
|
45
43
|
assert.deepStrictEqual(inspect(parser('***a** b*')), [['<em><strong>a</strong> b</em>'], '']);
|
|
46
44
|
assert.deepStrictEqual(inspect(parser('***a*')), [['**', '<em>a</em>'], '']);
|
|
47
45
|
assert.deepStrictEqual(inspect(parser('***a**')), [['*', '<strong>a</strong>'], '']);
|
|
@@ -13,7 +13,15 @@ describe('Unit: parser/source/escsource', () => {
|
|
|
13
13
|
it('basic', () => {
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('a')), [['a'], '']);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('ab')), [['ab'], '']);
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('09あいAZaz')), [['09あいAZaz'], '']);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('space', () => {
|
|
20
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
17
25
|
});
|
|
18
26
|
|
|
19
27
|
it('linebreak', () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EscapableSourceParser } from '../source';
|
|
2
2
|
import { creator } from '../../combinator';
|
|
3
|
+
import { nonWhitespace } from './text';
|
|
3
4
|
|
|
4
5
|
const separator = /[\s\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]/;
|
|
5
6
|
|
|
@@ -15,7 +16,12 @@ export const escsource: EscapableSourceParser = creator(source => {
|
|
|
15
16
|
case '\\':
|
|
16
17
|
return [[source.slice(0, 2)], source.slice(2)];
|
|
17
18
|
default:
|
|
18
|
-
|
|
19
|
+
const b = source[0] !== '\n' && source[0].trimStart() === '';
|
|
20
|
+
const i = b
|
|
21
|
+
? source.search(nonWhitespace)
|
|
22
|
+
: 1;
|
|
23
|
+
assert(i > 0);
|
|
24
|
+
return [[source.slice(0, i)], source.slice(i)];
|
|
19
25
|
}
|
|
20
26
|
default:
|
|
21
27
|
return [[source.slice(0, i)], source.slice(i)];
|
|
@@ -12,9 +12,8 @@ describe('Unit: parser/text/text', () => {
|
|
|
12
12
|
|
|
13
13
|
it('basic', () => {
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('a')), [['a'], '']);
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('09')), [['09'], '']);
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('azあい09')), [['az', 'あい', '09'], '']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('ab')), [['ab'], '']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('09あいAZaz')), [['09', 'あい', 'AZaz'], '']);
|
|
18
17
|
assert.deepStrictEqual(inspect(parser('a\nb')), [['a', '<br>', 'b'], '']);
|
|
19
18
|
});
|
|
20
19
|
|
|
@@ -13,6 +13,15 @@ describe('Unit: parser/source/unescapable', () => {
|
|
|
13
13
|
it('basic', () => {
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('a')), [['a'], '']);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('ab')), [['ab'], '']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('09あいAZaz')), [['09', 'あい', 'AZaz'], '']);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('space', () => {
|
|
20
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
16
25
|
});
|
|
17
26
|
|
|
18
27
|
it('linebreak', () => {
|
package/src/parser/util.ts
CHANGED
|
@@ -135,22 +135,21 @@ export function isStartTightNodes(nodes: readonly (HTMLElement | string)[]): boo
|
|
|
135
135
|
}
|
|
136
136
|
export function isEndTightNodes(nodes: readonly (HTMLElement | string)[]): boolean {
|
|
137
137
|
if (nodes.length === 0) return true;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
for (let i = nodes.length; i--;) {
|
|
139
|
+
const node = nodes[i];
|
|
140
|
+
if (typeof node === 'object' && node.className === 'comment') continue;
|
|
141
|
+
return isVisible(node, -1);
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
144
|
}
|
|
145
|
-
function isVisible(node: HTMLElement | string,
|
|
146
|
-
if (!node) return false;
|
|
145
|
+
function isVisible(node: HTMLElement | string, strpos?: number): boolean {
|
|
147
146
|
switch (typeof node) {
|
|
148
147
|
case 'string':
|
|
149
|
-
const char =
|
|
150
|
-
? node
|
|
151
|
-
: node
|
|
152
|
-
assert(char);
|
|
148
|
+
const char = node && strpos !== undefined
|
|
149
|
+
? node[strpos >= 0 ? strpos : node.length + strpos]
|
|
150
|
+
: node;
|
|
153
151
|
switch (char) {
|
|
152
|
+
case '':
|
|
154
153
|
case ' ':
|
|
155
154
|
case '\t':
|
|
156
155
|
case '\n':
|
|
@@ -177,28 +176,19 @@ export function trimNode(nodes: (HTMLElement | string)[]): (HTMLElement | string
|
|
|
177
176
|
return trimNodeStart(trimNodeEnd(nodes));
|
|
178
177
|
}
|
|
179
178
|
function trimNodeStart(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
for (
|
|
186
|
-
let first = nodes[0];
|
|
187
|
-
nodes.length > 0 &&
|
|
188
|
-
!isVisible(first, 0) &&
|
|
189
|
-
!(typeof first === 'object' && first.className === 'comment');
|
|
190
|
-
) {
|
|
191
|
-
assert(nodes.length > 0);
|
|
192
|
-
if (typeof first === 'string') {
|
|
193
|
-
const pos = first.length - first.trimStart().length;
|
|
179
|
+
for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[0], 0);) {
|
|
180
|
+
if (nodes.length === 1 && typeof node === 'object' && node.className === 'indexer') break;
|
|
181
|
+
if (typeof node === 'object' && node.className === 'comment') break;
|
|
182
|
+
if (typeof node === 'string') {
|
|
183
|
+
const pos = node.length - node.trimStart().length;
|
|
194
184
|
if (pos > 0) {
|
|
195
|
-
nodes[0] =
|
|
185
|
+
nodes[0] = node.slice(pos);
|
|
196
186
|
break;
|
|
197
187
|
}
|
|
198
188
|
}
|
|
199
|
-
nodes.
|
|
189
|
+
nodes.shift();
|
|
200
190
|
}
|
|
201
|
-
return
|
|
191
|
+
return nodes;
|
|
202
192
|
}
|
|
203
193
|
export function trimNodeEnd(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
204
194
|
const skip = nodes.length > 0 &&
|
|
@@ -206,17 +196,12 @@ export function trimNodeEnd(nodes: (HTMLElement | string)[]): (HTMLElement | str
|
|
|
206
196
|
nodes[nodes.length - 1]['className'] === 'indexer'
|
|
207
197
|
? [nodes.pop()!]
|
|
208
198
|
: [];
|
|
209
|
-
for (
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
!(typeof last === 'object' && last.className === 'comment');
|
|
214
|
-
) {
|
|
215
|
-
assert(nodes.length > 0);
|
|
216
|
-
if (typeof last === 'string') {
|
|
217
|
-
const pos = last.trimEnd().length;
|
|
199
|
+
for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[nodes.length - 1], -1);) {
|
|
200
|
+
if (typeof node === 'object' && node.className === 'comment') break;
|
|
201
|
+
if (typeof node === 'string') {
|
|
202
|
+
const pos = node.trimEnd().length;
|
|
218
203
|
if (pos > 0) {
|
|
219
|
-
nodes[nodes.length - 1] =
|
|
204
|
+
nodes[nodes.length - 1] = node.slice(0, pos);
|
|
220
205
|
break;
|
|
221
206
|
}
|
|
222
207
|
}
|
|
@@ -224,8 +209,8 @@ export function trimNodeEnd(nodes: (HTMLElement | string)[]): (HTMLElement | str
|
|
|
224
209
|
}
|
|
225
210
|
return push(nodes, skip);
|
|
226
211
|
}
|
|
227
|
-
export function
|
|
228
|
-
export function
|
|
212
|
+
export function trimNodeEndBR<T extends HTMLElement | string>(nodes: T[]): T[];
|
|
213
|
+
export function trimNodeEndBR(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
229
214
|
if (nodes.length === 0) return nodes;
|
|
230
215
|
const node = nodes[nodes.length - 1];
|
|
231
216
|
return typeof node === 'object' && node.tagName === 'BR'
|