securemark 0.284.0 → 0.285.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +191 -82
- package/markdown.d.ts +20 -19
- package/package.json +1 -1
- package/src/combinator/control/constraint/contract.ts +4 -4
- package/src/combinator/control/manipulation/convert.ts +3 -3
- package/src/combinator/control/manipulation/indent.ts +3 -3
- package/src/combinator/control/manipulation/scope.ts +3 -3
- package/src/combinator/control/manipulation/surround.ts +25 -13
- package/src/combinator/data/parser/context.ts +1 -1
- package/src/combinator/data/parser/some.ts +1 -0
- package/src/combinator/data/parser.ts +2 -1
- package/src/parser/api/parse.test.ts +14 -14
- package/src/parser/context.ts +11 -6
- package/src/parser/inline/annotation.ts +2 -2
- package/src/parser/inline/autolink/url.ts +14 -7
- package/src/parser/inline/bracket.test.ts +2 -2
- package/src/parser/inline/deletion.ts +15 -14
- package/src/parser/inline/emphasis.ts +2 -2
- package/src/parser/inline/emstrong.test.ts +115 -0
- package/src/parser/inline/emstrong.ts +71 -37
- package/src/parser/inline/extension/index.ts +14 -10
- package/src/parser/inline/extension/label.ts +1 -1
- package/src/parser/inline/extension/placeholder.ts +2 -2
- package/src/parser/inline/html.ts +2 -2
- package/src/parser/inline/insertion.ts +15 -14
- package/src/parser/inline/italic.test.ts +23 -4
- package/src/parser/inline/italic.ts +16 -15
- package/src/parser/inline/link.ts +3 -3
- package/src/parser/inline/mark.ts +22 -21
- package/src/parser/inline/media.ts +10 -6
- package/src/parser/inline/reference.ts +2 -2
- package/src/parser/inline/ruby.ts +6 -4
- package/src/parser/inline/strong.ts +2 -2
- package/src/parser/inline/template.ts +7 -8
- package/src/parser/inline.test.ts +18 -42
- package/src/parser/inline.ts +4 -4
- package/src/parser/source/text.ts +0 -4
- package/src/parser/util.ts +66 -1
- package/src/parser/visibility.ts +22 -19
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
|
|
2
|
-
import { Recursion } from '../context';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
3
3
|
import { Result, IntermediateParser } from '../../combinator/data/parser';
|
|
4
|
-
import { union, creation, precedence,
|
|
4
|
+
import { union, some, creation, precedence, validate, surround, open, lazy, bind } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { strong } from './strong';
|
|
7
7
|
import { emphasis } from './emphasis';
|
|
8
8
|
import { str } from '../source';
|
|
9
|
-
import {
|
|
9
|
+
import { tightStart, blankWith } from '../visibility';
|
|
10
|
+
import { repeat } from '../util';
|
|
10
11
|
import { html, defrag } from 'typed-dom/dom';
|
|
11
|
-
import { unshift } from 'spica/array';
|
|
12
|
+
import { unshift, push } from 'spica/array';
|
|
12
13
|
|
|
13
14
|
const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
|
|
14
15
|
some(inline, blankWith('**')),
|
|
@@ -27,36 +28,69 @@ const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
|
|
|
27
28
|
])),
|
|
28
29
|
])));
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
31
|
+
// 開閉が明示的でない構文は開閉の不明確な記号による再帰的適用を行わず早く閉じるよう解析しなければならない。
|
|
32
|
+
// このため終端記号の後ろを見て終端を中止し同じ構文を再帰的に適用してはならない。
|
|
33
|
+
export const emstrong: EmStrongParser = lazy(() => creation(1, Recursion.inline, validate('***',
|
|
34
|
+
precedence(0, repeat('***', surround(
|
|
35
|
+
'',
|
|
36
|
+
tightStart(some(union([
|
|
37
|
+
some(inline, blankWith('*')),
|
|
38
|
+
open(some(inline, '*'), inline),
|
|
39
|
+
]))),
|
|
40
|
+
str(/^\*{1,3}/), false,
|
|
41
|
+
([, bs, cs], rest, context): Result<HTMLElement | string, typeof context> => {
|
|
42
|
+
assert(cs.length === 1);
|
|
43
|
+
switch (cs[0]) {
|
|
44
|
+
case '***':
|
|
45
|
+
return [bs, rest];
|
|
46
|
+
case '**':
|
|
47
|
+
return bind<EmphasisParser>(
|
|
48
|
+
subemphasis,
|
|
49
|
+
(ds, rest) =>
|
|
50
|
+
rest.slice(0, 1) === '*'
|
|
51
|
+
? [[html('em', unshift([html('strong', defrag(bs))], defrag(ds))), Command.Separator], rest.slice(1)]
|
|
52
|
+
: [push(unshift(['*', html('strong', defrag(bs))], ds), [Command.Separator]), rest])
|
|
53
|
+
({ source: rest, context }) ?? [['*', html('strong', defrag(bs)), Command.Separator], rest];
|
|
54
|
+
case '*':
|
|
55
|
+
return bind<StrongParser>(
|
|
56
|
+
substrong,
|
|
57
|
+
(ds, rest) =>
|
|
58
|
+
rest.slice(0, 2) === '**'
|
|
59
|
+
? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds))), Command.Separator], rest.slice(2)]
|
|
60
|
+
: [push(unshift(['**', html('em', defrag(bs))], ds), [Command.Separator]), rest])
|
|
61
|
+
({ source: rest, context }) ?? [['**', html('em', defrag(bs)), Command.Separator], rest];
|
|
62
|
+
}
|
|
63
|
+
assert(false);
|
|
64
|
+
},
|
|
65
|
+
([as, bs], rest) => [push(unshift(as, bs), [Command.Escape]), rest]),
|
|
66
|
+
// 3以上の`*`に対してemの適用を保証する
|
|
67
|
+
nodes => [html('em', [html('strong', defrag(nodes))])],
|
|
68
|
+
(acc, rest, prefix, postfix, state) => {
|
|
69
|
+
const nodes = [];
|
|
70
|
+
let i = postfix;
|
|
71
|
+
if (state) while (i > 0) {
|
|
72
|
+
switch (i) {
|
|
73
|
+
case 1:
|
|
74
|
+
acc = [[html('em', acc.flat())]];
|
|
75
|
+
i -= 1;
|
|
76
|
+
break;
|
|
77
|
+
case 2:
|
|
78
|
+
acc = [[html('strong', acc.flat())]];
|
|
79
|
+
i -= 2;
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
acc = [[html('em', [html('strong', acc.flat())])]];
|
|
83
|
+
i -= 3;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (prefix > postfix) {
|
|
87
|
+
nodes.push('*'.repeat(prefix - postfix));
|
|
88
|
+
}
|
|
89
|
+
for (let i = 0; i < acc.length; ++i) {
|
|
90
|
+
nodes.push(...acc[i]);
|
|
91
|
+
}
|
|
92
|
+
if (postfix > 0) {
|
|
93
|
+
rest = rest.slice(postfix);
|
|
94
|
+
}
|
|
95
|
+
return [nodes, rest];
|
|
96
|
+
})))));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
-
import { State, Recursion, Backtrack } from '../../context';
|
|
3
|
-
import { union, inits, some, creation, precedence, state, constraint, validate, surround, open, lazy, fmap } from '../../../combinator';
|
|
2
|
+
import { State, Recursion, Backtrack, BacktrackState, Command } from '../../context';
|
|
3
|
+
import { union, inits, some, creation, precedence, state, constraint, validate, verify, surround, open, lazy, fmap } from '../../../combinator';
|
|
4
4
|
import { inline } from '../../inline';
|
|
5
5
|
import { indexee, identity } from './indexee';
|
|
6
6
|
import { txt, str } from '../../source';
|
|
7
|
-
import {
|
|
7
|
+
import { tightStart, trimBlankNodeEnd } from '../../visibility';
|
|
8
8
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
import IndexParser = ExtensionParser.IndexParser;
|
|
@@ -12,7 +12,7 @@ import IndexParser = ExtensionParser.IndexParser;
|
|
|
12
12
|
export const index: IndexParser = lazy(() => constraint(State.index, false, creation(1, Recursion.ignore, fmap(indexee(surround(
|
|
13
13
|
'[#',
|
|
14
14
|
precedence(1, state(State.linkers | State.media,
|
|
15
|
-
|
|
15
|
+
tightStart(
|
|
16
16
|
some(inits([
|
|
17
17
|
inline,
|
|
18
18
|
signature,
|
|
@@ -23,7 +23,7 @@ export const index: IndexParser = lazy(() => constraint(State.index, false, crea
|
|
|
23
23
|
trimBlankNodeEnd(ns).length > 0
|
|
24
24
|
? [[html('a', { 'data-index': dataindex(ns) }, defrag(ns))], rest]
|
|
25
25
|
: undefined,
|
|
26
|
-
undefined, 1 | Backtrack.bracket)),
|
|
26
|
+
undefined, 1 | Backtrack.linebracket, Backtrack.bracket | BacktrackState.nobreak)),
|
|
27
27
|
([el]: [HTMLAnchorElement]) => [
|
|
28
28
|
define(el,
|
|
29
29
|
{
|
|
@@ -35,16 +35,20 @@ export const index: IndexParser = lazy(() => constraint(State.index, false, crea
|
|
|
35
35
|
|
|
36
36
|
export const signature: IndexParser.SignatureParser = lazy(() => validate('|', creation(1, Recursion.ignore, fmap(open(
|
|
37
37
|
/^\|(?!\\?\s)/,
|
|
38
|
-
some(union([bracket, txt]), ']')),
|
|
38
|
+
some(verify(union([bracket, txt]), ns => ns[0] !== Command.Escape), ']')),
|
|
39
39
|
ns => [
|
|
40
40
|
html('span', { class: 'indexer', 'data-index': identity('index', undefined, ns.join(''))!.slice(7) }),
|
|
41
41
|
]))));
|
|
42
42
|
|
|
43
43
|
const bracket: IndexParser.SignatureParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
|
44
|
-
surround(str('('), some(union([bracket, txt]), ')'), str(')'), true,
|
|
45
|
-
|
|
46
|
-
surround(str('
|
|
47
|
-
|
|
44
|
+
surround(str('('), some(union([bracket, txt]), ')'), str(')'), true,
|
|
45
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
46
|
+
surround(str('['), some(union([bracket, txt]), ']'), str(']'), true,
|
|
47
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
48
|
+
surround(str('{'), some(union([bracket, txt]), '}'), str('}'), true,
|
|
49
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
50
|
+
surround(str('"'), precedence(2, some(txt, '"')), str('"'), true,
|
|
51
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.index),
|
|
48
52
|
])));
|
|
49
53
|
|
|
50
54
|
export function dataindex(ns: readonly (string | HTMLElement)[]): string | undefined {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
2
|
import { State, Recursion } from '../../context';
|
|
3
|
-
import { union,
|
|
3
|
+
import { union, creation, constraint, surround, clear, fmap } from '../../../combinator';
|
|
4
4
|
import { str } from '../../source';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
6
|
|
|
@@ -3,7 +3,7 @@ import { Recursion, Backtrack } from '../../context';
|
|
|
3
3
|
import { union, some, creation, precedence, surround, lazy } from '../../../combinator';
|
|
4
4
|
import { inline } from '../../inline';
|
|
5
5
|
import { str } from '../../source';
|
|
6
|
-
import {
|
|
6
|
+
import { tightStart } from '../../visibility';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
@@ -14,7 +14,7 @@ import { html, defrag } from 'typed-dom/dom';
|
|
|
14
14
|
export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => creation(1, Recursion.inline, surround(
|
|
15
15
|
str(/^\[[:^|]/),
|
|
16
16
|
precedence(1,
|
|
17
|
-
|
|
17
|
+
tightStart(some(union([inline]), ']', [[']', 1]]))),
|
|
18
18
|
str(']'), false,
|
|
19
19
|
([, bs], rest) => [[
|
|
20
20
|
html('span', {
|
|
@@ -3,7 +3,7 @@ import { Recursion } from '../context';
|
|
|
3
3
|
import { union, subsequence, some, creation, precedence, validate, focus, surround, open, match, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import {
|
|
6
|
+
import { isLooseNodeStart, blankWith } from '../visibility';
|
|
7
7
|
import { memoize } from 'spica/memoize';
|
|
8
8
|
import { Clock } from 'spica/clock';
|
|
9
9
|
import { unshift, push, splice } from 'spica/array';
|
|
@@ -219,7 +219,7 @@ function elem(tag: string, as: string[], bs: (HTMLElement | string)[], cs: strin
|
|
|
219
219
|
if (!tags.includes(tag)) return invalid('tag', `Invalid HTML tag name "${tag}"`, as, bs, cs);
|
|
220
220
|
if (cs.length === 0) return invalid('tag', `Missing the closing HTML tag "</${tag}>"`, as, bs, cs);
|
|
221
221
|
if (bs.length === 0) return invalid('content', `Missing the content`, as, bs, cs);
|
|
222
|
-
if (!
|
|
222
|
+
if (!isLooseNodeStart(bs)) return invalid('content', `Missing the visible content in the same line`, as, bs, cs);
|
|
223
223
|
const attrs = attributes('html', [], attrspecs[tag], as.slice(1, -1));
|
|
224
224
|
return 'data-invalid-syntax' in attrs
|
|
225
225
|
? invalid('attribute', 'Invalid HTML attribute', as, bs, cs)
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { InsertionParser } from '../inline';
|
|
2
|
-
import { Recursion } from '../context';
|
|
3
|
-
import { union, some, creation, precedence, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
3
|
+
import { union, some, creation, precedence, validate, surround, open, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import { str } from '../source';
|
|
6
5
|
import { blankWith } from '../visibility';
|
|
7
|
-
import {
|
|
6
|
+
import { repeat } from '../util';
|
|
7
|
+
import { push } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
|
-
export const insertion: InsertionParser = lazy(() => creation(1, Recursion.inline,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
export const insertion: InsertionParser = lazy(() => creation(1, Recursion.inline, validate('++',
|
|
11
|
+
precedence(0, repeat('++', surround(
|
|
12
|
+
'',
|
|
13
|
+
some(union([
|
|
14
|
+
some(inline, blankWith('\n', '++')),
|
|
15
|
+
open('\n', some(insertion, '+'), true),
|
|
16
|
+
])),
|
|
17
|
+
'++', false,
|
|
18
|
+
([, bs], rest) => [bs, rest],
|
|
19
|
+
([, bs], rest) => [push(bs, [Command.Escape]), rest]),
|
|
20
|
+
nodes => [html('ins', defrag(nodes))])))));
|
|
@@ -15,8 +15,8 @@ describe('Unit: parser/inline/italic', () => {
|
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('///a\\ ///')), [['///', 'a'], '\\ ///']);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('///a\\\n///')), [['///', 'a'], '\\\n///']);
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('///a/b')), [['///', 'a', '/', 'b'], '']);
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('///a//b')), [['///', 'a', '
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('///a*b///')), [['///', 'a', '*', 'b', '
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('///a//b')), [['///', 'a', '/', '/', 'b'], '']);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('///a*b///')), [['///', 'a', '*', 'b', '/', '/', '/'], '']);
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('/// ///')), undefined);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('/// a///')), undefined);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('/// a ///')), undefined);
|
|
@@ -25,8 +25,6 @@ describe('Unit: parser/inline/italic', () => {
|
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('///\\ a///')), undefined);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('///\\\na///')), undefined);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('///<wbr>a///')), undefined);
|
|
28
|
-
assert.deepStrictEqual(inspect(parser('////a////')), undefined);
|
|
29
|
-
assert.deepStrictEqual(inspect(parser('/////a/////')), undefined);
|
|
30
28
|
assert.deepStrictEqual(inspect(parser(' ///a///')), undefined);
|
|
31
29
|
});
|
|
32
30
|
|
|
@@ -39,8 +37,29 @@ describe('Unit: parser/inline/italic', () => {
|
|
|
39
37
|
});
|
|
40
38
|
|
|
41
39
|
it('nest', () => {
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('////a///')), [['/', '<i>a</i>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('////a///b')), [['/', '<i>a</i>'], 'b']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('////a////')), [['/', '<i>a</i>', '/'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('////a////b')), [['/', '<i>a</i>', '/'], 'b']);
|
|
44
|
+
assert.deepStrictEqual(inspect(parser('/////a///')), [['//', '<i>a</i>'], '']);
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('/////a///b')), [['//', '<i>a</i>'], 'b']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('/////a////')), [['//', '<i>a</i>', '/'], '']);
|
|
47
|
+
assert.deepStrictEqual(inspect(parser('/////a////b')), [['//', '<i>a</i>', '/'], 'b']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('/////a/////')), [['//', '<i>a</i>', '//'], '']);
|
|
49
|
+
assert.deepStrictEqual(inspect(parser('/////a/////b')), [['//', '<i>a</i>', '//'], 'b']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('//////a///')), [['///', '<i>a</i>'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('//////a///b')), [['///', '<i>a</i>', 'b'], '']);
|
|
52
|
+
assert.deepStrictEqual(inspect(parser('//////a////')), [['///', '<i>a</i>', '/'], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('//////a////b')), [['///', '<i>a</i>', '/', 'b'], '']);
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('//////a/////')), [['///', '<i>a</i>', '/', '/'], '']);
|
|
55
|
+
assert.deepStrictEqual(inspect(parser('//////a/////b')), [['///', '<i>a</i>', '/', '/', 'b'], '']);
|
|
56
|
+
assert.deepStrictEqual(inspect(parser('//////a//////')), [['<i><i>a</i></i>'], '']);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('//////a///b///')), [['<i><i>a</i>b</i>'], '']);
|
|
42
58
|
assert.deepStrictEqual(inspect(parser('///a ///b//////')), [['<i>a <i>b</i></i>'], '']);
|
|
43
59
|
assert.deepStrictEqual(inspect(parser('///a\\ ///b//////')), [['<i>a <i>b</i></i>'], '']);
|
|
60
|
+
assert.deepStrictEqual(inspect(parser('///a //////b/////////')), [['<i>a <i><i>b</i></i></i>'], '']);
|
|
61
|
+
assert.deepStrictEqual(inspect(parser('///a ///b///c///')), [['<i>a <i>b</i>c</i>'], '']);
|
|
62
|
+
assert.deepStrictEqual(inspect(parser('///a ///b ///c/////////')), [['<i>a <i>b <i>c</i></i></i>'], '']);
|
|
44
63
|
assert.deepStrictEqual(inspect(parser('///a	///b//////')), [['<i>a\t<i>b</i></i>'], '']);
|
|
45
64
|
assert.deepStrictEqual(inspect(parser('///a<wbr>///b//////')), [['<i>a<wbr><i>b</i></i>'], '']);
|
|
46
65
|
assert.deepStrictEqual(inspect(parser('///`a`///')), [['<i><code data-src="`a`">a</code></i>'], '']);
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { ItalicParser } from '../inline';
|
|
2
|
-
import { Recursion } from '../context';
|
|
3
|
-
import { union, some, creation, precedence, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
3
|
+
import { union, some, creation, precedence, validate, surround, open, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { tightStart, blankWith } from '../visibility';
|
|
6
|
+
import { repeat } from '../util';
|
|
7
|
+
import { push } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
// 斜体は単語に使うとかえって見づらく読み飛ばしやすくなるため使わないべきであり
|
|
11
11
|
// ある程度の長さのある文に使うのが望ましい。
|
|
12
|
-
export const italic: ItalicParser = lazy(() => creation(1, Recursion.inline,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
export const italic: ItalicParser = lazy(() => creation(1, Recursion.inline, validate('///',
|
|
13
|
+
precedence(0, repeat('///', surround(
|
|
14
|
+
'',
|
|
15
|
+
tightStart(some(union([
|
|
16
|
+
some(inline, blankWith('///')),
|
|
17
|
+
open(some(inline, '/'), italic),
|
|
18
|
+
]))),
|
|
19
|
+
'///', false,
|
|
20
|
+
([, bs], rest) => [bs, rest],
|
|
21
|
+
([, bs], rest) => [push(bs, [Command.Escape]), rest]),
|
|
22
|
+
nodes => [html('i', defrag(nodes))])))));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../../markdown';
|
|
2
2
|
import { LinkParser } from '../inline';
|
|
3
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
4
|
-
import { union, inits, tails, sequence, some,
|
|
3
|
+
import { State, Recursion, Backtrack, BacktrackState } from '../context';
|
|
4
|
+
import { union, inits, tails, sequence, some, creation, precedence, state, constraint, validate, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
|
|
5
5
|
import { inline, media, shortmedia } from '../inline';
|
|
6
6
|
import { attributes } from './html';
|
|
7
7
|
import { linebreak, unescsource, str } from '../source';
|
|
@@ -22,7 +22,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
22
22
|
'[',
|
|
23
23
|
trimBlankStart(some(union([inline]), ']', [['\n', 9], [']', 1]])),
|
|
24
24
|
']',
|
|
25
|
-
true, undefined, undefined, 1 | Backtrack.bracket)),
|
|
25
|
+
true, undefined, undefined, 1 | Backtrack.linebracket, Backtrack.bracket | BacktrackState.nobreak)),
|
|
26
26
|
dup(surround(
|
|
27
27
|
/^{(?![{}])/,
|
|
28
28
|
inits([uri, some(option)]),
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import { MarkParser } from '../inline';
|
|
2
|
-
import { State, Recursion } from '../context';
|
|
3
|
-
import { union, some, creation, precedence, constraint, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { State, Recursion, Command } from '../context';
|
|
3
|
+
import { union, some, creation, precedence, constraint, validate, surround, open, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { identity, signature } from './extension/indexee';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { tightStart, blankWith } from '../visibility';
|
|
7
|
+
import { repeat } from '../util';
|
|
8
|
+
import { push } from 'spica/array';
|
|
9
9
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
|
-
export const mark: MarkParser = lazy(() => constraint(State.mark, false, creation(1, Recursion.inline,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
el
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
export const mark: MarkParser = lazy(() => constraint(State.mark, false, creation(1, Recursion.inline, validate('==',
|
|
12
|
+
precedence(0, repeat('==', surround(
|
|
13
|
+
'',
|
|
14
|
+
tightStart(some(union([
|
|
15
|
+
some(inline, blankWith('==')),
|
|
16
|
+
open(some(inline, '='), mark),
|
|
17
|
+
]))),
|
|
18
|
+
'==', false,
|
|
19
|
+
([, bs], rest) => [bs, rest],
|
|
20
|
+
([, bs], rest) => [push(bs, [Command.Escape]), rest]),
|
|
21
|
+
(nodes, { id }) => {
|
|
22
|
+
const el = html('mark', defrag(nodes));
|
|
23
|
+
define(el, { id: identity('mark', id, signature(el)) });
|
|
24
|
+
return el.id
|
|
25
|
+
? [el, el.id && html('a', { href: `#${el.id}` })]
|
|
26
|
+
: [el];
|
|
27
|
+
}))))));
|
|
@@ -7,7 +7,7 @@ import { unsafehtmlentity } from './htmlentity';
|
|
|
7
7
|
import { txt, linebreak, str } from '../source';
|
|
8
8
|
import { markInvalid } from '../util';
|
|
9
9
|
import { ReadonlyURL } from 'spica/url';
|
|
10
|
-
import {
|
|
10
|
+
import { push } from 'spica/array';
|
|
11
11
|
import { html, define } from 'typed-dom/dom';
|
|
12
12
|
|
|
13
13
|
const optspec = {
|
|
@@ -23,7 +23,11 @@ export const media: MediaParser = lazy(() => constraint(State.media, false, vali
|
|
|
23
23
|
bind(verify(fmap(tails([
|
|
24
24
|
dup(surround(
|
|
25
25
|
'[',
|
|
26
|
-
precedence(1, some(union([
|
|
26
|
+
precedence(1, some(verify(union([
|
|
27
|
+
unsafehtmlentity,
|
|
28
|
+
bracket,
|
|
29
|
+
txt,
|
|
30
|
+
]), ns => ns[0] !== Command.Escape), ']', [['\n', 9]])),
|
|
27
31
|
']',
|
|
28
32
|
true, undefined, undefined, 1 | Backtrack.media)),
|
|
29
33
|
dup(surround(
|
|
@@ -71,13 +75,13 @@ export const linemedia: MediaParser.LineMediaParser = surround(
|
|
|
71
75
|
|
|
72
76
|
const bracket: MediaParser.TextParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
|
73
77
|
surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true,
|
|
74
|
-
undefined, (
|
|
78
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
75
79
|
surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true,
|
|
76
|
-
undefined, (
|
|
80
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
77
81
|
surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'), true,
|
|
78
|
-
undefined, (
|
|
82
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
79
83
|
surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'), true,
|
|
80
|
-
undefined,
|
|
84
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.media),
|
|
81
85
|
])));
|
|
82
86
|
|
|
83
87
|
const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReferenceParser } from '../inline';
|
|
2
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
2
|
+
import { State, Recursion, Backtrack, BacktrackState } from '../context';
|
|
3
3
|
import { union, subsequence, some, creation, precedence, state, constraint, surround, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
@@ -19,7 +19,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
19
19
|
trimBlankNodeEnd(ns).length > 0
|
|
20
20
|
? [[html('sup', attributes(ns), [html('span', defrag(ns))])], rest]
|
|
21
21
|
: undefined,
|
|
22
|
-
undefined, 1 | Backtrack.bracket))));
|
|
22
|
+
undefined, 1 | Backtrack.linebracket, Backtrack.bracket | BacktrackState.nobreak))));
|
|
23
23
|
|
|
24
24
|
// Chicago-Style
|
|
25
25
|
const abbr: ReferenceParser.AbbrParser = creation(1, Recursion.ignore, surround(
|
|
@@ -4,7 +4,7 @@ import { eval, exec } from '../../combinator/data/parser';
|
|
|
4
4
|
import { sequence, creation, surround, lazy, fmap, bind } from '../../combinator';
|
|
5
5
|
import { unsafehtmlentity } from './htmlentity';
|
|
6
6
|
import { text as txt, str } from '../source';
|
|
7
|
-
import {
|
|
7
|
+
import { isTightNodeStart } from '../visibility';
|
|
8
8
|
import { unshift, push } from 'spica/array';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@ export const ruby: RubyParser = lazy(() => creation(1, Recursion.ignore, fmap(
|
|
|
13
13
|
bind(surround('[', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']', false, undefined, undefined, 3 | Backtrack.ruby), ([source], rest, context) => {
|
|
14
14
|
const ns = eval(text({ source, context }), [undefined])[0];
|
|
15
15
|
ns && ns.at(-1) === '' && ns.pop();
|
|
16
|
-
return ns &&
|
|
16
|
+
return ns && isTightNodeStart(ns) ? [[ns], rest] : undefined;
|
|
17
17
|
}),
|
|
18
18
|
bind(surround('(', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')', false, undefined, undefined, 3 | Backtrack.ruby), ([source], rest, context) => {
|
|
19
19
|
const ns = eval(text({ source, context }), [undefined])[0];
|
|
@@ -26,7 +26,8 @@ export const ruby: RubyParser = lazy(() => creation(1, Recursion.ignore, fmap(
|
|
|
26
26
|
return [
|
|
27
27
|
html('ruby', attributes(texts, rubies), defrag(texts
|
|
28
28
|
.reduce((acc, _, i) =>
|
|
29
|
-
push(acc, unshift(
|
|
29
|
+
push(acc, unshift(
|
|
30
|
+
[texts[i]],
|
|
30
31
|
i < rubies.length && rubies[i]
|
|
31
32
|
? [html('rp', '('), html('rt', rubies[i]), html('rp', ')')]
|
|
32
33
|
: [html('rt')]))
|
|
@@ -36,7 +37,8 @@ export const ruby: RubyParser = lazy(() => creation(1, Recursion.ignore, fmap(
|
|
|
36
37
|
return [
|
|
37
38
|
html('ruby', attributes(texts, rubies), defrag([...texts[0]]
|
|
38
39
|
.reduce((acc, _, i, texts) =>
|
|
39
|
-
push(acc, unshift(
|
|
40
|
+
push(acc, unshift(
|
|
41
|
+
[texts[i]],
|
|
40
42
|
i < rubies.length && rubies[i]
|
|
41
43
|
? [html('rp', '('), html('rt', rubies[i]), html('rp', ')')]
|
|
42
44
|
: [html('rt')]))
|
|
@@ -4,14 +4,14 @@ import { union, some, creation, precedence, surround, open, lazy } from '../../c
|
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { emstrong } from './emstrong';
|
|
6
6
|
import { str } from '../source';
|
|
7
|
-
import {
|
|
7
|
+
import { tightStart, blankWith } from '../visibility';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
11
|
export const strong: StrongParser = lazy(() => creation(1, Recursion.inline, surround(
|
|
12
12
|
str('**', '*'),
|
|
13
13
|
precedence(0,
|
|
14
|
-
|
|
14
|
+
tightStart(some(union([
|
|
15
15
|
some(inline, blankWith('**')),
|
|
16
16
|
open(some(inline, '*'), union([
|
|
17
17
|
emstrong,
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { TemplateParser } from '../inline';
|
|
2
|
-
import { Recursion, Backtrack } from '../context';
|
|
3
|
-
import { union, some, creation, precedence, surround, lazy } from '../../combinator';
|
|
2
|
+
import { Recursion, Backtrack, Command } from '../context';
|
|
3
|
+
import { union, some, creation, precedence, verify, surround, lazy } from '../../combinator';
|
|
4
4
|
import { escsource, str } from '../source';
|
|
5
|
-
import { unshift } from 'spica/array';
|
|
6
5
|
import { html } from 'typed-dom/dom';
|
|
7
6
|
|
|
8
7
|
export const template: TemplateParser = lazy(() => creation(1, Recursion.ignore, surround(
|
|
9
8
|
'{{',
|
|
10
|
-
precedence(1, some(union([bracket, escsource]), '}')),
|
|
9
|
+
precedence(1, some(verify(union([bracket, escsource]), ns => ns[0] !== Command.Escape), '}')),
|
|
11
10
|
'}}',
|
|
12
11
|
true,
|
|
13
12
|
([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('')}}}`)], rest],
|
|
@@ -15,11 +14,11 @@ export const template: TemplateParser = lazy(() => creation(1, Recursion.ignore,
|
|
|
15
14
|
|
|
16
15
|
const bracket: TemplateParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
|
17
16
|
surround(str('('), some(union([bracket, escsource]), ')'), str(')'), true,
|
|
18
|
-
undefined, (
|
|
17
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
19
18
|
surround(str('['), some(union([bracket, escsource]), ']'), str(']'), true,
|
|
20
|
-
undefined, (
|
|
19
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
21
20
|
surround(str('{'), some(union([bracket, escsource]), '}'), str('}'), true,
|
|
22
|
-
undefined, (
|
|
21
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
23
22
|
surround(str('"'), precedence(2, some(escsource, /^["\n]/)), str('"'), true,
|
|
24
|
-
undefined,
|
|
23
|
+
undefined, () => [[Command.Escape], ''], 3 | Backtrack.template),
|
|
25
24
|
])));
|