securemark 0.268.1 → 0.269.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.269.0
4
+
5
+ - Change media syntax to line-level syntax.
6
+
7
+ ## 0.268.2
8
+
9
+ - Refactoring.
10
+
3
11
  ## 0.268.1
4
12
 
5
13
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.268.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.269.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory(require("Prism"), require("DOMPurify"));
@@ -4274,14 +4274,11 @@ exports.parse = parse;
4274
4274
  Object.defineProperty(exports, "__esModule", ({
4275
4275
  value: true
4276
4276
  }));
4277
- exports.lineurl = exports.autolink = void 0;
4277
+ exports.autolink = void 0;
4278
4278
  const combinator_1 = __webpack_require__(2087);
4279
- const link_1 = __webpack_require__(9628);
4280
4279
  const autolink_1 = __webpack_require__(6051);
4281
4280
  const source_1 = __webpack_require__(6743);
4282
- const util_1 = __webpack_require__(9437);
4283
- exports.autolink = (0, combinator_1.lazy)(() => (0, combinator_1.some)((0, combinator_1.line)((0, combinator_1.subsequence)([exports.lineurl, (0, combinator_1.some)((0, combinator_1.union)([autolink_1.autolink, source_1.linebreak, source_1.unescsource]))]))));
4284
- exports.lineurl = (0, combinator_1.lazy)(() => (0, combinator_1.focus)(/^!?https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/, (0, util_1.format)((0, combinator_1.tails)([(0, source_1.str)('!'), link_1.link]))));
4281
+ exports.autolink = (0, combinator_1.lazy)(() => (0, combinator_1.convert)(source => `\r${source}`, (0, combinator_1.some)((0, combinator_1.union)([autolink_1.autolink, source_1.linebreak, source_1.unescsource]))));
4285
4282
 
4286
4283
  /***/ }),
4287
4284
 
@@ -5378,7 +5375,7 @@ const combinator_1 = __webpack_require__(2087);
5378
5375
  const inline_1 = __webpack_require__(1160);
5379
5376
  const visibility_1 = __webpack_require__(7618);
5380
5377
  const dom_1 = __webpack_require__(3252);
5381
- exports.paragraph = (0, combinator_1.block)((0, combinator_1.fmap)((0, visibility_1.visualize)((0, combinator_1.trimEnd)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline])))), ns => [(0, dom_1.html)('p', (0, dom_1.defrag)(ns))]));
5378
+ exports.paragraph = (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.convert)(source => `\r${source}`, (0, visibility_1.visualize)((0, combinator_1.trimEnd)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]))))), ns => [(0, dom_1.html)('p', (0, dom_1.defrag)(ns))]));
5382
5379
 
5383
5380
  /***/ }),
5384
5381
 
@@ -5462,7 +5459,6 @@ const combinator_1 = __webpack_require__(2087);
5462
5459
  const math_1 = __webpack_require__(8946);
5463
5460
  const autolink_1 = __webpack_require__(6051);
5464
5461
  const source_1 = __webpack_require__(6743);
5465
- const autolink_2 = __webpack_require__(7185);
5466
5462
  const dom_1 = __webpack_require__(3252);
5467
5463
  exports.syntax = /^>+(?=[^\S\n])|^>(?=[^\s>])|^>+(?=[^\s>])(?![0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:]))/;
5468
5464
  exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, false, (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.validate)('>', (0, combinator_1.union)([(0, combinator_1.rewrite)((0, combinator_1.some)((0, combinator_1.validate)(new RegExp(exports.syntax.source.split('|')[0]), source_1.anyline)), qblock), (0, combinator_1.rewrite)((0, combinator_1.validate)(new RegExp(exports.syntax.source.split('|').slice(1).join('|')), source_1.anyline), (0, combinator_1.line)((0, combinator_1.union)([(0, source_1.str)(/^.+/)])))])), ns => [(0, dom_1.html)('span', ns.length > 1 ? {
@@ -5482,7 +5478,7 @@ const qblock = ({
5482
5478
  const quotes = source.match(/^>+[^\S\n]/mg);
5483
5479
  const content = lines.reduce((acc, line, i) => acc + line.slice(quotes[i].length), '');
5484
5480
  const nodes = (0, parser_1.eval)(text({
5485
- source: content,
5481
+ source: `\r${content}`,
5486
5482
  context
5487
5483
  }), []);
5488
5484
  nodes.unshift(quotes.shift());
@@ -5508,7 +5504,7 @@ const qblock = ({
5508
5504
  nodes.unshift('');
5509
5505
  return [nodes, ''];
5510
5506
  };
5511
- const text = (0, combinator_1.some)((0, combinator_1.line)((0, combinator_1.subsequence)([autolink_2.lineurl, (0, combinator_1.some)((0, combinator_1.union)([math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource]))])));
5507
+ const text = (0, combinator_1.some)((0, combinator_1.union)([math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource]));
5512
5508
 
5513
5509
  /***/ }),
5514
5510
 
@@ -5702,7 +5698,7 @@ const shortmedia_1 = __webpack_require__(4189);
5702
5698
  const autolink_1 = __webpack_require__(6051);
5703
5699
  const bracket_1 = __webpack_require__(5196);
5704
5700
  const source_1 = __webpack_require__(6743);
5705
- exports.inline = (0, combinator_1.union)([annotation_1.annotation, reference_1.reference, template_1.template, comment_1.comment, math_1.math, extension_1.extension, ruby_1.ruby, link_1.link, media_1.media, html_1.html, insertion_1.insertion, deletion_1.deletion, mark_1.mark, strong_1.strong, emphasis_1.emphasis, code_1.code, htmlentity_1.htmlentity, shortmedia_1.shortmedia, autolink_1.autolink, bracket_1.bracket, source_1.text]);
5701
+ exports.inline = (0, combinator_1.union)([annotation_1.annotation, reference_1.reference, template_1.template, comment_1.comment, math_1.math, extension_1.extension, ruby_1.ruby, link_1.textlink, link_1.linemedialink, media_1.linemedia, html_1.html, insertion_1.insertion, deletion_1.deletion, mark_1.mark, strong_1.strong, emphasis_1.emphasis, code_1.code, htmlentity_1.htmlentity, shortmedia_1.lineshortmedia, autolink_1.autolink, bracket_1.bracket, source_1.text]);
5706
5702
  var indexee_1 = __webpack_require__(1269);
5707
5703
  Object.defineProperty(exports, "indexee", ({
5708
5704
  enumerable: true,
@@ -5776,7 +5772,7 @@ const hashnum_1 = __webpack_require__(5631);
5776
5772
  const anchor_1 = __webpack_require__(6495);
5777
5773
  const source_1 = __webpack_require__(6743);
5778
5774
  const util_1 = __webpack_require__(9437);
5779
- exports.autolink = (0, combinator_1.fmap)((0, combinator_1.validate)(/^(?:[@#>0-9a-z]|\S[#>])/i, (0, combinator_1.constraint)(2 /* State.autolink */, false, (0, combinator_1.syntax)(2 /* Syntax.autolink */, 1, 1, ~1 /* State.shortcut */, (0, combinator_1.some)((0, combinator_1.union)([url_1.url, email_1.email,
5775
+ exports.autolink = (0, combinator_1.validate)(/^(?:[@#>0-9a-z\r\n]|\S[#>])/i, (0, combinator_1.constraint)(2 /* State.autolink */, false, (0, combinator_1.syntax)(2 /* Syntax.autolink */, 1, 1, ~1 /* State.shortcut */, (0, combinator_1.union)([(0, combinator_1.some)((0, combinator_1.union)([url_1.lineurl])), (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([url_1.url, email_1.email,
5780
5776
  // Escape unmatched email-like strings.
5781
5777
  (0, combinator_1.focus)(/^[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z])*(?:@(?:[0-9a-z]+(?:[.-][0-9a-z]+)*)?)*/i, ({
5782
5778
  source
@@ -5793,7 +5789,7 @@ exports.autolink = (0, combinator_1.fmap)((0, combinator_1.validate)(/^(?:[@#>0-
5793
5789
  // Escape unmatched hashtag-like strings.
5794
5790
  (0, source_1.str)(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|')*/u.source.replace('emoji', hashtag_1.emoji), 'u')),
5795
5791
  // Escape invalid leading characters.
5796
- (0, source_1.str)(/^[0-9\p{Sc}](?=>)/u), anchor_1.anchor]))))), ns => ns.length === 1 ? ns : [(0, util_1.stringify)(ns)]);
5792
+ (0, source_1.str)(/^[0-9\p{Sc}](?=>)/u), anchor_1.anchor])), ns => ns.length === 1 ? ns : [(0, util_1.stringify)(ns)])]))));
5797
5793
 
5798
5794
  /***/ }),
5799
5795
 
@@ -5949,12 +5945,13 @@ exports.hashtag = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combin
5949
5945
  Object.defineProperty(exports, "__esModule", ({
5950
5946
  value: true
5951
5947
  }));
5952
- exports.url = void 0;
5948
+ exports.lineurl = exports.url = void 0;
5953
5949
  const combinator_1 = __webpack_require__(2087);
5954
5950
  const link_1 = __webpack_require__(9628);
5955
5951
  const source_1 = __webpack_require__(6743);
5956
5952
  const closer = /^[-+*=~^_,.;:!?]*(?=[\\"`|\[\](){}<>]|$)/;
5957
5953
  exports.url = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['http://', 'https://'], (0, combinator_1.rewrite)((0, combinator_1.open)(/^https?:\/\/(?=[\x21-\x7E])/, (0, combinator_1.focus)(/^[\x21-\x7E]+/, (0, combinator_1.some)((0, combinator_1.union)([bracket, (0, combinator_1.some)(source_1.unescsource, closer)])))), (0, combinator_1.convert)(url => `{ ${url} }`, (0, combinator_1.union)([link_1.unsafelink])))));
5954
+ exports.lineurl = (0, combinator_1.open)(source_1.linebreak, (0, combinator_1.tails)([(0, source_1.str)('!'), (0, combinator_1.focus)(/^https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/, (0, combinator_1.convert)(url => `{ ${url} }`, link_1.unsafelink))]));
5958
5955
  const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, combinator_1.precedence)(2, (0, combinator_1.union)([(0, combinator_1.surround)('(', (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')'), ')', true), (0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ']'), ']', true), (0, combinator_1.surround)('{', (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), '}'), '}', true), (0, combinator_1.surround)('"', (0, combinator_1.precedence)(8, (0, combinator_1.some)(source_1.unescsource, '"')), '"', true)]))));
5959
5956
 
5960
5957
  /***/ }),
@@ -6143,12 +6140,13 @@ function identity(id, text, name = 'index') {
6143
6140
  if (id === '') return undefined;
6144
6141
  text &&= text.trim().replace(/\s+/g, '_');
6145
6142
  if (text === '') return undefined;
6146
- if (text.length <= 100) return `${name}:${id ?? ''}:${text}`;
6143
+ const cs = [...text];
6144
+ if (cs.length <= 100) return `${name}:${id ?? ''}:${text}`;
6147
6145
  switch (name) {
6148
6146
  case 'index':
6149
- return `${name}:${id ?? ''}:${text.slice(0, 97)}...`;
6147
+ return `${name}:${id ?? ''}:${cs.slice(0, 97).join('')}...`;
6150
6148
  case 'mark':
6151
- return `${name}:${id ?? ''}:${text.slice(0, 50)}...${text.slice(-47)}`;
6149
+ return `${name}:${id ?? ''}:${cs.slice(0, 50).join('')}...${cs.slice(-47).join('')}`;
6152
6150
  }
6153
6151
  }
6154
6152
  exports.identity = identity;
@@ -6418,7 +6416,7 @@ exports.insertion = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0,
6418
6416
  Object.defineProperty(exports, "__esModule", ({
6419
6417
  value: true
6420
6418
  }));
6421
- exports.resolve = exports.option = exports.uri = exports.unsafelink = exports.link = void 0;
6419
+ exports.resolve = exports.option = exports.uri = exports.unsafelink = exports.linemedialink = exports.medialink = exports.textlink = exports.link = void 0;
6422
6420
  const combinator_1 = __webpack_require__(2087);
6423
6421
  const inline_1 = __webpack_require__(1160);
6424
6422
  const html_1 = __webpack_require__(5994);
@@ -6431,11 +6429,12 @@ const optspec = {
6431
6429
  rel: ['nofollow']
6432
6430
  };
6433
6431
  Object.setPrototypeOf(optspec, null);
6434
- exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['[', '{'], (0, combinator_1.union)([medialink, textlink])));
6435
- const textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(16 /* State.link */, false, (0, combinator_1.syntax)(16 /* Syntax.link */, 2, 10, 502 /* State.linkers */ | 8 /* State.media */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[/^\\?\n/, 9], [']', 2]]), ']', true)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => {
6432
+ exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['[', '{'], (0, combinator_1.union)([exports.medialink, exports.textlink])));
6433
+ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(16 /* State.link */, false, (0, combinator_1.syntax)(16 /* Syntax.link */, 2, 10, 502 /* State.linkers */ | 8 /* State.media */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[/^\\?\n/, 9], [']', 2]]), ']', true)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => {
6436
6434
  return parse(content, params, rest, context);
6437
6435
  }))));
6438
- const medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(16 /* State.link */ | 8 /* State.media */, false, (0, combinator_1.syntax)(16 /* Syntax.link */, 2, 10, 502 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => parse(content, params, rest, context)))));
6436
+ exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(16 /* State.link */ | 8 /* State.media */, false, (0, combinator_1.syntax)(16 /* Syntax.link */, 2, 10, 502 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => parse(content, params, rest, context)))));
6437
+ exports.linemedialink = (0, combinator_1.surround)(source_1.linebreak, (0, combinator_1.union)([exports.medialink]), /^(?=[^\S\n]*(?:$|\n))/);
6439
6438
  exports.unsafelink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(10, (0, combinator_1.precedence)(2, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([source_1.unescsource]), ']'), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => parse(content, params, rest, context)))));
6440
6439
  exports.uri = (0, combinator_1.union)([(0, combinator_1.open)(/^[^\S\n]+/, (0, source_1.str)(/^\S+/)), (0, source_1.str)(/^[^\s{}]+/)]);
6441
6440
  exports.option = (0, combinator_1.union)([(0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+nofollow(?=[^\S\n]|})/), () => [` rel="nofollow"`]), (0, source_1.str)(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|})/), (0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+[^\s{}]+/), opt => [` \\${opt.slice(1)}`])]);
@@ -6600,7 +6599,7 @@ const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, comb
6600
6599
  Object.defineProperty(exports, "__esModule", ({
6601
6600
  value: true
6602
6601
  }));
6603
- exports.media = void 0;
6602
+ exports.linemedia = exports.media = void 0;
6604
6603
  const combinator_1 = __webpack_require__(2087);
6605
6604
  const link_1 = __webpack_require__(9628);
6606
6605
  const html_1 = __webpack_require__(5994);
@@ -6645,6 +6644,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['![', '
6645
6644
  context
6646
6645
  });
6647
6646
  }))))));
6647
+ exports.linemedia = (0, combinator_1.surround)(source_1.linebreak, (0, combinator_1.union)([exports.media]), /^(?=[^\S\n]*(?:$|\n))/);
6648
6648
  const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']'), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), '}'), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(8, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, source_1.txt]), '"')), (0, source_1.str)('"'), true)])));
6649
6649
  const option = (0, combinator_1.union)([(0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+[1-9][0-9]*x[1-9][0-9]*(?=[^\S\n]|})/), ([opt]) => [` width="${opt.slice(1).split('x')[0]}"`, ` height="${opt.slice(1).split('x')[1]}"`]), (0, combinator_1.fmap)((0, source_1.str)(/^[^\S\n]+[1-9][0-9]*:[1-9][0-9]*(?=[^\S\n]|})/), ([opt]) => [` aspect-ratio="${opt.slice(1).split(':').join('/')}"`]), link_1.option]);
6650
6650
  function sanitize(target, uri, alt) {
@@ -6824,11 +6824,13 @@ function attributes(texts, rubies) {
6824
6824
  Object.defineProperty(exports, "__esModule", ({
6825
6825
  value: true
6826
6826
  }));
6827
- exports.shortmedia = void 0;
6827
+ exports.lineshortmedia = exports.shortmedia = void 0;
6828
6828
  const combinator_1 = __webpack_require__(2087);
6829
6829
  const url_1 = __webpack_require__(4318);
6830
6830
  const media_1 = __webpack_require__(1303);
6831
+ const source_1 = __webpack_require__(6743);
6831
6832
  exports.shortmedia = (0, combinator_1.rewrite)((0, combinator_1.constraint)(8 /* State.media */, false, (0, combinator_1.open)('!', url_1.url)), (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media])));
6833
+ exports.lineshortmedia = (0, combinator_1.open)(source_1.linebreak, (0, combinator_1.focus)(/^!https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/, (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media]))));
6832
6834
 
6833
6835
  /***/ }),
6834
6836
 
@@ -7335,7 +7337,8 @@ const combinator_1 = __webpack_require__(2087);
7335
7337
  const text_1 = __webpack_require__(7763);
7336
7338
  const delimiter = /[\s\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]/;
7337
7339
  exports.escsource = (0, combinator_1.creation)(1, false, ({
7338
- source
7340
+ source,
7341
+ context
7339
7342
  }) => {
7340
7343
  if (source === '') return;
7341
7344
  const i = source.search(delimiter);
@@ -7344,6 +7347,9 @@ exports.escsource = (0, combinator_1.creation)(1, false, ({
7344
7347
  return [[source], ''];
7345
7348
  case 0:
7346
7349
  switch (source[0]) {
7350
+ case '\r':
7351
+ context.resources && ++context.resources.clock;
7352
+ return [[], source.slice(1)];
7347
7353
  case '\x1B':
7348
7354
  return [[source.slice(1, 2)], source.slice(2)];
7349
7355
  case '\\':
@@ -7457,6 +7463,9 @@ exports.text = (0, combinator_1.creation)(1, false, ({
7457
7463
  return [[source], ''];
7458
7464
  case 0:
7459
7465
  switch (source[0]) {
7466
+ case '\r':
7467
+ context.resources && ++context.resources.clock;
7468
+ return [[], source.slice(1)];
7460
7469
  case '\x1B':
7461
7470
  case '\\':
7462
7471
  switch (source[1]) {
@@ -7488,7 +7497,7 @@ exports.text = (0, combinator_1.creation)(1, false, ({
7488
7497
  }
7489
7498
  });
7490
7499
  exports.txt = (0, combinator_1.union)([exports.text]);
7491
- exports.linebreak = (0, combinator_1.focus)('\n', (0, combinator_1.union)([exports.text]));
7500
+ exports.linebreak = (0, combinator_1.focus)(/^[\r\n]/, (0, combinator_1.union)([exports.text]));
7492
7501
  function isAlphanumeric(char) {
7493
7502
  if (char < '0' || '\x7F' < char) return false;
7494
7503
  return '0' <= char && char <= '9' || 'a' <= char && char <= 'z' || 'A' <= char && char <= 'Z';
@@ -7510,7 +7519,8 @@ exports.unescsource = void 0;
7510
7519
  const combinator_1 = __webpack_require__(2087);
7511
7520
  const text_1 = __webpack_require__(7763);
7512
7521
  exports.unescsource = (0, combinator_1.creation)(1, false, ({
7513
- source
7522
+ source,
7523
+ context
7514
7524
  }) => {
7515
7525
  if (source === '') return;
7516
7526
  const i = source.search(text_1.delimiter);
@@ -7519,6 +7529,11 @@ exports.unescsource = (0, combinator_1.creation)(1, false, ({
7519
7529
  return [[source], ''];
7520
7530
  case 0:
7521
7531
  {
7532
+ switch (source[0]) {
7533
+ case '\r':
7534
+ context.resources && ++context.resources.clock;
7535
+ return [[], source.slice(1)];
7536
+ }
7522
7537
  const b = source[0] !== '\n' && source[0].trimStart() === '';
7523
7538
  const i = b || (0, text_1.isAlphanumeric)(source[0]) ? source.search(b ? text_1.nonWhitespace : text_1.nonAlphanumeric) || 1 : 1;
7524
7539
  return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
@@ -7531,7 +7546,7 @@ exports.unescsource = (0, combinator_1.creation)(1, false, ({
7531
7546
  /***/ }),
7532
7547
 
7533
7548
  /***/ 9437:
7534
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
7549
+ /***/ ((__unused_webpack_module, exports) => {
7535
7550
 
7536
7551
  "use strict";
7537
7552
 
@@ -7539,12 +7554,7 @@ exports.unescsource = (0, combinator_1.creation)(1, false, ({
7539
7554
  Object.defineProperty(exports, "__esModule", ({
7540
7555
  value: true
7541
7556
  }));
7542
- exports.stringify = exports.format = void 0;
7543
- const combinator_1 = __webpack_require__(2087);
7544
- function format(parser) {
7545
- return (0, combinator_1.convert)(source => source.replace(/(?<=^!?)https?:\/\/(?:[[]|[^\p{C}\p{S}\p{P}\s])\S*(?=[^\S\n]*(?:$|\n))/gm, '{ $& }'), parser);
7546
- }
7547
- exports.format = format;
7557
+ exports.stringify = void 0;
7548
7558
  function stringify(nodes) {
7549
7559
  let acc = '';
7550
7560
  for (let i = 0; i < nodes.length; ++i) {
@@ -7576,13 +7586,12 @@ const parser_1 = __webpack_require__(6728);
7576
7586
  const combinator_1 = __webpack_require__(2087);
7577
7587
  const htmlentity_1 = __webpack_require__(1562);
7578
7588
  const source_1 = __webpack_require__(6743);
7579
- const util_1 = __webpack_require__(9437);
7580
7589
  const normalize_1 = __webpack_require__(185);
7581
7590
  const memoize_1 = __webpack_require__(1808);
7582
7591
  const array_1 = __webpack_require__(8112);
7583
7592
  function visualize(parser) {
7584
7593
  const blankline = new RegExp(/^(?:\\$|\\?[^\S\n]|&IHN;|<wbr[^\S\n]*>)+$/.source.replace('IHN', `(?:${normalize_1.invisibleHTMLEntityNames.join('|')})`), 'gm');
7585
- return (0, combinator_1.union)([(0, combinator_1.convert)(source => source.replace(blankline, line => line.replace(/[\\&<]/g, '\x1B$&')), (0, combinator_1.verify)((0, util_1.format)(parser), (ns, rest, context) => !rest && hasVisible(ns, context))), (0, combinator_1.some)((0, combinator_1.union)([source_1.linebreak, source_1.unescsource]))]);
7594
+ return (0, combinator_1.union)([(0, combinator_1.convert)(source => source.replace(blankline, line => line.replace(/[\\&<]/g, '\x1B$&')), (0, combinator_1.verify)(parser, (ns, rest, context) => !rest && hasVisible(ns, context))), (0, combinator_1.some)((0, combinator_1.union)([source_1.linebreak, source_1.unescsource]))]);
7586
7595
  }
7587
7596
  exports.visualize = visualize;
7588
7597
  function hasVisible(nodes, {
@@ -8388,7 +8397,7 @@ function unlink(h) {
8388
8397
  /***/ 3252:
8389
8398
  /***/ (function(module) {
8390
8399
 
8391
- /*! typed-dom v0.0.316 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8400
+ /*! typed-dom v0.0.317 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8392
8401
  (function webpackUniversalModuleDefinition(root, factory) {
8393
8402
  if(true)
8394
8403
  module.exports = factory();
@@ -8719,7 +8728,7 @@ exports.defrag = defrag;
8719
8728
  /***/ 6120:
8720
8729
  /***/ (function(module) {
8721
8730
 
8722
- /*! typed-dom v0.0.316 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8731
+ /*! typed-dom v0.0.317 https://github.com/falsandtru/typed-dom | (c) 2016, falsandtru | (Apache-2.0 AND MPL-2.0) License */
8723
8732
  (function webpackUniversalModuleDefinition(root, factory) {
8724
8733
  if(true)
8725
8734
  module.exports = factory();
package/markdown.d.ts CHANGED
@@ -346,7 +346,7 @@ export namespace MarkdownParser {
346
346
  BlockquoteParser,
347
347
  PlaceholderParser,
348
348
  InlineParser.MediaParser,
349
- InlineParser.ShortmediaParser,
349
+ InlineParser.ShortMediaParser,
350
350
  ]>,
351
351
  SourceParser.EmptyLineParser,
352
352
  InlineParser,
@@ -598,13 +598,10 @@ export namespace MarkdownParser {
598
598
  export interface TextParser extends
599
599
  Block<'reply/quote/text'>,
600
600
  Parser<string | HTMLElement, Context, [
601
- AutolinkParser.LineUrlParser,
602
- Parser<string | HTMLElement, Context, [
603
- InlineParser.MathParser,
604
- InlineParser.AutolinkParser,
605
- SourceParser.LinebreakParser,
606
- SourceParser.UnescapableSourceParser,
607
- ]>,
601
+ InlineParser.MathParser,
602
+ InlineParser.AutolinkParser,
603
+ SourceParser.LinebreakParser,
604
+ SourceParser.UnescapableSourceParser,
608
605
  ]> {
609
606
  }
610
607
  export interface PlaceholderParser extends
@@ -633,8 +630,9 @@ export namespace MarkdownParser {
633
630
  InlineParser.MathParser,
634
631
  InlineParser.ExtensionParser,
635
632
  InlineParser.RubyParser,
636
- InlineParser.LinkParser,
637
- InlineParser.MediaParser,
633
+ InlineParser.LinkParser.TextLinkParser,
634
+ InlineParser.LinkParser.LineMediaLinkParser,
635
+ InlineParser.MediaParser.LineMediaParser,
638
636
  InlineParser.HTMLParser,
639
637
  InlineParser.InsertionParser,
640
638
  InlineParser.DeletionParser,
@@ -643,7 +641,7 @@ export namespace MarkdownParser {
643
641
  InlineParser.EmphasisParser,
644
642
  InlineParser.CodeParser,
645
643
  InlineParser.HTMLEntityParser,
646
- InlineParser.ShortmediaParser,
644
+ InlineParser.ShortMediaParser.LineShortMediaParser,
647
645
  InlineParser.AutolinkParser,
648
646
  InlineParser.BracketParser,
649
647
  SourceParser.TextParser,
@@ -842,6 +840,12 @@ export namespace MarkdownParser {
842
840
  ]> {
843
841
  }
844
842
  export namespace LinkParser {
843
+ export interface LineMediaLinkParser extends
844
+ Inline<'link/linemedialink'>,
845
+ Parser<HTMLElement, Context, [
846
+ LinkParser.MediaLinkParser,
847
+ ]> {
848
+ }
845
849
  export interface TextLinkParser extends
846
850
  Inline<'link/textlink'>,
847
851
  Parser<HTMLAnchorElement, Context, [
@@ -856,7 +860,7 @@ export namespace MarkdownParser {
856
860
  Parser<HTMLAnchorElement, Context, [
857
861
  Parser<HTMLElement[], Context, [
858
862
  MediaParser,
859
- ShortmediaParser,
863
+ ShortMediaParser,
860
864
  ]>,
861
865
  LinkParser.ParameterParser,
862
866
  ]> {
@@ -872,7 +876,7 @@ export namespace MarkdownParser {
872
876
  Inline<'link/content'>,
873
877
  Parser<(HTMLElement | string)[], Context, [
874
878
  MediaParser,
875
- ShortmediaParser,
879
+ ShortMediaParser,
876
880
  InlineParser,
877
881
  ]> {
878
882
  }
@@ -917,6 +921,12 @@ export namespace MarkdownParser {
917
921
  ]> {
918
922
  }
919
923
  export namespace MediaParser {
924
+ export interface LineMediaParser extends
925
+ Inline<'media/linemedia'>,
926
+ Parser<HTMLElement, Context, [
927
+ MediaParser,
928
+ ]> {
929
+ }
920
930
  export interface TextParser extends
921
931
  Inline<'media/text'>,
922
932
  Parser<string[], Context, [
@@ -1060,28 +1070,41 @@ export namespace MarkdownParser {
1060
1070
  Inline<'unsafehtmlentity'>,
1061
1071
  Parser<string, Context, []> {
1062
1072
  }
1063
- export interface ShortmediaParser extends
1073
+ export interface ShortMediaParser extends
1064
1074
  // !https://host
1065
1075
  Inline<'shortmedia'>,
1066
1076
  Parser<HTMLElement, Context, [
1067
1077
  MediaParser,
1068
1078
  ]> {
1069
1079
  }
1080
+ export namespace ShortMediaParser {
1081
+ export interface LineShortMediaParser extends
1082
+ Inline<'shortmedia/lineshortmedia'>,
1083
+ Parser<HTMLElement, Context, [
1084
+ MediaParser,
1085
+ ]> {
1086
+ }
1087
+ }
1070
1088
  export interface AutolinkParser extends
1071
1089
  Inline<'autolink'>,
1072
1090
  Parser<HTMLElement | string, Context, [
1073
- AutolinkParser.UrlParser,
1074
- AutolinkParser.EmailParser,
1075
- SourceParser.StrParser,
1076
- AutolinkParser.ChannelParser,
1077
- AutolinkParser.AccountParser,
1078
- SourceParser.StrParser,
1079
- SourceParser.StrParser,
1080
- AutolinkParser.HashtagParser,
1081
- AutolinkParser.HashnumParser,
1082
- SourceParser.StrParser,
1083
- SourceParser.StrParser,
1084
- AutolinkParser.AnchorParser,
1091
+ Parser<HTMLElement | string, Context, [
1092
+ AutolinkParser.UrlParser.LineUrlParser,
1093
+ ]>,
1094
+ Parser<HTMLElement | string, Context, [
1095
+ AutolinkParser.UrlParser,
1096
+ AutolinkParser.EmailParser,
1097
+ SourceParser.StrParser,
1098
+ AutolinkParser.ChannelParser,
1099
+ AutolinkParser.AccountParser,
1100
+ SourceParser.StrParser,
1101
+ SourceParser.StrParser,
1102
+ AutolinkParser.HashtagParser,
1103
+ AutolinkParser.HashnumParser,
1104
+ SourceParser.StrParser,
1105
+ SourceParser.StrParser,
1106
+ AutolinkParser.AnchorParser,
1107
+ ]>,
1085
1108
  ]> {
1086
1109
  }
1087
1110
  export namespace AutolinkParser {
@@ -1093,6 +1116,13 @@ export namespace MarkdownParser {
1093
1116
  ]> {
1094
1117
  }
1095
1118
  export namespace UrlParser {
1119
+ export interface LineUrlParser extends
1120
+ Inline<'url/lineurl'>,
1121
+ Parser<string | HTMLElement, Context, [
1122
+ SourceParser.StrParser,
1123
+ InlineParser.LinkParser.UnsafeLinkParser,
1124
+ ]> {
1125
+ }
1096
1126
  export interface BracketParser extends
1097
1127
  Inline<'url/bracket'>,
1098
1128
  Parser<string, Context, [
@@ -1176,23 +1206,11 @@ export namespace MarkdownParser {
1176
1206
  export interface AutolinkParser extends
1177
1207
  Markdown<'autolink'>,
1178
1208
  Parser<string | HTMLElement, Context, [
1179
- AutolinkParser.LineUrlParser,
1180
- Parser<string | HTMLElement, Context, [
1181
- InlineParser.AutolinkParser,
1182
- SourceParser.LinebreakParser,
1183
- SourceParser.UnescapableSourceParser,
1184
- ]>,
1209
+ InlineParser.AutolinkParser,
1210
+ SourceParser.LinebreakParser,
1211
+ SourceParser.UnescapableSourceParser,
1185
1212
  ]> {
1186
1213
  }
1187
- export namespace AutolinkParser {
1188
- export interface LineUrlParser extends
1189
- Markdown<'autolink/lineurl'>,
1190
- Parser<string | HTMLElement, Context, [
1191
- SourceParser.StrParser,
1192
- InlineParser.LinkParser,
1193
- ]> {
1194
- }
1195
- }
1196
1214
  export namespace SourceParser {
1197
1215
  interface Source<T extends string> extends Markdown<`source/${T}`> { }
1198
1216
  export interface TextParser extends
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.268.1",
3
+ "version": "0.269.0",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
@@ -34,7 +34,7 @@
34
34
  "@types/mocha": "10.0.1",
35
35
  "@types/power-assert": "1.5.8",
36
36
  "@types/prismjs": "1.26.0",
37
- "@typescript-eslint/parser": "^5.53.0",
37
+ "@typescript-eslint/parser": "^5.54.0",
38
38
  "babel-loader": "^9.1.2",
39
39
  "babel-plugin-unassert": "^3.2.0",
40
40
  "concurrently": "^7.6.0",
@@ -49,11 +49,11 @@
49
49
  "karma-mocha": "^2.0.1",
50
50
  "karma-power-assert": "^1.0.0",
51
51
  "mocha": "^10.2.0",
52
- "npm-check-updates": "^16.7.9",
52
+ "npm-check-updates": "^16.7.10",
53
53
  "semver": "^7.3.8",
54
54
  "spica": "0.0.719",
55
55
  "ts-loader": "^9.4.2",
56
- "typed-dom": "^0.0.316",
56
+ "typed-dom": "^0.0.317",
57
57
  "typescript": "4.9.5",
58
58
  "webpack": "^5.75.0",
59
59
  "webpack-cli": "^5.0.1",
@@ -6,8 +6,8 @@ describe('Unit: parser/autolink', () => {
6
6
  const parser = (source: string) => autolink({ source, context: {} });
7
7
 
8
8
  it('basic', () => {
9
- assert.deepStrictEqual(inspect(parser(' http://host')), [[' ', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
10
- assert.deepStrictEqual(inspect(parser('!http://host')), [['!', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
9
+ assert.deepStrictEqual(inspect(parser('http://host#\\')), [['<a class="url" href="http://host#\\" target="_blank">http://host#\\</a>'], '']);
10
+ assert.deepStrictEqual(inspect(parser('!http://host#\\')), [['!', '<a class="url" href="http://host#\\" target="_blank">http://host#\\</a>'], '']);
11
11
  assert.deepStrictEqual(inspect(parser('#a')), [['<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
12
12
  assert.deepStrictEqual(inspect(parser('@a#b')), [['<a class="channel" href="/@a?ch=b">@a#b</a>'], '']);
13
13
  assert.deepStrictEqual(inspect(parser('\\\n')), [['\\', '<br>'], '']);
@@ -1,21 +1,14 @@
1
1
  import { MarkdownParser } from '../../markdown';
2
- import { union, tails, subsequence, some, line, focus, lazy } from '../combinator';
3
- import { link } from './inline/link';
2
+ import { union, some, convert, lazy } from '../combinator';
4
3
  import { autolink as autolink_ } from './inline/autolink';
5
- import { linebreak, unescsource, str } from './source';
6
- import { format } from './util';
4
+ import { linebreak, unescsource } from './source';
7
5
 
8
6
  export import AutolinkParser = MarkdownParser.AutolinkParser;
9
7
 
10
- export const autolink: AutolinkParser = lazy(() => some(line(subsequence([
11
- lineurl,
8
+ export const autolink: AutolinkParser = lazy(() =>
9
+ convert(source => `\r${source}`,
12
10
  some(union([
13
11
  autolink_,
14
12
  linebreak,
15
13
  unescsource,
16
- ])),
17
- ]))));
18
-
19
- export const lineurl: AutolinkParser.LineUrlParser = lazy(() => focus(
20
- /^!?https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/,
21
- format(tails([str('!'), link]))));
14
+ ]))));
@@ -30,9 +30,11 @@ describe('Unit: parser/block/paragraph', () => {
30
30
  assert.deepStrictEqual(inspect(parser('_a\n<wbr>_\nb')), [['<p>_a<br><wbr>_<br>b</p>'], '']);
31
31
  assert.deepStrictEqual(inspect(parser('*a\n<wbr>*\nb')), [['<p>*a<br><wbr>*<br>b</p>'], '']);
32
32
  assert.deepStrictEqual(inspect(parser('==a\n<wbr>==\nb')), [['<p>==a<br><wbr>==<br>b</p>'], '']);
33
- assert.deepStrictEqual(inspect(parser('http://host#!')), [['<p><a class="url" href="http://host#!" target="_blank">http://host#!</a></p>'], '']);
33
+ assert.deepStrictEqual(inspect(parser('http://host#\\')), [['<p><a class="url" href="http://host#\\" target="_blank">http://host#\\</a></p>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('a\nhttp://host#\\ \nb')), [['<p>a<br><a class="url" href="http://host#\\" target="_blank">http://host#\\</a><br>b</p>'], '']);
35
- assert.deepStrictEqual(inspect(parser('!http://host#!')), [['<p><a href="http://host#!" target="_blank"><img class="media" data-src="http://host#!" alt=""></a></p>'], '']);
35
+ assert.deepStrictEqual(inspect(parser('!http://host#\\')), [['<p><a href="http://host#\\" target="_blank"><img class="media" data-src="http://host#\\" alt=""></a></p>'], '']);
36
+ assert.deepStrictEqual(inspect(parser('!http://host#\\ a')), [['<p>!<a class="url" href="http://host#" target="_blank">http://host#</a> a</p>'], '']);
37
+ assert.deepStrictEqual(inspect(parser(' !http://host#\\')), [['<p> !<a class="url" href="http://host#" target="_blank">http://host#</a></p>'], '']);
36
38
  assert.deepStrictEqual(inspect(parser('\ta')), [['<p>\ta</p>'], '']);
37
39
  });
38
40
 
@@ -1,9 +1,10 @@
1
1
  import { ParagraphParser } from '../block';
2
- import { union, some, block, trimEnd, fmap } from '../../combinator';
2
+ import { union, some, block, convert, trimEnd, fmap } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { visualize } from '../visibility';
5
5
  import { html, defrag } from 'typed-dom/dom';
6
6
 
7
7
  export const paragraph: ParagraphParser = block(fmap(
8
- visualize(trimEnd(some(union([inline])))),
8
+ convert(source => `\r${source}`,
9
+ visualize(trimEnd(some(union([inline]))))),
9
10
  ns => [html('p', defrag(ns))]));
@@ -55,9 +55,9 @@ describe('Unit: parser/block/reply/quote', () => {
55
55
  assert.deepStrictEqual(inspect(parser('> $-a, $-b')), [['<span class="quote">&gt; $-a, $-b</span>', '<br>'], '']);
56
56
  assert.deepStrictEqual(inspect(parser('> $a=b$')), [['<span class="quote">&gt; <span class="math" translate="no" data-src="$a=b$">$a=b$</span></span>', '<br>'], '']);
57
57
  assert.deepStrictEqual(inspect(parser('> ${a}$')), [['<span class="quote">&gt; <span class="math" translate="no" data-src="${a}$">${a}$</span></span>', '<br>'], '']);
58
- assert.deepStrictEqual(inspect(parser('> http://host#!')), [['<span class="quote">&gt; <a class="url" href="http://host#!" target="_blank">http://host#!</a></span>', '<br>'], '']);
58
+ assert.deepStrictEqual(inspect(parser('> http://host#\\')), [['<span class="quote">&gt; <a class="url" href="http://host#\\" target="_blank">http://host#\\</a></span>', '<br>'], '']);
59
59
  assert.deepStrictEqual(inspect(parser('> a\n> http://host#\\ \n> b')), [['<span class="quote">&gt; a<br>&gt; <a class="url" href="http://host#\\" target="_blank">http://host#\\</a> <br>&gt; b</span>', '<br>'], '']);
60
- assert.deepStrictEqual(inspect(parser('> !http://host#!')), [['<span class="quote">&gt; !<a class="url" href="http://host#!" target="_blank">http://host#!</a></span>', '<br>'], '']);
60
+ assert.deepStrictEqual(inspect(parser('> !http://host#\\')), [['<span class="quote">&gt; !<a class="url" href="http://host#\\" target="_blank">http://host#\\</a></span>', '<br>'], '']);
61
61
  });
62
62
 
63
63
  });
@@ -1,10 +1,9 @@
1
1
  import { ReplyParser } from '../../block';
2
2
  import { eval } from '../../../combinator/data/parser';
3
- import { union, subsequence, some, creation, block, line, validate, rewrite, lazy, fmap } from '../../../combinator';
3
+ import { union, some, creation, block, line, validate, rewrite, lazy, fmap } from '../../../combinator';
4
4
  import { math } from '../../inline/math';
5
5
  import { autolink } from '../../inline/autolink';
6
6
  import { linebreak, unescsource, str, anyline } from '../../source';
7
- import { lineurl } from '../../autolink';
8
7
  import { html, defrag } from 'typed-dom/dom';
9
8
 
10
9
  export const syntax = /^>+(?=[^\S\n])|^>(?=[^\s>])|^>+(?=[^\s>])(?![0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:]))/;
@@ -42,7 +41,7 @@ const qblock: ReplyParser.QuoteParser.BlockParser = ({ source, context }) => {
42
41
  assert(quotes);
43
42
  assert(quotes.length > 0);
44
43
  const content = lines.reduce((acc, line, i) => acc + line.slice(quotes[i].length), '');
45
- const nodes = eval(text({ source: content, context }), []);
44
+ const nodes = eval(text({ source: `\r${content}`, context }), []);
46
45
  nodes.unshift(quotes.shift()!);
47
46
  for (let i = 0; i < nodes.length; ++i) {
48
47
  const child = nodes[i] as string | Text | Element;
@@ -72,12 +71,9 @@ const qblock: ReplyParser.QuoteParser.BlockParser = ({ source, context }) => {
72
71
  return [nodes, ''];
73
72
  };
74
73
 
75
- const text: ReplyParser.QuoteParser.TextParser = some(line(subsequence([
76
- lineurl,
77
- some(union([
78
- math, // quote補助関数が残した数式をパースする。他の構文で数式を残す場合はソーステキストを直接使用する。
79
- autolink,
80
- linebreak,
81
- unescsource,
82
- ])),
83
- ])));
74
+ const text: ReplyParser.QuoteParser.TextParser = some(union([
75
+ math, // quote補助関数が残した数式をパースする。他の構文で数式を残す場合はソーステキストを直接使用する。
76
+ autolink,
77
+ linebreak,
78
+ unescsource,
79
+ ]));
@@ -28,6 +28,8 @@ describe('Unit: parser/inline/autolink/url', () => {
28
28
  assert.deepStrictEqual(inspect(parser('http://a#( )')), [['<a class="url" href="http://a#" target="_blank">http://a#</a>'], '( )']);
29
29
  assert.deepStrictEqual(inspect(parser('http://a#(\n)')), [['<a class="url" href="http://a#" target="_blank">http://a#</a>'], '(\n)']);
30
30
  assert.deepStrictEqual(inspect(parser('http://[::]')), [['<a class="url" href="http://[::]" target="_blank">http://[::]</a>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('\rhttp://a#\\')), [['<a class="url" href="http://a#\\" target="_blank">http://a#\\</a>'], '']);
32
+ assert.deepStrictEqual(inspect(parser('\rhttp://a#\\\nhttp://b#\\')), [['<a class="url" href="http://a#\\" target="_blank">http://a#\\</a>', '<br>', '<a class="url" href="http://b#\\" target="_blank">http://b#\\</a>'], '']);
31
33
  });
32
34
 
33
35
  it('trailing symbols', () => {
@@ -1,7 +1,7 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, some, creation, precedence, validate, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
2
+ import { union, tails, some, creation, precedence, validate, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
3
3
  import { unsafelink } from '../link';
4
- import { unescsource } from '../../source';
4
+ import { linebreak, unescsource, str } from '../../source';
5
5
 
6
6
  const closer = /^[-+*=~^_,.;:!?]*(?=[\\"`|\[\](){}<>]|$)/;
7
7
 
@@ -13,6 +13,17 @@ export const url: AutolinkParser.UrlParser = lazy(() => validate(['http://', 'ht
13
13
  url => `{ ${url} }`,
14
14
  union([unsafelink])))));
15
15
 
16
+ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = open(
17
+ linebreak,
18
+ tails([
19
+ str('!'),
20
+ focus(
21
+ /^https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/,
22
+ convert(
23
+ url => `{ ${url} }`,
24
+ unsafelink)),
25
+ ]));
26
+
16
27
  const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => creation(precedence(2, union([
17
28
  surround('(', some(union([bracket, unescsource]), ')'), ')', true),
18
29
  surround('[', some(union([bracket, unescsource]), ']'), ']', true),
@@ -1,6 +1,6 @@
1
1
  import { AutolinkParser } from '../inline';
2
2
  import { union, some, syntax, constraint, validate, focus, fmap } from '../../combinator';
3
- import { url } from './autolink/url';
3
+ import { url, lineurl } from './autolink/url';
4
4
  import { email } from './autolink/email';
5
5
  import { channel } from './autolink/channel';
6
6
  import { account } from './autolink/account';
@@ -11,34 +11,37 @@ import { str } from '../source';
11
11
  import { Syntax, State } from '../context';
12
12
  import { stringify } from '../util';
13
13
 
14
- export const autolink: AutolinkParser = fmap(
15
- validate(/^(?:[@#>0-9a-z]|\S[#>])/i,
14
+ export const autolink: AutolinkParser =
15
+ validate(/^(?:[@#>0-9a-z\r\n]|\S[#>])/i,
16
16
  constraint(State.autolink, false,
17
17
  syntax(Syntax.autolink, 1, 1, ~State.shortcut,
18
- some(union([
19
- url,
20
- email,
21
- // Escape unmatched email-like strings.
22
- focus(
23
- /^[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z])*(?:@(?:[0-9a-z]+(?:[.-][0-9a-z]+)*)?)*/i,
24
- ({ source }) => {
25
- if (source.length > 255 || source.includes('@')) return [[source], ''];
26
- const i = source.indexOf('_');
27
- if (i === -1) return [[source], ''];
28
- return [[source.slice(0, i)], source.slice(i)];
29
- }),
30
- channel,
31
- account,
32
- // Escape unmatched account-like strings.
33
- str(/^@+[0-9a-z]*(?:-[0-9a-z]+)*/i),
34
- // Escape invalid leading characters.
35
- str(new RegExp(/^(?:[^\p{C}\p{S}\p{P}\s]|emoji)(?=#)/u.source.replace('emoji', emoji), 'u')),
36
- hashtag,
37
- hashnum,
38
- // Escape unmatched hashtag-like strings.
39
- str(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|')*/u.source.replace('emoji', emoji), 'u')),
40
- // Escape invalid leading characters.
41
- str(/^[0-9\p{Sc}](?=>)/u),
42
- anchor,
43
- ]))))),
44
- ns => ns.length === 1 ? ns : [stringify(ns)]);
18
+ union([
19
+ some(union([lineurl])),
20
+ fmap(some(union([
21
+ url,
22
+ email,
23
+ // Escape unmatched email-like strings.
24
+ focus(
25
+ /^[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z])*(?:@(?:[0-9a-z]+(?:[.-][0-9a-z]+)*)?)*/i,
26
+ ({ source }) => {
27
+ if (source.length > 255 || source.includes('@')) return [[source], ''];
28
+ const i = source.indexOf('_');
29
+ if (i === -1) return [[source], ''];
30
+ return [[source.slice(0, i)], source.slice(i)];
31
+ }),
32
+ channel,
33
+ account,
34
+ // Escape unmatched account-like strings.
35
+ str(/^@+[0-9a-z]*(?:-[0-9a-z]+)*/i),
36
+ // Escape invalid leading characters.
37
+ str(new RegExp(/^(?:[^\p{C}\p{S}\p{P}\s]|emoji)(?=#)/u.source.replace('emoji', emoji), 'u')),
38
+ hashtag,
39
+ hashnum,
40
+ // Escape unmatched hashtag-like strings.
41
+ str(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|')*/u.source.replace('emoji', emoji), 'u')),
42
+ // Escape invalid leading characters.
43
+ str(/^[0-9\p{Sc}](?=>)/u),
44
+ anchor,
45
+ ])),
46
+ ns => ns.length === 1 ? ns : [stringify(ns)]),
47
+ ]))));
@@ -14,12 +14,13 @@ export function identity(id: string | undefined, text: string, name: 'index' | '
14
14
  if (id === '') return undefined;
15
15
  text &&= text.trim().replace(/\s+/g, '_');
16
16
  if (text === '') return undefined;
17
- if (text.length <= 100) return `${name}:${id ?? ''}:${text}`;
17
+ const cs = [...text];
18
+ if (cs.length <= 100) return `${name}:${id ?? ''}:${text}`;
18
19
  switch (name) {
19
20
  case 'index':
20
- return `${name}:${id ?? ''}:${text.slice(0, 97)}...`;
21
+ return `${name}:${id ?? ''}:${cs.slice(0, 97).join('')}...`;
21
22
  case 'mark':
22
- return `${name}:${id ?? ''}:${text.slice(0, 50)}...${text.slice(-47)}`;
23
+ return `${name}:${id ?? ''}:${cs.slice(0, 50).join('')}...${cs.slice(-47).join('')}`;
23
24
  }
24
25
  assert(false);
25
26
  }
@@ -48,7 +48,7 @@ describe('Unit: parser/inline/extension/placeholder', () => {
48
48
  assert.deepStrictEqual(inspect(parser('[^a[% b %][% c %]]')), [['<span class="invalid">a<span class="comment"><input type="checkbox"><span>[% b %]</span></span><span class="comment"><input type="checkbox"><span>[% c %]</span></span></span>'], '']);
49
49
  assert.deepStrictEqual(inspect(parser('[^\\]]')), [['<span class="invalid">]</span>'], '']);
50
50
  assert.deepStrictEqual(inspect(parser('[^(])]')), [['<span class="invalid"><span class="paren">(])</span></span>'], '']);
51
- assert.deepStrictEqual(inspect(parser('[^!http://host]')), [['<span class="invalid"><a href="http://host" target="_blank"><img class="media" data-src="http://host" alt=""></a></span>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('[^!http://host]')), [['<span class="invalid">!<a class="url" href="http://host" target="_blank">http://host</a></span>'], '']);
52
52
  assert.deepStrictEqual(inspect(parser('[^[% a %]]')), [['<span class="invalid"><span class="comment"><input type="checkbox"><span>[% a %]</span></span></span>'], '']);
53
53
  assert.deepStrictEqual(inspect(parser('[^[% a %]b]')), [['<span class="invalid"><span class="comment"><input type="checkbox"><span>[% a %]</span></span>b</span>'], '']);
54
54
  });
@@ -4,7 +4,7 @@ import { Result } from '../../combinator/data/parser';
4
4
  import { union, inits, tails, sequence, some, constraint, syntax, creation, precedence, 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
- import { unescsource, str } from '../source';
7
+ import { linebreak, unescsource, str } from '../source';
8
8
  import { Syntax, State } from '../context';
9
9
  import { trimNode } from '../visibility';
10
10
  import { stringify } from '../util';
@@ -21,7 +21,7 @@ export const link: LinkParser = lazy(() => validate(['[', '{'], union([
21
21
  textlink,
22
22
  ])));
23
23
 
24
- const textlink: LinkParser.TextLinkParser = lazy(() =>
24
+ export const textlink: LinkParser.TextLinkParser = lazy(() =>
25
25
  constraint(State.link, false,
26
26
  syntax(Syntax.link, 2, 10, State.linkers | State.media,
27
27
  bind(reverse(tails([
@@ -37,7 +37,7 @@ const textlink: LinkParser.TextLinkParser = lazy(() =>
37
37
  return parse(content, params, rest, context);
38
38
  }))));
39
39
 
40
- const medialink: LinkParser.MediaLinkParser = lazy(() =>
40
+ export const medialink: LinkParser.MediaLinkParser = lazy(() =>
41
41
  constraint(State.link | State.media, false,
42
42
  syntax(Syntax.link, 2, 10, State.linkers,
43
43
  bind(reverse(sequence([
@@ -50,6 +50,11 @@ const medialink: LinkParser.MediaLinkParser = lazy(() =>
50
50
  ([params, content = []]: [string[], (HTMLElement | string)[]], rest, context) =>
51
51
  parse(content, params, rest, context)))));
52
52
 
53
+ export const linemedialink: LinkParser.LineMediaLinkParser = surround(
54
+ linebreak,
55
+ union([medialink]),
56
+ /^(?=[^\S\n]*(?:$|\n))/);
57
+
53
58
  export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
54
59
  creation(10, precedence(2,
55
60
  bind(reverse(tails([
@@ -3,7 +3,7 @@ import { union, inits, tails, some, syntax, creation, precedence, constraint, va
3
3
  import { unsafelink, uri, option as linkoption, resolve } from './link';
4
4
  import { attributes } from './html';
5
5
  import { unsafehtmlentity } from './htmlentity';
6
- import { txt, str } from '../source';
6
+ import { txt, linebreak, str } from '../source';
7
7
  import { Syntax, State } from '../context';
8
8
  import { ReadonlyURL } from 'spica/url';
9
9
  import { unshift, push } from 'spica/array';
@@ -61,6 +61,11 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
61
61
  ({ source: `{ ${INSECURE_URI}${params.join('')} }${rest}`, context });
62
62
  }))))));
63
63
 
64
+ export const linemedia: MediaParser.LineMediaParser = surround(
65
+ linebreak,
66
+ union([media]),
67
+ /^(?=[^\S\n]*(?:$|\n))/);
68
+
64
69
  const bracket: MediaParser.TextParser.BracketParser = lazy(() => creation(union([
65
70
  surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
66
71
  surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
@@ -1,12 +1,21 @@
1
- import { ShortmediaParser } from '../inline';
2
- import { union, constraint, rewrite, open, convert } from '../../combinator';
1
+ import { ShortMediaParser } from '../inline';
2
+ import { union, constraint, focus, rewrite, open, convert } from '../../combinator';
3
3
  import { url } from './autolink/url';
4
4
  import { media } from './media';
5
+ import { linebreak } from '../source';
5
6
  import { State } from '../context';
6
7
 
7
- export const shortmedia: ShortmediaParser = rewrite(
8
+ export const shortmedia: ShortMediaParser = rewrite(
8
9
  constraint(State.media, false,
9
10
  open('!', url)),
10
11
  convert(
11
12
  source => `!{ ${source.slice(1)} }`,
12
13
  union([media])));
14
+
15
+ export const lineshortmedia: ShortMediaParser.LineShortMediaParser = open(
16
+ linebreak,
17
+ focus(
18
+ /^!https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/,
19
+ convert(
20
+ source => `!{ ${source.slice(1)} }`,
21
+ union([media]))));
@@ -56,11 +56,11 @@ describe('Unit: parser/inline', () => {
56
56
  assert.deepStrictEqual(inspect(parser('{}')), [['{', '}'], '']);
57
57
  assert.deepStrictEqual(inspect(parser('{a}')), [['<a class="url" href="a">a</a>'], '']);
58
58
  assert.deepStrictEqual(inspect(parser('{{a}}')), [['<span class="template">{{a}}</span>'], '']);
59
- assert.deepStrictEqual(inspect(parser('!{}')), [['!', '{', '}'], '']);
60
- assert.deepStrictEqual(inspect(parser('!{a}')), [['<a href="a" target="_blank"><img class="media" data-src="a" alt=""></a>'], '']);
61
- assert.deepStrictEqual(inspect(parser('!{{a}}')), [['!', '<span class="template">{{a}}</span>'], '']);
62
- assert.deepStrictEqual(inspect(parser('!{{{a}}}')), [['!', '<span class="template">{{{a}}}</span>'], '']);
63
- assert.deepStrictEqual(inspect(parser('!!{a}')), [['!', '<a href="a" target="_blank"><img class="media" data-src="a" alt=""></a>'], '']);
59
+ assert.deepStrictEqual(inspect(parser('\r!{}')), [['!', '{', '}'], '']);
60
+ assert.deepStrictEqual(inspect(parser('\r!{a}')), [['<a href="a" target="_blank"><img class="media" data-src="a" alt=""></a>'], '']);
61
+ assert.deepStrictEqual(inspect(parser('\r!{{a}}')), [['!', '<span class="template">{{a}}</span>'], '']);
62
+ assert.deepStrictEqual(inspect(parser('\r!{{{a}}}')), [['!', '<span class="template">{{{a}}}</span>'], '']);
63
+ assert.deepStrictEqual(inspect(parser('\r!!{a}')), [['!', '!', '<a class="url" href="a">a</a>'], '']);
64
64
  assert.deepStrictEqual(inspect(parser('${a}')), [['$', '<a class="url" href="a">a</a>'], '']);
65
65
  assert.deepStrictEqual(inspect(parser('${{a}}')), [['$', '<span class="template">{{a}}</span>'], '']);
66
66
  assert.deepStrictEqual(inspect(parser('${{{a}}}')), [['$', '<span class="template">{{{a}}}</span>'], '']);
@@ -105,11 +105,8 @@ describe('Unit: parser/inline', () => {
105
105
  assert.deepStrictEqual(inspect(parser('0http://host')), [['0http', ':', '/', '/', 'host'], '']);
106
106
  assert.deepStrictEqual(inspect(parser('0aAhttp://host')), [['0aAhttp', ':', '/', '/', 'host'], '']);
107
107
  assert.deepStrictEqual(inspect(parser('?http://host')), [['?', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
108
- assert.deepStrictEqual(inspect(parser('0!http://host')), [['0', '<a href="http://host" target="_blank"><img class="media" data-src="http://host" alt=""></a>'], '']);
108
+ assert.deepStrictEqual(inspect(parser('0!http://host')), [['0', '!', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
109
109
  assert.deepStrictEqual(inspect(parser('0?http://host')), [['0', '?', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
110
- assert.deepStrictEqual(inspect(parser('0!!http://host')), [['0', '!', '<a href="http://host" target="_blank"><img class="media" data-src="http://host" alt=""></a>'], '']);
111
- assert.deepStrictEqual(inspect(parser('0?!http://host')), [['0', '?', '<a href="http://host" target="_blank"><img class="media" data-src="http://host" alt=""></a>'], '']);
112
- assert.deepStrictEqual(inspect(parser('0!?http://host')), [['0', '!', '?', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
113
110
  assert.deepStrictEqual(inspect(parser('_http://host')), [['_', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
114
111
  assert.deepStrictEqual(inspect(parser('_http://host_')), [['<em><a class="url" href="http://host" target="_blank">http://host</a></em>'], '']);
115
112
  assert.deepStrictEqual(inspect(parser('*http://host*')), [['<strong><a class="url" href="http://host" target="_blank">http://host</a></strong>'], '']);
@@ -7,7 +7,7 @@ import { comment } from './inline/comment';
7
7
  import { math } from './inline/math';
8
8
  import { extension } from './inline/extension';
9
9
  import { ruby } from './inline/ruby';
10
- import { link } from './inline/link';
10
+ import { textlink, linemedialink } from './inline/link';
11
11
  import { html } from './inline/html';
12
12
  import { insertion } from './inline/insertion';
13
13
  import { deletion } from './inline/deletion';
@@ -15,9 +15,9 @@ import { mark } from './inline/mark';
15
15
  import { emphasis } from './inline/emphasis';
16
16
  import { strong } from './inline/strong';
17
17
  import { code } from './inline/code';
18
- import { media } from './inline/media';
18
+ import { linemedia } from './inline/media';
19
19
  import { htmlentity } from './inline/htmlentity';
20
- import { shortmedia } from './inline/shortmedia';
20
+ import { lineshortmedia } from './inline/shortmedia';
21
21
  import { autolink } from './inline/autolink';
22
22
  import { bracket } from './inline/bracket';
23
23
  import { text } from './source';
@@ -41,7 +41,7 @@ export import CodeParser = InlineParser.CodeParser;
41
41
  export import MediaParser = InlineParser.MediaParser;
42
42
  export import HTMLEntityParser = InlineParser.HTMLEntityParser;
43
43
  export import UnsafeHTMLEntityParser = InlineParser.UnsafeHTMLEntityParser;
44
- export import ShortmediaParser = InlineParser.ShortmediaParser;
44
+ export import ShortMediaParser = InlineParser.ShortMediaParser;
45
45
  export import AutolinkParser = InlineParser.AutolinkParser;
46
46
  export import BracketParser = InlineParser.BracketParser;
47
47
 
@@ -53,8 +53,9 @@ export const inline: InlineParser = union([
53
53
  math,
54
54
  extension,
55
55
  ruby,
56
- link,
57
- media,
56
+ textlink,
57
+ linemedialink,
58
+ linemedia,
58
59
  html,
59
60
  insertion,
60
61
  deletion,
@@ -63,7 +64,7 @@ export const inline: InlineParser = union([
63
64
  emphasis,
64
65
  code,
65
66
  htmlentity,
66
- shortmedia,
67
+ lineshortmedia,
67
68
  autolink,
68
69
  bracket,
69
70
  text
@@ -4,7 +4,7 @@ import { nonWhitespace } from './text';
4
4
 
5
5
  const delimiter = /[\s\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]/;
6
6
 
7
- export const escsource: EscapableSourceParser = creation(1, false, ({ source }) => {
7
+ export const escsource: EscapableSourceParser = creation(1, false, ({ source, context }) => {
8
8
  if (source === '') return;
9
9
  const i = source.search(delimiter);
10
10
  switch (i) {
@@ -12,6 +12,10 @@ export const escsource: EscapableSourceParser = creation(1, false, ({ source })
12
12
  return [[source], ''];
13
13
  case 0:
14
14
  switch (source[0]) {
15
+ case '\r':
16
+ assert(!source.includes('\r', 1));
17
+ context.resources && ++context.resources.clock;
18
+ return [[], source.slice(1)];
15
19
  case '\x1B':
16
20
  return [[source.slice(1, 2)], source.slice(2)];
17
21
  case '\\':
@@ -16,6 +16,10 @@ export const text: TextParser = creation(1, false, ({ source, context }) => {
16
16
  return [[source], ''];
17
17
  case 0:
18
18
  switch (source[0]) {
19
+ case '\r':
20
+ assert(!source.includes('\r', 1));
21
+ context.resources && ++context.resources.clock;
22
+ return [[], source.slice(1)];
19
23
  case '\x1B':
20
24
  case '\\':
21
25
  switch (source[1]) {
@@ -60,7 +64,7 @@ export const txt: TxtParser = union([
60
64
  text,
61
65
  ]) as TxtParser;
62
66
 
63
- export const linebreak: LinebreakParser = focus('\n', union([
67
+ export const linebreak: LinebreakParser = focus(/^[\r\n]/, union([
64
68
  text,
65
69
  ])) as LinebreakParser;
66
70
 
@@ -2,7 +2,7 @@ import { UnescapableSourceParser } from '../source';
2
2
  import { creation } from '../../combinator';
3
3
  import { delimiter, nonWhitespace, nonAlphanumeric, isAlphanumeric } from './text';
4
4
 
5
- export const unescsource: UnescapableSourceParser = creation(1, false, ({ source }) => {
5
+ export const unescsource: UnescapableSourceParser = creation(1, false, ({ source, context }) => {
6
6
  assert(source[0] !== '\x1B');
7
7
  if (source === '') return;
8
8
  const i = source.search(delimiter);
@@ -10,6 +10,12 @@ export const unescsource: UnescapableSourceParser = creation(1, false, ({ source
10
10
  case -1:
11
11
  return [[source], ''];
12
12
  case 0: {
13
+ switch (source[0]) {
14
+ case '\r':
15
+ assert(!source.includes('\r', 1));
16
+ context.resources && ++context.resources.clock;
17
+ return [[], source.slice(1)];
18
+ }
13
19
  const b = source[0] !== '\n' && source[0].trimStart() === '';
14
20
  const i = b || isAlphanumeric(source[0])
15
21
  ? source.search(b ? nonWhitespace : nonAlphanumeric) || 1
@@ -1,13 +1,3 @@
1
- import { Parser } from '../combinator/data/parser';
2
- import { convert } from '../combinator';
3
-
4
- export function format<P extends Parser<HTMLElement | string>>(parser: P): P;
5
- export function format<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
6
- return convert(
7
- source => source.replace(/(?<=^!?)https?:\/\/(?:[[]|[^\p{C}\p{S}\p{P}\s])\S*(?=[^\S\n]*(?:$|\n))/gm, '{ $& }'),
8
- parser);
9
- }
10
-
11
1
  export function stringify(nodes: readonly (HTMLElement | string)[]): string {
12
2
  let acc = '';
13
3
  for (let i = 0; i < nodes.length; ++i) {
@@ -4,7 +4,6 @@ import { union, some, verify, convert, fmap } from '../combinator';
4
4
  import { unsafehtmlentity } from './inline/htmlentity';
5
5
  import { linebreak, unescsource } from './source';
6
6
  import { State } from './context';
7
- import { format } from './util';
8
7
  import { invisibleHTMLEntityNames } from './api/normalize';
9
8
  import { reduce } from 'spica/memoize';
10
9
  import { push } from 'spica/array';
@@ -17,7 +16,7 @@ export function visualize<T extends HTMLElement | string>(parser: Parser<T>): Pa
17
16
  return union([
18
17
  convert(
19
18
  source => source.replace(blankline, line => line.replace(/[\\&<]/g, '\x1B$&')),
20
- verify(format(parser), (ns, rest, context) => !rest && hasVisible(ns, context))),
19
+ verify(parser, (ns, rest, context) => !rest && hasVisible(ns, context))),
21
20
  some(union([linebreak, unescsource])),
22
21
  ]);
23
22
  }
package/src/util/info.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ParseSelector } from 'typed-query-selector/parser';
1
2
  import { Info } from '../..';
2
3
  import { scope } from './scope';
3
4
 
@@ -16,9 +17,10 @@ export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info
16
17
  media: find('.media[data-src]'),
17
18
  };
18
19
 
19
- function find<T extends HTMLElement>(selector: string): T[] {
20
- const acc: T[] = [];
21
- for (let es = source.querySelectorAll<T>(selector),
20
+ function find<T extends string>(selector: T): ParseSelector<T, HTMLElement>[];
21
+ function find(selector: string): HTMLElement[] {
22
+ const acc = [];
23
+ for (let es = source.querySelectorAll<HTMLElement>(selector),
22
24
  len = es.length, i = 0; i < len; ++i) {
23
25
  const el = es[i];
24
26
  match(el) && acc.push(el);
@@ -5,10 +5,10 @@ describe('Unit: util/quote', () => {
5
5
  describe('quote', () => {
6
6
  it('basic', () => {
7
7
  const range = document.createRange();
8
- const el = parse('>>1\n>2\n> a\n>>4 `b` ${c}$ !{d}\n [e](f) ').firstElementChild!;
8
+ const el = parse('>>1\n>2\n> a\n>>4 `b` ${c}$\n!{d}\n [e](f) ').firstElementChild!;
9
9
  range.setStart(el.firstChild!.firstChild!, 0);
10
10
  range.setEnd(el.lastChild!.lastChild!.lastChild!, 1);
11
- assert(quote('3', range) === `>>>1\n> >2\n>> a\n>>3\n> >>4 \`b\` \${c}$ !{d}\n> e`);
11
+ assert(quote('3', range) === `>>>1\n> >2\n>> a\n>>3\n> >>4 \`b\` \${c}$\n> !{d}\n> e`);
12
12
  });
13
13
 
14
14
  it('adjustment', () => {