securemark 0.234.0 → 0.234.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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.234.1
4
+
5
+ - Fix emstrong parser, emphasis parser, strong parser, and mark parser.
6
+
3
7
  ## 0.234.0
4
8
 
5
9
  - Extend anchor syntax.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.234.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.234.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) {
@@ -6674,7 +6674,11 @@ 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, '*')
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
+ ])
6678
6682
  ]))), (0, source_1.str)('*'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
6679
6683
  [(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))],
6680
6684
  rest
@@ -6703,11 +6707,33 @@ require = function () {
6703
6707
  exports.emstrong = void 0;
6704
6708
  const combinator_1 = _dereq_('../../combinator');
6705
6709
  const inline_1 = _dereq_('../inline');
6710
+ const strong_1 = _dereq_('./strong');
6706
6711
  const source_1 = _dereq_('../source');
6707
6712
  const util_1 = _dereq_('../util');
6708
6713
  const typed_dom_1 = _dereq_('typed-dom');
6709
6714
  const array_1 = _dereq_('spica/array');
6710
- 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.union)([(0, combinator_1.some)(inline_1.inline, '*')])), (0, source_1.str)(/^\*{1,3}/), false, ([as, bs, cs], rest, context) => {
6715
+ 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
+ ])
6721
+ ])));
6722
+ const subemphasis = (0, combinator_1.lazy)(() => (0, combinator_1.some)((0, combinator_1.union)([
6723
+ 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
+ ])
6729
+ ])));
6730
+ 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
+ ])
6736
+ ]))), (0, source_1.str)(/^\*{1,3}/), false, ([as, bs, cs], rest, context) => {
6711
6737
  var _a, _b;
6712
6738
  if (!(0, util_1.isEndTightNodes)(bs))
6713
6739
  return [
@@ -6716,7 +6742,7 @@ require = function () {
6716
6742
  ];
6717
6743
  switch (cs[0]) {
6718
6744
  case '*':
6719
- 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) ? [
6745
+ return (_a = (0, combinator_1.bind)(substrong, (ds, rest) => rest.slice(0, 2) === '**' && (0, util_1.isEndTightNodes)(ds) ? [
6720
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)))],
6721
6747
  rest.slice(2)
6722
6748
  ] : [
@@ -6733,7 +6759,7 @@ require = function () {
6733
6759
  rest
6734
6760
  ];
6735
6761
  case '**':
6736
- 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) ? [
6762
+ return (_b = (0, combinator_1.bind)(subemphasis, (ds, rest) => rest.slice(0, 1) === '*' && (0, util_1.isEndTightNodes)(ds) ? [
6737
6763
  [(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)))],
6738
6764
  rest.slice(1)
6739
6765
  ] : [
@@ -6765,6 +6791,7 @@ require = function () {
6765
6791
  '../inline': 88,
6766
6792
  '../source': 128,
6767
6793
  '../util': 134,
6794
+ './strong': 121,
6768
6795
  'spica/array': 6,
6769
6796
  'typed-dom': 26
6770
6797
  }
@@ -7422,7 +7449,13 @@ require = function () {
7422
7449
  const util_1 = _dereq_('../util');
7423
7450
  const typed_dom_1 = _dereq_('typed-dom');
7424
7451
  const array_1 = _dereq_('spica/array');
7425
- 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) ? [
7452
+ 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
+ ])
7458
+ ]))), (0, source_1.str)('=='), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7426
7459
  [(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)(bs))],
7427
7460
  rest
7428
7461
  ] : [
@@ -7449,11 +7482,10 @@ require = function () {
7449
7482
  exports.math = void 0;
7450
7483
  const combinator_1 = _dereq_('../../combinator');
7451
7484
  const source_1 = _dereq_('../source');
7452
- const util_1 = _dereq_('../util');
7453
7485
  const typed_dom_1 = _dereq_('typed-dom');
7454
7486
  const disallowedCommand = /\\(?:begin|tiny|huge|large)(?![0-9a-z])/i;
7455
7487
  exports.math = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('$', (0, combinator_1.rewrite)((0, combinator_1.union)([
7456
- (0, combinator_1.surround)('$', (0, combinator_1.verify)((0, source_1.str)(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*[^-+*/=<>^_~\\$]|-[\da-z]|[a-z]+-)(?:\\\$|[\x20-\x23\x25-\x7E])+/i), util_1.isEndTightNodes), /^\$(?![0-9a-z])/i),
7488
+ (0, combinator_1.surround)('$', (0, source_1.str)(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*[^-+*/=<>^_~\\$]|-[\da-z]|[a-z]+-)(?:\\\$|\x20(?!\$)|[\x21-\x23\x25-\x7E])+/i), /^\$(?![0-9a-z])/i),
7457
7489
  (0, combinator_1.surround)('$', bracket, '$')
7458
7490
  ]), (source, {
7459
7491
  caches: {math: cache} = {}
@@ -7482,7 +7514,6 @@ require = function () {
7482
7514
  {
7483
7515
  '../../combinator': 27,
7484
7516
  '../source': 128,
7485
- '../util': 134,
7486
7517
  'typed-dom': 26
7487
7518
  }
7488
7519
  ],
@@ -7836,16 +7867,17 @@ require = function () {
7836
7867
  exports.strong = void 0;
7837
7868
  const combinator_1 = _dereq_('../../combinator');
7838
7869
  const inline_1 = _dereq_('../inline');
7839
- const emphasis_1 = _dereq_('./emphasis');
7840
7870
  const source_1 = _dereq_('../source');
7841
7871
  const util_1 = _dereq_('../util');
7842
7872
  const typed_dom_1 = _dereq_('typed-dom');
7843
7873
  const array_1 = _dereq_('spica/array');
7844
7874
  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)([
7845
- emphasis_1.emphasis,
7846
- (0, combinator_1.some)(inline_1.inline, '*'),
7847
- (0, source_1.str)('*')
7848
- ]), '**')), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
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
+ ])
7880
+ ]))), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7849
7881
  [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))],
7850
7882
  rest
7851
7883
  ] : [
@@ -7861,7 +7893,6 @@ require = function () {
7861
7893
  '../inline': 88,
7862
7894
  '../source': 128,
7863
7895
  '../util': 134,
7864
- './emphasis': 102,
7865
7896
  'spica/array': 6,
7866
7897
  'typed-dom': 26
7867
7898
  }
@@ -8736,7 +8767,6 @@ require = function () {
8736
8767
  case '\t':
8737
8768
  case '\n':
8738
8769
  return false;
8739
- case '\x1B':
8740
8770
  case '\\':
8741
8771
  return ((_a = source[1]) === null || _a === void 0 ? void 0 : _a.trimStart()) !== '';
8742
8772
  case '&':
package/markdown.d.ts CHANGED
@@ -970,6 +970,10 @@ 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
977
  ]> {
974
978
  }
975
979
  export interface EmStrongParser extends
@@ -977,15 +981,21 @@ export namespace MarkdownParser {
977
981
  Inline<'emstrong'>,
978
982
  Parser<HTMLElement | string, Context, [
979
983
  InlineParser,
984
+ Parser<HTMLElement | string, Context, [
985
+ InlineParser,
986
+ InlineParser,
987
+ ]>,
980
988
  ]> {
981
989
  }
982
990
  export interface StrongParser extends
983
991
  // **abc**
984
992
  Inline<'strong'>,
985
993
  Parser<HTMLElement | string, Context, [
986
- EmphasisParser,
987
994
  InlineParser,
988
- SourceParser.StrParser,
995
+ Parser<HTMLElement | string, Context, [
996
+ InlineParser,
997
+ InlineParser,
998
+ ]>,
989
999
  ]> {
990
1000
  }
991
1001
  export interface EmphasisParser extends
@@ -994,6 +1004,10 @@ export namespace MarkdownParser {
994
1004
  Parser<HTMLElement | string, Context, [
995
1005
  StrongParser,
996
1006
  InlineParser,
1007
+ Parser<HTMLElement | string, Context, [
1008
+ InlineParser,
1009
+ InlineParser,
1010
+ ]>,
997
1011
  ]> {
998
1012
  }
999
1013
  export interface CodeParser extends
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.234.0",
3
+ "version": "0.234.1",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -3210,9 +3210,9 @@
3210
3210
  }
3211
3211
  },
3212
3212
  "es-abstract": {
3213
- "version": "1.19.1",
3214
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
3215
- "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
3213
+ "version": "1.19.2",
3214
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz",
3215
+ "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==",
3216
3216
  "dev": true,
3217
3217
  "requires": {
3218
3218
  "call-bind": "^1.0.2",
@@ -3221,15 +3221,15 @@
3221
3221
  "get-intrinsic": "^1.1.1",
3222
3222
  "get-symbol-description": "^1.0.0",
3223
3223
  "has": "^1.0.3",
3224
- "has-symbols": "^1.0.2",
3224
+ "has-symbols": "^1.0.3",
3225
3225
  "internal-slot": "^1.0.3",
3226
3226
  "is-callable": "^1.2.4",
3227
- "is-negative-zero": "^2.0.1",
3227
+ "is-negative-zero": "^2.0.2",
3228
3228
  "is-regex": "^1.1.4",
3229
3229
  "is-shared-array-buffer": "^1.0.1",
3230
3230
  "is-string": "^1.0.7",
3231
- "is-weakref": "^1.0.1",
3232
- "object-inspect": "^1.11.0",
3231
+ "is-weakref": "^1.0.2",
3232
+ "object-inspect": "^1.12.0",
3233
3233
  "object-keys": "^1.1.1",
3234
3234
  "object.assign": "^4.1.2",
3235
3235
  "string.prototype.trimend": "^1.0.4",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.234.0",
3
+ "version": "0.234.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",
@@ -8,7 +8,8 @@ export interface Ctx {
8
8
  export type Parser<T, C extends Ctx = Ctx, D extends Parser<unknown, C>[] = any>
9
9
  = (source: string, context: C) => Result<T, C, D>;
10
10
  export type Result<T, C extends Ctx = Ctx, D extends Parser<unknown, C>[] = any>
11
- = readonly [T[], string, C?, D?]
11
+ = readonly [T[], string, C, D]
12
+ | readonly [T[], string]
12
13
  | undefined;
13
14
  export type Tree<P extends Parser<unknown>> = P extends Parser<infer T> ? T : never;
14
15
  export type SubParsers<P extends Parser<unknown>> = P extends Parser<unknown, any, infer D> ? D : never;
@@ -25,6 +25,12 @@ describe('Unit: parser/block/paragraph', () => {
25
25
  assert.deepStrictEqual(inspect(parser('<wbr>\na')), [['<p>&lt;wbr&gt;<br>a</p>'], '']);
26
26
  assert.deepStrictEqual(inspect(parser('a\n<wbr>\n')), [['<p>a<br>&lt;wbr&gt;</p>'], '']);
27
27
  assert.deepStrictEqual(inspect(parser('a\n<wbr>\nb')), [['<p>a<br>&lt;wbr&gt;<br>b</p>'], '']);
28
+ assert.deepStrictEqual(inspect(parser('*a\n<wbr>*\nb')), [['<p>*a<br><wbr>*<br>b</p>'], '']);
29
+ assert.deepStrictEqual(inspect(parser('**a\n<wbr>**\nb')), [['<p>**a<br><wbr>**<br>b</p>'], '']);
30
+ assert.deepStrictEqual(inspect(parser('***a\n<wbr>***\nb')), [['<p>***a<br><wbr>***<br>b</p>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('***a*b\n<wbr>**\nc')), [['<p>**<em>a</em>b<br><wbr>**<br>c</p>'], '']);
32
+ assert.deepStrictEqual(inspect(parser('***a**b\n<wbr>*\nc')), [['<p>*<strong>a</strong>b<br><wbr>*<br>c</p>'], '']);
33
+ assert.deepStrictEqual(inspect(parser('==a\n<wbr>==\nb')), [['<p>==a<br><wbr>==<br>b</p>'], '']);
28
34
  assert.deepStrictEqual(inspect(parser(' a')), [['<p>a</p>'], '']);
29
35
  });
30
36
 
@@ -9,8 +9,8 @@ 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', ' '], '*']);
13
- assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a', '<br>'], '*']);
12
+ assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' ', '*'], '']);
13
+ assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a', '<br>', '*'], '']);
14
14
  assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a', ' '], '*']);
15
15
  assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a', '<span class="linebreak"> </span>'], '*']);
16
16
  assert.deepStrictEqual(inspect(parser('*a**b')), [['*', 'a', '**', 'b'], '']);
@@ -39,6 +39,8 @@ describe('Unit: parser/inline/emphasis', () => {
39
39
  it('nest', () => {
40
40
  assert.deepStrictEqual(inspect(parser('*a**b**c*')), [['<em>a<strong>b</strong>c</em>'], '']);
41
41
  assert.deepStrictEqual(inspect(parser('*a**b**c*d')), [['<em>a<strong>b</strong>c</em>'], 'd']);
42
+ assert.deepStrictEqual(inspect(parser('*a *b**')), [['<em>a <em>b</em></em>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('*a **b***')), [['<em>a <strong>b</strong></em>'], '']);
42
44
  assert.deepStrictEqual(inspect(parser('*`a`*')), [['<em><code data-src="`a`">a</code></em>'], '']);
43
45
  assert.deepStrictEqual(inspect(parser('*<small>*')), [['<em>&lt;small&gt;</em>'], '']);
44
46
  assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
@@ -1,5 +1,5 @@
1
1
  import { EmphasisParser } from '../inline';
2
- import { union, some, creator, surround, close, lazy } from '../../combinator';
2
+ import { union, sequence, 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';
@@ -9,7 +9,11 @@ import { unshift } from 'spica/array';
9
9
 
10
10
  export const emphasis: EmphasisParser = lazy(() => creator(surround(close(
11
11
  str('*'), /^(?!\*)/),
12
- startTight(some(union([strong, some(inline, '*')]))),
12
+ startTight(some(union([
13
+ strong,
14
+ some(inline, /^\s*\*/),
15
+ sequence([some(inline, '*'), inline]),
16
+ ]))),
13
17
  str('*'), false,
14
18
  ([as, bs, cs], rest) =>
15
19
  isEndTightNodes(bs)
@@ -1,29 +1,45 @@
1
- import { EmStrongParser } from '../inline';
2
- import { union, some, creator, surround, lazy, bind } from '../../combinator';
1
+ import { MarkdownParser } from '../../../markdown';
2
+ import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
3
+ import { Result, IntermediateParser } from '../../combinator/data/parser';
4
+ import { union, sequence, some, creator, surround, lazy, bind } from '../../combinator';
3
5
  import { inline } from '../inline';
6
+ import { strong } from './strong';
4
7
  import { str } from '../source';
5
8
  import { startTight, isEndTightNodes } from '../util';
6
9
  import { html, defrag } from 'typed-dom';
7
10
  import { unshift } from 'spica/array';
8
11
 
12
+ const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
13
+ some(inline, /^\s*\*\*/),
14
+ sequence([some(inline, '*'), inline]),
15
+ ])));
16
+ const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
17
+ strong,
18
+ some(inline, /^\s*\*/),
19
+ sequence([some(inline, '*'), inline]),
20
+ ])));
21
+
9
22
  export const emstrong: EmStrongParser = lazy(() => creator(surround(
10
23
  str('***'),
11
- startTight(union([some(inline, '*')])),
24
+ startTight(some(union([
25
+ some(inline, /^\s*\*/),
26
+ sequence([some(inline, '*'), inline]),
27
+ ]))),
12
28
  str(/^\*{1,3}/), false,
13
- ([as, bs, cs], rest, context) => {
29
+ ([as, bs, cs], rest, context): Result<HTMLElement | string, MarkdownParser.Context> => {
14
30
  if (!isEndTightNodes(bs)) return [unshift(as, bs), cs[0] + rest];
15
31
  switch (cs[0]) {
16
32
  case '*':
17
- return bind<EmStrongParser>(
18
- union([some(inline, '**')]),
33
+ return bind<StrongParser>(
34
+ substrong,
19
35
  (ds, rest) =>
20
36
  rest.slice(0, 2) === '**' && isEndTightNodes(ds)
21
37
  ? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds)))], rest.slice(2)]
22
38
  : [unshift(['**', html('em', defrag(bs))], ds), rest])
23
39
  (rest, context) ?? [['**', html('em', defrag(bs))], rest];
24
40
  case '**':
25
- return bind<EmStrongParser>(
26
- union([some(inline, '*')]),
41
+ return bind<EmphasisParser>(
42
+ subemphasis,
27
43
  (ds, rest) =>
28
44
  rest.slice(0, 1) === '*' && isEndTightNodes(ds)
29
45
  ? [[html('em', unshift([html('strong', defrag(bs))], defrag(ds)))], rest.slice(1)]
@@ -12,8 +12,8 @@ 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', ' '], '==']);
16
- assert.deepStrictEqual(inspect(parser('==a\n==')), [['==', 'a', '<br>'], '==']);
15
+ assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' ', '=='], '']);
16
+ assert.deepStrictEqual(inspect(parser('==a\n==')), [['==', 'a', '<br>', '=='], '']);
17
17
  assert.deepStrictEqual(inspect(parser('==a\\ ==')), [['==', 'a', ' '], '==']);
18
18
  assert.deepStrictEqual(inspect(parser('==a\\\n==')), [['==', 'a', '<span class="linebreak"> </span>'], '==']);
19
19
  assert.deepStrictEqual(inspect(parser('== ==')), undefined);
@@ -36,6 +36,7 @@ describe('Unit: parser/inline/mark', () => {
36
36
 
37
37
  it('nest', () => {
38
38
  assert.deepStrictEqual(inspect(parser('==*==a==*==')), [['<mark><em><mark>a</mark></em></mark>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('==a ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
39
40
  });
40
41
 
41
42
  });
@@ -1,5 +1,5 @@
1
1
  import { MarkParser } from '../inline';
2
- import { union, some, creator, surround, lazy } from '../../combinator';
2
+ import { union, sequence, some, creator, surround, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
5
  import { startTight, isEndTightNodes } from '../util';
@@ -8,7 +8,10 @@ import { unshift } from 'spica/array';
8
8
 
9
9
  export const mark: MarkParser = lazy(() => creator(surround(
10
10
  str('=='),
11
- startTight(union([some(inline, '==')])),
11
+ startTight(some(union([
12
+ some(inline, /^\s*==/),
13
+ sequence([some(inline, '='), inline]),
14
+ ]))),
12
15
  str('=='), false,
13
16
  ([as, bs, cs], rest) =>
14
17
  isEndTightNodes(bs)
@@ -1,7 +1,6 @@
1
1
  import { MathParser } from '../inline';
2
- import { union, some, validate, verify, rewrite, creator, surround, lazy } from '../../combinator';
2
+ import { union, some, validate, rewrite, creator, surround, lazy } from '../../combinator';
3
3
  import { escsource, str } from '../source';
4
- import { isEndTightNodes } from '../util';
5
4
  import { html } from 'typed-dom';
6
5
 
7
6
  const disallowedCommand = /\\(?:begin|tiny|huge|large)(?![0-9a-z])/i;
@@ -10,15 +9,13 @@ export const math: MathParser = lazy(() => creator(validate('$', rewrite(
10
9
  union([
11
10
  surround(
12
11
  '$',
13
- verify(
14
- // Latex's reserved characters: # $ % ^ & _ { } ~ \
15
- // $[0-9]+ : Dollar
16
- // $[A-z]*- : Label
17
- // $[A-z]*(?!-) : Math
18
- // $[\^_[({|] : Math
19
- // $[#$%&] : Invalid first character in Latex syntax
20
- str(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*[^-+*/=<>^_~\\$]|-[\da-z]|[a-z]+-)(?:\\\$|[\x20-\x23\x25-\x7E])+/i),
21
- isEndTightNodes),
12
+ // Latex's reserved characters: # $ % ^ & _ { } ~ \
13
+ // $[0-9]+ : Dollar
14
+ // $[A-z]*- : Label
15
+ // $[A-z]*(?!-) : Math
16
+ // $[\^_[({|] : Math
17
+ // $[#$%&] : Invalid first character in Latex syntax
18
+ str(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*[^-+*/=<>^_~\\$]|-[\da-z]|[a-z]+-)(?:\\\$|\x20(?!\$)|[\x21-\x23\x25-\x7E])+/i),
22
19
  /^\$(?![0-9a-z])/i),
23
20
  surround('$', bracket, '$'),
24
21
  ]),
@@ -10,8 +10,8 @@ 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', ' '], '**']);
14
- assert.deepStrictEqual(inspect(parser('**a\n**')), [['**', 'a', '<br>'], '**']);
13
+ assert.deepStrictEqual(inspect(parser('**a **')), [['**', 'a', ' ', '**'], '']);
14
+ assert.deepStrictEqual(inspect(parser('**a\n**')), [['**', 'a', '<br>', '**'], '']);
15
15
  assert.deepStrictEqual(inspect(parser('**a\\ **')), [['**', 'a', ' '], '**']);
16
16
  assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['**', 'a', '<span class="linebreak"> </span>'], '**']);
17
17
  assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
@@ -38,6 +38,7 @@ describe('Unit: parser/inline/strong', () => {
38
38
  assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
39
39
  assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
40
40
  assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('**a **b****')), [['<strong>a <strong>b</strong></strong>'], '']);
41
42
  assert.deepStrictEqual(inspect(parser('**`a`**')), [['<strong><code data-src="`a`">a</code></strong>'], '']);
42
43
  assert.deepStrictEqual(inspect(parser('**<small>**')), [['<strong>&lt;small&gt;</strong>'], '']);
43
44
  assert.deepStrictEqual(inspect(parser('**(*a*)**')), [['<strong><span class="paren">(<em>a</em>)</span></strong>'], '']);
@@ -1,7 +1,6 @@
1
1
  import { StrongParser } from '../inline';
2
- import { union, some, creator, surround, close, lazy } from '../../combinator';
2
+ import { union, sequence, some, creator, surround, close, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
- import { emphasis } from './emphasis';
5
4
  import { str } from '../source';
6
5
  import { startTight, isEndTightNodes } from '../util';
7
6
  import { html, defrag } from 'typed-dom';
@@ -9,7 +8,10 @@ import { unshift } from 'spica/array';
9
8
 
10
9
  export const strong: StrongParser = lazy(() => creator(surround(close(
11
10
  str('**'), /^(?!\*)/),
12
- startTight(some(union([emphasis, some(inline, '*'), str('*')]), '**')),
11
+ startTight(some(union([
12
+ some(inline, /^\s*\*\*/),
13
+ sequence([some(inline, '*'), inline]),
14
+ ]))),
13
15
  str('**'), false,
14
16
  ([as, bs, cs], rest) =>
15
17
  isEndTightNodes(bs)
@@ -26,26 +26,63 @@ describe('Unit: parser/inline', () => {
26
26
  assert.deepStrictEqual(inspect(parser('*** a***')), [['***', ' ', 'a', '***'], '']);
27
27
  assert.deepStrictEqual(inspect(parser('**** a****')), [['****', ' ', 'a', '****'], '']);
28
28
  assert.deepStrictEqual(inspect(parser('*a**')), [['<em>a</em>', '*'], '']);
29
+ assert.deepStrictEqual(inspect(parser('*a**b')), [['*', 'a', '**', 'b'], '']);
29
30
  assert.deepStrictEqual(inspect(parser('*a**b*')), [['*', 'a', '**', 'b', '*'], '']);
30
31
  assert.deepStrictEqual(inspect(parser('*a**b*c')), [['*', 'a', '**', 'b', '*', 'c'], '']);
31
32
  assert.deepStrictEqual(inspect(parser('*a**b*c*')), [['*', 'a', '**', 'b', '<em>c</em>'], '']);
32
33
  assert.deepStrictEqual(inspect(parser('*a**b**')), [['*', 'a', '<strong>b</strong>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('*a**b**c')), [['*', 'a', '<strong>b</strong>', 'c'], '']);
35
+ assert.deepStrictEqual(inspect(parser('*a**b***')), [['<em>a<strong>b</strong></em>'], '']);
36
+ assert.deepStrictEqual(inspect(parser('*a**b***c')), [['<em>a<strong>b</strong></em>', 'c'], '']);
37
+ assert.deepStrictEqual(inspect(parser('*a**b****')), [['<em>a<strong>b</strong></em>', '*'], '']);
38
+ assert.deepStrictEqual(inspect(parser('*a**b****c')), [['*', 'a', '<strong>b</strong>', '**', 'c'], '']);
39
+ assert.deepStrictEqual(inspect(parser('*a***b****')), [['<em>a</em>', '<strong>b</strong>', '**'], '']);
40
+ assert.deepStrictEqual(inspect(parser('*a***b****c')), [['<em>a</em>', '<strong>b</strong>', '**', 'c'], '']);
41
+ assert.deepStrictEqual(inspect(parser('*a *b**')), [['<em>a <em>b</em></em>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('*a *b**c')), [['*', 'a', ' ', '*', 'b', '**', 'c'], '']);
33
43
  assert.deepStrictEqual(inspect(parser('*a **b***')), [['<em>a <strong>b</strong></em>'], '']);
34
44
  assert.deepStrictEqual(inspect(parser('*a **b***c')), [['<em>a <strong>b</strong></em>', 'c'], '']);
45
+ assert.deepStrictEqual(inspect(parser('*a ***b****')), [['<em>a <em><strong>b</strong></em></em>'], '']);
46
+ assert.deepStrictEqual(inspect(parser('*a ***b****c')), [['<em>a <em><strong>b</strong></em></em>', 'c'], '']);
35
47
  assert.deepStrictEqual(inspect(parser('**a*')), [['**', 'a', '*'], '']);
36
48
  assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
37
49
  assert.deepStrictEqual(inspect(parser('**a*b**c')), [['**', 'a', '*', 'b', '**', 'c'], '']);
50
+ assert.deepStrictEqual(inspect(parser('**a*b***')), [['<strong>a<em>b</em></strong>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('**a*b***c')), [['<strong>a<em>b</em></strong>', 'c'], '']);
52
+ assert.deepStrictEqual(inspect(parser('**a**b****')), [['<strong>a</strong>', 'b', '****'], '']);
53
+ assert.deepStrictEqual(inspect(parser('**a**b****c')), [['<strong>a</strong>', 'b', '****', 'c'], '']);
54
+ assert.deepStrictEqual(inspect(parser('**a***b*****')), [['<strong>a</strong>', '<em>b</em>', '****'], '']);
55
+ assert.deepStrictEqual(inspect(parser('**a***b*****c')), [['<strong>a</strong>', '<em>b</em>', '****', 'c'], '']);
38
56
  assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
39
57
  assert.deepStrictEqual(inspect(parser('**a *b***c')), [['<strong>a <em>b</em></strong>', 'c'], '']);
58
+ assert.deepStrictEqual(inspect(parser('**a **b****')), [['<strong>a <strong>b</strong></strong>'], '']);
59
+ assert.deepStrictEqual(inspect(parser('**a **b****c')), [['<strong>a <strong>b</strong></strong>', 'c'], '']);
60
+ assert.deepStrictEqual(inspect(parser('**a ***b*****')), [['<strong>a <em><strong>b</strong></em></strong>'], '']);
61
+ assert.deepStrictEqual(inspect(parser('**a ***b*****c')), [['<strong>a <em><strong>b</strong></em></strong>', 'c'], '']);
40
62
  assert.deepStrictEqual(inspect(parser('***a*b**')), [['<strong><em>a</em>b</strong>'], '']);
63
+ assert.deepStrictEqual(inspect(parser('***a*b**c')), [['<strong><em>a</em>b</strong>', 'c'], '']);
64
+ assert.deepStrictEqual(inspect(parser('***a*b*c***')), [['<strong><em>a</em>b<em>c</em></strong>'], '']);
65
+ assert.deepStrictEqual(inspect(parser('***a*b*c***d')), [['<strong><em>a</em>b<em>c</em></strong>', 'd'], '']);
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>', '*'], '']);
69
+ assert.deepStrictEqual(inspect(parser('***a*b\\ **')), [['**', '<em>a</em>', 'b', ' ', '**'], '']);
41
70
  assert.deepStrictEqual(inspect(parser('***a* b**')), [['<strong><em>a</em> b</strong>'], '']);
42
71
  assert.deepStrictEqual(inspect(parser('***a**b*')), [['<em><strong>a</strong>b</em>'], '']);
72
+ assert.deepStrictEqual(inspect(parser('***a**b*c')), [['<em><strong>a</strong>b</em>', 'c'], '']);
73
+ assert.deepStrictEqual(inspect(parser('***a**b*c**')), [['<em><strong>a</strong>b</em>', 'c', '**'], '']);
74
+ assert.deepStrictEqual(inspect(parser('***a**b**c***')), [['<em><strong>a</strong>b<strong>c</strong></em>'], '']);
75
+ 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>'], '']);
43
77
  assert.deepStrictEqual(inspect(parser('***a** b*')), [['<em><strong>a</strong> b</em>'], '']);
78
+ assert.deepStrictEqual(inspect(parser('***a\\ **b*')), [['***', 'a', ' ', '**', 'b', '*'], '']);
79
+ assert.deepStrictEqual(inspect(parser('***a**b\\ *')), [['*', '<strong>a</strong>', 'b', ' ', '*'], '']);
44
80
  assert.deepStrictEqual(inspect(parser('***a*')), [['**', '<em>a</em>'], '']);
45
81
  assert.deepStrictEqual(inspect(parser('***a**')), [['*', '<strong>a</strong>'], '']);
46
82
  assert.deepStrictEqual(inspect(parser('***a***')), [['<em><strong>a</strong></em>'], '']);
47
83
  assert.deepStrictEqual(inspect(parser('***a***b')), [['<em><strong>a</strong></em>', 'b'], '']);
48
84
  assert.deepStrictEqual(inspect(parser('***a****')), [['<em><strong>a</strong></em>', '*'], '']);
85
+ assert.deepStrictEqual(inspect(parser('***a *b****')), [['<em><strong>a <em>b</em></strong></em>'], '']);
49
86
  assert.deepStrictEqual(inspect(parser('****a***')), [['****', 'a', '***'], '']);
50
87
  assert.deepStrictEqual(inspect(parser('****a****')), [['****', 'a', '****'], '']);
51
88
  assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
@@ -97,7 +97,6 @@ function isStartTight(source: string, context: MarkdownParser.Context): boolean
97
97
  case '\t':
98
98
  case '\n':
99
99
  return false;
100
- case '\x1B':
101
100
  case '\\':
102
101
  return source[1]?.trimStart() !== '';
103
102
  case '&':