securemark 0.233.1 → 0.234.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,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.234.0
4
+
5
+ - Extend anchor syntax.
6
+ - Refine comment parser.
7
+
8
+ ## 0.233.3
9
+
10
+ - Refactoring.
11
+
12
+ ## 0.233.2
13
+
14
+ - Refactoring.
15
+
3
16
  ## 0.233.1
4
17
 
5
18
  - Refactoring.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.233.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.234.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
2
2
  require = function () {
3
3
  function r(e, n, t) {
4
4
  function o(i, f) {
@@ -4467,22 +4467,19 @@ require = function () {
4467
4467
  const typed_dom_1 = _dereq_('typed-dom');
4468
4468
  const url_1 = _dereq_('spica/url');
4469
4469
  function parse(source, opts = {}, context) {
4470
- var _a, _b, _c, _d, _e, _f, _g, _h;
4470
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
4471
4471
  if (!(0, segment_1.validate)(source, segment_1.MAX_SEGMENT_SIZE))
4472
4472
  throw new Error(`Too large input over ${ segment_1.MAX_SEGMENT_SIZE.toLocaleString('en') } bytes.`);
4473
4473
  const url = (_b = (_a = (0, header_2.headers)(source).find(field => field.toLowerCase().startsWith('url:'))) === null || _a === void 0 ? void 0 : _a.slice(4).trim()) !== null && _b !== void 0 ? _b : '';
4474
4474
  source = !context ? (0, normalize_1.normalize)(source) : source;
4475
- context = context && url === '' && context.id === opts.id ? context : (0, alias_1.ObjectAssign)({
4476
- ...context,
4477
- ...opts
4478
- }, {
4475
+ context = context && url === '' && context.id === opts.id ? context : (0, alias_1.ObjectAssign)((0, alias_1.ObjectCreate)(context !== null && context !== void 0 ? context : {}), opts, {
4479
4476
  host: (_d = (_c = opts.host) !== null && _c !== void 0 ? _c : context === null || context === void 0 ? void 0 : context.host) !== null && _d !== void 0 ? _d : new url_1.ReadonlyURL(global_1.location.pathname, global_1.location.origin),
4480
4477
  url: url ? new url_1.ReadonlyURL(url) : context === null || context === void 0 ? void 0 : context.url,
4481
4478
  id: (_e = opts.id) !== null && _e !== void 0 ? _e : context === null || context === void 0 ? void 0 : context.id,
4482
4479
  footnotes: global_1.undefined,
4483
4480
  test: global_1.undefined
4484
4481
  });
4485
- if (((_f = context.host) === null || _f === void 0 ? void 0 : _f.origin) === 'null')
4482
+ if (((_g = context.host) === null || _g === void 0 ? void 0 : _g.origin) === 'null')
4486
4483
  throw new Error(`Invalid host: ${ context.host.href }`);
4487
4484
  const node = (0, typed_dom_1.frag)();
4488
4485
  let index = 0;
@@ -5625,7 +5622,7 @@ require = function () {
5625
5622
  } = {}
5626
5623
  }) => {
5627
5624
  var _a;
5628
- return [delim.length === 2 && closer && param.trimStart() === '' ? ((_a = cache === null || cache === void 0 ? void 0 : cache.get(`\n${ body }`)) === null || _a === void 0 ? void 0 : _a.cloneNode(true)) || (0, typed_dom_1.html)('div', {
5625
+ return [delim.length === 2 && closer && param.trimStart() === '' ? ((_a = cache === null || cache === void 0 ? void 0 : cache.get(`${ delim }\n${ body }${ delim }`)) === null || _a === void 0 ? void 0 : _a.cloneNode(true)) || (0, typed_dom_1.html)('div', {
5629
5626
  class: 'math',
5630
5627
  translate: 'no'
5631
5628
  }, `${ delim }\n${ body }${ delim }`) : (0, typed_dom_1.html)('pre', {
@@ -5847,8 +5844,14 @@ require = function () {
5847
5844
  const source_1 = _dereq_('../../source');
5848
5845
  const typed_dom_1 = _dereq_('typed-dom');
5849
5846
  exports.cite = (0, combinator_1.creator)((0, combinator_1.line)((0, combinator_1.fmap)((0, combinator_1.validate)('>>', (0, combinator_1.reverse)((0, combinator_1.tails)([
5850
- (0, source_1.str)(/^>*(?=>>)/),
5851
- (0, combinator_1.validate)(new RegExp(`${ anchor_1.syntax.source }[^\S\n]*(?:$|\n)`), anchor_1.anchor)
5847
+ (0, source_1.str)(/^>*(?=>>[^>\s]+[^\S\n]*(?:$|\n))/),
5848
+ (0, combinator_1.union)([
5849
+ anchor_1.anchor,
5850
+ (0, combinator_1.focus)(/^>>\.[^\S\n]*(?:$|\n)/, () => [
5851
+ [(0, typed_dom_1.html)('a', { class: 'anchor' }, '>>.')],
5852
+ ''
5853
+ ])
5854
+ ])
5852
5855
  ]))), ([el, quotes = '']) => [
5853
5856
  (0, typed_dom_1.html)('span', { class: 'cite' }, (0, typed_dom_1.defrag)([
5854
5857
  `${ quotes }>`,
@@ -6340,24 +6343,21 @@ require = function () {
6340
6343
  function (_dereq_, module, exports) {
6341
6344
  'use strict';
6342
6345
  Object.defineProperty(exports, '__esModule', { value: true });
6343
- exports.anchor = exports.syntax = void 0;
6346
+ exports.anchor = void 0;
6344
6347
  const combinator_1 = _dereq_('../../../combinator');
6345
6348
  const link_1 = _dereq_('../link');
6346
- const source_1 = _dereq_('../../source');
6347
6349
  const typed_dom_1 = _dereq_('typed-dom');
6348
- exports.syntax = /^>>[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:])/;
6349
- exports.anchor = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('>>', (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, source_1.str)(exports.syntax), (0, combinator_1.context)({
6350
+ exports.anchor = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('>>', (0, combinator_1.fmap)((0, combinator_1.focus)(/^>>(?:[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*\/)?[0-9A-Za-z]+(?:-[0-9A-Za-z]+)*(?![0-9A-Za-z@#:])/, (0, combinator_1.context)({
6350
6351
  syntax: {
6351
6352
  inline: {
6352
6353
  link: true,
6353
6354
  autolink: false
6354
6355
  }
6355
6356
  }
6356
- }, (0, combinator_1.convert)(source => `[${ source }]{ ?comment=${ source.slice(2) } }`, (0, combinator_1.union)([link_1.link])))), ([el]) => [(0, typed_dom_1.define)(el, { class: 'anchor' })])));
6357
+ }, (0, combinator_1.convert)(source => `[${ source }]{ ${ source.includes('/') ? `/@${ source.slice(2).replace('/', '/timeline/') }` : `?at=${ source.slice(2) }` } }`, (0, combinator_1.union)([link_1.link])))), ([el]) => [(0, typed_dom_1.define)(el, { class: 'anchor' })])));
6357
6358
  },
6358
6359
  {
6359
6360
  '../../../combinator': 27,
6360
- '../../source': 128,
6361
6361
  '../link': 114,
6362
6362
  'typed-dom': 26
6363
6363
  }
@@ -6606,24 +6606,25 @@ require = function () {
6606
6606
  'use strict';
6607
6607
  Object.defineProperty(exports, '__esModule', { value: true });
6608
6608
  exports.comment = void 0;
6609
- const parser_1 = _dereq_('../../combinator/data/parser');
6610
6609
  const combinator_1 = _dereq_('../../combinator');
6611
6610
  const inline_1 = _dereq_('../inline');
6612
6611
  const source_1 = _dereq_('../source');
6613
6612
  const typed_dom_1 = _dereq_('typed-dom');
6614
6613
  const memoize_1 = _dereq_('spica/memoize');
6615
6614
  const array_1 = _dereq_('spica/array');
6616
- exports.comment = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[#', (0, combinator_1.match)(/^(?=\[(#+)\s)/, (0, memoize_1.memoize)(([, fence], closer = new RegExp(String.raw`^\s+${ fence }\]`)) => (0, combinator_1.surround)((0, source_1.str)(/^\[(\S+)\s+(?!\1\])/), (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, closer)]), (0, source_1.str)(closer), true, ([, bs = []], rest) => [
6617
- [(0, typed_dom_1.html)('span', { class: 'comment' }, (0, typed_dom_1.defrag)((0, array_1.push)((0, array_1.unshift)([`[${ fence } `], bs), [` ${ fence }]`])))],
6615
+ exports.comment = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[#', (0, combinator_1.match)(/^(?=\[(#+)\s)/, (0, memoize_1.memoize)(([, fence]) => (0, combinator_1.surround)((0, combinator_1.open)((0, source_1.str)(`[${ fence }`), (0, combinator_1.some)(source_1.text, new RegExp(String.raw`^\s+${ fence }\]|^\S`)), true), (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, new RegExp(String.raw`^\s+${ fence }\]`))]), (0, combinator_1.close)((0, combinator_1.some)(source_1.text, /^\S/), (0, source_1.str)(`${ fence }]`)), true, ([as, bs = [], cs], rest) => [
6616
+ [(0, typed_dom_1.html)('span', { class: 'comment' }, [
6617
+ (0, typed_dom_1.html)('input', { type: 'checkbox' }),
6618
+ (0, typed_dom_1.html)('span', (0, typed_dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))
6619
+ ])],
6618
6620
  rest
6619
- ], ([as, bs = []], rest, context) => [
6620
- (0, array_1.unshift)((0, array_1.pop)((0, parser_1.eval)((0, combinator_1.some)(source_1.text)(`${ as[0] }!`, context)))[0], bs),
6621
+ ], ([as, bs = []], rest) => [
6622
+ (0, array_1.unshift)(as, bs),
6621
6623
  rest
6622
6624
  ]), ([, fence]) => fence)))));
6623
6625
  },
6624
6626
  {
6625
6627
  '../../combinator': 27,
6626
- '../../combinator/data/parser': 47,
6627
6628
  '../inline': 88,
6628
6629
  '../source': 128,
6629
6630
  'spica/array': 6,
@@ -7284,13 +7285,13 @@ require = function () {
7284
7285
  const url_1 = _dereq_('spica/url');
7285
7286
  const optspec = { rel: ['nofollow'] };
7286
7287
  (0, alias_1.ObjectSetPrototypeOf)(optspec, null);
7287
- exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.validate)([
7288
+ exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.bind)((0, combinator_1.validate)([
7288
7289
  '[',
7289
7290
  '{'
7290
7291
  ], '}', '\n', (0, combinator_1.guard)(context => {
7291
7292
  var _a, _b, _c;
7292
7293
  return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.link) !== null && _c !== void 0 ? _c : true;
7293
- }, (0, combinator_1.tails)([
7294
+ }, (0, combinator_1.reverse)((0, combinator_1.tails)([
7294
7295
  (0, combinator_1.context)({ syntax: { inline: { link: false } } }, (0, combinator_1.dup)((0, combinator_1.union)([
7295
7296
  (0, combinator_1.surround)('[', inline_1.media, ']'),
7296
7297
  (0, combinator_1.surround)('[', inline_1.shortmedia, ']'),
@@ -8763,11 +8764,7 @@ require = function () {
8763
8764
  function isEndTightNodes(nodes) {
8764
8765
  if (nodes.length === 0)
8765
8766
  return true;
8766
- for (let i = nodes.length; i--;) {
8767
- const node = nodes[i];
8768
- return isVisible(node, -1);
8769
- }
8770
- return false;
8767
+ return isVisible(nodes[nodes.length - 1], -1);
8771
8768
  }
8772
8769
  exports.isEndTightNodes = isEndTightNodes;
8773
8770
  function isVisible(node, strpos) {
package/markdown.d.ts CHANGED
@@ -572,7 +572,10 @@ export namespace MarkdownParser {
572
572
  Block<'reply/cite'>,
573
573
  Parser<HTMLSpanElement | HTMLBRElement, Context, [
574
574
  SourceParser.StrParser,
575
- InlineParser.AutolinkParser.AnchorParser,
575
+ Parser<HTMLAnchorElement, Context, [
576
+ InlineParser.AutolinkParser.AnchorParser,
577
+ Parser<HTMLAnchorElement, Context, []>,
578
+ ]>,
576
579
  ]> {
577
580
  }
578
581
  export interface QuoteParser extends
@@ -1057,7 +1060,7 @@ export namespace MarkdownParser {
1057
1060
  export interface UrlParser extends
1058
1061
  // https://host
1059
1062
  Inline<'url'>,
1060
- Parser<HTMLElement, Context, [
1063
+ Parser<HTMLAnchorElement, Context, [
1061
1064
  LinkParser,
1062
1065
  ]> {
1063
1066
  }
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.233.1",
3
+ "version": "0.234.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -3030,9 +3030,9 @@
3030
3030
  "dev": true
3031
3031
  },
3032
3032
  "electron-to-chromium": {
3033
- "version": "1.4.93",
3034
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.93.tgz",
3035
- "integrity": "sha512-ywq9Pc5Gwwpv7NG767CtoU8xF3aAUQJjH9//Wy3MBCg4w5JSLbJUq2L8IsCdzPMjvSgxuue9WcVaTOyyxCL0aQ==",
3033
+ "version": "1.4.96",
3034
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.96.tgz",
3035
+ "integrity": "sha512-DPNjvNGPabv6FcyjzLAN4C0psN/GgD9rSGvMTuv81SeXG/EX3mCz0wiw9N1tUEnfQXYCJi3H8M0oFPRziZh7rw==",
3036
3036
  "dev": true
3037
3037
  },
3038
3038
  "elliptic": {
@@ -6359,9 +6359,9 @@
6359
6359
  "dev": true
6360
6360
  },
6361
6361
  "isbinaryfile": {
6362
- "version": "4.0.9",
6363
- "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.9.tgz",
6364
- "integrity": "sha512-GhwgwhMeEkMF/PmVpA+zRGCxoQvJ7PONqsKI+eq+ivgYolKe7AQdlqLFiSEBSTrO3YsQ2jvgwT2Gd6Z1TDcoaw==",
6362
+ "version": "4.0.10",
6363
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
6364
+ "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
6365
6365
  "dev": true
6366
6366
  },
6367
6367
  "isexe": {
@@ -11500,9 +11500,9 @@
11500
11500
  },
11501
11501
  "dependencies": {
11502
11502
  "ansi-regex": {
11503
- "version": "3.0.0",
11504
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
11505
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
11503
+ "version": "3.0.1",
11504
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
11505
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
11506
11506
  "dev": true
11507
11507
  },
11508
11508
  "is-fullwidth-code-point": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.233.1",
3
+ "version": "0.234.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",
@@ -53,10 +53,10 @@ describe('Unit: parser/api/parse', () => {
53
53
  ['<p>&lt;wbr&gt;<br>a</p>']);
54
54
  assert.deepStrictEqual(
55
55
  [...parse('[#\n<wbr>\n#]').children].map(el => el.outerHTML),
56
- ['<p><span class="comment">[# &lt;wbr&gt; #]</span></p>']);
56
+ ['<p><span class="comment"><input type="checkbox"><span>[#<br>&lt;wbr&gt;<br>#]</span></span></p>']);
57
57
  assert.deepStrictEqual(
58
58
  [...parse('[#\n<wbr>\n#]\na').children].map(el => el.outerHTML),
59
- ['<p><span class="comment">[# &lt;wbr&gt; #]</span><br>a</p>']);
59
+ ['<p><span class="comment"><input type="checkbox"><span>[#<br>&lt;wbr&gt;<br>#]</span></span><br>a</p>']);
60
60
  });
61
61
 
62
62
  it('linebreak', () => {
@@ -1,5 +1,5 @@
1
1
  import { undefined, location } from 'spica/global';
2
- import { ObjectAssign } from 'spica/alias';
2
+ import { ObjectAssign, ObjectCreate } from 'spica/alias';
3
3
  import { ParserOptions } from '../../..';
4
4
  import { MarkdownParser } from '../../../markdown';
5
5
  import { eval } from '../../combinator/data/parser';
@@ -24,13 +24,14 @@ export function parse(source: string, opts: Options = {}, context?: MarkdownPars
24
24
  assert(!context?.delimiters);
25
25
  context = context && url === '' && context.id === opts.id
26
26
  ? context
27
- : ObjectAssign({ ...context, ...opts }, {
27
+ : ObjectAssign(ObjectCreate(context ?? {}), opts, {
28
28
  host: opts.host ?? context?.host ?? new ReadonlyURL(location.pathname, location.origin),
29
29
  url: url ? new ReadonlyURL(url as ':') : context?.url,
30
30
  id: opts.id ?? context?.id,
31
31
  footnotes: undefined,
32
32
  test: undefined,
33
33
  });
34
+ assert(context.caches === arguments[2]?.caches);
34
35
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
35
36
  const node = frag();
36
37
  let index = 0;
@@ -25,13 +25,13 @@ describe('Unit: parser/block/blockquote', () => {
25
25
  assert.deepStrictEqual(inspect(parser('> a\nb')), [['<blockquote><pre>a<br>b</pre></blockquote>'], '']);
26
26
  assert.deepStrictEqual(inspect(parser('> a\n b ')), [['<blockquote><pre>a<br> b </pre></blockquote>'], '']);
27
27
  assert.deepStrictEqual(inspect(parser('> a\n>')), [['<blockquote><pre>a<br></pre></blockquote>'], '']);
28
- assert.deepStrictEqual(inspect(parser('> a\n>>1')), [['<blockquote><pre>a<br><a href="?comment=1" class="anchor">&gt;&gt;1</a></pre></blockquote>'], '']);
28
+ assert.deepStrictEqual(inspect(parser('> a\n>>1')), [['<blockquote><pre>a<br><a href="?at=1" class="anchor">&gt;&gt;1</a></pre></blockquote>'], '']);
29
29
  assert.deepStrictEqual(inspect(parser('> a\n> b ')), [['<blockquote><pre>a<br>b </pre></blockquote>'], '']);
30
30
  assert.deepStrictEqual(inspect(parser('> a\n>\n')), [['<blockquote><pre>a<br></pre></blockquote>'], '']);
31
31
  assert.deepStrictEqual(inspect(parser('> a\n>\nb')), [['<blockquote><pre>a<br><br>b</pre></blockquote>'], '']);
32
32
  assert.deepStrictEqual(inspect(parser('> a\n>\n b ')), [['<blockquote><pre>a<br><br> b </pre></blockquote>'], '']);
33
33
  assert.deepStrictEqual(inspect(parser('> a\n>\n>')), [['<blockquote><pre>a<br><br></pre></blockquote>'], '']);
34
- assert.deepStrictEqual(inspect(parser('> a\n>\n>>1')), [['<blockquote><pre>a<br><br><a href="?comment=1" class="anchor">&gt;&gt;1</a></pre></blockquote>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('> a\n>\n>>1')), [['<blockquote><pre>a<br><br><a href="?at=1" class="anchor">&gt;&gt;1</a></pre></blockquote>'], '']);
35
35
  assert.deepStrictEqual(inspect(parser('> a\n>\n> b ')), [['<blockquote><pre>a<br><br>b </pre></blockquote>'], '']);
36
36
  assert.deepStrictEqual(inspect(parser('> a\\\nb')), [['<blockquote><pre>a\\<br>b</pre></blockquote>'], '']);
37
37
  assert.deepStrictEqual(inspect(parser('> a ')), [['<blockquote><pre> a </pre></blockquote>'], '']);
@@ -44,8 +44,8 @@ describe('Unit: parser/block/blockquote', () => {
44
44
  assert.deepStrictEqual(inspect(parser('> !http://host')), [['<blockquote><pre>!<a href="http://host" target="_blank">http://host</a></pre></blockquote>'], '']);
45
45
  assert.deepStrictEqual(inspect(parser('> #a')), [['<blockquote><pre><a href="/hashtags/a" class="hashtag">#a</a></pre></blockquote>'], '']);
46
46
  assert.deepStrictEqual(inspect(parser('> @a#b')), [['<blockquote><pre><a href="/@a?ch=b" class="channel">@a#b</a></pre></blockquote>'], '']);
47
- assert.deepStrictEqual(inspect(parser('> >>1\n> > b')), [['<blockquote><pre><a href="?comment=1" class="anchor">&gt;&gt;1</a><br>&gt; b</pre></blockquote>'], '']);
48
- assert.deepStrictEqual(inspect(parser('> >>1\n> > b\n> c')), [['<blockquote><pre><a href="?comment=1" class="anchor">&gt;&gt;1</a><br>&gt; b<br>c</pre></blockquote>'], '']);
47
+ assert.deepStrictEqual(inspect(parser('> >>1\n> > b')), [['<blockquote><pre><a href="?at=1" class="anchor">&gt;&gt;1</a><br>&gt; b</pre></blockquote>'], '']);
48
+ assert.deepStrictEqual(inspect(parser('> >>1\n> > b\n> c')), [['<blockquote><pre><a href="?at=1" class="anchor">&gt;&gt;1</a><br>&gt; b<br>c</pre></blockquote>'], '']);
49
49
  });
50
50
 
51
51
  it('nest', () => {
@@ -16,7 +16,7 @@ export const mathblock: MathBlockParser = block(validate('$$', fmap(
16
16
  // Bug: Type mismatch between outer and inner.
17
17
  ([body, closer, opener, delim, param]: string[], _, { caches: { math: cache = undefined } = {} }) => [
18
18
  delim.length === 2 && closer && param.trimStart() === ''
19
- ? cache?.get(`\n${body}`)?.cloneNode(true) as HTMLDivElement ||
19
+ ? cache?.get(`${delim}\n${body}${delim}`)?.cloneNode(true) as HTMLDivElement ||
20
20
  html('div', { class: 'math', translate: 'no' }, `${delim}\n${body}${delim}`)
21
21
  : html('pre', {
22
22
  class: 'invalid',
@@ -29,31 +29,31 @@ describe('Unit: parser/block/paragraph', () => {
29
29
  });
30
30
 
31
31
  it('anchor', () => {
32
- assert.deepStrictEqual(inspect(parser('>>1 a\nb')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a> a<br>b</p>'], '']);
33
- assert.deepStrictEqual(inspect(parser('>>1 a\n>>2')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a> a<br><a href="?comment=2" class="anchor">&gt;&gt;2</a></p>'], '']);
34
- assert.deepStrictEqual(inspect(parser('>>1 a\n>>b')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a> a<br><a href="?comment=b" class="anchor">&gt;&gt;b</a></p>'], '']);
35
- assert.deepStrictEqual(inspect(parser('>>1 a\n>> b')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a> a<br>&gt;&gt; b</p>'], '']);
36
- assert.deepStrictEqual(inspect(parser('>>11.')), [['<p><a href="?comment=11" class="anchor">&gt;&gt;11</a>.</p>'], '']);
37
- assert.deepStrictEqual(inspect(parser('>>11 a')), [['<p><a href="?comment=11" class="anchor">&gt;&gt;11</a> a</p>'], '']);
38
- assert.deepStrictEqual(inspect(parser('>>>11 a')), [['<p>&gt;<a href="?comment=11" class="anchor">&gt;&gt;11</a> a</p>'], '']);
39
- assert.deepStrictEqual(inspect(parser('>> a\n>>1')), [['<p>&gt;&gt; a<br><a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
40
- assert.deepStrictEqual(inspect(parser('a>>1')), [['<p>a<a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
41
- assert.deepStrictEqual(inspect(parser('a >>1')), [['<p>a <a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
42
- assert.deepStrictEqual(inspect(parser('a\n>>1')), [['<p>a<br><a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
43
- assert.deepStrictEqual(inspect(parser('a\n>>1\nb')), [['<p>a<br><a href="?comment=1" class="anchor">&gt;&gt;1</a><br>b</p>'], '']);
32
+ assert.deepStrictEqual(inspect(parser('>>1 a\nb')), [['<p><a href="?at=1" class="anchor">&gt;&gt;1</a> a<br>b</p>'], '']);
33
+ assert.deepStrictEqual(inspect(parser('>>1 a\n>>2')), [['<p><a href="?at=1" class="anchor">&gt;&gt;1</a> a<br><a href="?at=2" class="anchor">&gt;&gt;2</a></p>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('>>1 a\n>>b')), [['<p><a href="?at=1" class="anchor">&gt;&gt;1</a> a<br><a href="?at=b" class="anchor">&gt;&gt;b</a></p>'], '']);
35
+ assert.deepStrictEqual(inspect(parser('>>1 a\n>> b')), [['<p><a href="?at=1" class="anchor">&gt;&gt;1</a> a<br>&gt;&gt; b</p>'], '']);
36
+ assert.deepStrictEqual(inspect(parser('>>11.')), [['<p><a href="?at=11" class="anchor">&gt;&gt;11</a>.</p>'], '']);
37
+ assert.deepStrictEqual(inspect(parser('>>11 a')), [['<p><a href="?at=11" class="anchor">&gt;&gt;11</a> a</p>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('>>>11 a')), [['<p>&gt;<a href="?at=11" class="anchor">&gt;&gt;11</a> a</p>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('>> a\n>>1')), [['<p>&gt;&gt; a<br><a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('a>>1')), [['<p>a<a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('a >>1')), [['<p>a <a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('a\n>>1')), [['<p>a<br><a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('a\n>>1\nb')), [['<p>a<br><a href="?at=1" class="anchor">&gt;&gt;1</a><br>b</p>'], '']);
44
44
  assert.deepStrictEqual(inspect(parser('a\n>> b\nc')), [['<p>a<br>&gt;&gt; b<br>c</p>'], '']);
45
- assert.deepStrictEqual(inspect(parser(' >>1')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
46
- assert.deepStrictEqual(inspect(parser(' >>>1')), [['<p>&gt;<a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
45
+ assert.deepStrictEqual(inspect(parser(' >>1')), [['<p><a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
46
+ assert.deepStrictEqual(inspect(parser(' >>>1')), [['<p>&gt;<a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
47
47
  });
48
48
 
49
49
  it('comment', () => {
50
- assert.deepStrictEqual(inspect(parser('[# a #]')), [['<p><span class="comment">[# a #]</span></p>'], '']);
51
- assert.deepStrictEqual(inspect(parser('[# a #]b')), [['<p><span class="comment">[# a #]</span>b</p>'], '']);
52
- assert.deepStrictEqual(inspect(parser('[# a #]\nb')), [['<p><span class="comment">[# a #]</span><br>b</p>'], '']);
53
- assert.deepStrictEqual(inspect(parser('[## a ##]')), [['<p><span class="comment">[## a ##]</span></p>'], '']);
54
- assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]')), [['<p><span class="comment">[# &lt;wbr&gt; #]</span></p>'], '']);
55
- assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]a')), [['<p><span class="comment">[# &lt;wbr&gt; #]</span>a</p>'], '']);
56
- assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]\na')), [['<p><span class="comment">[# &lt;wbr&gt; #]</span><br>a</p>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('[# a #]')), [['<p><span class="comment"><input type="checkbox"><span>[# a #]</span></span></p>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('[# a #]b')), [['<p><span class="comment"><input type="checkbox"><span>[# a #]</span></span>b</p>'], '']);
52
+ assert.deepStrictEqual(inspect(parser('[# a #]\nb')), [['<p><span class="comment"><input type="checkbox"><span>[# a #]</span></span><br>b</p>'], '']);
53
+ assert.deepStrictEqual(inspect(parser('[## a ##]')), [['<p><span class="comment"><input type="checkbox"><span>[## a ##]</span></span></p>'], '']);
54
+ assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]')), [['<p><span class="comment"><input type="checkbox"><span>[#<br>&lt;wbr&gt;<br>#]</span></span></p>'], '']);
55
+ assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]a')), [['<p><span class="comment"><input type="checkbox"><span>[#<br>&lt;wbr&gt;<br>#]</span></span>a</p>'], '']);
56
+ assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]\na')), [['<p><span class="comment"><input type="checkbox"><span>[#<br>&lt;wbr&gt;<br>#]</span></span><br>a</p>'], '']);
57
57
  });
58
58
 
59
59
  it('template', () => {
@@ -13,32 +13,32 @@ describe('Unit: parser/block/reply/cite', () => {
13
13
  assert.deepStrictEqual(inspect(parser('>\n')), undefined);
14
14
  assert.deepStrictEqual(inspect(parser('>>')), undefined);
15
15
  assert.deepStrictEqual(inspect(parser('>> ')), undefined);
16
- assert.deepStrictEqual(inspect(parser('>>0A')), undefined);
17
16
  assert.deepStrictEqual(inspect(parser('>>0 a')), undefined);
18
- assert.deepStrictEqual(inspect(parser('>>A')), undefined);
19
17
  assert.deepStrictEqual(inspect(parser('>>/')), undefined);
20
18
  assert.deepStrictEqual(inspect(parser('>>\\')), undefined);
21
19
  assert.deepStrictEqual(inspect(parser('>>01#')), undefined);
22
20
  assert.deepStrictEqual(inspect(parser('>>01@')), undefined);
23
21
  assert.deepStrictEqual(inspect(parser('>>https://host')), undefined);
24
22
  assert.deepStrictEqual(inspect(parser('>>tel:1234567890')), undefined);
23
+ assert.deepStrictEqual(inspect(parser('>>..')), undefined);
25
24
  assert.deepStrictEqual(inspect(parser('>> 0')), undefined);
26
25
  assert.deepStrictEqual(inspect(parser(' >>0')), undefined);
27
26
  assert.deepStrictEqual(inspect(parser('\\>>0')), undefined);
28
27
  });
29
28
 
30
29
  it('valid', () => {
31
- assert.deepStrictEqual(inspect(parser('>>0')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '']);
32
- assert.deepStrictEqual(inspect(parser('>>0 ')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '']);
33
- assert.deepStrictEqual(inspect(parser('>>0\n')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '']);
34
- assert.deepStrictEqual(inspect(parser('>>>0')), [['<span class="cite">&gt;&gt;<a href="?comment=0" class="anchor" data-depth="2">&gt;0</a></span>', '<br>'], '']);
35
- assert.deepStrictEqual(inspect(parser('>>0\n1')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '1']);
36
- assert.deepStrictEqual(inspect(parser('>>0\n>1')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '>1']);
37
- assert.deepStrictEqual(inspect(parser('>>0\n>>')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '>>']);
38
- assert.deepStrictEqual(inspect(parser('>>0\n>>1')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>', '<span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span>', '<br>'], '']);
39
- assert.deepStrictEqual(inspect(parser('>>0\n>>>1')), [['<span class="cite">&gt;<a href="?comment=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>', '<span class="cite">&gt;&gt;<a href="?comment=1" class="anchor" data-depth="2">&gt;1</a></span>', '<br>'], '']);
40
- assert.deepStrictEqual(inspect(parser('>>>0\n>>')), [['<span class="cite">&gt;&gt;<a href="?comment=0" class="anchor" data-depth="2">&gt;0</a></span>', '<br>'], '>>']);
41
- assert.deepStrictEqual(inspect(parser('>>>0\n>>1')), [['<span class="cite">&gt;&gt;<a href="?comment=0" class="anchor" data-depth="2">&gt;0</a></span>', '<br>', '<span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span>', '<br>'], '']);
30
+ assert.deepStrictEqual(inspect(parser('>>0')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('>>0 ')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '']);
32
+ assert.deepStrictEqual(inspect(parser('>>0\n')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '']);
33
+ assert.deepStrictEqual(inspect(parser('>>>0')), [['<span class="cite">&gt;&gt;<a href="?at=0" class="anchor" data-depth="2">&gt;0</a></span>', '<br>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('>>0\n1')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '1']);
35
+ assert.deepStrictEqual(inspect(parser('>>0\n>1')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '>1']);
36
+ assert.deepStrictEqual(inspect(parser('>>0\n>>')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>'], '>>']);
37
+ assert.deepStrictEqual(inspect(parser('>>0\n>>1')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>', '<span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span>', '<br>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('>>0\n>>>1')), [['<span class="cite">&gt;<a href="?at=0" class="anchor" data-depth="1">&gt;0</a></span>', '<br>', '<span class="cite">&gt;&gt;<a href="?at=1" class="anchor" data-depth="2">&gt;1</a></span>', '<br>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('>>>0\n>>')), [['<span class="cite">&gt;&gt;<a href="?at=0" class="anchor" data-depth="2">&gt;0</a></span>', '<br>'], '>>']);
40
+ assert.deepStrictEqual(inspect(parser('>>>0\n>>1')), [['<span class="cite">&gt;&gt;<a href="?at=0" class="anchor" data-depth="2">&gt;0</a></span>', '<br>', '<span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span>', '<br>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('>>.')), [['<span class="cite">&gt;<a class="anchor" data-depth="1">&gt;.</a></span>', '<br>'], '']);
42
42
  });
43
43
 
44
44
  });
@@ -1,14 +1,19 @@
1
1
  import { ReplyParser } from '../../block';
2
- import { tails, line, validate, creator, reverse, fmap } from '../../../combinator';
3
- import { anchor, syntax } from '../../inline/autolink/anchor';
2
+ import { union, tails, line, validate, focus, creator, reverse, fmap } from '../../../combinator';
3
+ import { anchor } from '../../inline/autolink/anchor';
4
4
  import { str } from '../../source';
5
5
  import { html, define, defrag } from 'typed-dom';
6
6
 
7
7
  export const cite: ReplyParser.CiteParser = creator(line(fmap(validate(
8
8
  '>>',
9
9
  reverse(tails([
10
- str(/^>*(?=>>)/),
11
- validate(new RegExp(`${syntax.source}[^\S\n]*(?:$|\n)`), anchor),
10
+ str(/^>*(?=>>[^>\s]+[^\S\n]*(?:$|\n))/),
11
+ union([
12
+ anchor,
13
+ // Subject page representation.
14
+ // リンクの実装は後で検討
15
+ focus(/^>>\.[^\S\n]*(?:$|\n)/, () => [[html('a', { class: 'anchor' }, '>>.')], '']),
16
+ ]),
12
17
  ]))),
13
18
  ([el, quotes = '']: [HTMLElement, string?]) => [
14
19
  html('span', { class: 'cite' }, defrag([
@@ -47,8 +47,8 @@ describe('Unit: parser/block/reply/quote', () => {
47
47
  assert.deepStrictEqual(inspect(parser('> 0\n>> 1')), [['<span class="quote">&gt; 0<br>&gt;&gt; 1</span>', '<br>'], '']);
48
48
  assert.deepStrictEqual(inspect(parser('>> 0\n> 1')), [['<span class="quote">&gt;&gt; 0<br>&gt; 1</span>', '<br>'], '']);
49
49
  assert.deepStrictEqual(inspect(parser('> \\')), [['<span class="quote">&gt; \\</span>', '<br>'], '']);
50
- assert.deepStrictEqual(inspect(parser('> >>0\n> > b')), [['<span class="quote">&gt; <a href="?comment=0" class="anchor">&gt;&gt;0</a><br>&gt; &gt; b</span>', '<br>'], '']);
51
- assert.deepStrictEqual(inspect(parser('> >>0\n> > b\n> c')), [['<span class="quote">&gt; <a href="?comment=0" class="anchor">&gt;&gt;0</a><br>&gt; &gt; b<br>&gt; c</span>', '<br>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('> >>0\n> > b')), [['<span class="quote">&gt; <a href="?at=0" class="anchor">&gt;&gt;0</a><br>&gt; &gt; b</span>', '<br>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('> >>0\n> > b\n> c')), [['<span class="quote">&gt; <a href="?at=0" class="anchor">&gt;&gt;0</a><br>&gt; &gt; b<br>&gt; c</span>', '<br>'], '']);
52
52
  assert.deepStrictEqual(inspect(parser('> > a\n> > b\n> > c')), [['<span class="quote">&gt; &gt; a<br>&gt; &gt; b<br>&gt; &gt; c</span>', '<br>'], '']);
53
53
  assert.deepStrictEqual(inspect(parser('> > > a\n> > > b')), [['<span class="quote">&gt; &gt; &gt; a<br>&gt; &gt; &gt; b</span>', '<br>'], '']);
54
54
  assert.deepStrictEqual(inspect(parser('> #a')), [['<span class="quote">&gt; <a href="/hashtags/a" class="hashtag">#a</a></span>', '<br>'], '']);
@@ -7,14 +7,14 @@ describe('Unit: parser/block/reply', () => {
7
7
  const parser = (source: string) => some(reply)(source, {});
8
8
 
9
9
  it('basic', () => {
10
- assert.deepStrictEqual(inspect(parser('>>1')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span></p>'], '']);
11
- assert.deepStrictEqual(inspect(parser('>>1\na')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span><br>a</p>'], '']);
12
- assert.deepStrictEqual(inspect(parser('>>1\na\n>>2')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span><br>a<br><a href="?comment=2" class="anchor">&gt;&gt;2</a></p>'], '']);
13
- assert.deepStrictEqual(inspect(parser('>>1\n>>2')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="cite">&gt;<a href="?comment=2" class="anchor" data-depth="1">&gt;2</a></span></p>'], '']);
14
- assert.deepStrictEqual(inspect(parser('>>1\n> a')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a</span></p>'], '']);
15
- assert.deepStrictEqual(inspect(parser('>>1\n> a\nb')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a</span><br>b</p>'], '']);
16
- assert.deepStrictEqual(inspect(parser('>>1\n> a\n>>2')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a</span><br><span class="cite">&gt;<a href="?comment=2" class="anchor" data-depth="1">&gt;2</a></span></p>'], '']);
17
- assert.deepStrictEqual(inspect(parser('>>1\n> a\n>> b')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a<br>&gt;&gt; b</span></p>'], '']);
10
+ assert.deepStrictEqual(inspect(parser('>>1')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span></p>'], '']);
11
+ assert.deepStrictEqual(inspect(parser('>>1\na')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span><br>a</p>'], '']);
12
+ assert.deepStrictEqual(inspect(parser('>>1\na\n>>2')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span><br>a<br><a href="?at=2" class="anchor">&gt;&gt;2</a></p>'], '']);
13
+ assert.deepStrictEqual(inspect(parser('>>1\n>>2')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="cite">&gt;<a href="?at=2" class="anchor" data-depth="1">&gt;2</a></span></p>'], '']);
14
+ assert.deepStrictEqual(inspect(parser('>>1\n> a')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a</span></p>'], '']);
15
+ assert.deepStrictEqual(inspect(parser('>>1\n> a\nb')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a</span><br>b</p>'], '']);
16
+ assert.deepStrictEqual(inspect(parser('>>1\n> a\n>>2')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a</span><br><span class="cite">&gt;<a href="?at=2" class="anchor" data-depth="1">&gt;2</a></span></p>'], '']);
17
+ assert.deepStrictEqual(inspect(parser('>>1\n> a\n>> b')), [['<p><span class="cite">&gt;<a href="?at=1" class="anchor" data-depth="1">&gt;1</a></span><br><span class="quote">&gt; a<br>&gt;&gt; b</span></p>'], '']);
18
18
  });
19
19
 
20
20
  });
@@ -9,6 +9,13 @@ import { visualize } from '../util';
9
9
  import { html, defrag } from 'typed-dom';
10
10
  import { push, pop } from 'spica/array';
11
11
 
12
+ /*
13
+ 必ず対象指定から始まる
14
+ 対象がページである場合>>.を表現方法とする
15
+ 対象をURLで指定すべき(引用ツリーにルートを追加する)場合はない
16
+ 対象と引用は1:N(分割)、N:1(統合)のみ可能、N:N(混合)は不可能
17
+ */
18
+
12
19
  export const reply: ReplyParser = block(validate('>', localize(fmap(
13
20
  inits([
14
21
  some(inits([
@@ -17,10 +24,9 @@ export const reply: ReplyParser = block(validate('>', localize(fmap(
17
24
  ])),
18
25
  some(subsequence([
19
26
  some(quote),
20
- fmap(
21
- rewrite(
22
- some(anyline, delimiter),
23
- trim(visualize(some(inline)))),
27
+ fmap(rewrite(
28
+ some(anyline, delimiter),
29
+ trim(visualize(some(inline)))),
24
30
  ns => push(ns, [html('br')])),
25
31
  ])),
26
32
  ]),
@@ -10,8 +10,6 @@ describe('Unit: parser/inline/autolink/anchor', () => {
10
10
  assert.deepStrictEqual(inspect(parser('')), undefined);
11
11
  assert.deepStrictEqual(inspect(parser('>')), undefined);
12
12
  assert.deepStrictEqual(inspect(parser('>>')), undefined);
13
- assert.deepStrictEqual(inspect(parser('>>0A')), undefined);
14
- assert.deepStrictEqual(inspect(parser('>>A')), undefined);
15
13
  assert.deepStrictEqual(inspect(parser('>>-0')), undefined);
16
14
  assert.deepStrictEqual(inspect(parser('>>01#')), undefined);
17
15
  assert.deepStrictEqual(inspect(parser('>>01@')), undefined);
@@ -22,12 +20,15 @@ describe('Unit: parser/inline/autolink/anchor', () => {
22
20
  });
23
21
 
24
22
  it('valid', () => {
25
- assert.deepStrictEqual(inspect(parser('>>0')), [['<a href="?comment=0" class="anchor">&gt;&gt;0</a>'], '']);
26
- assert.deepStrictEqual(inspect(parser('>>a')), [['<a href="?comment=a" class="anchor">&gt;&gt;a</a>'], '']);
27
- assert.deepStrictEqual(inspect(parser('>>0-')), [['<a href="?comment=0" class="anchor">&gt;&gt;0</a>'], '-']);
28
- assert.deepStrictEqual(inspect(parser('>>0-a')), [['<a href="?comment=0-a" class="anchor">&gt;&gt;0-a</a>'], '']);
29
- assert.deepStrictEqual(inspect(parser('>>0-A')), [['<a href="?comment=0" class="anchor">&gt;&gt;0</a>'], '-A']);
30
- assert.deepStrictEqual(inspect(parser('>>0--a')), [['<a href="?comment=0" class="anchor">&gt;&gt;0</a>'], '--a']);
23
+ assert.deepStrictEqual(inspect(parser('>>0')), [['<a href="?at=0" class="anchor">&gt;&gt;0</a>'], '']);
24
+ assert.deepStrictEqual(inspect(parser('>>a')), [['<a href="?at=a" class="anchor">&gt;&gt;a</a>'], '']);
25
+ assert.deepStrictEqual(inspect(parser('>>A')), [['<a href="?at=A" class="anchor">&gt;&gt;A</a>'], '']);
26
+ assert.deepStrictEqual(inspect(parser('>>0-')), [['<a href="?at=0" class="anchor">&gt;&gt;0</a>'], '-']);
27
+ assert.deepStrictEqual(inspect(parser('>>0-a')), [['<a href="?at=0-a" class="anchor">&gt;&gt;0-a</a>'], '']);
28
+ assert.deepStrictEqual(inspect(parser('>>0-A')), [['<a href="?at=0-A" class="anchor">&gt;&gt;0-A</a>'], '']);
29
+ assert.deepStrictEqual(inspect(parser('>>0--a')), [['<a href="?at=0" class="anchor">&gt;&gt;0</a>'], '--a']);
30
+ assert.deepStrictEqual(inspect(parser('>>2000-01-31-23-59-59-999-JST')), [['<a href="?at=2000-01-31-23-59-59-999-JST" class="anchor">&gt;&gt;2000-01-31-23-59-59-999-JST</a>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('>>A/2000-01-31-23-59-59-JST')), [['<a href="/@A/timeline/2000-01-31-23-59-59-JST" class="anchor">&gt;&gt;A/2000-01-31-23-59-59-JST</a>'], '']);
31
32
  });
32
33
 
33
34
  });
@@ -1,18 +1,29 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, validate, rewrite, context, convert, fmap, lazy } from '../../../combinator';
2
+ import { union, validate, focus, context, convert, fmap, lazy } from '../../../combinator';
3
3
  import { link } from '../link';
4
- import { str } from '../../source';
5
4
  import { define } from 'typed-dom';
6
5
 
7
- export const syntax = /^>>[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:])/;
6
+ // Timeline(pseudonym): user/tid
7
+ // Thread(anonymous): cid
8
8
 
9
- export const anchor: AutolinkParser.AnchorParser = lazy(() => validate('>>', fmap(rewrite(
10
- str(syntax),
9
+ // tid: YYYY-MM-DD-HH-MM-SS-TMZ
10
+ // cid: YYYY-MM-DD-HH-MM-SS-mmm-TMZ
11
+
12
+ // 内部表現はUnixTimeに統一する(時系列順)
13
+ // 外部表現は投稿ごとに投稿者の投稿時のタイムゾーンに統一する(非時系列順)
14
+
15
+ export const anchor: AutolinkParser.AnchorParser = lazy(() => validate('>>', fmap(focus(
16
+ /^>>(?:[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*\/)?[0-9A-Za-z]+(?:-[0-9A-Za-z]+)*(?![0-9A-Za-z@#:])/,
11
17
  context({ syntax: { inline: {
12
18
  link: true,
13
19
  autolink: false,
14
20
  }}},
15
21
  convert(
16
- source => `[${source}]{ ?comment=${source.slice(2)} }`,
22
+ source =>
23
+ `[${source}]{ ${
24
+ source.includes('/')
25
+ ? `/@${source.slice(2).replace('/', '/timeline/')}`
26
+ : `?at=${source.slice(2)}`
27
+ } }`,
17
28
  union([link])))),
18
29
  ([el]) => [define(el, { class: 'anchor' })])));
@@ -13,50 +13,49 @@ describe('Unit: parser/inline/comment', () => {
13
13
  assert.deepStrictEqual(inspect(parser('[#[#')), undefined);
14
14
  assert.deepStrictEqual(inspect(parser('[#a#]')), undefined);
15
15
  assert.deepStrictEqual(inspect(parser('[#a b#]')), undefined);
16
- assert.deepStrictEqual(inspect(parser('[# ')), [['[', '#', ' '], '']);
17
- assert.deepStrictEqual(inspect(parser('[# \n a')), [['[', '#', '<br>', ' ', 'a'], '']);
16
+ assert.deepStrictEqual(inspect(parser('[# ')), [['[#'], '']);
17
+ assert.deepStrictEqual(inspect(parser('[# \n a')), [['[#', '<br>', ' ', 'a'], '']);
18
18
  assert.deepStrictEqual(inspect(parser('[##]')), undefined);
19
- assert.deepStrictEqual(inspect(parser('[# #]')), undefined);
20
- assert.deepStrictEqual(inspect(parser('[# #] #]')), undefined);
21
- assert.deepStrictEqual(inspect(parser('[# [#')), [['[', '#', ' ', '[', '#'], '']);
22
- assert.deepStrictEqual(inspect(parser('[# [# ')), [['[', '#', ' ', '[', '#', ' '], '']);
23
- assert.deepStrictEqual(inspect(parser('[# [# a')), [['[', '#', ' ', '[', '#', ' ', 'a'], '']);
24
- assert.deepStrictEqual(inspect(parser('[# [# a #]')), [['[', '#', ' ', '<span class="comment">[# a #]</span>'], '']);
25
- assert.deepStrictEqual(inspect(parser('[# a[#')), [['[', '#', ' ', 'a', '[', '#'], '']);
26
- assert.deepStrictEqual(inspect(parser('[# a [#')), [['[', '#', ' ', 'a', ' ', '[', '#'], '']);
27
- assert.deepStrictEqual(inspect(parser('[# a [# ')), [['[', '#', ' ', 'a', ' ', '[', '#', ' '], '']);
28
- assert.deepStrictEqual(inspect(parser('[# a [# b')), [['[', '#', ' ', 'a', ' ', '[', '#', ' ', 'b'], '']);
29
- assert.deepStrictEqual(inspect(parser('[# a [## b')), [['[', '#', ' ', 'a', ' ', '[', '#', '#', ' ', 'b'], '']);
30
- assert.deepStrictEqual(inspect(parser('[## a [# b')), [['[', '#', '#', ' ', 'a', ' ', '[', '#', ' ', 'b'], '']);
19
+ assert.deepStrictEqual(inspect(parser('[# [#')), [['[#', ' ', '[', '#'], '']);
20
+ assert.deepStrictEqual(inspect(parser('[# [# ')), [['[#', ' ', '[#'], '']);
21
+ assert.deepStrictEqual(inspect(parser('[# [# a')), [['[#', ' ', '[#', ' ', 'a'], '']);
22
+ assert.deepStrictEqual(inspect(parser('[# [# a #]')), [['[#', ' ', '<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], '']);
23
+ assert.deepStrictEqual(inspect(parser('[# a[#')), [['[#', ' ', 'a', '[', '#'], '']);
24
+ assert.deepStrictEqual(inspect(parser('[# a [#')), [['[#', ' ', 'a', ' ', '[', '#'], '']);
25
+ assert.deepStrictEqual(inspect(parser('[# a [# ')), [['[#', ' ', 'a', ' ', '[#'], '']);
26
+ assert.deepStrictEqual(inspect(parser('[# a [# b')), [['[#', ' ', 'a', ' ', '[#', ' ', 'b'], '']);
27
+ assert.deepStrictEqual(inspect(parser('[# a [## b')), [['[#', ' ', 'a', ' ', '[##', ' ', 'b'], '']);
28
+ assert.deepStrictEqual(inspect(parser('[## a [# b')), [['[##', ' ', 'a', ' ', '[#', ' ', 'b'], '']);
31
29
  assert.deepStrictEqual(inspect(parser('[#\\ a #]')), undefined);
32
- assert.deepStrictEqual(inspect(parser('[# a\\ #]')), [['[', '#', ' ', 'a', ' ', '#', ']'], '']);
33
- assert.deepStrictEqual(inspect(parser('[# a#]')), [['[', '#', ' ', 'a#', ']'], '']);
34
- assert.deepStrictEqual(inspect(parser('[# a ##]')), [['[', '#', ' ', 'a', ' ', '##', ']'], '']);
35
- assert.deepStrictEqual(inspect(parser('[# [## #]')), [['[', '#', ' ', '[', '#', '#', ' ', '#', ']'], '']);
36
- assert.deepStrictEqual(inspect(parser('[## [# ##]')), [['[', '#', '#', ' ', '[', '#', ' ', '##', ']'], '']);
37
- assert.deepStrictEqual(inspect(parser('[## a #]')), [['[', '#', '#', ' ', 'a', ' ', '#', ']'], '']);
30
+ assert.deepStrictEqual(inspect(parser('[# a\\ #]')), [['[#', ' ', 'a', ' ', '#', ']'], '']);
31
+ assert.deepStrictEqual(inspect(parser('[# a#]')), [['[#', ' ', 'a#', ']'], '']);
32
+ assert.deepStrictEqual(inspect(parser('[# a ##]')), [['[#', ' ', 'a', ' ', '##', ']'], '']);
33
+ assert.deepStrictEqual(inspect(parser('[# [## #]')), [['[#', ' ', '[##', ' ', '#', ']'], '']);
34
+ assert.deepStrictEqual(inspect(parser('[## [# ##]')), [['[##', ' ', '[#', ' ', '##', ']'], '']);
35
+ assert.deepStrictEqual(inspect(parser('[## a #]')), [['[##', ' ', 'a', ' ', '#', ']'], '']);
38
36
  assert.deepStrictEqual(inspect(parser(' [# a #]')), undefined);
39
37
  });
40
38
 
41
39
  it('basic', () => {
42
- assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment">[# #]</span>'], '']);
43
- assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment">[# #]</span>'], '']);
44
- assert.deepStrictEqual(inspect(parser('[# a #]')), [['<span class="comment">[# a #]</span>'], '']);
45
- assert.deepStrictEqual(inspect(parser('[# a b #]')), [['<span class="comment">[# a b #]</span>'], '']);
46
- assert.deepStrictEqual(inspect(parser('[# a\nb #]')), [['<span class="comment">[# a<br>b #]</span>'], '']);
47
- assert.deepStrictEqual(inspect(parser('[# a #] #]')), [['<span class="comment">[# a #]</span>'], ' #]']);
48
- assert.deepStrictEqual(inspect(parser('[# ##] #]')), [['<span class="comment">[# ##] #]</span>'], '']);
49
- assert.deepStrictEqual(inspect(parser('[# [# a #] #]')), [['<span class="comment">[# <span class="comment">[# a #]</span> #]</span>'], '']);
50
- assert.deepStrictEqual(inspect(parser('[# [## a ##] #]')), [['<span class="comment">[# <span class="comment">[## a ##]</span> #]</span>'], '']);
51
- assert.deepStrictEqual(inspect(parser('[## a ##]')), [['<span class="comment">[## a ##]</span>'], '']);
52
- assert.deepStrictEqual(inspect(parser('[## #] ##]')), [['<span class="comment">[## #] ##]</span>'], '']);
53
- assert.deepStrictEqual(inspect(parser('[## [# a #] ##]')), [['<span class="comment">[## <span class="comment">[# a #]</span> ##]</span>'], '']);
54
- assert.deepStrictEqual(inspect(parser('[# a #]b')), [['<span class="comment">[# a #]</span>'], 'b']);
55
- assert.deepStrictEqual(inspect(parser('[#\na\n#]')), [['<span class="comment">[# a #]</span>'], '']);
56
- assert.deepStrictEqual(inspect(parser('[# &a; #]')), [['<span class="comment">[# <span class="invalid">&amp;a;</span> #]</span>'], '']);
57
- assert.deepStrictEqual(inspect(parser('[# &copy; #]')), [['<span class="comment">[# © #]</span>'], '']);
58
- assert.deepStrictEqual(inspect(parser('[# &amp;copy; #]')), [['<span class="comment">[# &amp;copy; #]</span>'], '']);
59
- assert.deepStrictEqual(inspect(parser('[# \\ a #]')), [['<span class="comment">[# a #]</span>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment"><input type="checkbox"><span>[# #]</span></span>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment"><input type="checkbox"><span>[# #]</span></span>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment"><input type="checkbox"><span>[# #]</span></span>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('[# a #]')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], '']);
44
+ assert.deepStrictEqual(inspect(parser('[# a b #]')), [['<span class="comment"><input type="checkbox"><span>[# a b #]</span></span>'], '']);
45
+ assert.deepStrictEqual(inspect(parser('[# a\nb #]')), [['<span class="comment"><input type="checkbox"><span>[# a<br>b #]</span></span>'], '']);
46
+ assert.deepStrictEqual(inspect(parser('[# a #] #]')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], ' #]']);
47
+ assert.deepStrictEqual(inspect(parser('[# ##] #]')), [['<span class="comment"><input type="checkbox"><span>[# ##] #]</span></span>'], '']);
48
+ assert.deepStrictEqual(inspect(parser('[# [# a #] #]')), [['<span class="comment"><input type="checkbox"><span>[# <span class="comment"><input type="checkbox"><span>[# a #]</span></span> #]</span></span>'], '']);
49
+ assert.deepStrictEqual(inspect(parser('[# [## a ##] #]')), [['<span class="comment"><input type="checkbox"><span>[# <span class="comment"><input type="checkbox"><span>[## a ##]</span></span> #]</span></span>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('[## a ##]')), [['<span class="comment"><input type="checkbox"><span>[## a ##]</span></span>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('[## #] ##]')), [['<span class="comment"><input type="checkbox"><span>[## #] ##]</span></span>'], '']);
52
+ assert.deepStrictEqual(inspect(parser('[## [# a #] ##]')), [['<span class="comment"><input type="checkbox"><span>[## <span class="comment"><input type="checkbox"><span>[# a #]</span></span> ##]</span></span>'], '']);
53
+ assert.deepStrictEqual(inspect(parser('[# a #]b')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], 'b']);
54
+ assert.deepStrictEqual(inspect(parser('[#\na\n#]')), [['<span class="comment"><input type="checkbox"><span>[#<br>a<br>#]</span></span>'], '']);
55
+ assert.deepStrictEqual(inspect(parser('[# &a; #]')), [['<span class="comment"><input type="checkbox"><span>[# <span class="invalid">&amp;a;</span> #]</span></span>'], '']);
56
+ assert.deepStrictEqual(inspect(parser('[# &copy; #]')), [['<span class="comment"><input type="checkbox"><span>[# © #]</span></span>'], '']);
57
+ assert.deepStrictEqual(inspect(parser('[# &amp;copy; #]')), [['<span class="comment"><input type="checkbox"><span>[# &amp;copy; #]</span></span>'], '']);
58
+ assert.deepStrictEqual(inspect(parser('[# \\ a #]')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], '']);
60
59
  });
61
60
 
62
61
  });
@@ -1,24 +1,24 @@
1
1
  import { CommentParser } from '../inline';
2
- import { eval } from '../../combinator/data/parser';
3
- import { union, some, validate, creator, surround, match, lazy } from '../../combinator';
2
+ import { union, some, validate, creator, surround, open, close, match, lazy } from '../../combinator';
4
3
  import { inline } from '../inline';
5
4
  import { text, str } from '../source';
6
5
  import { html, defrag } from 'typed-dom';
7
6
  import { memoize } from 'spica/memoize';
8
- import { unshift, push, pop } from 'spica/array';
7
+ import { unshift, push } from 'spica/array';
9
8
 
10
9
  export const comment: CommentParser = lazy(() => creator(validate('[#', match(
11
10
  /^(?=\[(#+)\s)/,
12
11
  memoize(
13
- ([, fence], closer = new RegExp(String.raw`^\s+${fence}\]`)) =>
12
+ ([, fence]) =>
14
13
  surround(
15
- str(/^\[(\S+)\s+(?!\1\])/),
16
- union([some(inline, closer)]),
17
- str(closer), true,
18
- ([, bs = []], rest) => [[
19
- html('span',
20
- { class: 'comment' },
21
- defrag(push(unshift([`[${fence} `], bs), [` ${fence}]`]))),
14
+ open(str(`[${fence}`), some(text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true),
15
+ union([some(inline, new RegExp(String.raw`^\s+${fence}\]`))]),
16
+ close(some(text, /^\S/), str(`${fence}]`)), true,
17
+ ([as, bs = [], cs], rest) => [[
18
+ html('span', { class: 'comment' }, [
19
+ html('input', { type: 'checkbox' }),
20
+ html('span', defrag(push(unshift(as, bs), cs))),
21
+ ]),
22
22
  ], rest],
23
- ([as, bs = []], rest, context) => [unshift(pop(eval(some(text)(`${as[0]}!`, context))!)[0], bs), rest]),
23
+ ([as, bs = []], rest) => [unshift(as, bs), rest]),
24
24
  ([, fence]) => fence)))));
@@ -38,7 +38,7 @@ describe('Unit: parser/inline/extension/index', () => {
38
38
  assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
39
39
  assert.deepStrictEqual(inspect(parser('[#a &nbsp;]')), [['<a class="index" href="#index:a">a</a>'], '']);
40
40
  assert.deepStrictEqual(inspect(parser('[#a <wbr>]')), [['<a class="index" href="#index:a">a</a>'], '']);
41
- assert.deepStrictEqual(inspect(parser('[#a [# b #]]')), [['<a class="index" href="#index:a">a <span class="comment">[# b #]</span></a>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('[#a [# b #]]')), [['<a class="index" href="#index:a">a <span class="comment"><input type="checkbox"><span>[# b #]</span></span></a>'], '']);
42
42
  assert.deepStrictEqual(inspect(parser('[#a\\ ]')), [['<a class="index" href="#index:a">a</a>'], '']);
43
43
  assert.deepStrictEqual(inspect(parser('[#a\\ b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
44
44
  assert.deepStrictEqual(inspect(parser('[#[]]')), [['<a class="index" href="#index:[]">[]</a>'], '']);
@@ -54,8 +54,8 @@ describe('Unit: parser/inline/extension/index', () => {
54
54
  assert.deepStrictEqual(inspect(parser('[#@a]')), [['<a class="index" href="#index:@a">@a</a>'], '']);
55
55
  assert.deepStrictEqual(inspect(parser('[#http://host]')), [['<a class="index" href="#index:http://host">http://host</a>'], '']);
56
56
  assert.deepStrictEqual(inspect(parser('[#!http://host]')), [['<a class="index" href="#index:!http://host">!http://host</a>'], '']);
57
- assert.deepStrictEqual(inspect(parser('[#[# #]]')), [['<a class="index"><span class="comment">[# #]</span></a>'], '']);
58
- assert.deepStrictEqual(inspect(parser('[#[# a #]]')), [['<a class="index"><span class="comment">[# a #]</span></a>'], '']);
57
+ assert.deepStrictEqual(inspect(parser('[#[# #]]')), [['<a class="index"><span class="comment"><input type="checkbox"><span>[# #]</span></span></a>'], '']);
58
+ assert.deepStrictEqual(inspect(parser('[#[# a #]]')), [['<a class="index"><span class="comment"><input type="checkbox"><span>[# a #]</span></span></a>'], '']);
59
59
  assert.deepStrictEqual(inspect(parser('[#a((b))]')), [['<a class="index" href="#index:a((b))">a<span class="paren">((b))</span></a>'], '']);
60
60
  assert.deepStrictEqual(inspect(parser('[#a[[b]]]')), [['<a class="index" href="#index:a[[b]]">a[[b]]</a>'], '']);
61
61
  });
@@ -83,7 +83,7 @@ describe('Unit: parser/inline/extension/index', () => {
83
83
  assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
84
84
  assert.deepStrictEqual(inspect(parser('[#a &nbsp;|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
85
85
  assert.deepStrictEqual(inspect(parser('[#a <wbr>|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
86
- assert.deepStrictEqual(inspect(parser('[#a [# b #]|#b]')), [['<a class="index" href="#index:b">a <span class="comment">[# b #]</span><span class="indexer" data-index="b"></span></a>'], '']);
86
+ assert.deepStrictEqual(inspect(parser('[#a [# b #]|#b]')), [['<a class="index" href="#index:b">a <span class="comment"><input type="checkbox"><span>[# b #]</span></span><span class="indexer" data-index="b"></span></a>'], '']);
87
87
  });
88
88
 
89
89
  });
@@ -45,13 +45,13 @@ describe('Unit: parser/inline/extension/placeholder', () => {
45
45
  assert.deepStrictEqual(inspect(parser('[^a\\ \\ ]')), [['<span class="invalid">a </span>'], '']);
46
46
  assert.deepStrictEqual(inspect(parser('[^a<wbr>]')), [['<span class="invalid">a<wbr></span>'], '']);
47
47
  assert.deepStrictEqual(inspect(parser('[^a<wbr><wbr>]')), [['<span class="invalid">a<wbr><wbr></span>'], '']);
48
- assert.deepStrictEqual(inspect(parser('[^a[# b #]]')), [['<span class="invalid">a<span class="comment">[# b #]</span></span>'], '']);
49
- assert.deepStrictEqual(inspect(parser('[^a[# b #][# c #]]')), [['<span class="invalid">a<span class="comment">[# b #]</span><span class="comment">[# c #]</span></span>'], '']);
48
+ assert.deepStrictEqual(inspect(parser('[^a[# b #]]')), [['<span class="invalid">a<span class="comment"><input type="checkbox"><span>[# b #]</span></span></span>'], '']);
49
+ 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>'], '']);
50
50
  assert.deepStrictEqual(inspect(parser('[^\\]]')), [['<span class="invalid">]</span>'], '']);
51
51
  assert.deepStrictEqual(inspect(parser('[^(])]')), [['<span class="invalid"><span class="paren">(])</span></span>'], '']);
52
52
  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>'], '']);
53
- assert.deepStrictEqual(inspect(parser('[^[# a #]]')), [['<span class="invalid"><span class="comment">[# a #]</span></span>'], '']);
54
- assert.deepStrictEqual(inspect(parser('[^[# a #]b]')), [['<span class="invalid"><span class="comment">[# a #]</span>b</span>'], '']);
53
+ assert.deepStrictEqual(inspect(parser('[^[# a #]]')), [['<span class="invalid"><span class="comment"><input type="checkbox"><span>[# a #]</span></span></span>'], '']);
54
+ assert.deepStrictEqual(inspect(parser('[^[# a #]b]')), [['<span class="invalid"><span class="comment"><input type="checkbox"><span>[# a #]</span></span>b</span>'], '']);
55
55
  });
56
56
 
57
57
  });
@@ -16,10 +16,10 @@ const optspec = {
16
16
  } as const;
17
17
  ObjectSetPrototypeOf(optspec, null);
18
18
 
19
- export const link: LinkParser = lazy(() => creator(10, bind(reverse(
19
+ export const link: LinkParser = lazy(() => creator(10, bind(
20
20
  validate(['[', '{'], '}', '\n',
21
21
  guard(context => context.syntax?.inline?.link ?? true,
22
- tails([
22
+ reverse(tails([
23
23
  context({ syntax: { inline: {
24
24
  link: false,
25
25
  }}},
@@ -126,11 +126,7 @@ export function isStartTightNodes(nodes: readonly (HTMLElement | string)[]): boo
126
126
  }
127
127
  export function isEndTightNodes(nodes: readonly (HTMLElement | string)[]): boolean {
128
128
  if (nodes.length === 0) return true;
129
- for (let i = nodes.length; i--;) {
130
- const node = nodes[i];
131
- return isVisible(node, -1);
132
- }
133
- return false;
129
+ return isVisible(nodes[nodes.length - 1], -1);
134
130
  }
135
131
  function isVisible(node: HTMLElement | string, strpos?: number): boolean {
136
132
  switch (typeof node) {