securemark 0.234.1 → 0.234.2

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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.234.2
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.234.1
4
8
 
5
9
  - Fix emstrong parser, emphasis parser, strong parser, and mark parser.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.234.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.234.2 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) {
@@ -6674,11 +6674,8 @@ require = function () {
6674
6674
  const array_1 = _dereq_('spica/array');
6675
6675
  exports.emphasis = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, combinator_1.close)((0, source_1.str)('*'), /^(?!\*)/), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
6676
6676
  strong_1.strong,
6677
- (0, combinator_1.some)(inline_1.inline, /^\s*\*/),
6678
- (0, combinator_1.sequence)([
6679
- (0, combinator_1.some)(inline_1.inline, '*'),
6680
- inline_1.inline
6681
- ])
6677
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*`)),
6678
+ (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6682
6679
  ]))), (0, source_1.str)('*'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
6683
6680
  [(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))],
6684
6681
  rest
@@ -6713,26 +6710,17 @@ require = function () {
6713
6710
  const typed_dom_1 = _dereq_('typed-dom');
6714
6711
  const array_1 = _dereq_('spica/array');
6715
6712
  const substrong = (0, combinator_1.lazy)(() => (0, combinator_1.some)((0, combinator_1.union)([
6716
- (0, combinator_1.some)(inline_1.inline, /^\s*\*\*/),
6717
- (0, combinator_1.sequence)([
6718
- (0, combinator_1.some)(inline_1.inline, '*'),
6719
- inline_1.inline
6720
- ])
6713
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*\*`)),
6714
+ (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6721
6715
  ])));
6722
6716
  const subemphasis = (0, combinator_1.lazy)(() => (0, combinator_1.some)((0, combinator_1.union)([
6723
6717
  strong_1.strong,
6724
- (0, combinator_1.some)(inline_1.inline, /^\s*\*/),
6725
- (0, combinator_1.sequence)([
6726
- (0, combinator_1.some)(inline_1.inline, '*'),
6727
- inline_1.inline
6728
- ])
6718
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*`)),
6719
+ (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6729
6720
  ])));
6730
6721
  exports.emstrong = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('***'), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
6731
- (0, combinator_1.some)(inline_1.inline, /^\s*\*/),
6732
- (0, combinator_1.sequence)([
6733
- (0, combinator_1.some)(inline_1.inline, '*'),
6734
- inline_1.inline
6735
- ])
6722
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*`)),
6723
+ (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6736
6724
  ]))), (0, source_1.str)(/^\*{1,3}/), false, ([as, bs, cs], rest, context) => {
6737
6725
  var _a, _b;
6738
6726
  if (!(0, util_1.isEndTightNodes)(bs))
@@ -6741,25 +6729,13 @@ require = function () {
6741
6729
  cs[0] + rest
6742
6730
  ];
6743
6731
  switch (cs[0]) {
6744
- case '*':
6745
- return (_a = (0, combinator_1.bind)(substrong, (ds, rest) => rest.slice(0, 2) === '**' && (0, util_1.isEndTightNodes)(ds) ? [
6746
- [(0, typed_dom_1.html)('strong', (0, array_1.unshift)([(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))], (0, typed_dom_1.defrag)(ds)))],
6747
- rest.slice(2)
6748
- ] : [
6749
- (0, array_1.unshift)([
6750
- '**',
6751
- (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
6752
- ], ds),
6753
- rest
6754
- ])(rest, context)) !== null && _a !== void 0 ? _a : [
6755
- [
6756
- '**',
6757
- (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
6758
- ],
6732
+ case '***':
6733
+ return [
6734
+ [(0, typed_dom_1.html)('em', [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))])],
6759
6735
  rest
6760
6736
  ];
6761
6737
  case '**':
6762
- return (_b = (0, combinator_1.bind)(subemphasis, (ds, rest) => rest.slice(0, 1) === '*' && (0, util_1.isEndTightNodes)(ds) ? [
6738
+ return (_a = (0, combinator_1.bind)(subemphasis, (ds, rest) => rest.slice(0, 1) === '*' && (0, util_1.isEndTightNodes)(ds) ? [
6763
6739
  [(0, typed_dom_1.html)('em', (0, array_1.unshift)([(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))], (0, typed_dom_1.defrag)(ds)))],
6764
6740
  rest.slice(1)
6765
6741
  ] : [
@@ -6768,16 +6744,28 @@ require = function () {
6768
6744
  (0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))
6769
6745
  ], ds),
6770
6746
  rest
6771
- ])(rest, context)) !== null && _b !== void 0 ? _b : [
6747
+ ])(rest, context)) !== null && _a !== void 0 ? _a : [
6772
6748
  [
6773
6749
  '*',
6774
6750
  (0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))
6775
6751
  ],
6776
6752
  rest
6777
6753
  ];
6778
- case '***':
6779
- return [
6780
- [(0, typed_dom_1.html)('em', [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))])],
6754
+ case '*':
6755
+ return (_b = (0, combinator_1.bind)(substrong, (ds, rest) => rest.slice(0, 2) === '**' && (0, util_1.isEndTightNodes)(ds) ? [
6756
+ [(0, typed_dom_1.html)('strong', (0, array_1.unshift)([(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))], (0, typed_dom_1.defrag)(ds)))],
6757
+ rest.slice(2)
6758
+ ] : [
6759
+ (0, array_1.unshift)([
6760
+ '**',
6761
+ (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
6762
+ ], ds),
6763
+ rest
6764
+ ])(rest, context)) !== null && _b !== void 0 ? _b : [
6765
+ [
6766
+ '**',
6767
+ (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
6768
+ ],
6781
6769
  rest
6782
6770
  ];
6783
6771
  }
@@ -7250,7 +7238,7 @@ require = function () {
7250
7238
  const combinator_1 = _dereq_('../../combinator');
7251
7239
  const typed_dom_1 = _dereq_('typed-dom');
7252
7240
  const parser = (0, typed_dom_1.html)('textarea');
7253
- exports.unsafehtmlentity = (0, combinator_1.creator)((0, combinator_1.validate)('&', (0, combinator_1.fmap)((0, combinator_1.focus)(/^&[0-9A-Za-z]+;/, entity => [
7241
+ exports.unsafehtmlentity = (0, combinator_1.creator)((0, combinator_1.validate)('&', (0, combinator_1.fmap)((0, combinator_1.focus)(/^&(?!NewLine;)[0-9A-Za-z]+;/, entity => [
7254
7242
  [(parser.innerHTML = entity, parser.value)],
7255
7243
  ''
7256
7244
  ]), ([str]) => [str[0] !== '&' || str.length < 3 ? str : `\0${ str }`])));
@@ -7450,11 +7438,8 @@ require = function () {
7450
7438
  const typed_dom_1 = _dereq_('typed-dom');
7451
7439
  const array_1 = _dereq_('spica/array');
7452
7440
  exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('=='), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
7453
- (0, combinator_1.some)(inline_1.inline, /^\s*==/),
7454
- (0, combinator_1.sequence)([
7455
- (0, combinator_1.some)(inline_1.inline, '='),
7456
- inline_1.inline
7457
- ])
7441
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)('==')),
7442
+ (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '='), inline_1.inline)
7458
7443
  ]))), (0, source_1.str)('=='), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7459
7444
  [(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)(bs))],
7460
7445
  rest
@@ -7872,11 +7857,8 @@ require = function () {
7872
7857
  const typed_dom_1 = _dereq_('typed-dom');
7873
7858
  const array_1 = _dereq_('spica/array');
7874
7859
  exports.strong = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, combinator_1.close)((0, source_1.str)('**'), /^(?!\*)/), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
7875
- (0, combinator_1.some)(inline_1.inline, /^\s*\*\*/),
7876
- (0, combinator_1.sequence)([
7877
- (0, combinator_1.some)(inline_1.inline, '*'),
7878
- inline_1.inline
7879
- ])
7860
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*\*`)),
7861
+ (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
7880
7862
  ]))), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7881
7863
  [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))],
7882
7864
  rest
@@ -8668,7 +8650,7 @@ require = function () {
8668
8650
  function (_dereq_, module, exports) {
8669
8651
  'use strict';
8670
8652
  Object.defineProperty(exports, '__esModule', { value: true });
8671
- exports.stringify = exports.trimNodeEndBR = exports.trimNodeEnd = exports.trimNode = exports.isEndTightNodes = exports.isStartTightNodes = exports.startTight = exports.isStartLoose = exports.startLoose = exports.visualize = void 0;
8653
+ exports.stringify = exports.trimNodeEndBR = exports.trimNodeEnd = exports.trimNode = exports.isEndTightNodes = exports.isStartTightNodes = exports.startTight = exports.isStartLoose = exports.startLoose = exports.visualize = exports.delimiter = void 0;
8672
8654
  const global_1 = _dereq_('spica/global');
8673
8655
  const parser_1 = _dereq_('../combinator/data/parser');
8674
8656
  const combinator_1 = _dereq_('../combinator');
@@ -8709,7 +8691,11 @@ require = function () {
8709
8691
  'InvisibleComma',
8710
8692
  'ic'
8711
8693
  ];
8712
- const blankline = new RegExp(String.raw`^(?!$)(?:\\$|\\?[^\S\n]|&(?:${ invisibleHTMLEntityNames.join('|') });|<wbr>)+$`, 'gm');
8694
+ const blankline = new RegExp(String.raw`^(?:\\$|\\?[^\S\n]|&(?:${ invisibleHTMLEntityNames.join('|') });|<wbr>)+$`, 'gm');
8695
+ function delimiter(opener) {
8696
+ return new RegExp(String.raw`^(?:\s+|\\\s|&(?:${ invisibleHTMLEntityNames.join('|') });|<wbr>)?${ opener }`);
8697
+ }
8698
+ exports.delimiter = delimiter;
8713
8699
  function visualize(parser) {
8714
8700
  return (0, combinator_1.union)([
8715
8701
  (0, combinator_1.convert)(source => source.replace(blankline, line => line.replace(/[\\&<]/g, '\x1B$&')), (0, combinator_1.verify)(parser, (ns, rest, context) => !rest && hasVisible(ns, context))),
package/markdown.d.ts CHANGED
@@ -970,10 +970,7 @@ export namespace MarkdownParser {
970
970
  Inline<'mark'>,
971
971
  Parser<HTMLElement | string, Context, [
972
972
  InlineParser,
973
- Parser<HTMLElement | string, Context, [
974
- InlineParser,
975
- InlineParser,
976
- ]>,
973
+ InlineParser,
977
974
  ]> {
978
975
  }
979
976
  export interface EmStrongParser extends
@@ -981,10 +978,7 @@ export namespace MarkdownParser {
981
978
  Inline<'emstrong'>,
982
979
  Parser<HTMLElement | string, Context, [
983
980
  InlineParser,
984
- Parser<HTMLElement | string, Context, [
985
- InlineParser,
986
- InlineParser,
987
- ]>,
981
+ InlineParser,
988
982
  ]> {
989
983
  }
990
984
  export interface StrongParser extends
@@ -992,10 +986,7 @@ export namespace MarkdownParser {
992
986
  Inline<'strong'>,
993
987
  Parser<HTMLElement | string, Context, [
994
988
  InlineParser,
995
- Parser<HTMLElement | string, Context, [
996
- InlineParser,
997
- InlineParser,
998
- ]>,
989
+ InlineParser,
999
990
  ]> {
1000
991
  }
1001
992
  export interface EmphasisParser extends
@@ -1004,10 +995,7 @@ export namespace MarkdownParser {
1004
995
  Parser<HTMLElement | string, Context, [
1005
996
  StrongParser,
1006
997
  InlineParser,
1007
- Parser<HTMLElement | string, Context, [
1008
- InlineParser,
1009
- InlineParser,
1010
- ]>,
998
+ InlineParser,
1011
999
  ]> {
1012
1000
  }
1013
1001
  export interface CodeParser extends
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.234.1",
3
+ "version": "0.234.2",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -4608,9 +4608,9 @@
4608
4608
  "dev": true
4609
4609
  },
4610
4610
  "gauge": {
4611
- "version": "4.0.3",
4612
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz",
4613
- "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==",
4611
+ "version": "4.0.4",
4612
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
4613
+ "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
4614
4614
  "dev": true,
4615
4615
  "requires": {
4616
4616
  "aproba": "^1.0.3 || ^2.0.0",
@@ -8918,9 +8918,9 @@
8918
8918
  "dev": true
8919
8919
  },
8920
8920
  "proc-log": {
8921
- "version": "2.0.0",
8922
- "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.0.tgz",
8923
- "integrity": "sha512-I/35MfCX2H8jBUhKN8JB8nmqvQo/nKdrBodBY7L3RhDSPPyvOHwLYNmPuhwuJq7a7C3vgFKWGQM+ecPStcvOHA==",
8921
+ "version": "2.0.1",
8922
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz",
8923
+ "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==",
8924
8924
  "dev": true
8925
8925
  },
8926
8926
  "process": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.234.1",
3
+ "version": "0.234.2",
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",
@@ -20,6 +20,8 @@ describe('Unit: parser/block/paragraph', () => {
20
20
  assert.deepStrictEqual(inspect(parser('a\\ \n')), [['<p>a</p>'], '']);
21
21
  assert.deepStrictEqual(inspect(parser('a\\\n')), [['<p>a</p>'], '']);
22
22
  assert.deepStrictEqual(inspect(parser('a\\\nb')), [['<p>a<span class="linebreak"> </span>b</p>'], '']);
23
+ assert.deepStrictEqual(inspect(parser('a&NewLine;b')), [['<p>a&amp;NewLine;b</p>'], '']);
24
+ assert.deepStrictEqual(inspect(parser('&Tab;&NewLine;')), [['<p>&amp;Tab;&amp;NewLine;</p>'], '']);
23
25
  assert.deepStrictEqual(inspect(parser('<wbr>')), [['<p>&lt;wbr&gt;</p>'], '']);
24
26
  assert.deepStrictEqual(inspect(parser('<wbr>\n')), [['<p>&lt;wbr&gt;</p>'], '']);
25
27
  assert.deepStrictEqual(inspect(parser('<wbr>\na')), [['<p>&lt;wbr&gt;<br>a</p>'], '']);
@@ -11,8 +11,8 @@ describe('Unit: parser/inline/emphasis', () => {
11
11
  assert.deepStrictEqual(inspect(parser('*a')), [['*', 'a'], '']);
12
12
  assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' ', '*'], '']);
13
13
  assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a', '<br>', '*'], '']);
14
- assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a', ' '], '*']);
15
- assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a', '<span class="linebreak"> </span>'], '*']);
14
+ assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a', ' ', '*'], '']);
15
+ assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a', '<span class="linebreak"> </span>', '*'], '']);
16
16
  assert.deepStrictEqual(inspect(parser('*a**b')), [['*', 'a', '**', 'b'], '']);
17
17
  assert.deepStrictEqual(inspect(parser('*a**b*')), [['*', 'a', '**', 'b', '*'], '']);
18
18
  assert.deepStrictEqual(inspect(parser('* *')), undefined);
@@ -37,10 +37,13 @@ describe('Unit: parser/inline/emphasis', () => {
37
37
  });
38
38
 
39
39
  it('nest', () => {
40
- assert.deepStrictEqual(inspect(parser('*a**b**c*')), [['<em>a<strong>b</strong>c</em>'], '']);
41
- assert.deepStrictEqual(inspect(parser('*a**b**c*d')), [['<em>a<strong>b</strong>c</em>'], 'd']);
42
40
  assert.deepStrictEqual(inspect(parser('*a *b**')), [['<em>a <em>b</em></em>'], '']);
43
41
  assert.deepStrictEqual(inspect(parser('*a **b***')), [['<em>a <strong>b</strong></em>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('*a\\ *b**')), [['<em>a <em>b</em></em>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('*a&Tab;*b**')), [['<em>a\t<em>b</em></em>'], '']);
44
+ assert.deepStrictEqual(inspect(parser('*a<wbr>*b**')), [['<em>a<wbr><em>b</em></em>'], '']);
45
+ assert.deepStrictEqual(inspect(parser('*a**b**c*')), [['<em>a<strong>b</strong>c</em>'], '']);
46
+ assert.deepStrictEqual(inspect(parser('*a**b**c*d')), [['<em>a<strong>b</strong>c</em>'], 'd']);
44
47
  assert.deepStrictEqual(inspect(parser('*`a`*')), [['<em><code data-src="`a`">a</code></em>'], '']);
45
48
  assert.deepStrictEqual(inspect(parser('*<small>*')), [['<em>&lt;small&gt;</em>'], '']);
46
49
  assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
@@ -1,9 +1,9 @@
1
1
  import { EmphasisParser } from '../inline';
2
- import { union, sequence, some, creator, surround, close, lazy } from '../../combinator';
2
+ import { union, some, creator, surround, open, close, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { strong } from './strong';
5
5
  import { str } from '../source';
6
- import { startTight, isEndTightNodes } from '../util';
6
+ import { startTight, isEndTightNodes, delimiter } from '../util';
7
7
  import { html, defrag } from 'typed-dom';
8
8
  import { unshift } from 'spica/array';
9
9
 
@@ -11,8 +11,8 @@ export const emphasis: EmphasisParser = lazy(() => creator(surround(close(
11
11
  str('*'), /^(?!\*)/),
12
12
  startTight(some(union([
13
13
  strong,
14
- some(inline, /^\s*\*/),
15
- sequence([some(inline, '*'), inline]),
14
+ some(inline, delimiter(String.raw`\*`)),
15
+ open(some(inline, '*'), inline),
16
16
  ]))),
17
17
  str('*'), false,
18
18
  ([as, bs, cs], rest) =>
@@ -1,42 +1,37 @@
1
1
  import { MarkdownParser } from '../../../markdown';
2
2
  import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
3
3
  import { Result, IntermediateParser } from '../../combinator/data/parser';
4
- import { union, sequence, some, creator, surround, lazy, bind } from '../../combinator';
4
+ import { union, some, creator, surround, open, lazy, bind } from '../../combinator';
5
5
  import { inline } from '../inline';
6
6
  import { strong } from './strong';
7
7
  import { str } from '../source';
8
- import { startTight, isEndTightNodes } from '../util';
8
+ import { startTight, isEndTightNodes, delimiter } from '../util';
9
9
  import { html, defrag } from 'typed-dom';
10
10
  import { unshift } from 'spica/array';
11
11
 
12
12
  const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
13
- some(inline, /^\s*\*\*/),
14
- sequence([some(inline, '*'), inline]),
13
+ some(inline, delimiter(String.raw`\*\*`)),
14
+ open(some(inline, '*'), inline),
15
15
  ])));
16
16
  const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
17
17
  strong,
18
- some(inline, /^\s*\*/),
19
- sequence([some(inline, '*'), inline]),
18
+ some(inline, delimiter(String.raw`\*`)),
19
+ open(some(inline, '*'), inline),
20
20
  ])));
21
21
 
22
22
  export const emstrong: EmStrongParser = lazy(() => creator(surround(
23
23
  str('***'),
24
24
  startTight(some(union([
25
- some(inline, /^\s*\*/),
26
- sequence([some(inline, '*'), inline]),
25
+ some(inline, delimiter(String.raw`\*`)),
26
+ open(some(inline, '*'), inline),
27
27
  ]))),
28
28
  str(/^\*{1,3}/), false,
29
29
  ([as, bs, cs], rest, context): Result<HTMLElement | string, MarkdownParser.Context> => {
30
+ assert(cs.length === 1);
30
31
  if (!isEndTightNodes(bs)) return [unshift(as, bs), cs[0] + rest];
31
32
  switch (cs[0]) {
32
- case '*':
33
- return bind<StrongParser>(
34
- substrong,
35
- (ds, rest) =>
36
- rest.slice(0, 2) === '**' && isEndTightNodes(ds)
37
- ? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds)))], rest.slice(2)]
38
- : [unshift(['**', html('em', defrag(bs))], ds), rest])
39
- (rest, context) ?? [['**', html('em', defrag(bs))], rest];
33
+ case '***':
34
+ return [[html('em', [html('strong', defrag(bs))])], rest];
40
35
  case '**':
41
36
  return bind<EmphasisParser>(
42
37
  subemphasis,
@@ -45,8 +40,14 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
45
40
  ? [[html('em', unshift([html('strong', defrag(bs))], defrag(ds)))], rest.slice(1)]
46
41
  : [unshift(['*', html('strong', defrag(bs))], ds), rest])
47
42
  (rest, context) ?? [['*', html('strong', defrag(bs))], rest];
48
- case '***':
49
- return [[html('em', [html('strong', defrag(bs))])], rest];
43
+ case '*':
44
+ return bind<StrongParser>(
45
+ substrong,
46
+ (ds, rest) =>
47
+ rest.slice(0, 2) === '**' && isEndTightNodes(ds)
48
+ ? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds)))], rest.slice(2)]
49
+ : [unshift(['**', html('em', defrag(bs))], ds), rest])
50
+ (rest, context) ?? [['**', html('em', defrag(bs))], rest];
50
51
  }
51
52
  assert(false);
52
53
  },
@@ -14,6 +14,7 @@ describe('Unit: parser/inline/htmlentity', () => {
14
14
  assert.deepStrictEqual(inspect(parser('& ;')), undefined);
15
15
  assert.deepStrictEqual(inspect(parser('&\n;')), undefined);
16
16
  assert.deepStrictEqual(inspect(parser('&a;')), [['<span class="invalid">&amp;a;</span>'], '']);
17
+ assert.deepStrictEqual(inspect(parser('&NewLine;')), undefined);
17
18
  assert.deepStrictEqual(inspect(parser('&#;')), undefined);
18
19
  assert.deepStrictEqual(inspect(parser('&#g;')), undefined);
19
20
  assert.deepStrictEqual(inspect(parser('&#x;')), undefined);
@@ -5,7 +5,7 @@ import { html } from 'typed-dom';
5
5
  const parser = html('textarea');
6
6
 
7
7
  export const unsafehtmlentity: UnsafeHTMLEntityParser = creator(validate('&', fmap(focus(
8
- /^&[0-9A-Za-z]+;/,
8
+ /^&(?!NewLine;)[0-9A-Za-z]+;/,
9
9
  entity => [[(parser.innerHTML = entity, parser.value)], '']),
10
10
  ([str]) => [
11
11
  str[0] !== '&' || str.length < 3
@@ -14,8 +14,8 @@ describe('Unit: parser/inline/mark', () => {
14
14
  assert.deepStrictEqual(inspect(parser('==a=')), [['==', 'a', '='], '']);
15
15
  assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' ', '=='], '']);
16
16
  assert.deepStrictEqual(inspect(parser('==a\n==')), [['==', 'a', '<br>', '=='], '']);
17
- assert.deepStrictEqual(inspect(parser('==a\\ ==')), [['==', 'a', ' '], '==']);
18
- assert.deepStrictEqual(inspect(parser('==a\\\n==')), [['==', 'a', '<span class="linebreak"> </span>'], '==']);
17
+ assert.deepStrictEqual(inspect(parser('==a\\ ==')), [['==', 'a', ' ', '=='], '']);
18
+ assert.deepStrictEqual(inspect(parser('==a\\\n==')), [['==', 'a', '<span class="linebreak"> </span>', '=='], '']);
19
19
  assert.deepStrictEqual(inspect(parser('== ==')), undefined);
20
20
  assert.deepStrictEqual(inspect(parser('== a==')), undefined);
21
21
  assert.deepStrictEqual(inspect(parser('== a ==')), undefined);
@@ -35,8 +35,11 @@ describe('Unit: parser/inline/mark', () => {
35
35
  });
36
36
 
37
37
  it('nest', () => {
38
- assert.deepStrictEqual(inspect(parser('==*==a==*==')), [['<mark><em><mark>a</mark></em></mark>'], '']);
39
38
  assert.deepStrictEqual(inspect(parser('==a ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('==a\\ ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('==a&Tab;==b====')), [['<mark>a\t<mark>b</mark></mark>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('==a<wbr>==b====')), [['<mark>a<wbr><mark>b</mark></mark>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('==*==a==*==')), [['<mark><em><mark>a</mark></em></mark>'], '']);
40
43
  });
41
44
 
42
45
  });
@@ -1,16 +1,16 @@
1
1
  import { MarkParser } from '../inline';
2
- import { union, sequence, some, creator, surround, lazy } from '../../combinator';
2
+ import { union, some, creator, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
- import { startTight, isEndTightNodes } from '../util';
5
+ import { startTight, isEndTightNodes, delimiter } from '../util';
6
6
  import { html, defrag } from 'typed-dom';
7
7
  import { unshift } from 'spica/array';
8
8
 
9
9
  export const mark: MarkParser = lazy(() => creator(surround(
10
10
  str('=='),
11
11
  startTight(some(union([
12
- some(inline, /^\s*==/),
13
- sequence([some(inline, '='), inline]),
12
+ some(inline, delimiter('==')),
13
+ open(some(inline, '='), inline),
14
14
  ]))),
15
15
  str('=='), false,
16
16
  ([as, bs, cs], rest) =>
@@ -12,8 +12,8 @@ describe('Unit: parser/inline/strong', () => {
12
12
  assert.deepStrictEqual(inspect(parser('**a*')), [['**', 'a', '*'], '']);
13
13
  assert.deepStrictEqual(inspect(parser('**a **')), [['**', 'a', ' ', '**'], '']);
14
14
  assert.deepStrictEqual(inspect(parser('**a\n**')), [['**', 'a', '<br>', '**'], '']);
15
- assert.deepStrictEqual(inspect(parser('**a\\ **')), [['**', 'a', ' '], '**']);
16
- assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['**', 'a', '<span class="linebreak"> </span>'], '**']);
15
+ assert.deepStrictEqual(inspect(parser('**a\\ **')), [['**', 'a', ' ', '**'], '']);
16
+ assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['**', 'a', '<span class="linebreak"> </span>', '**'], '']);
17
17
  assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
18
18
  assert.deepStrictEqual(inspect(parser('** **')), undefined);
19
19
  assert.deepStrictEqual(inspect(parser('** a**')), undefined);
@@ -35,10 +35,12 @@ describe('Unit: parser/inline/strong', () => {
35
35
  });
36
36
 
37
37
  it('nest', () => {
38
- assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
39
- assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
40
38
  assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
41
39
  assert.deepStrictEqual(inspect(parser('**a **b****')), [['<strong>a <strong>b</strong></strong>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('**a&Tab;**b****')), [['<strong>a\t<strong>b</strong></strong>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('**a<wbr>**b****')), [['<strong>a<wbr><strong>b</strong></strong>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
42
44
  assert.deepStrictEqual(inspect(parser('**`a`**')), [['<strong><code data-src="`a`">a</code></strong>'], '']);
43
45
  assert.deepStrictEqual(inspect(parser('**<small>**')), [['<strong>&lt;small&gt;</strong>'], '']);
44
46
  assert.deepStrictEqual(inspect(parser('**(*a*)**')), [['<strong><span class="paren">(<em>a</em>)</span></strong>'], '']);
@@ -1,16 +1,16 @@
1
1
  import { StrongParser } from '../inline';
2
- import { union, sequence, some, creator, surround, close, lazy } from '../../combinator';
2
+ import { union, some, creator, surround, open, close, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
- import { startTight, isEndTightNodes } from '../util';
5
+ import { startTight, isEndTightNodes, delimiter } from '../util';
6
6
  import { html, defrag } from 'typed-dom';
7
7
  import { unshift } from 'spica/array';
8
8
 
9
9
  export const strong: StrongParser = lazy(() => creator(surround(close(
10
10
  str('**'), /^(?!\*)/),
11
11
  startTight(some(union([
12
- some(inline, /^\s*\*\*/),
13
- sequence([some(inline, '*'), inline]),
12
+ some(inline, delimiter(String.raw`\*\*`)),
13
+ open(some(inline, '*'), inline),
14
14
  ]))),
15
15
  str('**'), false,
16
16
  ([as, bs, cs], rest) =>
@@ -64,18 +64,28 @@ describe('Unit: parser/inline', () => {
64
64
  assert.deepStrictEqual(inspect(parser('***a*b*c***')), [['<strong><em>a</em>b<em>c</em></strong>'], '']);
65
65
  assert.deepStrictEqual(inspect(parser('***a*b*c***d')), [['<strong><em>a</em>b<em>c</em></strong>', 'd'], '']);
66
66
  assert.deepStrictEqual(inspect(parser('***a*b**c****')), [['<strong><em>a</em>b</strong>', 'c', '****'], '']);
67
- assert.deepStrictEqual(inspect(parser('***a*b *c***')), [['<strong><em>a</em>b <em>c</em></strong>'], '']);
68
- assert.deepStrictEqual(inspect(parser('***a\\ *b**')), [['***', 'a', ' ', '<em>b</em>', '*'], '']);
67
+ assert.deepStrictEqual(inspect(parser('***a* **b****')), [['<strong><em>a</em> <strong>b</strong></strong>'], '']);
68
+ assert.deepStrictEqual(inspect(parser('***a*\\ **b****')), [['<strong><em>a</em> <strong>b</strong></strong>'], '']);
69
+ assert.deepStrictEqual(inspect(parser('***a*&Tab;**b****')), [['<strong><em>a</em>\t<strong>b</strong></strong>'], '']);
70
+ assert.deepStrictEqual(inspect(parser('***a*<wbr>**b****')), [['<strong><em>a</em><wbr><strong>b</strong></strong>'], '']);
71
+ assert.deepStrictEqual(inspect(parser('***a *b****')), [['<em><strong>a <em>b</em></strong></em>'], '']);
72
+ assert.deepStrictEqual(inspect(parser('***a\\ *b****')), [['<em><strong>a <em>b</em></strong></em>'], '']);
73
+ assert.deepStrictEqual(inspect(parser('***a&Tab;*b****')), [['<em><strong>a\t<em>b</em></strong></em>'], '']);
74
+ assert.deepStrictEqual(inspect(parser('***a<wbr>*b****')), [['<em><strong>a<wbr><em>b</em></strong></em>'], '']);
75
+ assert.deepStrictEqual(inspect(parser('***a*b **')), [['**', '<em>a</em>', 'b', ' ', '**'], '']);
69
76
  assert.deepStrictEqual(inspect(parser('***a*b\\ **')), [['**', '<em>a</em>', 'b', ' ', '**'], '']);
70
- assert.deepStrictEqual(inspect(parser('***a* b**')), [['<strong><em>a</em> b</strong>'], '']);
71
77
  assert.deepStrictEqual(inspect(parser('***a**b*')), [['<em><strong>a</strong>b</em>'], '']);
72
78
  assert.deepStrictEqual(inspect(parser('***a**b*c')), [['<em><strong>a</strong>b</em>', 'c'], '']);
73
79
  assert.deepStrictEqual(inspect(parser('***a**b*c**')), [['<em><strong>a</strong>b</em>', 'c', '**'], '']);
74
80
  assert.deepStrictEqual(inspect(parser('***a**b**c***')), [['<em><strong>a</strong>b<strong>c</strong></em>'], '']);
75
81
  assert.deepStrictEqual(inspect(parser('***a**b**c***d')), [['<em><strong>a</strong>b<strong>c</strong></em>', 'd'], '']);
76
- assert.deepStrictEqual(inspect(parser('***a**b **c***')), [['<em><strong>a</strong>b <strong>c</strong></em>'], '']);
77
- assert.deepStrictEqual(inspect(parser('***a** b*')), [['<em><strong>a</strong> b</em>'], '']);
82
+ assert.deepStrictEqual(inspect(parser('***a** *b**')), [['<em><strong>a</strong> <em>b</em></em>'], '']);
83
+ assert.deepStrictEqual(inspect(parser('***a**\\ *b**')), [['<em><strong>a</strong> <em>b</em></em>'], '']);
84
+ assert.deepStrictEqual(inspect(parser('***a**&Tab;*b**')), [['<em><strong>a</strong>\t<em>b</em></em>'], '']);
85
+ assert.deepStrictEqual(inspect(parser('***a**<wbr>*b**')), [['<em><strong>a</strong><wbr><em>b</em></em>'], '']);
86
+ assert.deepStrictEqual(inspect(parser('***a **b*')), [['***', 'a', ' ', '**', 'b', '*'], '']);
78
87
  assert.deepStrictEqual(inspect(parser('***a\\ **b*')), [['***', 'a', ' ', '**', 'b', '*'], '']);
88
+ assert.deepStrictEqual(inspect(parser('***a**b *')), [['*', '<strong>a</strong>', 'b', ' ', '*'], '']);
79
89
  assert.deepStrictEqual(inspect(parser('***a**b\\ *')), [['*', '<strong>a</strong>', 'b', ' ', '*'], '']);
80
90
  assert.deepStrictEqual(inspect(parser('***a*')), [['**', '<em>a</em>'], '']);
81
91
  assert.deepStrictEqual(inspect(parser('***a**')), [['*', '<strong>a</strong>'], '']);
@@ -40,8 +40,12 @@ const invisibleHTMLEntityNames = [
40
40
  'it',
41
41
  'InvisibleComma',
42
42
  'ic',
43
- ];
44
- const blankline = new RegExp(String.raw`^(?!$)(?:\\$|\\?[^\S\n]|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)+$`, 'gm');
43
+ ] as const;
44
+ const blankline = new RegExp(String.raw`^(?:\\$|\\?[^\S\n]|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)+$`, 'gm');
45
+
46
+ export function delimiter(opener: string): RegExp {
47
+ return new RegExp(String.raw`^(?:\s+|\\\s|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)?${opener}`);
48
+ }
45
49
 
46
50
  export function visualize<P extends Parser<HTMLElement | string>>(parser: P): P;
47
51
  export function visualize<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {