securemark 0.224.1 → 0.225.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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.225.0
4
+
5
+ - Refine some parsers to disallow trailing whitespace.
6
+
3
7
  ## 0.224.1
4
8
 
5
9
  - Refactoring.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.224.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.225.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) {
@@ -6966,7 +6966,7 @@ require = function () {
6966
6966
  const typed_dom_1 = _dereq_('typed-dom');
6967
6967
  const array_1 = _dereq_('spica/array');
6968
6968
  exports.deletion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('~~'), (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '~~')]), (0, source_1.str)('~~'), false, ([, bs], rest) => [
6969
- [(0, typed_dom_1.html)('del', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
6969
+ [(0, typed_dom_1.html)('del', (0, typed_dom_1.defrag)((0, util_1.trimNodeEndBR)(bs)))],
6970
6970
  rest
6971
6971
  ], ([as, bs], rest) => [
6972
6972
  (0, array_1.unshift)(as, bs),
@@ -6998,7 +6998,7 @@ require = function () {
6998
6998
  strong_1.strong,
6999
6999
  (0, combinator_1.some)(inline_1.inline, '*')
7000
7000
  ]))), (0, source_1.str)('*'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7001
- [(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
7001
+ [(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))],
7002
7002
  rest
7003
7003
  ] : [
7004
7004
  (0, array_1.unshift)(as, bs),
@@ -7039,41 +7039,41 @@ require = function () {
7039
7039
  switch (cs[0]) {
7040
7040
  case '*':
7041
7041
  return (_a = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '**')]), (ds, rest) => rest.slice(0, 2) === '**' && (0, util_1.isEndTightNodes)(ds) ? [
7042
- [(0, typed_dom_1.html)('strong', (0, array_1.unshift)([(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))], (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(ds))))],
7042
+ [(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)))],
7043
7043
  rest.slice(2)
7044
7044
  ] : [
7045
7045
  (0, array_1.unshift)([
7046
7046
  '**',
7047
- (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))
7047
+ (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
7048
7048
  ], ds),
7049
7049
  rest
7050
7050
  ])(rest, context)) !== null && _a !== void 0 ? _a : [
7051
7051
  [
7052
7052
  '**',
7053
- (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))
7053
+ (0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))
7054
7054
  ],
7055
7055
  rest
7056
7056
  ];
7057
7057
  case '**':
7058
7058
  return (_b = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '*')]), (ds, rest) => rest.slice(0, 1) === '*' && (0, util_1.isEndTightNodes)(ds) ? [
7059
- [(0, typed_dom_1.html)('em', (0, array_1.unshift)([(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))], (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(ds))))],
7059
+ [(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)))],
7060
7060
  rest.slice(1)
7061
7061
  ] : [
7062
7062
  (0, array_1.unshift)([
7063
7063
  '*',
7064
- (0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))
7064
+ (0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))
7065
7065
  ], ds),
7066
7066
  rest
7067
7067
  ])(rest, context)) !== null && _b !== void 0 ? _b : [
7068
7068
  [
7069
7069
  '*',
7070
- (0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))
7070
+ (0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))
7071
7071
  ],
7072
7072
  rest
7073
7073
  ];
7074
7074
  case '***':
7075
7075
  return [
7076
- [(0, typed_dom_1.html)('em', [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))])],
7076
+ [(0, typed_dom_1.html)('em', [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))])],
7077
7077
  rest
7078
7078
  ];
7079
7079
  }
@@ -7441,11 +7441,11 @@ require = function () {
7441
7441
  return {};
7442
7442
  }
7443
7443
  })(), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`)), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
7444
- [elem(tag, as, (0, util_1.trimEndBR)((0, typed_dom_1.defrag)(bs)), cs, context)],
7444
+ [elem(tag, as, (0, util_1.trimNodeEndBR)((0, typed_dom_1.defrag)(bs)), cs, context)],
7445
7445
  rest
7446
7446
  ])), ([, tag]) => tag)),
7447
7447
  (0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`), `</${ tag }>`), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest) => [
7448
- [elem(tag, as, (0, util_1.trimEndBR)((0, typed_dom_1.defrag)(bs)), cs, {})],
7448
+ [elem(tag, as, (0, util_1.trimNodeEndBR)((0, typed_dom_1.defrag)(bs)), cs, {})],
7449
7449
  rest
7450
7450
  ], ([as, bs], rest) => as.length === 1 ? [
7451
7451
  (0, array_1.unshift)(as, bs),
@@ -7561,7 +7561,7 @@ require = function () {
7561
7561
  const typed_dom_1 = _dereq_('typed-dom');
7562
7562
  const array_1 = _dereq_('spica/array');
7563
7563
  exports.insertion = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('++'), (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '++')]), (0, source_1.str)('++'), false, ([, bs], rest) => [
7564
- [(0, typed_dom_1.html)('ins', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
7564
+ [(0, typed_dom_1.html)('ins', (0, typed_dom_1.defrag)((0, util_1.trimNodeEndBR)(bs)))],
7565
7565
  rest
7566
7566
  ], ([as, bs], rest) => [
7567
7567
  (0, array_1.unshift)(as, bs),
@@ -7733,7 +7733,7 @@ require = function () {
7733
7733
  const typed_dom_1 = _dereq_('typed-dom');
7734
7734
  const array_1 = _dereq_('spica/array');
7735
7735
  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.union)([(0, combinator_1.some)(inline_1.inline, '==')])), (0, source_1.str)('=='), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7736
- [(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
7736
+ [(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)(bs))],
7737
7737
  rest
7738
7738
  ] : [
7739
7739
  (0, array_1.unshift)(as, bs),
@@ -8123,7 +8123,7 @@ require = function () {
8123
8123
  (0, combinator_1.some)(inline_1.inline, '*'),
8124
8124
  (0, source_1.str)('*')
8125
8125
  ]), '**')), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
8126
- [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
8126
+ [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))],
8127
8127
  rest
8128
8128
  ] : [
8129
8129
  (0, array_1.unshift)(as, bs),
@@ -8886,7 +8886,7 @@ require = function () {
8886
8886
  function (_dereq_, module, exports) {
8887
8887
  'use strict';
8888
8888
  Object.defineProperty(exports, '__esModule', { value: true });
8889
- exports.stringify = exports.trimEndBR = exports.trimNodeEnd = exports.trimNode = exports.isEndTightNodes = exports.isStartTightNodes = exports.startTight = exports.isStartLoose = exports.startLoose = exports.visualize = void 0;
8889
+ exports.stringify = exports.trimNodeEndBR = exports.trimNodeEnd = exports.trimNode = exports.isEndTightNodes = exports.isStartTightNodes = exports.startTight = exports.isStartLoose = exports.startLoose = exports.visualize = void 0;
8890
8890
  const global_1 = _dereq_('spica/global');
8891
8891
  const parser_1 = _dereq_('../combinator/data/parser');
8892
8892
  const combinator_1 = _dereq_('../combinator');
@@ -9020,8 +9020,7 @@ require = function () {
9020
9020
  function isEndTightNodes(nodes) {
9021
9021
  if (nodes.length === 0)
9022
9022
  return true;
9023
- const last = nodes.length - 1;
9024
- return typeof nodes[last] === 'string' && nodes[last].length > 1 ? isVisible(nodes[last], -1) || isVisible(nodes[last], -2) : isVisible(nodes[last], -1) || last === 0 || isVisible(nodes[last - 1], -1);
9023
+ return isVisible(nodes[nodes.length - 1], -1);
9025
9024
  }
9026
9025
  exports.isEndTightNodes = isEndTightNodes;
9027
9026
  function isVisible(node, position) {
@@ -9085,13 +9084,13 @@ require = function () {
9085
9084
  return (0, array_1.push)(nodes, skip);
9086
9085
  }
9087
9086
  exports.trimNodeEnd = trimNodeEnd;
9088
- function trimEndBR(nodes) {
9087
+ function trimNodeEndBR(nodes) {
9089
9088
  if (nodes.length === 0)
9090
9089
  return nodes;
9091
9090
  const node = nodes[nodes.length - 1];
9092
9091
  return typeof node === 'object' && node.tagName === 'BR' ? (0, array_1.pop)(nodes)[0] : nodes;
9093
9092
  }
9094
- exports.trimEndBR = trimEndBR;
9093
+ exports.trimNodeEndBR = trimNodeEndBR;
9095
9094
  function stringify(nodes) {
9096
9095
  let acc = '';
9097
9096
  for (let i = 0; i < nodes.length; ++i) {
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.224.1",
3
+ "version": "0.225.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.224.1",
3
+ "version": "0.225.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",
@@ -60,9 +60,6 @@ describe('Unit: parser/api/parse', () => {
60
60
  });
61
61
 
62
62
  it('linebreak', () => {
63
- assert.deepStrictEqual(
64
- [...parse('*a\n*\nb').children].map(el => el.outerHTML),
65
- ['<p><em>a</em><br>b</p>']);
66
63
  assert.deepStrictEqual(
67
64
  [...parse('\\ ').children].map(el => el.outerHTML),
68
65
  ['<p>\\</p>']);
@@ -32,8 +32,6 @@ describe('Unit: parser/inline/deletion', () => {
32
32
  assert.deepStrictEqual(inspect(parser('~~a\\\nb~~')), [['<del>a<span class="linebreak"> </span>b</del>'], '']);
33
33
  assert.deepStrictEqual(inspect(parser('~~\\~~~')), [['<del>~</del>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('~~a~~~')), [['<del>a</del>'], '~']);
35
- assert.deepStrictEqual(inspect(parser('~~~a~~')), [['<del>~a</del>'], '']);
36
- assert.deepStrictEqual(inspect(parser('~~~a~~~')), [['<del>~a</del>'], '~']);
37
35
  });
38
36
 
39
37
  it('nest', () => {
@@ -2,7 +2,7 @@ import { DeletionParser } from '../inline';
2
2
  import { union, some, creator, surround, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
- import { trimEndBR } from '../util';
5
+ import { trimNodeEndBR } from '../util';
6
6
  import { html, defrag } from 'typed-dom';
7
7
  import { unshift } from 'spica/array';
8
8
 
@@ -10,5 +10,5 @@ export const deletion: DeletionParser = lazy(() => creator(surround(
10
10
  str('~~'),
11
11
  union([some(inline, '~~')]),
12
12
  str('~~'), false,
13
- ([, bs], rest) => [[html('del', defrag(trimEndBR(bs)))], rest],
13
+ ([, bs], rest) => [[html('del', defrag(trimNodeEndBR(bs)))], rest],
14
14
  ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -9,7 +9,10 @@ describe('Unit: parser/inline/emphasis', () => {
9
9
  it('invalid', () => {
10
10
  assert.deepStrictEqual(inspect(parser('*')), undefined);
11
11
  assert.deepStrictEqual(inspect(parser('*a')), [['*', 'a'], '']);
12
- assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' '], '*']);
12
+ assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' '], '*']);
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>'], '*']);
13
16
  assert.deepStrictEqual(inspect(parser('*a**b')), [['*', 'a', '**', 'b'], '']);
14
17
  assert.deepStrictEqual(inspect(parser('*a**b*')), [['*', 'a', '**', 'b', '*'], '']);
15
18
  assert.deepStrictEqual(inspect(parser('* *')), undefined);
@@ -28,9 +31,6 @@ describe('Unit: parser/inline/emphasis', () => {
28
31
 
29
32
  it('basic', () => {
30
33
  assert.deepStrictEqual(inspect(parser('*a*')), [['<em>a</em>'], '']);
31
- assert.deepStrictEqual(inspect(parser('*a *')), [['<em>a </em>'], '']);
32
- assert.deepStrictEqual(inspect(parser('*a\n*')), [['<em>a</em>'], '']);
33
- assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['<em>a<span class="linebreak"> </span></em>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('*ab*')), [['<em>ab</em>'], '']);
35
35
  assert.deepStrictEqual(inspect(parser('*a\nb*')), [['<em>a<br>b</em>'], '']);
36
36
  assert.deepStrictEqual(inspect(parser('*a\\\nb*')), [['<em>a<span class="linebreak"> </span>b</em>'], '']);
@@ -3,7 +3,7 @@ import { union, some, creator, surround, 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, trimEndBR } from '../util';
6
+ import { startTight, isEndTightNodes } from '../util';
7
7
  import { html, defrag } from 'typed-dom';
8
8
  import { unshift } from 'spica/array';
9
9
 
@@ -13,6 +13,6 @@ export const emphasis: EmphasisParser = lazy(() => creator(surround(close(
13
13
  str('*'), false,
14
14
  ([as, bs, cs], rest) =>
15
15
  isEndTightNodes(bs)
16
- ? [[html('em', defrag(trimEndBR(bs)))], rest]
16
+ ? [[html('em', defrag(bs))], rest]
17
17
  : [unshift(as, bs), cs[0] + rest],
18
18
  ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -2,7 +2,7 @@ import { EmStrongParser } from '../inline';
2
2
  import { union, some, creator, surround, lazy, bind } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
- import { startTight, isEndTightNodes, trimEndBR } from '../util';
5
+ import { startTight, isEndTightNodes } from '../util';
6
6
  import { html, defrag } from 'typed-dom';
7
7
  import { unshift } from 'spica/array';
8
8
 
@@ -18,19 +18,19 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
18
18
  union([some(inline, '**')]),
19
19
  (ds, rest) =>
20
20
  rest.slice(0, 2) === '**' && isEndTightNodes(ds)
21
- ? [[html('strong', unshift([html('em', defrag(trimEndBR(bs)))], defrag(trimEndBR(ds))))], rest.slice(2)]
22
- : [unshift(['**', html('em', defrag(trimEndBR(bs)))], ds), rest])
23
- (rest, context) ?? [['**', html('em', defrag(trimEndBR(bs)))], rest];
21
+ ? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds)))], rest.slice(2)]
22
+ : [unshift(['**', html('em', defrag(bs))], ds), rest])
23
+ (rest, context) ?? [['**', html('em', defrag(bs))], rest];
24
24
  case '**':
25
25
  return bind<EmStrongParser>(
26
26
  union([some(inline, '*')]),
27
27
  (ds, rest) =>
28
28
  rest.slice(0, 1) === '*' && isEndTightNodes(ds)
29
- ? [[html('em', unshift([html('strong', defrag(trimEndBR(bs)))], defrag(trimEndBR(ds))))], rest.slice(1)]
30
- : [unshift(['*', html('strong', defrag(trimEndBR(bs)))], ds), rest])
31
- (rest, context) ?? [['*', html('strong', defrag(trimEndBR(bs)))], rest];
29
+ ? [[html('em', unshift([html('strong', defrag(bs))], defrag(ds)))], rest.slice(1)]
30
+ : [unshift(['*', html('strong', defrag(bs))], ds), rest])
31
+ (rest, context) ?? [['*', html('strong', defrag(bs))], rest];
32
32
  case '***':
33
- return [[html('em', [html('strong', defrag(trimEndBR(bs)))])], rest];
33
+ return [[html('em', [html('strong', defrag(bs))])], rest];
34
34
  }
35
35
  assert(false);
36
36
  },
@@ -5,7 +5,7 @@ import { HTMLParser } from '../inline';
5
5
  import { union, some, validate, context, creator, surround, match, lazy } from '../../combinator';
6
6
  import { inline } from '../inline';
7
7
  import { str } from '../source';
8
- import { startLoose, trimEndBR } from '../util';
8
+ import { startLoose, trimNodeEndBR } from '../util';
9
9
  import { html as h, defrag } from 'typed-dom';
10
10
  import { memoize } from 'spica/memoize';
11
11
  import { Cache } from 'spica/cache';
@@ -66,7 +66,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
66
66
  some(union([inline]), `</${tag}>`)), `</${tag}>`),
67
67
  str(`</${tag}>`), false,
68
68
  ([as, bs, cs], rest, context) =>
69
- [[elem(tag, as, trimEndBR(defrag(bs)), cs, context)], rest])),
69
+ [[elem(tag, as, trimNodeEndBR(defrag(bs)), cs, context)], rest])),
70
70
  ([, tag]) => tag)),
71
71
  match(
72
72
  /^(?=<([a-z]+)(?=[^\S\n]|>))/,
@@ -78,7 +78,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
78
78
  startLoose(some(union([inline]), `</${tag}>`), `</${tag}>`),
79
79
  str(`</${tag}>`), false,
80
80
  ([as, bs, cs], rest) =>
81
- [[elem(tag, as, trimEndBR(defrag(bs)), cs, {})], rest],
81
+ [[elem(tag, as, trimNodeEndBR(defrag(bs)), cs, {})], rest],
82
82
  ([as, bs], rest) =>
83
83
  as.length === 1
84
84
  ? [unshift(as, bs), rest]
@@ -32,8 +32,6 @@ describe('Unit: parser/inline/insertion', () => {
32
32
  assert.deepStrictEqual(inspect(parser('++a\\\nb++')), [['<ins>a<span class="linebreak"> </span>b</ins>'], '']);
33
33
  assert.deepStrictEqual(inspect(parser('++\\+++')), [['<ins>+</ins>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('++a+++')), [['<ins>a</ins>'], '+']);
35
- assert.deepStrictEqual(inspect(parser('+++a++')), [['<ins>+a</ins>'], '']);
36
- assert.deepStrictEqual(inspect(parser('+++a+++')), [['<ins>+a</ins>'], '+']);
37
35
  });
38
36
 
39
37
  it('nest', () => {
@@ -2,7 +2,7 @@ import { InsertionParser } from '../inline';
2
2
  import { union, some, creator, surround, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
- import { trimEndBR } from '../util';
5
+ import { trimNodeEndBR } from '../util';
6
6
  import { html, defrag } from 'typed-dom';
7
7
  import { unshift } from 'spica/array';
8
8
 
@@ -10,5 +10,5 @@ export const insertion: InsertionParser = lazy(() => creator(surround(
10
10
  str('++'),
11
11
  union([some(inline, '++')]),
12
12
  str('++'), false,
13
- ([, bs], rest) => [[html('ins', defrag(trimEndBR(bs)))], rest],
13
+ ([, bs], rest) => [[html('ins', defrag(trimNodeEndBR(bs)))], rest],
14
14
  ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -12,7 +12,10 @@ describe('Unit: parser/inline/mark', () => {
12
12
  assert.deepStrictEqual(inspect(parser('==')), undefined);
13
13
  assert.deepStrictEqual(inspect(parser('==a')), [['==', 'a'], '']);
14
14
  assert.deepStrictEqual(inspect(parser('==a=')), [['==', 'a', '='], '']);
15
- assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' '], '==']);
15
+ assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' '], '==']);
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>'], '==']);
16
19
  assert.deepStrictEqual(inspect(parser('== ==')), undefined);
17
20
  assert.deepStrictEqual(inspect(parser('== a==')), undefined);
18
21
  assert.deepStrictEqual(inspect(parser('== a ==')), undefined);
@@ -26,14 +29,10 @@ describe('Unit: parser/inline/mark', () => {
26
29
  it('basic', () => {
27
30
  assert.deepStrictEqual(inspect(parser('==a==')), [['<mark>a</mark>'], '']);
28
31
  assert.deepStrictEqual(inspect(parser('==ab==')), [['<mark>ab</mark>'], '']);
29
- assert.deepStrictEqual(inspect(parser('==a ==')), [['<mark>a </mark>'], '']);
30
- assert.deepStrictEqual(inspect(parser('==a\n==')), [['<mark>a</mark>'], '']);
31
32
  assert.deepStrictEqual(inspect(parser('==a\nb==')), [['<mark>a<br>b</mark>'], '']);
32
33
  assert.deepStrictEqual(inspect(parser('==a\\\nb==')), [['<mark>a<span class="linebreak"> </span>b</mark>'], '']);
33
34
  assert.deepStrictEqual(inspect(parser('==\\===')), [['<mark>=</mark>'], '']);
34
35
  assert.deepStrictEqual(inspect(parser('==a===')), [['<mark>a</mark>'], '=']);
35
- assert.deepStrictEqual(inspect(parser('===a==')), [['<mark>=a</mark>'], '']);
36
- assert.deepStrictEqual(inspect(parser('===a===')), [['<mark>=a</mark>'], '=']);
37
36
  });
38
37
 
39
38
  it('nest', () => {
@@ -2,7 +2,7 @@ import { MarkParser } from '../inline';
2
2
  import { union, some, creator, surround, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
- import { startTight, isEndTightNodes, trimEndBR } from '../util';
5
+ import { startTight, isEndTightNodes } from '../util';
6
6
  import { html, defrag } from 'typed-dom';
7
7
  import { unshift } from 'spica/array';
8
8
 
@@ -12,6 +12,6 @@ export const mark: MarkParser = lazy(() => creator(surround(
12
12
  str('=='), false,
13
13
  ([as, bs, cs], rest) =>
14
14
  isEndTightNodes(bs)
15
- ? [[html('mark', defrag(trimEndBR(bs)))], rest]
15
+ ? [[html('mark', defrag(bs))], rest]
16
16
  : [unshift(as, bs), cs[0] + rest],
17
17
  ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -23,6 +23,7 @@ describe('Unit: parser/inline/math', () => {
23
23
  assert.deepStrictEqual(inspect(parser('$-0$-1')), undefined);
24
24
  assert.deepStrictEqual(inspect(parser('$-a$')), undefined);
25
25
  assert.deepStrictEqual(inspect(parser('$-a$-b')), undefined);
26
+ assert.deepStrictEqual(inspect(parser('$a $')), undefined);
26
27
  assert.deepStrictEqual(inspect(parser('$a-b$')), undefined);
27
28
  assert.deepStrictEqual(inspect(parser('$a-b$c-d')), undefined);
28
29
  assert.deepStrictEqual(inspect(parser('$a+b$')), undefined);
@@ -33,6 +34,8 @@ describe('Unit: parser/inline/math', () => {
33
34
  assert.deepStrictEqual(inspect(parser('$a$b')), undefined);
34
35
  assert.deepStrictEqual(inspect(parser('$a$b$')), undefined);
35
36
  assert.deepStrictEqual(inspect(parser('$ $')), undefined);
37
+ assert.deepStrictEqual(inspect(parser('$ a$')), undefined);
38
+ assert.deepStrictEqual(inspect(parser('$ a $')), undefined);
36
39
  assert.deepStrictEqual(inspect(parser('$\n$')), undefined);
37
40
  assert.deepStrictEqual(inspect(parser('$a\nb$')), undefined);
38
41
  assert.deepStrictEqual(inspect(parser('$a\\\nb$')), undefined);
@@ -59,6 +62,7 @@ describe('Unit: parser/inline/math', () => {
59
62
  assert.deepStrictEqual(inspect(parser('${}$')), [['<span class="math" translate="no" data-src="${}$">${}$</span>'], '']);
60
63
  assert.deepStrictEqual(inspect(parser('${ }$')), [['<span class="math" translate="no" data-src="${ }$">${ }$</span>'], '']);
61
64
  assert.deepStrictEqual(inspect(parser('${a}$')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], '']);
65
+ assert.deepStrictEqual(inspect(parser('${a}$$')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], '$']);
62
66
  assert.deepStrictEqual(inspect(parser('${a}$0')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], '0']);
63
67
  assert.deepStrictEqual(inspect(parser('${a}$b')), [['<span class="math" translate="no" data-src="${a}$">${a}$</span>'], 'b']);
64
68
  assert.deepStrictEqual(inspect(parser('${ab}$')), [['<span class="math" translate="no" data-src="${ab}$">${ab}$</span>'], '']);
@@ -71,14 +75,15 @@ describe('Unit: parser/inline/math', () => {
71
75
  assert.deepStrictEqual(inspect(parser('${\\$}$')), [['<span class="math" translate="no" data-src="${\\$}$">${\\$}$</span>'], '']);
72
76
  assert.deepStrictEqual(inspect(parser('${\\\\}$')), [['<span class="math" translate="no" data-src="${\\\\}$">${\\\\}$</span>'], '']);
73
77
  assert.deepStrictEqual(inspect(parser('$a$')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '']);
78
+ assert.deepStrictEqual(inspect(parser('$a$$')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '$']);
74
79
  assert.deepStrictEqual(inspect(parser(`$a'$`)), [[`<span class="math" translate="no" data-src="$a'$">$a'$</span>`], '']);
75
80
  assert.deepStrictEqual(inspect(parser(`$a''$`)), [[`<span class="math" translate="no" data-src="$a''$">$a''$</span>`], '']);
76
81
  assert.deepStrictEqual(inspect(parser('$a$[A](a)')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '[A](a)']);
77
- assert.deepStrictEqual(inspect(parser('$a$$')), [['<span class="math" translate="no" data-src="$a$">$a$</span>'], '$']);
78
82
  assert.deepStrictEqual(inspect(parser('$A$')), [['<span class="math" translate="no" data-src="$A$">$A$</span>'], '']);
79
83
  assert.deepStrictEqual(inspect(parser('$\\$$')), [['<span class="math" translate="no" data-src="$\\$$">$\\$$</span>'], '']);
80
84
  assert.deepStrictEqual(inspect(parser('$\\Pi$')), [['<span class="math" translate="no" data-src="$\\Pi$">$\\Pi$</span>'], '']);
81
- assert.deepStrictEqual(inspect(parser('$\\Pi $')), [['<span class="math" translate="no" data-src="$\\Pi $">$\\Pi $</span>'], '']);
85
+ assert.deepStrictEqual(inspect(parser('$\\ 0$')), [['<span class="math" translate="no" data-src="$\\ 0$">$\\ 0$</span>'], '']);
86
+ assert.deepStrictEqual(inspect(parser('$\\\\0$')), [['<span class="math" translate="no" data-src="$\\\\0$">$\\\\0$</span>'], '']);
82
87
  assert.deepStrictEqual(inspect(parser('$|1|$')), [['<span class="math" translate="no" data-src="$|1|$">$|1|$</span>'], '']);
83
88
  assert.deepStrictEqual(inspect(parser('$[0,1)$]')), [['<span class="math" translate="no" data-src="$[0,1)$">$[0,1)$</span>'], ']']);
84
89
  assert.deepStrictEqual(inspect(parser('$(0, 1]$)')), [['<span class="math" translate="no" data-src="$(0, 1]$">$(0, 1]$</span>'], ')']);
@@ -10,7 +10,10 @@ describe('Unit: parser/inline/strong', () => {
10
10
  assert.deepStrictEqual(inspect(parser('**')), undefined);
11
11
  assert.deepStrictEqual(inspect(parser('**a')), [['**', 'a'], '']);
12
12
  assert.deepStrictEqual(inspect(parser('**a*')), [['**', 'a', '*'], '']);
13
- assert.deepStrictEqual(inspect(parser('**a **')), [['**', 'a', ' '], '**']);
13
+ assert.deepStrictEqual(inspect(parser('**a **')), [['**', 'a', ' '], '**']);
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>'], '**']);
14
17
  assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
15
18
  assert.deepStrictEqual(inspect(parser('** **')), undefined);
16
19
  assert.deepStrictEqual(inspect(parser('** a**')), undefined);
@@ -27,15 +30,12 @@ describe('Unit: parser/inline/strong', () => {
27
30
 
28
31
  it('basic', () => {
29
32
  assert.deepStrictEqual(inspect(parser('**a**')), [['<strong>a</strong>'], '']);
30
- assert.deepStrictEqual(inspect(parser('**a **')), [['<strong>a </strong>'], '']);
31
- assert.deepStrictEqual(inspect(parser('**a\n**')), [['<strong>a</strong>'], '']);
32
- assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['<strong>a<span class="linebreak"> </span></strong>'], '']);
33
33
  assert.deepStrictEqual(inspect(parser('**ab**')), [['<strong>ab</strong>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('**a\nb**')), [['<strong>a<br>b</strong>'], '']);
35
35
  assert.deepStrictEqual(inspect(parser('**a\\\nb**')), [['<strong>a<span class="linebreak"> </span>b</strong>'], '']);
36
36
  assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
37
37
  assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
38
- assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
39
39
  });
40
40
 
41
41
  it('nest', () => {
@@ -3,7 +3,7 @@ import { union, some, creator, surround, close, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { emphasis } from './emphasis';
5
5
  import { str } from '../source';
6
- import { startTight, isEndTightNodes, trimEndBR } from '../util';
6
+ import { startTight, isEndTightNodes } from '../util';
7
7
  import { html, defrag } from 'typed-dom';
8
8
  import { unshift } from 'spica/array';
9
9
 
@@ -13,6 +13,6 @@ export const strong: StrongParser = lazy(() => creator(surround(close(
13
13
  str('**'), false,
14
14
  ([as, bs, cs], rest) =>
15
15
  isEndTightNodes(bs)
16
- ? [[html('strong', defrag(trimEndBR(bs)))], rest]
16
+ ? [[html('strong', defrag(bs))], rest]
17
17
  : [unshift(as, bs), cs[0] + rest],
18
18
  ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -30,18 +30,16 @@ describe('Unit: parser/inline', () => {
30
30
  assert.deepStrictEqual(inspect(parser('*a**b*c')), [['*', 'a', '**', 'b', '*', 'c'], '']);
31
31
  assert.deepStrictEqual(inspect(parser('*a**b*c*')), [['*', 'a', '**', 'b', '<em>c</em>'], '']);
32
32
  assert.deepStrictEqual(inspect(parser('*a**b**')), [['*', 'a', '<strong>b</strong>'], '']);
33
- assert.deepStrictEqual(inspect(parser('*a **b***')), [['<em>a <strong>b</strong></em>'], '']);
34
- assert.deepStrictEqual(inspect(parser('*a **b***c')), [['<em>a <strong>b</strong></em>', 'c'], '']);
33
+ assert.deepStrictEqual(inspect(parser('*a **b***')), [['<em>a <strong>b</strong></em>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('*a **b***c')), [['<em>a <strong>b</strong></em>', 'c'], '']);
35
35
  assert.deepStrictEqual(inspect(parser('**a*')), [['**', 'a', '*'], '']);
36
36
  assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
37
37
  assert.deepStrictEqual(inspect(parser('**a*b**c')), [['**', 'a', '*', 'b', '**', 'c'], '']);
38
- assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
39
- assert.deepStrictEqual(inspect(parser('**a *b***c')), [['<strong>a <em>b</em></strong>', 'c'], '']);
38
+ assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('**a *b***c')), [['<strong>a <em>b</em></strong>', 'c'], '']);
40
40
  assert.deepStrictEqual(inspect(parser('***a*b**')), [['<strong><em>a</em>b</strong>'], '']);
41
- assert.deepStrictEqual(inspect(parser('***a*b **')), [['**', '<em>a</em>', 'b', ' ', '**'], '']);
42
41
  assert.deepStrictEqual(inspect(parser('***a* b**')), [['<strong><em>a</em> b</strong>'], '']);
43
42
  assert.deepStrictEqual(inspect(parser('***a**b*')), [['<em><strong>a</strong>b</em>'], '']);
44
- assert.deepStrictEqual(inspect(parser('***a**b *')), [['*', '<strong>a</strong>', 'b', ' ', '*'], '']);
45
43
  assert.deepStrictEqual(inspect(parser('***a** b*')), [['<em><strong>a</strong> b</em>'], '']);
46
44
  assert.deepStrictEqual(inspect(parser('***a*')), [['**', '<em>a</em>'], '']);
47
45
  assert.deepStrictEqual(inspect(parser('***a**')), [['*', '<strong>a</strong>'], '']);
@@ -135,12 +135,7 @@ export function isStartTightNodes(nodes: readonly (HTMLElement | string)[]): boo
135
135
  }
136
136
  export function isEndTightNodes(nodes: readonly (HTMLElement | string)[]): boolean {
137
137
  if (nodes.length === 0) return true;
138
- const last = nodes.length - 1;
139
- return typeof nodes[last] === 'string' && (nodes[last] as string).length > 1
140
- ? isVisible(nodes[last], -1) ||
141
- isVisible(nodes[last], -2)
142
- : isVisible(nodes[last], -1) || last === 0 ||
143
- isVisible(nodes[last - 1], -1);
138
+ return isVisible(nodes[nodes.length - 1], -1);
144
139
  }
145
140
  function isVisible(node: HTMLElement | string, position?: number): boolean {
146
141
  if (!node) return false;
@@ -224,8 +219,8 @@ export function trimNodeEnd(nodes: (HTMLElement | string)[]): (HTMLElement | str
224
219
  }
225
220
  return push(nodes, skip);
226
221
  }
227
- export function trimEndBR<T extends HTMLElement | string>(nodes: T[]): T[];
228
- export function trimEndBR(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
222
+ export function trimNodeEndBR<T extends HTMLElement | string>(nodes: T[]): T[];
223
+ export function trimNodeEndBR(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
229
224
  if (nodes.length === 0) return nodes;
230
225
  const node = nodes[nodes.length - 1];
231
226
  return typeof node === 'object' && node.tagName === 'BR'