securemark 0.218.2 → 0.218.3

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.218.3
4
+
5
+ - Remove invisible tail in index, annotation, and reference syntax.
6
+
3
7
  ## 0.218.2
4
8
 
5
9
  - Improve abbr parser.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.218.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.218.3 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) {
@@ -6743,7 +6743,7 @@ require = function () {
6743
6743
  }
6744
6744
  },
6745
6745
  state: global_1.undefined
6746
- }, (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, ')', /^\\?\n/)])))), '))'), ns => [(0, typed_dom_1.html)('sup', { class: 'annotation' }, (0, typed_dom_1.defrag)(ns))]))));
6746
+ }, (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, ')', /^\\?\n/)])))), '))'), ns => [(0, typed_dom_1.html)('sup', { class: 'annotation' }, (0, util_1.trimEnd)((0, typed_dom_1.defrag)(ns)))]))));
6747
6747
  },
6748
6748
  {
6749
6749
  '../../combinator': 30,
@@ -7332,12 +7332,12 @@ require = function () {
7332
7332
  }, (0, combinator_1.open)((0, source_1.str)(/^\|?/, false), (0, combinator_1.some)((0, combinator_1.union)([
7333
7333
  signature,
7334
7334
  inline_1.inline
7335
- ]), ']', /^\\?\n/), true)))), ']'), ns => [(0, typed_dom_1.html)('a', (0, typed_dom_1.defrag)(ns))])), ([el]) => [(0, typed_dom_1.define)(el, {
7335
+ ]), ']', /^\\?\n/), true)))), ']'), ns => [(0, typed_dom_1.html)('a', (0, util_1.trimEnd)((0, typed_dom_1.defrag)(ns)))])), ([el]) => [(0, typed_dom_1.define)(el, {
7336
7336
  id: el.id ? null : global_1.undefined,
7337
7337
  class: 'index',
7338
7338
  href: el.id ? `#${ el.id }` : global_1.undefined
7339
7339
  }, el.childNodes)]))));
7340
- const signature = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.open)(/^[^\S\n]?\|#/, (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
7340
+ const signature = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.open)('|#', (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
7341
7341
  bracket,
7342
7342
  source_1.txt
7343
7343
  ]), ']', /^\\?\n/))), ns => [(0, typed_dom_1.html)('span', {
@@ -8115,7 +8115,7 @@ require = function () {
8115
8115
  ''
8116
8116
  ]),
8117
8117
  (0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/)
8118
- ])))), ']]'), ns => [(0, typed_dom_1.html)('sup', attributes(ns), (0, typed_dom_1.defrag)(ns))]))));
8118
+ ])))), ']]'), ns => [(0, typed_dom_1.html)('sup', attributes(ns), (0, util_1.trimEnd)((0, typed_dom_1.defrag)(ns)))]))));
8119
8119
  const abbr = (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.verify)((0, combinator_1.surround)('^', (0, combinator_1.union)([(0, source_1.str)(/^(?![0-9]+\s?[|\]])[0-9A-Za-z]+(?:(?:-|(?=\W)(?!'\d)'?(?!\.\d)\.?(?!,\S),? ?)[0-9A-Za-z]+)*(?:-|'?\.?,? ?)?/)]), /^\|?(?=]])|^\|[^\S\n]+/), (_, rest, context) => (0, util_1.isStartTight)(rest, context)), ([source]) => [(0, typed_dom_1.html)('abbr', source)]));
8120
8120
  function attributes(ns) {
8121
8121
  return typeof ns[0] === 'object' && ns[0].tagName === 'ABBR' ? {
@@ -8803,7 +8803,7 @@ require = function () {
8803
8803
  function (_dereq_, module, exports) {
8804
8804
  'use strict';
8805
8805
  Object.defineProperty(exports, '__esModule', { value: true });
8806
- exports.stringify = exports.trimEndBR = exports.verifyEndTight = exports.verifyStartTight = exports.isStartTight = exports.startTight = exports.visualize = void 0;
8806
+ exports.stringify = exports.trimEndBR = exports.trimEnd = exports.verifyEndTight = exports.verifyStartTight = exports.isStartTight = exports.startTight = exports.visualize = void 0;
8807
8807
  const global_1 = _dereq_('spica/global');
8808
8808
  const parser_1 = _dereq_('../combinator/data/parser');
8809
8809
  const combinator_1 = _dereq_('../combinator');
@@ -8903,15 +8903,15 @@ require = function () {
8903
8903
  return false;
8904
8904
  }
8905
8905
  return true;
8906
- case '[':
8906
+ case '<':
8907
8907
  switch (true) {
8908
- case source.length >= 7 && source[1] === '#' && !!(0, comment_1.comment)(source, context):
8908
+ case source.length >= 5 && source[1] === 'w' && source.slice(0, 5) === '<wbr>':
8909
8909
  return false;
8910
8910
  }
8911
8911
  return true;
8912
- case '<':
8912
+ case '[':
8913
8913
  switch (true) {
8914
- case source.length >= 5 && source[1] === 'w' && source.slice(0, 5) === '<wbr>':
8914
+ case source.length >= 7 && source[1] === '#' && !!(0, comment_1.comment)(source, context):
8915
8915
  return false;
8916
8916
  }
8917
8917
  return true;
@@ -8961,6 +8961,21 @@ require = function () {
8961
8961
  }
8962
8962
  }
8963
8963
  }
8964
+ function trimEnd(nodes) {
8965
+ const skip = nodes.length > 0 && typeof nodes[nodes.length - 1] === 'object' && nodes[nodes.length - 1]['className'] === 'indexer' ? [nodes.pop()] : [];
8966
+ for (let last = nodes[0]; nodes.length > 0 && !isVisible(last = nodes[nodes.length - 1], -1) && !(typeof last === 'object' && last.className === 'comment');) {
8967
+ if (typeof last === 'string') {
8968
+ const pos = last.trimEnd().length;
8969
+ if (pos > 0) {
8970
+ nodes[nodes.length - 1] = last.slice(0, pos);
8971
+ break;
8972
+ }
8973
+ }
8974
+ nodes.pop();
8975
+ }
8976
+ return (0, array_1.push)(nodes, skip);
8977
+ }
8978
+ exports.trimEnd = trimEnd;
8964
8979
  function trimEndBR(nodes) {
8965
8980
  if (nodes.length === 0)
8966
8981
  return nodes;
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.218.2",
3
+ "version": "0.218.3",
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.218.2",
3
+ "version": "0.218.3",
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",
@@ -35,8 +35,11 @@ describe('Unit: parser/inline/annotation', () => {
35
35
 
36
36
  it('basic', () => {
37
37
  assert.deepStrictEqual(inspect(parser('((a))')), [['<sup class="annotation">a</sup>'], '']);
38
- assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a </sup>'], '']);
39
- assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a </sup>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a</sup>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a</sup>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('((a &nbsp;))')), [['<sup class="annotation">a</sup>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('((a <wbr>))')), [['<sup class="annotation">a</sup>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('((a [# b #]))')), [['<sup class="annotation">a <sup class="comment" title="b"></sup></sup>'], '']);
40
43
  assert.deepStrictEqual(inspect(parser('((ab))')), [['<sup class="annotation">ab</sup>'], '']);
41
44
  });
42
45
 
@@ -2,7 +2,7 @@ import { undefined } from 'spica/global';
2
2
  import { AnnotationParser } from '../inline';
3
3
  import { union, some, validate, guard, context, creator, surround, lazy, fmap } from '../../combinator';
4
4
  import { inline } from '../inline';
5
- import { startTight } from '../util';
5
+ import { startTight, trimEnd } from '../util';
6
6
  import { html, defrag } from 'typed-dom';
7
7
 
8
8
  export const annotation: AnnotationParser = lazy(() => creator(validate('((', '))', '\n', fmap(surround(
@@ -21,4 +21,4 @@ export const annotation: AnnotationParser = lazy(() => creator(validate('((', ')
21
21
  }}, state: undefined },
22
22
  union([some(inline, ')', /^\\?\n/)])))),
23
23
  '))'),
24
- ns => [html('sup', { class: 'annotation' }, defrag(ns))]))));
24
+ ns => [html('sup', { class: 'annotation' }, trimEnd(defrag(ns)))]))));
@@ -33,11 +33,14 @@ describe('Unit: parser/inline/extension/index', () => {
33
33
 
34
34
  it('basic', () => {
35
35
  assert.deepStrictEqual(inspect(parser('[#a]')), [['<a class="index" href="#index:a">a</a>'], '']);
36
- assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index:a">a </a>'], '']);
37
- assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index:a">a </a>'], '']);
36
+ assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index:a">a</a>'], '']);
37
+ assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index:a">a</a>'], '']);
38
38
  assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
39
39
  assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
40
- assert.deepStrictEqual(inspect(parser('[#a\\ ]')), [['<a class="index" href="#index:a">a </a>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('[#a &nbsp;]')), [['<a class="index" href="#index:a">a</a>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('[#a <wbr>]')), [['<a class="index" href="#index:a">a</a>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('[#a [# b #]]')), [['<a class="index" href="#index:a">a <sup class="comment" title="b"></sup></a>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('[#a\\ ]')), [['<a class="index" href="#index:a">a</a>'], '']);
41
44
  assert.deepStrictEqual(inspect(parser('[#a\\ b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
42
45
  assert.deepStrictEqual(inspect(parser('[#[]]')), [['<a class="index" href="#index:[]">[]</a>'], '']);
43
46
  assert.deepStrictEqual(inspect(parser('[#\\]]')), [['<a class="index" href="#index:]">]</a>'], '']);
@@ -49,8 +52,6 @@ describe('Unit: parser/inline/extension/index', () => {
49
52
  assert.deepStrictEqual(inspect(parser('[#[A](a)]')), [['<a class="index" href="#index:A"><ruby>A<rp>(</rp><rt>a</rt><rp>)</rp></ruby></a>'], '']);
50
53
  assert.deepStrictEqual(inspect(parser('[#[]{a}]')), [['<a class="index" href="#index:[]{a}">[]{a}</a>'], '']);
51
54
  assert.deepStrictEqual(inspect(parser('[#![]{a}]')), [['<a class="index" href="#index:![]{a}">![]{a}</a>'], '']);
52
- assert.deepStrictEqual(inspect(parser('[#a<wbr>]')), [['<a class="index" href="#index:a">a<wbr></a>'], '']);
53
- assert.deepStrictEqual(inspect(parser('[#a[# b #]]')), [['<a class="index" href="#index:a">a<sup class="comment" title="b"></sup></a>'], '']);
54
55
  assert.deepStrictEqual(inspect(parser('[#@a]')), [['<a class="index" href="#index:@a">@a</a>'], '']);
55
56
  assert.deepStrictEqual(inspect(parser('[#http://host]')), [['<a class="index" href="#index:http://host">http://host</a>'], '']);
56
57
  assert.deepStrictEqual(inspect(parser('[#!http://host]')), [['<a class="index" href="#index:!http://host">!http://host</a>'], '']);
@@ -64,8 +65,8 @@ describe('Unit: parser/inline/extension/index', () => {
64
65
  assert.deepStrictEqual(inspect(parser('[#|#b]')), [['<a class="index" href="#index:|#b">|#b</a>'], '']);
65
66
  assert.deepStrictEqual(inspect(parser('[#a|]')), [['<a class="index" href="#index:a|">a|</a>'], '']);
66
67
  assert.deepStrictEqual(inspect(parser('[#a|#]')), [['<a class="index" href="#index:a|#">a|#</a>'], '']);
67
- assert.deepStrictEqual(inspect(parser('[#a|# ]')), [['<a class="index" href="#index:a|#">a|# </a>'], '']);
68
- assert.deepStrictEqual(inspect(parser('[#a|#\\ ]')), [['<a class="index" href="#index:a|#">a|# </a>'], '']);
68
+ assert.deepStrictEqual(inspect(parser('[#a|# ]')), [['<a class="index" href="#index:a|#">a|#</a>'], '']);
69
+ assert.deepStrictEqual(inspect(parser('[#a|#\\ ]')), [['<a class="index" href="#index:a|#">a|#</a>'], '']);
69
70
  assert.deepStrictEqual(inspect(parser('[#a|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
70
71
  assert.deepStrictEqual(inspect(parser('[#a|#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
71
72
  assert.deepStrictEqual(inspect(parser('[#a|#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
@@ -78,8 +79,10 @@ describe('Unit: parser/inline/extension/index', () => {
78
79
  assert.deepStrictEqual(inspect(parser('[#a |]')), [['<a class="index" href="#index:a_|">a |</a>'], '']);
79
80
  assert.deepStrictEqual(inspect(parser('[#a |#]')), [['<a class="index" href="#index:a_|#">a |#</a>'], '']);
80
81
  assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
81
- assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a <span class="indexer" data-index="b"></span></a>'], '']);
82
- assert.deepStrictEqual(inspect(parser('[#a <wbr>|#b]')), [['<a class="index" href="#index:b">a <wbr><span class="indexer" data-index="b"></span></a>'], '']);
82
+ assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
83
+ assert.deepStrictEqual(inspect(parser('[#a &nbsp;|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
84
+ assert.deepStrictEqual(inspect(parser('[#a <wbr>|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
85
+ assert.deepStrictEqual(inspect(parser('[#a [# b #]|#b]')), [['<a class="index" href="#index:b">a <sup class="comment" title="b"></sup><span class="indexer" data-index="b"></span></a>'], '']);
83
86
  });
84
87
 
85
88
  });
@@ -4,7 +4,7 @@ import { union, some, validate, guard, context, creator, surround, open, lazy, f
4
4
  import { inline } from '../../inline';
5
5
  import { indexee, identify } from './indexee';
6
6
  import { txt, str } from '../../source';
7
- import { startTight } from '../../util';
7
+ import { startTight, trimEnd } from '../../util';
8
8
  import { html, define, defrag } from 'typed-dom';
9
9
  import { join } from 'spica/array';
10
10
 
@@ -29,7 +29,7 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
29
29
  inline,
30
30
  ]), ']', /^\\?\n/), true)))),
31
31
  ']'),
32
- ns => [html('a', defrag(ns))])),
32
+ ns => [html('a', trimEnd(defrag(ns)))])),
33
33
  ([el]: [HTMLAnchorElement]) => [
34
34
  define(el,
35
35
  {
@@ -41,7 +41,7 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
41
41
  ]))));
42
42
 
43
43
  const signature: IndexParser.SignatureParser = lazy(() => creator(fmap(open(
44
- /^[^\S\n]?\|#/,
44
+ '|#',
45
45
  startTight(some(union([bracket, txt]), ']', /^\\?\n/))),
46
46
  ns => [
47
47
  html('span', { class: 'indexer', 'data-index': identify(join(ns).trim()).slice(6) }),
@@ -35,8 +35,11 @@ describe('Unit: parser/inline/reference', () => {
35
35
 
36
36
  it('basic', () => {
37
37
  assert.deepStrictEqual(inspect(parser('[[a]]')), [['<sup class="reference">a</sup>'], '']);
38
- assert.deepStrictEqual(inspect(parser('[[a ]]')), [['<sup class="reference">a </sup>'], '']);
39
- assert.deepStrictEqual(inspect(parser('[[a ]]')), [['<sup class="reference">a </sup>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('[[a ]]')), [['<sup class="reference">a</sup>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('[[a ]]')), [['<sup class="reference">a</sup>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('[[a &nbsp;]]')), [['<sup class="reference">a</sup>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('[[a <wbr>]]')), [['<sup class="reference">a</sup>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('[[a [# b #]]]')), [['<sup class="reference">a <sup class="comment" title="b"></sup></sup>'], '']);
40
43
  assert.deepStrictEqual(inspect(parser('[[ab]]')), [['<sup class="reference">ab</sup>'], '']);
41
44
  });
42
45
 
@@ -56,7 +59,7 @@ describe('Unit: parser/inline/reference', () => {
56
59
  assert.deepStrictEqual(inspect(parser('[[^a,]]')), [['<sup class="reference" data-abbr="a,"></sup>'], '']);
57
60
  assert.deepStrictEqual(inspect(parser('[[^a, ]]')), [['<sup class="reference" data-abbr="a,"></sup>'], '']);
58
61
  assert.deepStrictEqual(inspect(parser('[[^a ]]')), [['<sup class="reference" data-abbr="a"></sup>'], '']);
59
- assert.deepStrictEqual(inspect(parser('[[^a ]]')), [['<sup class="reference invalid">^a </sup>'], '']);
62
+ assert.deepStrictEqual(inspect(parser('[[^a ]]')), [['<sup class="reference invalid">^a</sup>'], '']);
60
63
  assert.deepStrictEqual(inspect(parser('[[^a b]]')), [['<sup class="reference" data-abbr="a b"></sup>'], '']);
61
64
  assert.deepStrictEqual(inspect(parser('[[^a b]]')), [['<sup class="reference invalid">^a b</sup>'], '']);
62
65
  assert.deepStrictEqual(inspect(parser('[[^a|]]')), [['<sup class="reference" data-abbr="a"></sup>'], '']);
@@ -65,16 +68,16 @@ describe('Unit: parser/inline/reference', () => {
65
68
  assert.deepStrictEqual(inspect(parser('[[^a|b]]')), [['<sup class="reference invalid">^a|b</sup>'], '']);
66
69
  assert.deepStrictEqual(inspect(parser('[[^a| ]]')), [['<sup class="reference" data-abbr="a"></sup>'], '']);
67
70
  assert.deepStrictEqual(inspect(parser('[[^a| b]]')), [['<sup class="reference" data-abbr="a">b</sup>'], '']);
68
- assert.deepStrictEqual(inspect(parser('[[^a| b ]]')), [['<sup class="reference" data-abbr="a">b </sup>'], '']);
69
- assert.deepStrictEqual(inspect(parser('[[^a| b ]]')), [['<sup class="reference" data-abbr="a">b </sup>'], '']);
71
+ assert.deepStrictEqual(inspect(parser('[[^a| b ]]')), [['<sup class="reference" data-abbr="a">b</sup>'], '']);
72
+ assert.deepStrictEqual(inspect(parser('[[^a| b ]]')), [['<sup class="reference" data-abbr="a">b</sup>'], '']);
70
73
  assert.deepStrictEqual(inspect(parser('[[^a| ]]')), [['<sup class="reference" data-abbr="a"></sup>'], '']);
71
74
  assert.deepStrictEqual(inspect(parser('[[^a| b]]')), [['<sup class="reference" data-abbr="a">b</sup>'], '']);
72
- assert.deepStrictEqual(inspect(parser('[[^a| <wbr>]]')), [['<sup class="reference invalid">^a| <wbr></sup>'], '']);
75
+ assert.deepStrictEqual(inspect(parser('[[^a| <wbr>]]')), [['<sup class="reference invalid">^a|</sup>'], '']);
73
76
  assert.deepStrictEqual(inspect(parser('[[^a| <wbr>b]]')), [['<sup class="reference invalid">^a| <wbr>b</sup>'], '']);
74
77
  assert.deepStrictEqual(inspect(parser('[[^a| ^b]]')), [['<sup class="reference" data-abbr="a">^b</sup>'], '']);
75
78
  assert.deepStrictEqual(inspect(parser('[[^1]]')), [['<sup class="reference invalid">^1</sup>'], '']);
76
79
  assert.deepStrictEqual(inspect(parser('[[^1a]]')), [['<sup class="reference" data-abbr="1a"></sup>'], '']);
77
- assert.deepStrictEqual(inspect(parser('[[^1 ]]')), [['<sup class="reference invalid">^1 </sup>'], '']);
80
+ assert.deepStrictEqual(inspect(parser('[[^1 ]]')), [['<sup class="reference invalid">^1</sup>'], '']);
78
81
  assert.deepStrictEqual(inspect(parser('[[^1 a]]')), [['<sup class="reference" data-abbr="1 a"></sup>'], '']);
79
82
  assert.deepStrictEqual(inspect(parser('[[^1|]]')), [['<sup class="reference invalid">^1|</sup>'], '']);
80
83
  assert.deepStrictEqual(inspect(parser('[[^1 |]]')), [['<sup class="reference invalid">^1 |</sup>'], '']);
@@ -85,11 +88,11 @@ describe('Unit: parser/inline/reference', () => {
85
88
  assert.deepStrictEqual(inspect(parser(`[[^A's, Aces']]`)), [[`<sup class="reference" data-abbr="A's, Aces'"></sup>`], '']);
86
89
  assert.deepStrictEqual(inspect(parser('[[^^]]')), [['<sup class="reference invalid">^^</sup>'], '']);
87
90
  assert.deepStrictEqual(inspect(parser('[[\\^]]')), [['<sup class="reference">^</sup>'], '']);
88
- assert.deepStrictEqual(inspect(parser('[[^ ]]')), [['<sup class="reference invalid">^ </sup>'], '']);
91
+ assert.deepStrictEqual(inspect(parser('[[^ ]]')), [['<sup class="reference invalid">^</sup>'], '']);
89
92
  assert.deepStrictEqual(inspect(parser('[[^ a]]')), [['<sup class="reference invalid">^ a</sup>'], '']);
90
93
  assert.deepStrictEqual(inspect(parser('[[^ |]]')), [['<sup class="reference invalid">^ |</sup>'], '']);
91
94
  assert.deepStrictEqual(inspect(parser('[[^ |b]]')), [['<sup class="reference invalid">^ |b</sup>'], '']);
92
- assert.deepStrictEqual(inspect(parser('[[^ | ]]')), [['<sup class="reference invalid">^ | </sup>'], '']);
95
+ assert.deepStrictEqual(inspect(parser('[[^ | ]]')), [['<sup class="reference invalid">^ |</sup>'], '']);
93
96
  assert.deepStrictEqual(inspect(parser('[[^ | b]]')), [['<sup class="reference invalid">^ | b</sup>'], '']);
94
97
  });
95
98
 
@@ -3,7 +3,7 @@ import { ReferenceParser } from '../inline';
3
3
  import { union, subsequence, some, validate, verify, focus, guard, context, creator, surround, lazy, fmap } from '../../combinator';
4
4
  import { inline } from '../inline';
5
5
  import { str } from '../source';
6
- import { startTight, isStartTight, stringify } from '../util';
6
+ import { startTight, isStartTight, trimEnd, stringify } from '../util';
7
7
  import { html, defrag } from 'typed-dom';
8
8
 
9
9
  export const reference: ReferenceParser = lazy(() => creator(validate('[[', ']]', '\n', fmap(surround(
@@ -26,7 +26,7 @@ export const reference: ReferenceParser = lazy(() => creator(validate('[[', ']]'
26
26
  some(inline, ']', /^\\?\n/),
27
27
  ])))),
28
28
  ']]'),
29
- ns => [html('sup', attributes(ns), defrag(ns))]))));
29
+ ns => [html('sup', attributes(ns), trimEnd(defrag(ns)))]))));
30
30
 
31
31
  const abbr: ReferenceParser.AbbrParser = creator(fmap(verify(surround(
32
32
  '^',
@@ -5,7 +5,7 @@ import { union, some, verify, clear, convert, trim } from '../combinator';
5
5
  import { comment } from './inline/comment';
6
6
  import { htmlentity } from './inline/htmlentity';
7
7
  import { linebreak, unescsource, str } from './source';
8
- import { pop } from 'spica/array';
8
+ import { push, pop } from 'spica/array';
9
9
 
10
10
  // https://dev.w3.org/html5/html-author/charref
11
11
  const invisibleHTMLEntityNames = [
@@ -100,14 +100,6 @@ export function isStartTight(source: string, context: MarkdownParser.Context): b
100
100
  return false;
101
101
  }
102
102
  return true;
103
- case '[':
104
- switch (true) {
105
- case source.length >= 7
106
- && source[1] === '#'
107
- && !!comment(source, context):
108
- return false;
109
- }
110
- return true;
111
103
  case '<':
112
104
  switch (true) {
113
105
  case source.length >= 5
@@ -116,6 +108,14 @@ export function isStartTight(source: string, context: MarkdownParser.Context): b
116
108
  return false;
117
109
  }
118
110
  return true;
111
+ case '[':
112
+ switch (true) {
113
+ case source.length >= 7
114
+ && source[1] === '#'
115
+ && !!comment(source, context):
116
+ return false;
117
+ }
118
+ return true;
119
119
  default:
120
120
  return source[0].trimStart() !== '';
121
121
  }
@@ -133,7 +133,7 @@ export function verifyEndTight(nodes: readonly (HTMLElement | string)[]): boolea
133
133
  : isVisible(nodes[last], -1) || last === 0 ||
134
134
  isVisible(nodes[last - 1], -1);
135
135
  }
136
- function isVisible(node: HTMLElement | string | undefined, position = 0): boolean {
136
+ function isVisible(node: HTMLElement | string, position = 0): boolean {
137
137
  if (!node) return false;
138
138
  switch (typeof node) {
139
139
  case 'string':
@@ -163,6 +163,31 @@ function isVisible(node: HTMLElement | string | undefined, position = 0): boolea
163
163
  }
164
164
  }
165
165
 
166
+ export function trimEnd(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
167
+ assert(verifyStartTight(nodes));
168
+ const skip = nodes.length > 0 &&
169
+ typeof nodes[nodes.length - 1] === 'object' &&
170
+ nodes[nodes.length - 1]['className'] === 'indexer'
171
+ ? [nodes.pop()!]
172
+ : [];
173
+ for (
174
+ let last = nodes[0];
175
+ nodes.length > 0 &&
176
+ !isVisible(last = nodes[nodes.length - 1], -1) &&
177
+ !(typeof last === 'object' && last.className === 'comment');
178
+ ) {
179
+ assert(nodes.length > 0);
180
+ if (typeof last === 'string') {
181
+ const pos = last.trimEnd().length;
182
+ if (pos > 0) {
183
+ nodes[nodes.length - 1] = last.slice(0, pos);
184
+ break;
185
+ }
186
+ }
187
+ nodes.pop();
188
+ }
189
+ return push(nodes, skip);
190
+ }
166
191
  export function trimEndBR<T extends HTMLElement | string>(nodes: T[]): T[];
167
192
  export function trimEndBR(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
168
193
  if (nodes.length === 0) return nodes;