securemark 0.294.7 → 0.294.8

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.js +176 -194
  3. package/markdown.d.ts +13 -36
  4. package/package.json +1 -1
  5. package/src/combinator/control/constraint/block.ts +2 -2
  6. package/src/combinator/control/constraint/line.ts +7 -5
  7. package/src/combinator/control/manipulation/convert.ts +2 -1
  8. package/src/combinator/control/manipulation/fence.ts +4 -4
  9. package/src/combinator/control/manipulation/surround.ts +9 -9
  10. package/src/combinator/data/parser/some.ts +1 -1
  11. package/src/combinator/data/parser/union.ts +6 -2
  12. package/src/parser/api/bind.test.ts +0 -1
  13. package/src/parser/api/normalize.test.ts +5 -8
  14. package/src/parser/api/normalize.ts +4 -2
  15. package/src/parser/autolink.ts +1 -2
  16. package/src/parser/block/extension/fig.ts +4 -1
  17. package/src/parser/block/heading.ts +12 -2
  18. package/src/parser/block/reply/quote.ts +1 -2
  19. package/src/parser/block/ulist.ts +1 -1
  20. package/src/parser/block.ts +0 -4
  21. package/src/parser/header.ts +28 -40
  22. package/src/parser/inline/annotation.ts +2 -3
  23. package/src/parser/inline/autolink/account.ts +48 -17
  24. package/src/parser/inline/autolink/anchor.test.ts +0 -1
  25. package/src/parser/inline/autolink/anchor.ts +16 -15
  26. package/src/parser/inline/autolink/email.test.ts +1 -1
  27. package/src/parser/inline/autolink/email.ts +10 -11
  28. package/src/parser/inline/autolink/hashnum.ts +17 -13
  29. package/src/parser/inline/autolink/hashtag.ts +19 -15
  30. package/src/parser/inline/autolink/url.ts +24 -19
  31. package/src/parser/inline/autolink.ts +1 -2
  32. package/src/parser/inline/bracket.ts +14 -14
  33. package/src/parser/inline/deletion.ts +2 -1
  34. package/src/parser/inline/emphasis.ts +2 -1
  35. package/src/parser/inline/emstrong.ts +2 -1
  36. package/src/parser/inline/extension/index.ts +4 -4
  37. package/src/parser/inline/extension/indexer.ts +1 -1
  38. package/src/parser/inline/extension/label.ts +1 -1
  39. package/src/parser/inline/extension/placeholder.ts +4 -3
  40. package/src/parser/inline/html.ts +4 -4
  41. package/src/parser/inline/htmlentity.ts +2 -2
  42. package/src/parser/inline/insertion.ts +2 -1
  43. package/src/parser/inline/italic.ts +2 -1
  44. package/src/parser/inline/link.ts +7 -20
  45. package/src/parser/inline/mark.ts +2 -1
  46. package/src/parser/inline/math.ts +4 -2
  47. package/src/parser/inline/media.ts +24 -25
  48. package/src/parser/inline/reference.ts +4 -4
  49. package/src/parser/inline/remark.ts +2 -1
  50. package/src/parser/inline/ruby.ts +3 -4
  51. package/src/parser/inline/strong.ts +2 -1
  52. package/src/parser/inline/template.ts +10 -10
  53. package/src/parser/segment.ts +2 -2
  54. package/src/parser/source/escapable.ts +3 -4
  55. package/src/parser/source/line.ts +3 -1
  56. package/src/parser/source/text.ts +5 -10
  57. package/src/parser/source/unescapable.ts +2 -4
  58. package/src/parser/source.ts +1 -2
  59. package/src/parser/inline/autolink/channel.ts +0 -44
@@ -14,7 +14,8 @@ export const math: MathParser = lazy(() => rewrite(
14
14
  /\$(?={)/y,
15
15
  precedence(4, bracket),
16
16
  '$',
17
- false, undefined, undefined, [3 | Backtrack.bracket]),
17
+ false,
18
+ [3 | Backtrack.bracket]),
18
19
  surround(
19
20
  /\$(?![\s{}])/y,
20
21
  precedence(2, some(union([
@@ -22,7 +23,8 @@ export const math: MathParser = lazy(() => rewrite(
22
23
  precedence(4, bracket),
23
24
  ]))),
24
25
  /\$(?![-0-9A-Za-z])/y,
25
- false, undefined, undefined, [3 | Backtrack.bracket]),
26
+ false,
27
+ [3 | Backtrack.bracket]),
26
28
  ]),
27
29
  ({ context: { source, caches: { math: cache } = {} } }) => new List([
28
30
  new Data(cache?.get(source)?.cloneNode(true) ||
@@ -1,8 +1,8 @@
1
1
  import { MediaParser } from '../inline';
2
2
  import { State, Recursion, Backtrack, Command } from '../context';
3
- import { List, Data, subinput } from '../../combinator/data/parser';
3
+ import { List, Data } from '../../combinator/data/parser';
4
4
  import { union, inits, tails, some, creation, recursion, precedence, constraint, surround, open, setBacktrack, dup, lazy, fmap, bind } from '../../combinator';
5
- import { unsafelink, uri, option as linkoption, resolve, decode } from './link';
5
+ import { uri, option as linkoption, resolve, decode, parse } from './link';
6
6
  import { attributes } from './html';
7
7
  import { unsafehtmlentity } from './htmlentity';
8
8
  import { txt, str } from '../source';
@@ -30,25 +30,24 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
30
30
  ]), ']')),
31
31
  ']',
32
32
  true,
33
+ [3 | Backtrack.escbracket],
33
34
  ([, ns = new List()], context) =>
34
35
  context.linebreak === 0
35
36
  ? ns
36
- : undefined,
37
- undefined,
38
- [3 | Backtrack.escbracket])),
37
+ : undefined)),
39
38
  dup(surround(
40
39
  /{(?![{}])/y,
41
40
  inits([uri, some(option)]),
42
41
  / ?}/y,
43
42
  false,
43
+ [3 | Backtrack.link],
44
44
  undefined,
45
45
  ([as, bs], context) => {
46
46
  if (!bs) return;
47
47
  const head = context.position - context.range!;
48
48
  setBacktrack(context, [2 | Backtrack.link], head);
49
49
  return as.import(bs).push(new Data(Command.Cancel)) && as;
50
- },
51
- [3 | Backtrack.link])),
50
+ })),
52
51
  ]),
53
52
  nodes =>
54
53
  nodes.length === 1
@@ -98,26 +97,26 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
98
97
  }
99
98
  if (context.state! & State.link) return new List([new Data(el)]);
100
99
  if (cache && cache.tagName !== 'IMG') return new List([new Data(el)]);
101
- const { source, position } = context;
102
- return fmap(
103
- unsafelink as MediaParser,
104
- ([{ value }]) => {
105
- context.source = source;
106
- context.position = position;
107
- return new List([new Data(define(value, { class: null, target: '_blank' }, [el]))]);
108
- })
109
- (subinput(`{ ${INSECURE_URI}${linkparams.join('')} }`, context));
100
+ return new List([new Data(define(
101
+ parse(
102
+ new List(),
103
+ linkparams.reduce(
104
+ (acc, p) => acc.push(new Data(p)) && acc,
105
+ new List([new Data(INSECURE_URI)])),
106
+ context),
107
+ { class: null, target: '_blank' }, [el]))
108
+ ]);
110
109
  })))));
111
110
 
112
111
  const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recursion.terminal, union([
113
- surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true,
114
- undefined, () => new List(), [3 | Backtrack.escbracket]),
115
- surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true,
116
- undefined, () => new List(), [3 | Backtrack.escbracket]),
117
- surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'), true,
118
- undefined, () => new List(), [3 | Backtrack.escbracket]),
119
- surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'), true,
120
- undefined, () => new List(), [3 | Backtrack.escbracket]),
112
+ surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'),
113
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
114
+ surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'),
115
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
116
+ surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'),
117
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
118
+ surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'),
119
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
121
120
  ])));
122
121
 
123
122
  const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
@@ -125,7 +124,7 @@ const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
125
124
  open(/ /y, str(/[1-9][0-9]*/y)),
126
125
  str(/[x:]/y),
127
126
  str(/[1-9][0-9]*(?=[ }])/y),
128
- false,
127
+ false, [],
129
128
  ([[{ value: a }], [{ value: b }], [{ value: c }]]) =>
130
129
  b === 'x'
131
130
  ? new List([new Data(`width="${a}"`), new Data(`height="${c}"`)])
@@ -18,6 +18,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
18
18
  ]))),
19
19
  ']]',
20
20
  false,
21
+ [1 | Backtrack.bracket, 3 | Backtrack.doublebracket],
21
22
  ([, ns], context) => {
22
23
  const { position, range = 0, linebreak = 0 } = context;
23
24
  if (linebreak === 0) {
@@ -69,7 +70,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
69
70
  '',
70
71
  some(inline, ']', [[']', 1]]),
71
72
  str(']'),
72
- true,
73
+ true, [],
73
74
  ([, cs = new List(), ds]) =>
74
75
  cs.import(ds),
75
76
  ([, cs = new List()]) => {
@@ -86,15 +87,14 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
86
87
  return state & State.annotation
87
88
  ? as.import(bs as List<Data<string>>)
88
89
  : undefined;
89
- },
90
- [1 | Backtrack.bracket, 3 | Backtrack.doublebracket])));
90
+ })));
91
91
 
92
92
  // Chicago-Style
93
93
  const abbr: ReferenceParser.AbbrParser = surround(
94
94
  str('^'),
95
95
  union([str(/(?=[A-Z])(?:[0-9A-Za-z]'?|(?:[-.:]|\.?\??,? ?)(?!['\-.:?, ]))+/y)]),
96
96
  /\|?(?=]])|\|/y,
97
- true,
97
+ true, [],
98
98
  ([, ns], context) => {
99
99
  const { source, position, range = 0 } = context;
100
100
  if (!ns) return new List([new Data(''), new Data(source.slice(position - range, source[position - 1] === '|' ? position - 1 : position))]);
@@ -11,7 +11,8 @@ export const remark: RemarkParser = lazy(() => fallback(surround(
11
11
  str(/\[%(?=[ \n])/y),
12
12
  precedence(3, recursion(Recursion.inline,
13
13
  some(union([inline]), /[ \n]%\]/y, [[/[ \n]%\]/y, 3]]))),
14
- close(text, str(`%]`)), true,
14
+ close(text, str(`%]`)),
15
+ true, [],
15
16
  ([as, bs = new List(), cs]) => new List([
16
17
  new Data(html('span', { class: 'remark' }, [
17
18
  html('input', { type: 'checkbox' }),
@@ -13,15 +13,14 @@ export const ruby: RubyParser = lazy(() => bind(
13
13
  dup(surround(
14
14
  '[', text, ']',
15
15
  false,
16
+ [1 | Backtrack.bracket, 3 | Backtrack.ruby],
16
17
  ([, ns]) => {
17
18
  ns && ns.last?.value === '' && ns.pop();
18
19
  return isTightNodeStart(ns) ? ns : undefined;
19
- },
20
- undefined,
21
- [1 | Backtrack.bracket, 3 | Backtrack.ruby])),
20
+ })),
22
21
  dup(surround(
23
22
  '(', text, ')',
24
- false, undefined, undefined,
23
+ false,
25
24
  [1 | Backtrack.bracket, 3 | Backtrack.ruby])),
26
25
  ]),
27
26
  ([{ value: texts }, { value: rubies = undefined } = {}], context) => {
@@ -17,6 +17,7 @@ export const strong: StrongParser = lazy(() => surround(
17
17
  some(inline, blankWith('*')),
18
18
  open(some(inline, '*'), inline),
19
19
  ]))))),
20
- str('**'), false,
20
+ str('**'),
21
+ false, [],
21
22
  ([, bs]) => new List([new Data(html('strong', defrag(unwrap(bs))))]),
22
23
  ([as, bs]) => bs && as.import(bs as List<Data<string>>)));
@@ -12,6 +12,7 @@ export const template: TemplateParser = lazy(() => surround(
12
12
  some(union([bracket, escsource]), '}')),
13
13
  str('}}'),
14
14
  true,
15
+ [3 | Backtrack.doublebracket, 3 | Backtrack.escbracket],
15
16
  ([as, bs = new List(), cs]) => new List([
16
17
  new Data(html('span', { class: 'template' }, defrag(unwrap(as.import(bs as List<Data<string>>).import(cs)))))
17
18
  ]),
@@ -23,25 +24,24 @@ export const template: TemplateParser = lazy(() => surround(
23
24
  ...invalid('template', 'syntax', `Missing the closing symbol "}}"`),
24
25
  },
25
26
  context.source.slice(context.position - context.range!, context.position)))
26
- ]),
27
- [3 | Backtrack.doublebracket, 3 | Backtrack.escbracket]));
27
+ ])));
28
28
 
29
29
  const bracket: TemplateParser.BracketParser = lazy(() => union([
30
- surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'), true,
31
- undefined, () => new List(), [3 | Backtrack.escbracket]),
32
- surround(str('['), recursion(Recursion.terminal, some(union([bracket, escsource]), ']')), str(']'), true,
33
- undefined, () => new List(), [3 | Backtrack.escbracket]),
34
- surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'), true,
35
- undefined, () => new List(), [3 | Backtrack.escbracket]),
30
+ surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'),
31
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
32
+ surround(str('['), recursion(Recursion.terminal, some(union([bracket, escsource]), ']')), str(']'),
33
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
34
+ surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'),
35
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
36
36
  surround(
37
37
  str('"'),
38
38
  precedence(2, recursion(Recursion.terminal, some(escsource, /["\n]/y, [['"', 2], ['\n', 3]]))),
39
39
  str('"'),
40
40
  true,
41
+ [3 | Backtrack.escbracket],
41
42
  ([as, bs = new List(), cs], context) =>
42
43
  context.linebreak === 0
43
44
  ? as.import(bs as List<Data<string>>).import(cs)
44
45
  : (context.position -= 1, as.import(bs as List<Data<string>>)),
45
- ([as, bs]) => bs && as.import(bs as List<Data<string>>),
46
- [3 | Backtrack.escbracket]),
46
+ ([as, bs]) => bs && as.import(bs as List<Data<string>>)),
47
47
  ]));
@@ -13,6 +13,7 @@ export const MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB
13
13
  export const MAX_INPUT_SIZE = MAX_SEGMENT_SIZE * 10;
14
14
 
15
15
  const parser: SegmentParser = union([
16
+ some(emptyline),
16
17
  input => {
17
18
  const { context: { source, position } } = input;
18
19
  if (position === source.length) return;
@@ -35,8 +36,7 @@ const parser: SegmentParser = union([
35
36
  return extension(input);
36
37
  }
37
38
  },
38
- some(contentline, MAX_SEGMENT_SIZE + 1),
39
- some(emptyline, MAX_SEGMENT_SIZE + 1),
39
+ some(contentline),
40
40
  ]) as any;
41
41
 
42
42
  export function* segment(source: string): Generator<string, undefined, undefined> {
@@ -14,10 +14,6 @@ export const escsource: EscapableSourceParser = ({ context }) => {
14
14
  consume(1, context);
15
15
  context.position += 1;
16
16
  switch (char) {
17
- case '\r':
18
- assert(!source.includes('\r', position + 1));
19
- consume(-1, context);
20
- return new List();
21
17
  case Command.Escape:
22
18
  consume(1, context);
23
19
  context.position += 1;
@@ -33,6 +29,9 @@ export const escsource: EscapableSourceParser = ({ context }) => {
33
29
  context.position += 1;
34
30
  return new List([new Data(source.slice(position, position + 2))]);
35
31
  }
32
+ case '\r':
33
+ consume(-1, context);
34
+ return new List();
36
35
  case '\n':
37
36
  context.linebreak ||= source.length - position;
38
37
  return new List([new Data(html('br'))]);
@@ -8,6 +8,7 @@ export const anyline: AnyLineParser = input => {
8
8
  context.position = source.indexOf('\n', position) + 1 || source.length;
9
9
  return new List();
10
10
  };
11
+
11
12
  const regEmptyline = /[^\S\n]*(?:$|\n)/y;
12
13
  export const emptyline: EmptyLineParser = input => {
13
14
  const { context } = input;
@@ -21,6 +22,7 @@ export const emptyline: EmptyLineParser = input => {
21
22
  context.position = i;
22
23
  return new List();
23
24
  };
25
+
24
26
  const regContentline = /[^\S\n]*\S[^\n]*(?:$|\n)/y;
25
27
  export const contentline: ContentLineParser = input => {
26
28
  const { context } = input;
@@ -33,4 +35,4 @@ export const contentline: ContentLineParser = input => {
33
35
  if (i === 0) return;
34
36
  context.position = i;
35
37
  return new List();
36
- }
38
+ };
@@ -1,7 +1,7 @@
1
- import { TextParser, TxtParser, LinebreakParser } from '../source';
1
+ import { TextParser, TxtParser } from '../source';
2
2
  import { Command } from '../context';
3
3
  import { List, Data } from '../../combinator/data/parser';
4
- import { union, consume, focus } from '../../combinator';
4
+ import { union, consume } from '../../combinator';
5
5
  import { html } from 'typed-dom/dom';
6
6
 
7
7
  //const delimiter = /(?=[\\!@#$&"`\[\](){}<>()[]{}*%|\r\n]|([+~=])\1|\/{3}|\s(?:\\?(?:$|\s)|[$%])|:\/\/)/g;
@@ -15,10 +15,6 @@ export const text: TextParser = input => {
15
15
  consume(1, context);
16
16
  context.position += 1;
17
17
  switch (char) {
18
- case '\r':
19
- assert(!source.includes('\r', position + 1));
20
- consume(-1, context);
21
- return new List();
22
18
  case Command.Escape:
23
19
  case '\\':
24
20
  switch (source[position + 1]) {
@@ -32,6 +28,9 @@ export const text: TextParser = input => {
32
28
  context.position += 1;
33
29
  return new List([new Data(source.slice(position + 1, context.position))]);
34
30
  }
31
+ case '\r':
32
+ consume(-1, context);
33
+ return new List();
35
34
  case '\n':
36
35
  context.linebreak ||= source.length - position;
37
36
  return new List([new Data(html('br'))]);
@@ -64,10 +63,6 @@ export const txt: TxtParser = union([
64
63
  text,
65
64
  ]) as TxtParser;
66
65
 
67
- export const linebreak: LinebreakParser = focus(/[\r\n]/y, union([
68
- text,
69
- ])) as LinebreakParser;
70
-
71
66
  export function canSkip(source: string, position: number): boolean {
72
67
  assert(position < source.length);
73
68
  if (!isWhitespace(source[position], false)) return false;
@@ -14,14 +14,12 @@ export const unescsource: UnescapableSourceParser = ({ context }) => {
14
14
  consume(1, context);
15
15
  context.position += 1;
16
16
  switch (char) {
17
- case '\r':
18
- assert(!source.includes('\r', position + 1));
19
- consume(-1, context);
20
- return new List();
21
17
  case Command.Escape:
22
18
  consume(1, context);
23
19
  context.position += 1;
24
20
  return new List([new Data(source.slice(position + 1, position + 2))]);
21
+ case '\r':
22
+ return new List();
25
23
  case '\n':
26
24
  context.linebreak ||= source.length - position;
27
25
  return new List([new Data(html('br'))]);
@@ -3,7 +3,6 @@ import { MarkdownParser } from '../../markdown';
3
3
  import SourceParser = MarkdownParser.SourceParser;
4
4
  export import TextParser = SourceParser.TextParser;
5
5
  export import TxtParser = SourceParser.TxtParser;
6
- export import LinebreakParser = SourceParser.LinebreakParser;
7
6
  export import EscapableSourceParser = SourceParser.EscapableSourceParser;
8
7
  export import UnescapableSourceParser = SourceParser.UnescapableSourceParser;
9
8
  export import StrParser = SourceParser.StrParser;
@@ -11,7 +10,7 @@ export import ContentLineParser = SourceParser.ContentLineParser;
11
10
  export import EmptyLineParser = SourceParser.EmptyLineParser;
12
11
  export import AnyLineParser = SourceParser.AnyLineParser;
13
12
 
14
- export { text, txt, linebreak } from './source/text';
13
+ export { text, txt } from './source/text';
15
14
  export { escsource } from './source/escapable';
16
15
  export { unescsource } from './source/unescapable';
17
16
  export { str, strs } from './source/str';
@@ -1,44 +0,0 @@
1
- import { AutolinkParser } from '../../inline';
2
- import { State, Backtrack } from '../../context';
3
- import { List, Data } from '../../../combinator/data/parser';
4
- import { union, sequence, some, state, constraint, verify, rewrite, surround, convert, fmap, lazy } from '../../../combinator';
5
- import { unsafelink } from '../link';
6
- import { emoji } from './hashtag';
7
- import { str } from '../../source';
8
- import { define } from 'typed-dom/dom';
9
-
10
- // https://example/@user?ch=a+b must be a user channel page or a redirect page going there.
11
-
12
- export const channel: AutolinkParser.ChannelParser = lazy(() => rewrite(
13
- sequence([
14
- surround(
15
- /(?<![0-9a-z])@/yi,
16
- /[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*\//yi,
17
- /[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*(?![-.]?[0-9a-z@]|>>|:\S)/yi,
18
- true, undefined, undefined,
19
- [3 | Backtrack.autolink]),
20
- some(verify(surround(
21
- '#',
22
- str(new RegExp([
23
- /(?!['_])(?:[^\p{C}\p{S}\p{P}\s]|emoji|'(?=[0-9A-Za-z])|_(?=[^\p{C}\p{S}\p{P}\s]|emoji))+/yu.source,
24
- ].join('|').replace(/emoji/g, emoji.source), 'yu')),
25
- new RegExp([
26
- /(?![0-9a-z@]|>>|:\S|[^\p{C}\p{S}\p{P}\s]|emoji)/yu.source,
27
- ].join('|').replace(/emoji/g, emoji.source), 'yu'),
28
- false, undefined, undefined,
29
- [3 | Backtrack.autolink]),
30
- ([{ value }]) => !/^[0-9]{1,4}$|^[0-9]{5}/.test(value as string))),
31
- ]),
32
- constraint(State.autolink, state(State.autolink, fmap(convert(
33
- source =>
34
- `[${source}]{ ${source.includes('/')
35
- ? `https://${source.slice(1, source.indexOf('#')).replace('/', '/@')}`
36
- : `/${source.slice(0, source.indexOf('#'))}`
37
- } }`,
38
- union([unsafelink]),
39
- false),
40
- ([{ value: el }], { source, position, range = 0 }) => {
41
- const src = source.slice(position - range, position);
42
- const url = `${el.getAttribute('href')}?ch=${src.slice(src.indexOf('#') + 1).replace(/#/g, '+')}`;
43
- return new List([new Data(define(el, { class: 'channel', href: url }, src))]);
44
- })))));