securemark 0.250.0 → 0.251.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.251.0
4
+
5
+ - Change indentblock parser to require 4 spaces or 1 tab to support text indent.
6
+
3
7
  ## 0.250.0
4
8
 
5
9
  - Change comment syntax.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.250.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.251.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory(require("DOMPurify"), require("Prism"));
@@ -2337,8 +2337,9 @@ const surround_1 = __webpack_require__(7130);
2337
2337
 
2338
2338
  const memoize_1 = __webpack_require__(1808);
2339
2339
 
2340
- function indent(parser, separation = false) {
2341
- return (0, bind_1.bind)((0, block_1.block)((0, match_1.match)(/^(?=(([ \t])\2*))/, (0, memoize_1.memoize)(([, indent]) => (0, some_1.some)((0, line_1.line)((0, surround_1.open)(indent, source => [[unline(source)], '']))), ([, indent]) => indent.length * 2 + +(indent[0] === ' '), [])), separation), (nodes, rest, context) => {
2340
+ function indent(opener, parser, separation = false) {
2341
+ if (typeof opener === 'function') return indent(/^([ \t])\1*/, opener, parser);
2342
+ return (0, bind_1.bind)((0, block_1.block)((0, match_1.match)(opener, (0, memoize_1.memoize)(([indent]) => (0, some_1.some)((0, line_1.line)((0, surround_1.open)(indent, source => [[unline(source)], '']))), ([indent]) => indent.length * 2 + +(indent[0] === ' '), [])), separation), (nodes, rest, context) => {
2342
2343
  const result = parser(nodes.join('\n'), context);
2343
2344
  return result && (0, parser_1.exec)(result) === '' ? [(0, parser_1.eval)(result), rest] : global_1.undefined;
2344
2345
  });
@@ -2392,10 +2393,9 @@ function match(pattern, f) {
2392
2393
  if (source === '') return;
2393
2394
  const param = source.match(pattern);
2394
2395
  if (!param) return;
2395
- const rest = source.slice(param[0].length);
2396
- const result = f(param)(rest, context);
2396
+ const result = f(param)(source, context);
2397
2397
  if (!result) return;
2398
- return (0, parser_1.exec)(result).length < source.length && (0, parser_1.exec)(result).length <= rest.length ? result : global_1.undefined;
2398
+ return (0, parser_1.exec)(result).length < source.length && (0, parser_1.exec)(result).length <= source.length ? result : global_1.undefined;
2399
2399
  };
2400
2400
  }
2401
2401
 
@@ -4128,9 +4128,9 @@ const memoize_1 = __webpack_require__(1808);
4128
4128
 
4129
4129
  const array_1 = __webpack_require__(8112);
4130
4130
 
4131
- exports.segment = (0, combinator_1.block)((0, combinator_1.match)(/^(~{3,})(?:figure[^\S\n]|(?=\[?\$))/, (0, memoize_1.memoize)(([, fence], closer = new RegExp(String.raw`^${fence}[^\S\n]*(?:$|\n)`)) => (0, combinator_1.close)((0, combinator_1.sequence)([source_1.contentline, (0, combinator_1.inits)([// All parsers which can include closing terms.
4131
+ exports.segment = (0, combinator_1.block)((0, combinator_1.match)(/^(~{3,})(?:figure[^\S\n])?(?=\[?\$)/, (0, memoize_1.memoize)(([, fence], closer = new RegExp(String.raw`^${fence}[^\S\n]*(?:$|\n)`)) => (0, combinator_1.close)((0, combinator_1.sequence)([source_1.contentline, (0, combinator_1.inits)([// All parsers which can include closing terms.
4132
4132
  (0, combinator_1.union)([codeblock_1.segment_, mathblock_1.segment_, table_2.segment_, blockquote_1.segment, placeholder_1.segment_, (0, combinator_1.some)(source_1.contentline, closer)]), source_1.emptyline, (0, combinator_1.union)([source_1.emptyline, (0, combinator_1.some)(source_1.contentline, closer)])])]), closer), ([, fence]) => fence.length, [])));
4133
- exports.figure = (0, combinator_1.block)((0, combinator_1.fallback)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.fmap)((0, combinator_1.convert)(source => source.slice(source.match(/^~+(?:figure[^\S\n]+)?/)[0].length, source.trimEnd().lastIndexOf('\n')), (0, combinator_1.sequence)([(0, combinator_1.line)((0, combinator_1.sequence)([label_1.label, (0, source_1.str)(/^(?=\s).*\n/)])), (0, combinator_1.inits)([(0, combinator_1.block)((0, combinator_1.union)([ulist_1.ulist, olist_1.olist, table_1.table, indentblock_1.indentblock, codeblock_1.codeblock, mathblock_1.mathblock, example_1.example, table_2.table, blockquote_1.blockquote, placeholder_1.placeholder, (0, combinator_1.line)(inline_1.media), (0, combinator_1.line)(inline_1.shortmedia)])), source_1.emptyline, (0, combinator_1.block)((0, locale_1.localize)((0, combinator_1.context)({
4133
+ exports.figure = (0, combinator_1.block)((0, combinator_1.fallback)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.fmap)((0, combinator_1.convert)(source => source.slice(source.match(/^~+(?:\w+\s+)?/)[0].length, source.trimEnd().lastIndexOf('\n')), (0, combinator_1.sequence)([(0, combinator_1.line)((0, combinator_1.sequence)([label_1.label, (0, source_1.str)(/^(?=\s).*\n/)])), (0, combinator_1.inits)([(0, combinator_1.block)((0, combinator_1.union)([ulist_1.ulist, olist_1.olist, table_1.table, indentblock_1.indentblock, codeblock_1.codeblock, mathblock_1.mathblock, example_1.example, table_2.table, blockquote_1.blockquote, placeholder_1.placeholder, (0, combinator_1.line)(inline_1.media), (0, combinator_1.line)(inline_1.shortmedia)])), source_1.emptyline, (0, combinator_1.block)((0, locale_1.localize)((0, combinator_1.context)({
4134
4134
  syntax: {
4135
4135
  inline: {
4136
4136
  media: false
@@ -4759,10 +4759,10 @@ const combinator_1 = __webpack_require__(2087);
4759
4759
  const codeblock_1 = __webpack_require__(1849); // 空行を含むインデントブロックはインデントの違いによるセグメント分割の境界が視認不能となるため採用しない
4760
4760
 
4761
4761
 
4762
- exports.indentblock = (0, combinator_1.block)((0, combinator_1.validate)(/^(?: |\t)/, (0, combinator_1.indent)((0, combinator_1.convert)(source => {
4762
+ exports.indentblock = (0, combinator_1.block)((0, combinator_1.indent)(/^( {4}|\t)\1*/, (0, combinator_1.convert)(source => {
4763
4763
  const fence = (source.match(/^`{3,}(?=[^\S\n]*$)/mg) ?? []).reduce((max, fence) => fence > max ? fence : max, '``') + '`';
4764
4764
  return `${fence}\n${source}\n${fence}`;
4765
- }, (0, combinator_1.union)([codeblock_1.codeblock])), true)));
4765
+ }, (0, combinator_1.union)([codeblock_1.codeblock])), true));
4766
4766
 
4767
4767
  /***/ }),
4768
4768
 
@@ -4836,8 +4836,8 @@ const memoize_1 = __webpack_require__(1808);
4836
4836
  const array_1 = __webpack_require__(8112);
4837
4837
 
4838
4838
  const openers = {
4839
- '.': /^(?:[0-9]+|[a-z]+|[A-Z]+)(?:-(?!-)[0-9]*)*(?![^\S\n])\.?(?=$|\s)/,
4840
- '(': /^\((?:[0-9]*|[a-z]*)(?![^)\n])\)?(?:-(?!-)[0-9]*)*(?=$|\s)/
4839
+ '.': /^([0-9]+|[a-z]+|[A-Z]+)(?:-(?!-)[0-9]*)*(?![^\S\n])\.?(?=$|\s)/,
4840
+ '(': /^\(([0-9]*|[a-z]*)(?![^)\n])\)?(?:-(?!-)[0-9]*)*(?=$|\s)/
4841
4841
  };
4842
4842
  exports.olist = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.validate)([/^([0-9]+|[a-z]+|[A-Z]+)(?:-[0-9]+)*\.(?=[^\S\n]|\n[^\S\n]*\S)/, /^\(([0-9]+|[a-z]+)\)(?:-[0-9]+)*(?=[^\S\n]|\n[^\S\n]*\S)/], (0, combinator_1.context)({
4843
4843
  syntax: {
@@ -4846,7 +4846,7 @@ exports.olist = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combina
4846
4846
  }
4847
4847
  }
4848
4848
  }, exports.olist_))));
4849
- exports.olist_ = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.union)([(0, combinator_1.match)(new RegExp(`^(?=${openers['.'].source.replace('?:', '')})`), (0, memoize_1.memoize)(ms => list(type(ms[1]), '.'), ms => type(ms[1]).charCodeAt(0) || 0, [])), (0, combinator_1.match)(new RegExp(`^(?=${openers['('].source.replace('?:', '')})`), (0, memoize_1.memoize)(ms => list(type(ms[1]), '('), ms => type(ms[1]).charCodeAt(0) || 0, []))])));
4849
+ exports.olist_ = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.union)([(0, combinator_1.match)(openers['.'], (0, memoize_1.memoize)(ms => list(type(ms[1]), '.'), ms => type(ms[1]).charCodeAt(0) || 0, [])), (0, combinator_1.match)(openers['('], (0, memoize_1.memoize)(ms => list(type(ms[1]), '('), ms => type(ms[1]).charCodeAt(0) || 0, []))])));
4850
4850
 
4851
4851
  const list = (type, form) => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.creator)((0, combinator_1.union)([(0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.fallback)((0, combinator_1.inits)([(0, combinator_1.line)((0, combinator_1.open)(heads[form], (0, combinator_1.trim)((0, combinator_1.subsequence)([ulist_1.checkbox, (0, util_1.trimBlank)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline])))])), true)), (0, combinator_1.indent)((0, combinator_1.union)([ulist_1.ulist_, exports.olist_, ilist_1.ilist_]))]), invalid), ns => [(0, dom_1.html)('li', {
4852
4852
  'data-marker': ns[0]
@@ -5776,7 +5776,7 @@ const dom_1 = __webpack_require__(3252);
5776
5776
 
5777
5777
  exports.code = (0, combinator_1.creator)((0, combinator_1.validate)('`', (0, combinator_1.match)(/^(`+)(?!`)([^\n]*?[^`\n])\1(?!`)/, ([whole,, body]) => rest => [[(0, dom_1.html)('code', {
5778
5778
  'data-src': whole
5779
- }, format(body))], rest])));
5779
+ }, format(body))], rest.slice(whole.length)])));
5780
5780
 
5781
5781
  function format(text) {
5782
5782
  return `${text[0]}${text[text.length - 1]}` === ' ' && text.trimStart() ? text.slice(1, -1) : text;
@@ -5807,7 +5807,7 @@ const memoize_1 = __webpack_require__(1808);
5807
5807
 
5808
5808
  const array_1 = __webpack_require__(8112);
5809
5809
 
5810
- exports.comment = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[%', (0, combinator_1.match)(/^(?=\[(%+)\s)/, (0, memoize_1.memoize)(([, fence]) => (0, combinator_1.surround)((0, combinator_1.open)((0, source_1.str)(`[${fence}`), (0, combinator_1.some)(source_1.text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), new RegExp(String.raw`^\s+${fence}\]`)), (0, combinator_1.close)((0, combinator_1.some)(source_1.text, /^\S/), (0, source_1.str)(`${fence}]`)), true, ([as, bs = [], cs], rest) => [[(0, dom_1.html)('span', {
5810
+ exports.comment = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[%', (0, combinator_1.match)(/^\[(%+)\s/, (0, memoize_1.memoize)(([, fence]) => (0, combinator_1.surround)((0, combinator_1.open)((0, source_1.str)(`[${fence}`), (0, combinator_1.some)(source_1.text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), new RegExp(String.raw`^\s+${fence}\]`)), (0, combinator_1.close)((0, combinator_1.some)(source_1.text, /^\S/), (0, source_1.str)(`${fence}]`)), true, ([as, bs = [], cs], rest) => [[(0, dom_1.html)('span', {
5811
5811
  class: 'comment'
5812
5812
  }, [(0, dom_1.html)('input', {
5813
5813
  type: 'checkbox'
@@ -6266,7 +6266,7 @@ const attrspec = {
6266
6266
  };
6267
6267
  global_1.Object.setPrototypeOf(attrspec, null);
6268
6268
  global_1.Object.values(attrspec).forEach(o => global_1.Object.setPrototypeOf(o, null));
6269
- exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('<', (0, combinator_1.validate)(/^<[a-z]+(?=[^\S\n]|>)/, (0, combinator_1.union)([(0, combinator_1.match)(/^(?=<(wbr)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)(`<${tag}`, (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), /^\s*>/, true, ([, bs = []], rest) => [[(0, dom_1.html)(tag, attributes('html', [], attrspec[tag], bs))], rest]), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => tag, new cache_1.Cache(10000)))])))));
6269
+ exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('<', (0, combinator_1.validate)(/^<[a-z]+(?=[^\S\n]|>)/, (0, combinator_1.union)([(0, combinator_1.match)(/^<(wbr)(?=[^\S\n]|>)/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)(`<${tag}`, (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), /^\s*>/, true, ([, bs = []], rest) => [[(0, dom_1.html)(tag, attributes('html', [], attrspec[tag], bs))], rest]), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>)/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => tags.indexOf(tag), [])), (0, combinator_1.match)(/^<([a-z]+)(?=[^\S\n]|>)/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)(/^\s*>/), true), (0, util_1.startLoose)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.open)(/^\n?/, (0, combinator_1.some)(inline_1.inline, (0, util_1.blankWith)('\n', `</${tag}>`)), true)])), `</${tag}>`), (0, source_1.str)(`</${tag}>`), false, ([as, bs, cs], rest) => [[elem(tag, as, bs, cs)], rest]), ([, tag]) => tag, new cache_1.Cache(10000)))])))));
6270
6270
  exports.attribute = (0, combinator_1.union)([(0, source_1.str)(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|>)/)]);
6271
6271
 
6272
6272
  function elem(tag, as, bs, cs) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.250.0",
3
+ "version": "0.251.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",
@@ -9,15 +9,18 @@ import { open } from './surround';
9
9
  import { memoize } from 'spica/memoize';
10
10
 
11
11
  export function indent<P extends Parser<unknown>>(parser: P, separation?: boolean): P;
12
- export function indent<T>(parser: Parser<T>, separation = false): Parser<T> {
12
+ export function indent<P extends Parser<unknown>>(opener: RegExp, parser: P, separation?: boolean): P;
13
+ export function indent<T>(opener: RegExp | Parser<T>, parser?: Parser<T> | boolean, separation = false): Parser<T> {
14
+ if (typeof opener === 'function') return indent(/^([ \t])\1*/, opener, parser as boolean);
13
15
  assert(parser);
14
16
  return bind(block(match(
15
- /^(?=(([ \t])\2*))/,
17
+ opener,
16
18
  memoize(
17
- ([, indent]) =>
19
+ ([indent]) =>
18
20
  some(line(open(indent, source => [[unline(source)], '']))),
19
- ([, indent]) => indent.length * 2 + +(indent[0] === ' '), [])), separation),
21
+ ([indent]) => indent.length * 2 + +(indent[0] === ' '), [])), separation),
20
22
  (nodes, rest, context) => {
23
+ assert(parser = parser as Parser<T>);
21
24
  const result = parser(nodes.join('\n'), context);
22
25
  return result && exec(result) === ''
23
26
  ? [eval(result), rest]
@@ -9,11 +9,10 @@ export function match<T>(pattern: RegExp, f: (matched: RegExpMatchArray) => Pars
9
9
  const param = source.match(pattern);
10
10
  if (!param) return;
11
11
  assert(source.startsWith(param[0]));
12
- const rest = source.slice(param[0].length);
13
- const result = f(param)(rest, context);
12
+ const result = f(param)(source, context);
14
13
  assert(check(source, result, false));
15
14
  if (!result) return;
16
- return exec(result).length < source.length && exec(result).length <= rest.length
15
+ return exec(result).length < source.length && exec(result).length <= source.length
17
16
  ? result
18
17
  : undefined;
19
18
  };
@@ -80,6 +80,12 @@ describe('Unit: parser/api/parse', () => {
80
80
  ['<p>a<br>\\<br>b</p>']);
81
81
  });
82
82
 
83
+ it('indent', () => {
84
+ assert.deepStrictEqual(
85
+ [...parse(' a').children].map(el => el.outerHTML),
86
+ ['<p> a</p>']);
87
+ });
88
+
83
89
  it('url', () => {
84
90
  assert.deepStrictEqual(
85
91
  [...parse([
@@ -23,7 +23,7 @@ import { unshift } from 'spica/array';
23
23
  import FigureParser = ExtensionParser.FigureParser;
24
24
 
25
25
  export const segment: FigureParser.SegmentParser = block(match(
26
- /^(~{3,})(?:figure[^\S\n]|(?=\[?\$))/,
26
+ /^(~{3,})(?:figure[^\S\n])?(?=\[?\$)/,
27
27
  memoize(
28
28
  ([, fence], closer = new RegExp(String.raw`^${fence}[^\S\n]*(?:$|\n)`)) => close(
29
29
  sequence([
@@ -49,7 +49,7 @@ export const segment: FigureParser.SegmentParser = block(match(
49
49
  ([, fence]) => fence.length, [])));
50
50
 
51
51
  export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
52
- convert(source => source.slice(source.match(/^~+(?:figure[^\S\n]+)?/)![0].length, source.trimEnd().lastIndexOf('\n')),
52
+ convert(source => source.slice(source.match(/^~+(?:\w+\s+)?/)![0].length, source.trimEnd().lastIndexOf('\n')),
53
53
  sequence([
54
54
  line(sequence([label, str(/^(?=\s).*\n/)])),
55
55
  inits([
@@ -9,20 +9,27 @@ describe('Unit: parser/block/indentblock', () => {
9
9
  it('invalid', () => {
10
10
  assert.deepStrictEqual(inspect(parser('')), undefined);
11
11
  assert.deepStrictEqual(inspect(parser('\na')), undefined);
12
- assert.deepStrictEqual(inspect(parser(' a')), undefined);
13
- assert.deepStrictEqual(inspect(parser(' \ta')), undefined);
14
- assert.deepStrictEqual(inspect(parser(' a\nb')), undefined);
15
- assert.deepStrictEqual(inspect(parser(' a\n b')), undefined);
12
+ assert.deepStrictEqual(inspect(parser('a')), undefined);
13
+ assert.deepStrictEqual(inspect(parser(' a')), undefined);
14
+ assert.deepStrictEqual(inspect(parser(' a')), undefined);
15
+ assert.deepStrictEqual(inspect(parser(' \ta')), undefined);
16
+ assert.deepStrictEqual(inspect(parser(' a\nb')), undefined);
17
+ assert.deepStrictEqual(inspect(parser(' a\n b')), undefined);
18
+ assert.deepStrictEqual(inspect(parser(' a\n\tb')), undefined);
16
19
  });
17
20
 
18
21
  it('valid', () => {
19
- assert.deepStrictEqual(inspect(parser(' a')), [['<pre class="text">a</pre>'], '']);
20
- assert.deepStrictEqual(inspect(parser(' a ')), [['<pre class="text">a </pre>'], '']);
21
- assert.deepStrictEqual(inspect(parser(' a \n')), [['<pre class="text">a </pre>'], '']);
22
- assert.deepStrictEqual(inspect(parser(' a \n b')), [['<pre class="text">a <br> b</pre>'], '']);
23
- assert.deepStrictEqual(inspect(parser(' a\\\n b')), [['<pre class="text">a\\<br>b</pre>'], '']);
22
+ assert.deepStrictEqual(inspect(parser(' a')), [['<pre class="text">a</pre>'], '']);
23
+ assert.deepStrictEqual(inspect(parser(' a ')), [['<pre class="text">a </pre>'], '']);
24
+ assert.deepStrictEqual(inspect(parser(' a \n')), [['<pre class="text">a </pre>'], '']);
25
+ assert.deepStrictEqual(inspect(parser(' a \n b')), [['<pre class="text">a <br> b</pre>'], '']);
26
+ assert.deepStrictEqual(inspect(parser(' a \\\n b')), [['<pre class="text">a \\<br> b</pre>'], '']);
27
+ assert.deepStrictEqual(inspect(parser(' a')), [['<pre class="text"> a</pre>'], '']);
28
+ assert.deepStrictEqual(inspect(parser(' a')), [['<pre class="text">a</pre>'], '']);
29
+ assert.deepStrictEqual(inspect(parser(' \ta')), [['<pre class="text">\ta</pre>'], '']);
24
30
  assert.deepStrictEqual(inspect(parser('\ta')), [['<pre class="text">a</pre>'], '']);
25
- assert.deepStrictEqual(inspect(parser('\t a')), [['<pre class="text"> a</pre>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('\t\ta')), [['<pre class="text">a</pre>'], '']);
32
+ assert.deepStrictEqual(inspect(parser('\t a')), [['<pre class="text"> a</pre>'], '']);
26
33
  });
27
34
 
28
35
  });
@@ -1,13 +1,13 @@
1
1
  import { IndentBlockParser } from '../block';
2
- import { union, block, validate, indent, convert } from '../../combinator';
2
+ import { union, block, indent, convert } from '../../combinator';
3
3
  import { codeblock } from './codeblock';
4
4
 
5
5
  // 空行を含むインデントブロックはインデントの違いによるセグメント分割の境界が視認不能となるため採用しない
6
6
 
7
- export const indentblock: IndentBlockParser = block(validate(/^(?: |\t)/, indent(convert(
7
+ export const indentblock: IndentBlockParser = block(indent(/^( {4}|\t)\1*/, convert(
8
8
  source => {
9
9
  const fence = (source.match(/^`{3,}(?=[^\S\n]*$)/mg) ?? [])
10
10
  .reduce((max, fence) => fence > max ? fence : max, '``') + '`';
11
11
  return `${fence}\n${source}\n${fence}`;
12
12
  },
13
- union([codeblock])), true)));
13
+ union([codeblock])), true));
@@ -11,8 +11,8 @@ import { memoize } from 'spica/memoize';
11
11
  import { shift } from 'spica/array';
12
12
 
13
13
  const openers = {
14
- '.': /^(?:[0-9]+|[a-z]+|[A-Z]+)(?:-(?!-)[0-9]*)*(?![^\S\n])\.?(?=$|\s)/,
15
- '(': /^\((?:[0-9]*|[a-z]*)(?![^)\n])\)?(?:-(?!-)[0-9]*)*(?=$|\s)/,
14
+ '.': /^([0-9]+|[a-z]+|[A-Z]+)(?:-(?!-)[0-9]*)*(?![^\S\n])\.?(?=$|\s)/,
15
+ '(': /^\(([0-9]*|[a-z]*)(?![^)\n])\)?(?:-(?!-)[0-9]*)*(?=$|\s)/,
16
16
  } as const;
17
17
 
18
18
  export const olist: OListParser = lazy(() => block(validate(
@@ -25,10 +25,10 @@ export const olist: OListParser = lazy(() => block(validate(
25
25
 
26
26
  export const olist_: OListParser = lazy(() => block(union([
27
27
  match(
28
- new RegExp(`^(?=${openers['.'].source.replace('?:', '')})`),
28
+ openers['.'],
29
29
  memoize(ms => list(type(ms[1]), '.'), ms => type(ms[1]).charCodeAt(0) || 0, [])),
30
30
  match(
31
- new RegExp(`^(?=${openers['('].source.replace('?:', '')})`),
31
+ openers['('],
32
32
  memoize(ms => list(type(ms[1]), '('), ms => type(ms[1]).charCodeAt(0) || 0, [])),
33
33
  ])));
34
34
 
@@ -33,7 +33,7 @@ describe('Unit: parser/block/paragraph', () => {
33
33
  assert.deepStrictEqual(inspect(parser('***a*b\n<wbr>**\nc')), [['<p>**<em>a</em>b<br><wbr>**<br>c</p>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('***a**b\n<wbr>*\nc')), [['<p>*<strong>a</strong>b<br><wbr>*<br>c</p>'], '']);
35
35
  assert.deepStrictEqual(inspect(parser('==a\n<wbr>==\nb')), [['<p>==a<br><wbr>==<br>b</p>'], '']);
36
- assert.deepStrictEqual(inspect(parser(' a')), [['<p> a</p>'], '']);
36
+ assert.deepStrictEqual(inspect(parser(' a')), [['<p> a</p>'], '']);
37
37
  });
38
38
 
39
39
  it('anchor', () => {
@@ -50,8 +50,8 @@ describe('Unit: parser/block/paragraph', () => {
50
50
  assert.deepStrictEqual(inspect(parser('a\n>>1')), [['<p>a<br><a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
51
51
  assert.deepStrictEqual(inspect(parser('a\n>>1\nb')), [['<p>a<br><a href="?at=1" class="anchor">&gt;&gt;1</a><br>b</p>'], '']);
52
52
  assert.deepStrictEqual(inspect(parser('a\n>> b\nc')), [['<p>a<br>&gt;&gt; b<br>c</p>'], '']);
53
- assert.deepStrictEqual(inspect(parser(' >>1')), [['<p> <a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
54
- assert.deepStrictEqual(inspect(parser(' >>>1')), [['<p> &gt;<a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
53
+ assert.deepStrictEqual(inspect(parser(' >>1')), [['<p> <a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
54
+ assert.deepStrictEqual(inspect(parser(' >>>1')), [['<p> &gt;<a href="?at=1" class="anchor">&gt;&gt;1</a></p>'], '']);
55
55
  });
56
56
 
57
57
  it('comment', () => {
@@ -5,7 +5,7 @@ import { html } from 'typed-dom/dom';
5
5
  export const code: CodeParser = creator(validate('`', match(
6
6
  /^(`+)(?!`)([^\n]*?[^`\n])\1(?!`)/,
7
7
  ([whole, , body]) => rest =>
8
- [[html('code', { 'data-src': whole }, format(body))], rest])));
8
+ [[html('code', { 'data-src': whole }, format(body))], rest.slice(whole.length)])));
9
9
 
10
10
  function format(text: string): string {
11
11
  assert(text.length > 0);
@@ -7,7 +7,7 @@ import { memoize } from 'spica/memoize';
7
7
  import { unshift, push } from 'spica/array';
8
8
 
9
9
  export const comment: CommentParser = lazy(() => creator(validate('[%', match(
10
- /^(?=\[(%+)\s)/,
10
+ /^\[(%+)\s/,
11
11
  memoize(
12
12
  ([, fence]) =>
13
13
  surround(
@@ -20,7 +20,7 @@ Object.values(attrspec).forEach(o => Object.setPrototypeOf(o, null));
20
20
 
21
21
  export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-z]+(?=[^\S\n]|>)/, union([
22
22
  match(
23
- /^(?=<(wbr)(?=[^\S\n]|>))/,
23
+ /^<(wbr)(?=[^\S\n]|>)/,
24
24
  memoize(
25
25
  ([, tag]) =>
26
26
  surround(
@@ -29,7 +29,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
29
29
  [[h(tag as 'span', attributes('html', [], attrspec[tag], bs))], rest]),
30
30
  ([, tag]) => tags.indexOf(tag), [])),
31
31
  match(
32
- /^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/,
32
+ /^<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>)/,
33
33
  memoize(
34
34
  ([, tag]) =>
35
35
  surround<HTMLParser.TagParser, string>(surround(
@@ -42,7 +42,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
42
42
  [[elem(tag, as, bs, cs)], rest]),
43
43
  ([, tag]) => tags.indexOf(tag), [])),
44
44
  match(
45
- /^(?=<([a-z]+)(?=[^\S\n]|>))/,
45
+ /^<([a-z]+)(?=[^\S\n]|>)/,
46
46
  memoize(
47
47
  ([, tag]) =>
48
48
  surround<HTMLParser.TagParser, string>(surround(