securemark 0.231.1 → 0.232.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.232.1
4
+
5
+ - Refactoring.
6
+
7
+ ## 0.232.0
8
+
9
+ - Refine paragraph syntax to separate mention syntax.
10
+ - Rename mention syntax to reply syntax.
11
+
12
+ ## 0.231.2
13
+
14
+ - Refactoring.
15
+
3
16
  ## 0.231.1
4
17
 
5
18
  - Fix comment syntax.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.231.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.232.1 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) {
@@ -4544,6 +4544,7 @@ require = function () {
4544
4544
  const codeblock_1 = _dereq_('./block/codeblock');
4545
4545
  const mathblock_1 = _dereq_('./block/mathblock');
4546
4546
  const extension_1 = _dereq_('./block/extension');
4547
+ const reply_1 = _dereq_('./block/reply');
4547
4548
  const paragraph_1 = _dereq_('./block/paragraph');
4548
4549
  const typed_dom_1 = _dereq_('typed-dom');
4549
4550
  const random_1 = _dereq_('spica/random');
@@ -4560,6 +4561,7 @@ require = function () {
4560
4561
  mathblock_1.mathblock,
4561
4562
  extension_1.extension,
4562
4563
  blockquote_1.blockquote,
4564
+ reply_1.reply,
4563
4565
  paragraph_1.paragraph
4564
4566
  ]))));
4565
4567
  function error(parser) {
@@ -4593,6 +4595,7 @@ require = function () {
4593
4595
  './block/mathblock': 79,
4594
4596
  './block/olist': 80,
4595
4597
  './block/paragraph': 81,
4598
+ './block/reply': 82,
4596
4599
  './block/table': 85,
4597
4600
  './block/ulist': 86,
4598
4601
  './source': 128,
@@ -5307,7 +5310,7 @@ require = function () {
5307
5310
  colspan,
5308
5311
  ...valid ? { 'data-highlight-level': +highlight > 1 ? highlight : global_1.undefined } : {
5309
5312
  'data-invalid-syntax': 'table',
5310
- 'data-invalid-type': 'highlight',
5313
+ 'data-invalid-type': 'syntax',
5311
5314
  'data-invalid-description': 'Too much highlight level.'
5312
5315
  }
5313
5316
  };
@@ -5776,31 +5779,17 @@ require = function () {
5776
5779
  Object.defineProperty(exports, '__esModule', { value: true });
5777
5780
  exports.paragraph = void 0;
5778
5781
  const combinator_1 = _dereq_('../../combinator');
5779
- const mention_1 = _dereq_('./paragraph/mention');
5780
- const quote_1 = _dereq_('./paragraph/mention/quote');
5781
5782
  const inline_1 = _dereq_('../inline');
5782
- const source_1 = _dereq_('../source');
5783
5783
  const locale_1 = _dereq_('../locale');
5784
5784
  const util_1 = _dereq_('../util');
5785
5785
  const typed_dom_1 = _dereq_('typed-dom');
5786
- const array_1 = _dereq_('spica/array');
5787
- exports.paragraph = (0, combinator_1.block)((0, locale_1.localize)((0, combinator_1.fmap)((0, combinator_1.subsequence)([
5788
- (0, combinator_1.some)(mention_1.mention),
5789
- (0, combinator_1.some)((0, combinator_1.union)([
5790
- quote_1.quote,
5791
- (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.some)(source_1.anyline, quote_1.syntax), (0, combinator_1.trim)((0, util_1.visualize)((0, combinator_1.some)(inline_1.inline)))), ns => (0, array_1.push)(ns, [(0, typed_dom_1.html)('br')]))
5792
- ]))
5793
- ]), ns => [(0, typed_dom_1.html)('p', (0, typed_dom_1.defrag)((0, array_1.pop)(ns)[0]))])));
5786
+ exports.paragraph = (0, combinator_1.block)((0, locale_1.localize)((0, combinator_1.fmap)((0, combinator_1.trim)((0, util_1.visualize)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline])))), ns => [(0, typed_dom_1.html)('p', (0, typed_dom_1.defrag)(ns))])));
5794
5787
  },
5795
5788
  {
5796
5789
  '../../combinator': 27,
5797
5790
  '../inline': 88,
5798
5791
  '../locale': 123,
5799
- '../source': 128,
5800
5792
  '../util': 134,
5801
- './paragraph/mention': 82,
5802
- './paragraph/mention/quote': 84,
5803
- 'spica/array': 6,
5804
5793
  'typed-dom': 26
5805
5794
  }
5806
5795
  ],
@@ -5808,19 +5797,37 @@ require = function () {
5808
5797
  function (_dereq_, module, exports) {
5809
5798
  'use strict';
5810
5799
  Object.defineProperty(exports, '__esModule', { value: true });
5811
- exports.mention = void 0;
5812
- const combinator_1 = _dereq_('../../../combinator');
5813
- const cite_1 = _dereq_('./mention/cite');
5814
- const quote_1 = _dereq_('./mention/quote');
5815
- exports.mention = (0, combinator_1.validate)('>', (0, combinator_1.inits)([
5816
- (0, combinator_1.some)(cite_1.cite),
5817
- quote_1.quote
5818
- ]));
5800
+ exports.reply = void 0;
5801
+ const combinator_1 = _dereq_('../../combinator');
5802
+ const cite_1 = _dereq_('./reply/cite');
5803
+ const quote_1 = _dereq_('./reply/quote');
5804
+ const inline_1 = _dereq_('../inline');
5805
+ const source_1 = _dereq_('../source');
5806
+ const locale_1 = _dereq_('../locale');
5807
+ const util_1 = _dereq_('../util');
5808
+ const typed_dom_1 = _dereq_('typed-dom');
5809
+ const array_1 = _dereq_('spica/array');
5810
+ exports.reply = (0, combinator_1.block)((0, combinator_1.validate)('>', (0, locale_1.localize)((0, combinator_1.fmap)((0, combinator_1.inits)([
5811
+ (0, combinator_1.some)((0, combinator_1.inits)([
5812
+ cite_1.cite,
5813
+ quote_1.quote
5814
+ ])),
5815
+ (0, combinator_1.some)((0, combinator_1.subsequence)([
5816
+ (0, combinator_1.some)(quote_1.quote),
5817
+ (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.some)(source_1.anyline, quote_1.syntax), (0, combinator_1.trim)((0, util_1.visualize)((0, combinator_1.some)(inline_1.inline)))), ns => (0, array_1.push)(ns, [(0, typed_dom_1.html)('br')]))
5818
+ ]))
5819
+ ]), ns => [(0, typed_dom_1.html)('p', (0, typed_dom_1.defrag)((0, array_1.pop)(ns)[0]))]))));
5819
5820
  },
5820
5821
  {
5821
- '../../../combinator': 27,
5822
- './mention/cite': 83,
5823
- './mention/quote': 84
5822
+ '../../combinator': 27,
5823
+ '../inline': 88,
5824
+ '../locale': 123,
5825
+ '../source': 128,
5826
+ '../util': 134,
5827
+ './reply/cite': 83,
5828
+ './reply/quote': 84,
5829
+ 'spica/array': 6,
5830
+ 'typed-dom': 26
5824
5831
  }
5825
5832
  ],
5826
5833
  83: [
@@ -5828,13 +5835,13 @@ require = function () {
5828
5835
  'use strict';
5829
5836
  Object.defineProperty(exports, '__esModule', { value: true });
5830
5837
  exports.cite = void 0;
5831
- const combinator_1 = _dereq_('../../../../combinator');
5832
- const anchor_1 = _dereq_('../../../inline/autolink/anchor');
5833
- const source_1 = _dereq_('../../../source');
5838
+ const combinator_1 = _dereq_('../../../combinator');
5839
+ const anchor_1 = _dereq_('../../inline/autolink/anchor');
5840
+ const source_1 = _dereq_('../../source');
5834
5841
  const typed_dom_1 = _dereq_('typed-dom');
5835
5842
  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)([
5836
5843
  (0, source_1.str)(/^>*(?=>>)/),
5837
- anchor_1.anchor
5844
+ (0, combinator_1.validate)(new RegExp(`${ anchor_1.syntax.source }[^\S\n]*(?:$|\n)`), anchor_1.anchor)
5838
5845
  ]))), ([el, quotes = '']) => [
5839
5846
  (0, typed_dom_1.html)('span', { class: 'cite' }, (0, typed_dom_1.defrag)([
5840
5847
  quotes + '>',
@@ -5844,9 +5851,9 @@ require = function () {
5844
5851
  ])));
5845
5852
  },
5846
5853
  {
5847
- '../../../../combinator': 27,
5848
- '../../../inline/autolink/anchor': 92,
5849
- '../../../source': 128,
5854
+ '../../../combinator': 27,
5855
+ '../../inline/autolink/anchor': 92,
5856
+ '../../source': 128,
5850
5857
  'typed-dom': 26
5851
5858
  }
5852
5859
  ],
@@ -5855,23 +5862,23 @@ require = function () {
5855
5862
  'use strict';
5856
5863
  Object.defineProperty(exports, '__esModule', { value: true });
5857
5864
  exports.quote = exports.syntax = void 0;
5858
- const parser_1 = _dereq_('../../../../combinator/data/parser');
5859
- const combinator_1 = _dereq_('../../../../combinator');
5860
- const math_1 = _dereq_('../../../inline/math');
5861
- const source_1 = _dereq_('../../../source');
5862
- const autolink_1 = _dereq_('../../../autolink');
5865
+ const parser_1 = _dereq_('../../../combinator/data/parser');
5866
+ const combinator_1 = _dereq_('../../../combinator');
5867
+ const math_1 = _dereq_('../../inline/math');
5868
+ const source_1 = _dereq_('../../source');
5869
+ const autolink_1 = _dereq_('../../autolink');
5863
5870
  const typed_dom_1 = _dereq_('typed-dom');
5864
5871
  exports.syntax = /^>+(?=[^\S\n])|^>(?=[^\s>])|^>+(?=[^\s>])(?![0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:]))/;
5865
5872
  exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.validate)('>', (0, combinator_1.union)([
5866
5873
  (0, combinator_1.rewrite)((0, combinator_1.some)((0, combinator_1.validate)(new RegExp(exports.syntax.source.split('|')[0]), source_1.anyline)), qblock),
5867
5874
  (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)(/^.+/)])))
5868
5875
  ])), ns => [
5869
- (0, typed_dom_1.html)('span', ns.length > 1 || /^>+(?=[^\S\n])/.test(ns[0]) ? { class: 'quote' } : {
5876
+ (0, typed_dom_1.html)('span', ns.length > 1 ? { class: 'quote' } : {
5870
5877
  class: 'quote invalid',
5871
5878
  'data-invalid-syntax': 'quote',
5872
5879
  'data-invalid-type': 'syntax',
5873
5880
  'data-invalid-description': `Missing the whitespace after "${ ns[0].split(/[^>]/, 1)[0] }".`
5874
- }, ns),
5881
+ }, (0, typed_dom_1.defrag)(ns)),
5875
5882
  (0, typed_dom_1.html)('br')
5876
5883
  ]), false)));
5877
5884
  const qblock = (source, context) => {
@@ -5901,8 +5908,9 @@ require = function () {
5901
5908
  continue;
5902
5909
  }
5903
5910
  }
5911
+ nodes.unshift('');
5904
5912
  return [
5905
- (0, typed_dom_1.defrag)(nodes),
5913
+ nodes,
5906
5914
  ''
5907
5915
  ];
5908
5916
  };
@@ -5912,11 +5920,11 @@ require = function () {
5912
5920
  ]);
5913
5921
  },
5914
5922
  {
5915
- '../../../../combinator': 27,
5916
- '../../../../combinator/data/parser': 47,
5917
- '../../../autolink': 62,
5918
- '../../../inline/math': 116,
5919
- '../../../source': 128,
5923
+ '../../../combinator': 27,
5924
+ '../../../combinator/data/parser': 47,
5925
+ '../../autolink': 62,
5926
+ '../../inline/math': 116,
5927
+ '../../source': 128,
5920
5928
  'typed-dom': 26
5921
5929
  }
5922
5930
  ],
@@ -6325,12 +6333,13 @@ require = function () {
6325
6333
  function (_dereq_, module, exports) {
6326
6334
  'use strict';
6327
6335
  Object.defineProperty(exports, '__esModule', { value: true });
6328
- exports.anchor = void 0;
6336
+ exports.anchor = exports.syntax = void 0;
6329
6337
  const combinator_1 = _dereq_('../../../combinator');
6330
6338
  const link_1 = _dereq_('../link');
6331
6339
  const source_1 = _dereq_('../../source');
6332
6340
  const typed_dom_1 = _dereq_('typed-dom');
6333
- exports.anchor = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('>>', (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, source_1.str)(/^>>[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:])/), (0, combinator_1.context)({
6341
+ exports.syntax = /^>>[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:])/;
6342
+ 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)({
6334
6343
  syntax: {
6335
6344
  inline: {
6336
6345
  link: true,
@@ -7318,7 +7327,7 @@ require = function () {
7318
7327
  if ((_a = (0, parser_1.eval)((0, combinator_1.some)(autolink_1.autolink)((0, util_1.stringify)(content), context))) === null || _a === void 0 ? void 0 : _a.some(node => typeof node === 'object'))
7319
7328
  return;
7320
7329
  const INSECURE_URI = params.shift();
7321
- const el = create(INSECURE_URI, (0, util_1.trimNode)((0, typed_dom_1.defrag)(content)), new url_1.ReadonlyURL(resolve(INSECURE_URI, (_b = context.host) !== null && _b !== void 0 ? _b : global_1.location, (_d = (_c = context.url) !== null && _c !== void 0 ? _c : context.host) !== null && _d !== void 0 ? _d : global_1.location), ((_e = context.host) === null || _e === void 0 ? void 0 : _e.href) || global_1.location.href), ((_f = context.host) === null || _f === void 0 ? void 0 : _f.origin) || global_1.location.origin);
7330
+ const el = elem(INSECURE_URI, (0, util_1.trimNode)((0, typed_dom_1.defrag)(content)), new url_1.ReadonlyURL(resolve(INSECURE_URI, (_b = context.host) !== null && _b !== void 0 ? _b : global_1.location, (_d = (_c = context.url) !== null && _c !== void 0 ? _c : context.host) !== null && _d !== void 0 ? _d : global_1.location), ((_e = context.host) === null || _e === void 0 ? void 0 : _e.href) || global_1.location.href), ((_f = context.host) === null || _f === void 0 ? void 0 : _f.origin) || global_1.location.origin);
7322
7331
  if (el.classList.contains('invalid'))
7323
7332
  return [
7324
7333
  [el],
@@ -7353,7 +7362,7 @@ require = function () {
7353
7362
  }
7354
7363
  }
7355
7364
  exports.resolve = resolve;
7356
- function create(INSECURE_URI, content, uri, origin) {
7365
+ function elem(INSECURE_URI, content, uri, origin) {
7357
7366
  let type;
7358
7367
  let description;
7359
7368
  switch (uri.protocol) {
@@ -8680,7 +8689,7 @@ require = function () {
8680
8689
  'InvisibleComma',
8681
8690
  'ic'
8682
8691
  ];
8683
- const blankline = new RegExp(String.raw`^(?!$|\n)(?:\\?[^\S\n]|&(?:${ invisibleHTMLEntityNames.join('|') });|<wbr>|\[(#+)(?!\S|\s+\1\]|\s*\[\1(?:$|\s))((?:\s+\S+)+?)(?:\s+(\1\])|\s*(?=\[\1(?:$|\s))))*(?:\\?(?:$|\n)|(\S))`, 'gm');
8692
+ const blankline = new RegExp(String.raw`^(?!$)(?:\\$|\\?[^\S\n]|&(?:${ invisibleHTMLEntityNames.join('|') });|<wbr>|\[(#+)(?!\S|\s+\1\]|\s*\[\1(?:$|\s))((?:\s+\S+)+?)(?:\s+(\1\])|\s*(?=\[\1(?:$|\s))))+(?=$|(\S))`, 'gm');
8684
8693
  function visualize(parser) {
8685
8694
  return (0, combinator_1.union)([
8686
8695
  (0, combinator_1.convert)(source => source.replace(blankline, (line, ...$) => !$[3] ? line.replace(/[\\&<\[]/g, '\x1B$&') : line), (0, combinator_1.verify)(parser, (ns, rest, context) => !rest && hasVisible(ns, context))),
@@ -9350,7 +9359,7 @@ require = function () {
9350
9359
  exports.info = void 0;
9351
9360
  const scope_1 = _dereq_('./scope');
9352
9361
  function info(source) {
9353
- const match = (0, scope_1.scope)(source, 'section, article, aside, blockquote, .quote, pre, .math, .media');
9362
+ const match = (0, scope_1.scope)(source, '.invalid');
9354
9363
  return {
9355
9364
  url: find('a:not(.email):not(.account):not(.channel):not(.hashtag):not(.hashnum):not(.anchor)').filter(el => [
9356
9365
  'http:',
@@ -9362,7 +9371,7 @@ require = function () {
9362
9371
  channel: find('a.channel'),
9363
9372
  hashtag: find('a.hashtag'),
9364
9373
  hashnum: find('a.hashnum'),
9365
- mention: find('.cite > a.anchor'),
9374
+ reply: find('.cite > a.anchor'),
9366
9375
  anchor: find(':not(.cite) > a.anchor'),
9367
9376
  media: find('.media[data-src]')
9368
9377
  };
@@ -9387,7 +9396,7 @@ require = function () {
9387
9396
  Object.defineProperty(exports, '__esModule', { value: true });
9388
9397
  exports.quote = void 0;
9389
9398
  const parser_1 = _dereq_('../combinator/data/parser');
9390
- const cite_1 = _dereq_('../parser/block/paragraph/mention/cite');
9399
+ const cite_1 = _dereq_('../parser/block/reply/cite');
9391
9400
  const typed_dom_1 = _dereq_('typed-dom');
9392
9401
  function quote(anchor, range) {
9393
9402
  var _a, _b;
@@ -9466,7 +9475,7 @@ require = function () {
9466
9475
  },
9467
9476
  {
9468
9477
  '../combinator/data/parser': 47,
9469
- '../parser/block/paragraph/mention/cite': 83,
9478
+ '../parser/block/reply/cite': 83,
9470
9479
  'typed-dom': 26
9471
9480
  }
9472
9481
  ],
@@ -9476,7 +9485,8 @@ require = function () {
9476
9485
  Object.defineProperty(exports, '__esModule', { value: true });
9477
9486
  exports.scope = void 0;
9478
9487
  const global_1 = _dereq_('spica/global');
9479
- function scope(base, bound = `${ 'id' in base && base.id ? `#${ base.id }, ` : '' }section, article, aside, blockquote`) {
9488
+ function scope(base, filter = '', bound = `${ 'id' in base && base.id ? `#${ base.id }, ` : '' }section, article, aside, blockquote, pre, .quote, .math, .media`) {
9489
+ bound += filter && `, ${ filter }`;
9480
9490
  const memory = new global_1.WeakMap();
9481
9491
  const context = 'id' in base && base.closest(bound) || null;
9482
9492
  return el => {
package/index.d.ts CHANGED
@@ -22,7 +22,7 @@ export function normalize(source: string): string;
22
22
  export function quote(anchor: string, range: Range): string;
23
23
  export function toc(source: DocumentFragment | HTMLElement | ShadowRoot): HTMLUListElement;
24
24
  export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info;
25
- export function scope(base: DocumentFragment | HTMLElement | ShadowRoot, bound?: string): (el: Element) => boolean;
25
+ export function scope(base: DocumentFragment | HTMLElement | ShadowRoot, filter?: string, bound?: string): (el: Element) => boolean;
26
26
  export function sync(editor: HTMLElement, viewer: HTMLElement, bottom?: Element | null): () => void;
27
27
 
28
28
  export type ParserOptions = Omit<Partial<ParserSettings>, 'chunk'>;
@@ -76,7 +76,7 @@ export interface Info {
76
76
  readonly channel: HTMLAnchorElement[];
77
77
  readonly hashtag: HTMLAnchorElement[];
78
78
  readonly hashnum: HTMLAnchorElement[];
79
- readonly mention: HTMLAnchorElement[];
79
+ readonly reply: HTMLAnchorElement[];
80
80
  readonly anchor: HTMLAnchorElement[];
81
81
  readonly media: HTMLElement[];
82
82
  }
package/markdown.d.ts CHANGED
@@ -87,6 +87,7 @@ export namespace MarkdownParser {
87
87
  BlockParser.MathBlockParser,
88
88
  BlockParser.ExtensionParser,
89
89
  BlockParser.BlockquoteParser,
90
+ BlockParser.ReplyParser,
90
91
  BlockParser.ParagraphParser,
91
92
  ]> {
92
93
  }
@@ -550,65 +551,66 @@ export namespace MarkdownParser {
550
551
  }
551
552
  }
552
553
  }
553
- export interface ParagraphParser extends
554
+ export interface ReplyParser extends
555
+ // >>1
556
+ // > text
554
557
  // abc
555
- Block<'paragraph'>,
558
+ Block<'reply'>,
556
559
  Parser<HTMLParagraphElement, Context, [
557
- ParagraphParser.MentionParser,
558
560
  Parser<string | HTMLElement, Context, [
559
- ParagraphParser.MentionParser.QuoteParser,
561
+ ReplyParser.CiteParser,
562
+ ReplyParser.QuoteParser,
563
+ ]>,
564
+ Parser<string | HTMLElement, Context, [
565
+ ReplyParser.QuoteParser,
560
566
  InlineParser,
561
567
  ]>,
562
568
  ]> {
563
569
  }
564
- export namespace ParagraphParser {
565
- export interface MentionParser extends
566
- // >>1
567
- // > text
568
- Block<'paragraph/mention'>,
570
+ export namespace ReplyParser {
571
+ export interface CiteParser extends
572
+ Block<'reply/cite'>,
569
573
  Parser<HTMLSpanElement | HTMLBRElement, Context, [
570
- ParagraphParser.MentionParser.CiteParser,
571
- ParagraphParser.MentionParser.QuoteParser,
574
+ SourceParser.StrParser,
575
+ InlineParser.AutolinkParser.AnchorParser,
572
576
  ]> {
573
577
  }
574
- export namespace MentionParser {
575
- export interface CiteParser extends
576
- Block<'paragraph/mention/cite'>,
577
- Parser<HTMLSpanElement | HTMLBRElement, Context, [
578
- SourceParser.StrParser,
579
- InlineParser.AutolinkParser.AnchorParser,
578
+ export interface QuoteParser extends
579
+ Block<'reply/quote'>,
580
+ Parser<HTMLSpanElement | HTMLBRElement, Context, [
581
+ QuoteParser.BlockParser,
582
+ QuoteParser.PlaceholderParser,
583
+ ]> {
584
+ }
585
+ export namespace QuoteParser {
586
+ export interface BlockParser extends
587
+ Block<'reply/quote/block'>,
588
+ Parser<string | HTMLElement, Context, [
589
+ TextParser,
580
590
  ]> {
581
591
  }
582
- export interface QuoteParser extends
583
- Block<'paragraph/mention/quote'>,
584
- Parser<HTMLSpanElement | HTMLBRElement, Context, [
585
- QuoteParser.BlockParser,
586
- QuoteParser.PlaceholderParser,
592
+ export interface TextParser extends
593
+ Block<'reply/quote/text'>,
594
+ Parser<string | HTMLElement, Context, [
595
+ InlineParser.MathParser,
596
+ AutolinkParser,
587
597
  ]> {
588
598
  }
589
- export namespace QuoteParser {
590
- export interface BlockParser extends
591
- Block<'paragraph/mention/quote/block'>,
592
- Parser<string | HTMLElement, Context, [
593
- TextParser,
594
- ]> {
595
- }
596
- export interface TextParser extends
597
- Block<'paragraph/mention/quote/text'>,
598
- Parser<string | HTMLElement, Context, [
599
- InlineParser.MathParser,
600
- AutolinkParser,
601
- ]> {
602
- }
603
- export interface PlaceholderParser extends
604
- Block<'paragraph/mention/quote/placeholder'>,
605
- Parser<string | HTMLElement, Context, [
606
- SourceParser.StrParser,
607
- ]> {
608
- }
599
+ export interface PlaceholderParser extends
600
+ Block<'reply/quote/placeholder'>,
601
+ Parser<string | HTMLElement, Context, [
602
+ SourceParser.StrParser,
603
+ ]> {
609
604
  }
610
605
  }
611
606
  }
607
+ export interface ParagraphParser extends
608
+ // abc
609
+ Block<'paragraph'>,
610
+ Parser<HTMLParagraphElement, Context, [
611
+ InlineParser,
612
+ ]> {
613
+ }
612
614
  }
613
615
  export interface InlineParser extends
614
616
  Markdown<'inline'>,
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.231.1",
3
+ "version": "0.232.1",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -449,9 +449,9 @@
449
449
  },
450
450
  "dependencies": {
451
451
  "lru-cache": {
452
- "version": "7.4.1",
453
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.4.1.tgz",
454
- "integrity": "sha512-NCD7/WRlFmADccuHjsRUYqdluYBr//n/O0fesCb/n52FoGcgKh8o4Dpm7YIbZwVcDs8rPBQbCZLmWWsp6m+xGQ==",
452
+ "version": "7.4.2",
453
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.4.2.tgz",
454
+ "integrity": "sha512-Xs3+hFPDSKQmL05Gs6NhvAADol1u9TmLoNoE03ZjszX6a5iYIO3rPUM4jIjoBUJeTaWEBMozjjmV70gvdRfIdw==",
455
455
  "dev": true
456
456
  },
457
457
  "mkdirp": {
@@ -1691,13 +1691,13 @@
1691
1691
  }
1692
1692
  },
1693
1693
  "browserslist": {
1694
- "version": "4.19.3",
1695
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz",
1696
- "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==",
1694
+ "version": "4.20.0",
1695
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz",
1696
+ "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==",
1697
1697
  "dev": true,
1698
1698
  "requires": {
1699
- "caniuse-lite": "^1.0.30001312",
1700
- "electron-to-chromium": "^1.4.71",
1699
+ "caniuse-lite": "^1.0.30001313",
1700
+ "electron-to-chromium": "^1.4.76",
1701
1701
  "escalade": "^3.1.1",
1702
1702
  "node-releases": "^2.0.2",
1703
1703
  "picocolors": "^1.0.0"
@@ -1918,9 +1918,9 @@
1918
1918
  "dev": true
1919
1919
  },
1920
1920
  "caniuse-lite": {
1921
- "version": "1.0.30001313",
1922
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001313.tgz",
1923
- "integrity": "sha512-rI1UN0koZUiKINjysQDuRi2VeSCce3bYJNmDcj3PIKREiAmjakugBul1QSkg/fPrlULYl6oWfGg3PbgOSY9X4Q==",
1921
+ "version": "1.0.30001314",
1922
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001314.tgz",
1923
+ "integrity": "sha512-0zaSO+TnCHtHJIbpLroX7nsD+vYuOVjl3uzFbJO1wMVbuveJA0RK2WcQA9ZUIOiO0/ArMiMgHJLxfEZhQiC0kw==",
1924
1924
  "dev": true
1925
1925
  },
1926
1926
  "chalk": {
@@ -3024,9 +3024,9 @@
3024
3024
  "dev": true
3025
3025
  },
3026
3026
  "electron-to-chromium": {
3027
- "version": "1.4.76",
3028
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.76.tgz",
3029
- "integrity": "sha512-3Vftv7cenJtQb+k00McEBZ2vVmZ/x+HEF7pcZONZIkOsESqAqVuACmBxMv0JhzX7u0YltU0vSqRqgBSTAhFUjA==",
3027
+ "version": "1.4.80",
3028
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.80.tgz",
3029
+ "integrity": "sha512-COsbJCGVYCc/aAY4cd94x1Js3q0r406YKGbdL8LXHg0O9dEjuFEFU/vZneRxBxKo/f1lLHi0YyAR7sbFM+i8Bg==",
3030
3030
  "dev": true
3031
3031
  },
3032
3032
  "elliptic": {
@@ -3243,14 +3243,14 @@
3243
3243
  }
3244
3244
  },
3245
3245
  "es5-ext": {
3246
- "version": "0.10.53",
3247
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
3248
- "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
3246
+ "version": "0.10.57",
3247
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.57.tgz",
3248
+ "integrity": "sha512-L7cCNoPwTkAp7IBHxrKLsh7NKiVFkcdxlP9vbVw9QUvb7gF0Mz9bEBN0WY9xqdTjGF907EMT/iG013vnbqwu1Q==",
3249
3249
  "dev": true,
3250
3250
  "requires": {
3251
- "es6-iterator": "~2.0.3",
3252
- "es6-symbol": "~3.1.3",
3253
- "next-tick": "~1.0.0"
3251
+ "es6-iterator": "^2.0.3",
3252
+ "es6-symbol": "^3.1.3",
3253
+ "next-tick": "^1.1.0"
3254
3254
  }
3255
3255
  },
3256
3256
  "es6-iterator": {
@@ -6715,9 +6715,9 @@
6715
6715
  }
6716
6716
  },
6717
6717
  "karma-chrome-launcher": {
6718
- "version": "3.1.0",
6719
- "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz",
6720
- "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==",
6718
+ "version": "3.1.1",
6719
+ "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz",
6720
+ "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==",
6721
6721
  "dev": true,
6722
6722
  "requires": {
6723
6723
  "which": "^1.2.1"
@@ -7090,9 +7090,9 @@
7090
7090
  }
7091
7091
  },
7092
7092
  "make-fetch-happen": {
7093
- "version": "10.0.4",
7094
- "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.4.tgz",
7095
- "integrity": "sha512-CiReW6usy3UXby5N46XjWfLPFPq1glugCszh18I0NYJCwr129ZAx9j3Dlv+cRsK0q3VjlVysEzhdtdw2+NhdYA==",
7093
+ "version": "10.0.5",
7094
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.5.tgz",
7095
+ "integrity": "sha512-0JQ0daMRDFEv14DelmcFlprdhSDNG7WEgInTjBeWYWZ78W0jfDqygZdPLhcrQ4s/G8skNhBrS4fiF6xA+YlFjQ==",
7096
7096
  "dev": true,
7097
7097
  "requires": {
7098
7098
  "agentkeepalive": "^4.2.1",
@@ -7101,10 +7101,10 @@
7101
7101
  "http-proxy-agent": "^5.0.0",
7102
7102
  "https-proxy-agent": "^5.0.0",
7103
7103
  "is-lambda": "^1.0.1",
7104
- "lru-cache": "^7.4.0",
7104
+ "lru-cache": "^7.4.1",
7105
7105
  "minipass": "^3.1.6",
7106
7106
  "minipass-collect": "^1.0.2",
7107
- "minipass-fetch": "^2.0.1",
7107
+ "minipass-fetch": "^2.0.2",
7108
7108
  "minipass-flush": "^1.0.5",
7109
7109
  "minipass-pipeline": "^1.2.4",
7110
7110
  "negotiator": "^0.6.3",
@@ -7114,9 +7114,9 @@
7114
7114
  },
7115
7115
  "dependencies": {
7116
7116
  "lru-cache": {
7117
- "version": "7.4.1",
7118
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.4.1.tgz",
7119
- "integrity": "sha512-NCD7/WRlFmADccuHjsRUYqdluYBr//n/O0fesCb/n52FoGcgKh8o4Dpm7YIbZwVcDs8rPBQbCZLmWWsp6m+xGQ==",
7117
+ "version": "7.4.2",
7118
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.4.2.tgz",
7119
+ "integrity": "sha512-Xs3+hFPDSKQmL05Gs6NhvAADol1u9TmLoNoE03ZjszX6a5iYIO3rPUM4jIjoBUJeTaWEBMozjjmV70gvdRfIdw==",
7120
7120
  "dev": true
7121
7121
  }
7122
7122
  }
@@ -7448,9 +7448,9 @@
7448
7448
  }
7449
7449
  },
7450
7450
  "minipass-fetch": {
7451
- "version": "2.0.2",
7452
- "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.2.tgz",
7453
- "integrity": "sha512-M63u5yWX0yxY1C3DcLVY1xWai0pNM3qa1xCMXFgdejY5F/NTmyzNVHGcBxKerX51lssqxwWWTjpg/ZPuD39gOQ==",
7451
+ "version": "2.0.3",
7452
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz",
7453
+ "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==",
7454
7454
  "dev": true,
7455
7455
  "requires": {
7456
7456
  "encoding": "^0.1.13",
@@ -7896,9 +7896,9 @@
7896
7896
  "dev": true
7897
7897
  },
7898
7898
  "next-tick": {
7899
- "version": "1.0.0",
7900
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
7901
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
7899
+ "version": "1.1.0",
7900
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
7901
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
7902
7902
  "dev": true
7903
7903
  },
7904
7904
  "nice-try": {
@@ -9158,9 +9158,9 @@
9158
9158
  }
9159
9159
  },
9160
9160
  "read-package-json": {
9161
- "version": "4.1.1",
9162
- "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-4.1.1.tgz",
9163
- "integrity": "sha512-P82sbZJ3ldDrWCOSKxJT0r/CXMWR0OR3KRh55SgKo3p91GSIEEC32v3lSHAvO/UcH3/IoL7uqhOFBduAnwdldw==",
9161
+ "version": "4.1.2",
9162
+ "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-4.1.2.tgz",
9163
+ "integrity": "sha512-Dqer4pqzamDE2O4M55xp1qZMuLPqi4ldk2ya648FOMHRjwMzFhuxVrG04wd0c38IsvkVdr3vgHI6z+QTPdAjrQ==",
9164
9164
  "dev": true,
9165
9165
  "requires": {
9166
9166
  "glob": "^7.1.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.231.1",
3
+ "version": "0.232.1",
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",
@@ -127,7 +127,7 @@ function attributes(source: string) {
127
127
  ? { 'data-highlight-level': +highlight! > 1 ? highlight : undefined }
128
128
  : {
129
129
  'data-invalid-syntax': 'table',
130
- 'data-invalid-type': 'highlight',
130
+ 'data-invalid-type': 'syntax',
131
131
  'data-invalid-description': 'Too much highlight level.',
132
132
  },
133
133
  };
@@ -28,28 +28,20 @@ describe('Unit: parser/block/paragraph', () => {
28
28
  assert.deepStrictEqual(inspect(parser(' a')), [['<p>a</p>'], '']);
29
29
  });
30
30
 
31
- it('mention', () => {
32
- assert.deepStrictEqual(inspect(parser('>>1')), [['<p><span class="cite">&gt;<a href="?comment=1" class="anchor" data-depth="1">&gt;1</a></span></p>'], '']);
33
- 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>'], '']);
34
- 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>'], '']);
35
- 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>'], '']);
36
- 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>'], '']);
37
- 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>'], '']);
38
- 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>'], '']);
39
- 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>'], '']);
31
+ it('anchor', () => {
40
32
  assert.deepStrictEqual(inspect(parser('>>1 a\nb')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a> a<br>b</p>'], '']);
41
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>'], '']);
42
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>'], '']);
43
- assert.deepStrictEqual(inspect(parser('>>1 a\n>> b')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a> a<br><span class="quote">&gt;&gt; b</span></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>'], '']);
44
36
  assert.deepStrictEqual(inspect(parser('>>11.')), [['<p><a href="?comment=11" class="anchor">&gt;&gt;11</a>.</p>'], '']);
45
37
  assert.deepStrictEqual(inspect(parser('>>11 a')), [['<p><a href="?comment=11" class="anchor">&gt;&gt;11</a> a</p>'], '']);
46
38
  assert.deepStrictEqual(inspect(parser('>>>11 a')), [['<p>&gt;<a href="?comment=11" class="anchor">&gt;&gt;11</a> a</p>'], '']);
47
- assert.deepStrictEqual(inspect(parser('>> a\n>>1')), [['<p><span class="quote">&gt;&gt; a</span><br><a href="?comment=1" class="anchor">&gt;&gt;1</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>'], '']);
48
40
  assert.deepStrictEqual(inspect(parser('a>>1')), [['<p>a<a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
49
41
  assert.deepStrictEqual(inspect(parser('a >>1')), [['<p>a <a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
50
42
  assert.deepStrictEqual(inspect(parser('a\n>>1')), [['<p>a<br><a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
51
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>'], '']);
52
- assert.deepStrictEqual(inspect(parser('a\n>> b\nc')), [['<p>a<br><span class="quote">&gt;&gt; b</span><br>c</p>'], '']);
44
+ assert.deepStrictEqual(inspect(parser('a\n>> b\nc')), [['<p>a<br>&gt;&gt; b<br>c</p>'], '']);
53
45
  assert.deepStrictEqual(inspect(parser(' >>1')), [['<p><a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
54
46
  assert.deepStrictEqual(inspect(parser(' >>>1')), [['<p>&gt;<a href="?comment=1" class="anchor">&gt;&gt;1</a></p>'], '']);
55
47
  });
@@ -1,24 +1,10 @@
1
1
  import { ParagraphParser } from '../block';
2
- import { union, subsequence, some, block, rewrite, trim, fmap } from '../../combinator';
3
- import { mention } from './paragraph/mention';
4
- import { quote, syntax as delimiter } from './paragraph/mention/quote';
2
+ import { union, some, block, trim, fmap } from '../../combinator';
5
3
  import { inline } from '../inline';
6
- import { anyline } from '../source';
7
4
  import { localize } from '../locale';
8
5
  import { visualize } from '../util';
9
6
  import { html, defrag } from 'typed-dom';
10
- import { push, pop } from 'spica/array';
11
7
 
12
8
  export const paragraph: ParagraphParser = block(localize(fmap(
13
- subsequence([
14
- some(mention),
15
- some(union([
16
- quote,
17
- fmap(
18
- rewrite(
19
- some(anyline, delimiter),
20
- trim(visualize(some(inline)))),
21
- ns => push(ns, [html('br')])),
22
- ])),
23
- ]),
24
- ns => [html('p', defrag(pop(ns)[0]))])));
9
+ trim(visualize(some(union([inline])))),
10
+ ns => [html('p', defrag(ns))])));
@@ -1,8 +1,8 @@
1
1
  import { cite } from './cite';
2
- import { some } from '../../../../combinator';
3
- import { inspect } from '../../../../debug.test';
2
+ import { some } from '../../../combinator';
3
+ import { inspect } from '../../../debug.test';
4
4
 
5
- describe('Unit: parser/block/paragraph/mention/cite', () => {
5
+ describe('Unit: parser/block/reply/cite', () => {
6
6
  describe('cite', () => {
7
7
  const parser = (source: string) => some(cite)(source, {});
8
8
 
@@ -1,14 +1,14 @@
1
- import { ParagraphParser } from '../../../block';
2
- import { tails, line, validate, creator, reverse, fmap } from '../../../../combinator';
3
- import { anchor } from '../../../inline/autolink/anchor';
4
- import { str } from '../../../source';
1
+ import { ReplyParser } from '../../block';
2
+ import { tails, line, validate, creator, reverse, fmap } from '../../../combinator';
3
+ import { anchor, syntax } from '../../inline/autolink/anchor';
4
+ import { str } from '../../source';
5
5
  import { html, define, defrag } from 'typed-dom';
6
6
 
7
- export const cite: ParagraphParser.MentionParser.CiteParser = creator(line(fmap(validate(
7
+ export const cite: ReplyParser.CiteParser = creator(line(fmap(validate(
8
8
  '>>',
9
9
  reverse(tails([
10
10
  str(/^>*(?=>>)/),
11
- anchor,
11
+ validate(new RegExp(`${syntax.source}[^\S\n]*(?:$|\n)`), anchor),
12
12
  ]))),
13
13
  ([el, quotes = '']: [HTMLElement, string?]) => [
14
14
  html('span', { class: 'cite' }, defrag([
@@ -1,8 +1,8 @@
1
1
  import { quote } from './quote';
2
- import { some } from '../../../../combinator';
3
- import { inspect } from '../../../../debug.test';
2
+ import { some } from '../../../combinator';
3
+ import { inspect } from '../../../debug.test';
4
4
 
5
- describe('Unit: parser/block/paragraph/mention/quote', () => {
5
+ describe('Unit: parser/block/reply/quote', () => {
6
6
  describe('quote', () => {
7
7
  const parser = (source: string) => some(quote)(source, {});
8
8
 
@@ -1,14 +1,14 @@
1
- import { ParagraphParser } from '../../../block';
2
- import { eval } from '../../../../combinator/data/parser';
3
- import { union, some, block, line, validate, rewrite, creator, lazy, fmap } from '../../../../combinator';
4
- import { math } from '../../../inline/math';
5
- import { str, anyline } from '../../../source';
6
- import { autolink } from '../../../autolink';
1
+ import { ReplyParser } from '../../block';
2
+ import { eval } from '../../../combinator/data/parser';
3
+ import { union, some, block, line, validate, rewrite, creator, lazy, fmap } from '../../../combinator';
4
+ import { math } from '../../inline/math';
5
+ import { str, anyline } from '../../source';
6
+ import { autolink } from '../../autolink';
7
7
  import { html, defrag } from 'typed-dom';
8
8
 
9
9
  export const syntax = /^>+(?=[^\S\n])|^>(?=[^\s>])|^>+(?=[^\s>])(?![0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:]))/;
10
10
 
11
- export const quote: ParagraphParser.MentionParser.QuoteParser = lazy(() => creator(block(fmap(validate(
11
+ export const quote: ReplyParser.QuoteParser = lazy(() => creator(block(fmap(validate(
12
12
  '>',
13
13
  union([
14
14
  rewrite(
@@ -20,7 +20,7 @@ export const quote: ParagraphParser.MentionParser.QuoteParser = lazy(() => creat
20
20
  ])),
21
21
  (ns: [string, ...(string | HTMLElement)[]]) => [
22
22
  html('span',
23
- ns.length > 1 || /^>+(?=[^\S\n])/.test(ns[0])
23
+ ns.length > 1
24
24
  ? { class: 'quote' }
25
25
  : {
26
26
  class: 'quote invalid',
@@ -28,12 +28,12 @@ export const quote: ParagraphParser.MentionParser.QuoteParser = lazy(() => creat
28
28
  'data-invalid-type': 'syntax',
29
29
  'data-invalid-description': `Missing the whitespace after "${ns[0].split(/[^>]/, 1)[0]}".`,
30
30
  },
31
- ns),
31
+ defrag(ns)),
32
32
  html('br'),
33
33
  ]),
34
34
  false)));
35
35
 
36
- const qblock: ParagraphParser.MentionParser.QuoteParser.BlockParser = (source, context) => {
36
+ const qblock: ReplyParser.QuoteParser.BlockParser = (source, context) => {
37
37
  source = source.replace(/\n$/, '');
38
38
  const lines = source.match(/^.*\n?/mg)!;
39
39
  assert(lines);
@@ -64,12 +64,14 @@ const qblock: ParagraphParser.MentionParser.QuoteParser.BlockParser = (source, c
64
64
  continue;
65
65
  }
66
66
  }
67
+ nodes.unshift('');
68
+ assert(nodes.length > 1);
67
69
  assert(nodes.every(n => typeof n === 'string' || n instanceof HTMLElement));
68
70
  assert(quotes.length === 0);
69
- return [defrag(nodes), ''];
71
+ return [nodes, ''];
70
72
  };
71
73
 
72
- const text: ParagraphParser.MentionParser.QuoteParser.TextParser = union([
74
+ const text: ReplyParser.QuoteParser.TextParser = union([
73
75
  math,
74
76
  autolink,
75
77
  ]);
@@ -0,0 +1,22 @@
1
+ import { reply } from './reply';
2
+ import { some } from '../../combinator';
3
+ import { inspect } from '../../debug.test';
4
+
5
+ describe('Unit: parser/block/reply', () => {
6
+ describe('reply', () => {
7
+ const parser = (source: string) => some(reply)(source, {});
8
+
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>'], '']);
18
+ });
19
+
20
+ });
21
+
22
+ });
@@ -0,0 +1,27 @@
1
+ import { ReplyParser } from '../block';
2
+ import { inits, subsequence, some, block, validate, rewrite, trim, fmap } from '../../combinator';
3
+ import { cite } from './reply/cite';
4
+ import { quote, syntax as delimiter } from './reply/quote';
5
+ import { inline } from '../inline';
6
+ import { anyline } from '../source';
7
+ import { localize } from '../locale';
8
+ import { visualize } from '../util';
9
+ import { html, defrag } from 'typed-dom';
10
+ import { push, pop } from 'spica/array';
11
+
12
+ export const reply: ReplyParser = block(validate('>', localize(fmap(
13
+ inits([
14
+ some(inits([
15
+ cite,
16
+ quote,
17
+ ])),
18
+ some(subsequence([
19
+ some(quote),
20
+ fmap(
21
+ rewrite(
22
+ some(anyline, delimiter),
23
+ trim(visualize(some(inline)))),
24
+ ns => push(ns, [html('br')])),
25
+ ])),
26
+ ]),
27
+ ns => [html('p', defrag(pop(ns)[0]))]))));
@@ -13,6 +13,7 @@ import { blockquote } from './block/blockquote';
13
13
  import { codeblock } from './block/codeblock';
14
14
  import { mathblock } from './block/mathblock';
15
15
  import { extension } from './block/extension';
16
+ import { reply } from './block/reply';
16
17
  import { paragraph } from './block/paragraph';
17
18
  import { html } from 'typed-dom';
18
19
  import { rnd0Z } from 'spica/random';
@@ -29,6 +30,7 @@ export import CodeBlockParser = BlockParser.CodeBlockParser;
29
30
  export import MathBlockParser = BlockParser.MathBlockParser;
30
31
  export import ExtensionParser = BlockParser.ExtensionParser;
31
32
  export import BlockquoteParser = BlockParser.BlockquoteParser;
33
+ export import ReplyParser = BlockParser.ReplyParser;
32
34
  export import ParagraphParser = BlockParser.ParagraphParser;
33
35
 
34
36
  export const block: BlockParser = creator(error(
@@ -46,6 +48,7 @@ export const block: BlockParser = creator(error(
46
48
  mathblock,
47
49
  extension,
48
50
  blockquote,
51
+ reply,
49
52
  paragraph
50
53
  ]))));
51
54
 
@@ -4,8 +4,10 @@ import { link } from '../link';
4
4
  import { str } from '../../source';
5
5
  import { define } from 'typed-dom';
6
6
 
7
+ export const syntax = /^>>[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:])/;
8
+
7
9
  export const anchor: AutolinkParser.AnchorParser = lazy(() => validate('>>', fmap(rewrite(
8
- str(/^>>[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:])/),
10
+ str(syntax),
9
11
  context({ syntax: { inline: {
10
12
  link: true,
11
13
  autolink: false,
@@ -7,7 +7,7 @@ import { html, defrag } from 'typed-dom';
7
7
  import { unshift, push } from 'spica/array';
8
8
 
9
9
  const index = /^(?:[0-9]+(?:\.[0-9]+)*|[A-Za-z])/;
10
- const indexFW = new RegExp(index.source.replace(/[019AZaz](?!,)/g, c => String.fromCharCode(c.charCodeAt(0) + 0xfee0)));
10
+ const indexFW = new RegExp(index.source.replace(/[019AZaz](?!,)/g, c => String.fromCharCode(c.charCodeAt(0) + 0xFEE0)));
11
11
 
12
12
  export const bracket: BracketParser = lazy(() => union([
13
13
  surround(str('('), str(index), str(')'), false,
@@ -52,7 +52,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(reverse(
52
52
  const INSECURE_URI = params.shift()!;
53
53
  assert(INSECURE_URI === INSECURE_URI.trim());
54
54
  assert(!INSECURE_URI.match(/\s/));
55
- const el = create(
55
+ const el = elem(
56
56
  INSECURE_URI,
57
57
  trimNode(defrag(content)),
58
58
  new ReadonlyURL(
@@ -98,7 +98,7 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
98
98
  }
99
99
  }
100
100
 
101
- function create(
101
+ function elem(
102
102
  INSECURE_URI: string,
103
103
  content: readonly (string | HTMLElement)[],
104
104
  uri: ReadonlyURL,
@@ -42,7 +42,7 @@ const invisibleHTMLEntityNames = [
42
42
  'InvisibleComma',
43
43
  'ic',
44
44
  ];
45
- const blankline = new RegExp(String.raw`^(?!$|\n)(?:\\?[^\S\n]|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>|\[(#+)(?!\S|\s+\1\]|\s*\[\1(?:$|\s))((?:\s+\S+)+?)(?:\s+(\1\])|\s*(?=\[\1(?:$|\s))))*(?:\\?(?:$|\n)|(\S))`, 'gm');
45
+ const blankline = new RegExp(String.raw`^(?!$)(?:\\$|\\?[^\S\n]|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>|\[(#+)(?!\S|\s+\1\]|\s*\[\1(?:$|\s))((?:\s+\S+)+?)(?:\s+(\1\])|\s*(?=\[\1(?:$|\s))))+(?=$|(\S))`, 'gm');
46
46
 
47
47
  export function visualize<P extends Parser<HTMLElement | string>>(parser: P): P;
48
48
  export function visualize<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
@@ -229,7 +229,7 @@ export function stringify(nodes: readonly (HTMLElement | string)[]): string {
229
229
  }
230
230
  else {
231
231
  assert(!node.matches('br') && !node.querySelector('br'));
232
- // Note: Doesn't reflect line breaks.
232
+ // NOTE: Doesn't reflect line breaks.
233
233
  acc += node.innerText;
234
234
  }
235
235
  }
@@ -14,7 +14,7 @@ describe('Unit: util/info', () => {
14
14
  channel: [],
15
15
  hashtag: [],
16
16
  hashnum: [],
17
- mention: [],
17
+ reply: [],
18
18
  anchor: [],
19
19
  media: [],
20
20
  });
package/src/util/info.ts CHANGED
@@ -2,7 +2,7 @@ import { Info } from '../..';
2
2
  import { scope } from './scope';
3
3
 
4
4
  export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info {
5
- const match = scope(source, 'section, article, aside, blockquote, .quote, pre, .math, .media');
5
+ const match = scope(source, '.invalid');
6
6
  return {
7
7
  url: find<HTMLAnchorElement>('a:not(.email):not(.account):not(.channel):not(.hashtag):not(.hashnum):not(.anchor)')
8
8
  .filter(el => ['http:', 'https:'].includes(el.protocol)),
@@ -13,7 +13,7 @@ export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info
13
13
  channel: find('a.channel'),
14
14
  hashtag: find('a.hashtag'),
15
15
  hashnum: find('a.hashnum'),
16
- mention: find('.cite > a.anchor'),
16
+ reply: find('.cite > a.anchor'),
17
17
  anchor: find(':not(.cite) > a.anchor'),
18
18
  media: find('.media[data-src]'),
19
19
  };
package/src/util/quote.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { exec } from '../combinator/data/parser';
2
- import { cite } from '../parser/block/paragraph/mention/cite';
2
+ import { cite } from '../parser/block/reply/cite';
3
3
  import { define } from 'typed-dom';
4
4
 
5
5
  export function quote(anchor: string, range: Range): string {
package/src/util/scope.ts CHANGED
@@ -2,8 +2,10 @@ import { undefined, WeakMap } from 'spica/global';
2
2
 
3
3
  export function scope(
4
4
  base: DocumentFragment | HTMLElement | ShadowRoot,
5
- bound: string = `${'id' in base && base.id ? `#${base.id}, ` : ''}section, article, aside, blockquote`,
5
+ filter: string = '',
6
+ bound: string = `${'id' in base && base.id ? `#${base.id}, ` : ''}section, article, aside, blockquote, pre, .quote, .math, .media`,
6
7
  ): (el: Element) => boolean {
8
+ bound += filter && `, ${filter}`;
7
9
  const memory = new WeakMap<Node, boolean>();
8
10
  const context = 'id' in base && base.closest(bound) || null;
9
11
  return el => {
@@ -1,9 +0,0 @@
1
- import { ParagraphParser } from '../../block';
2
- import { inits, some, validate } from '../../../combinator';
3
- import { cite } from './mention/cite';
4
- import { quote } from './mention/quote';
5
-
6
- export const mention: ParagraphParser.MentionParser = validate('>', inits([
7
- some(cite),
8
- quote,
9
- ]));