securemark 0.294.9 → 0.294.10

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/.eslintrc.json CHANGED
@@ -15,11 +15,6 @@
15
15
  "error",
16
16
  {
17
17
  "ignoreErrors": false,
18
- "maxPatternSize": 3000,
19
- "maxRepeatCount": 256,
20
- "maxSimpleRepeatCount": 256,
21
- "attackTimeout": null,
22
- "incubationTimeout": null,
23
18
  "timeout": 1e6
24
19
  }
25
20
  ]
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.294.10
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.294.9
4
8
 
5
9
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.294.9 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.294.10 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("Prism"), require("DOMPurify"));
@@ -2722,7 +2722,7 @@ Object.defineProperty(exports, "__esModule", ({
2722
2722
  }));
2723
2723
  exports.convert = void 0;
2724
2724
  const parser_1 = __webpack_require__(605);
2725
- function convert(conv, parser, continuous, empty = false) {
2725
+ function convert(conv, parser, empty = false) {
2726
2726
  return (0, parser_1.failsafe)(input => {
2727
2727
  const {
2728
2728
  context
@@ -2738,20 +2738,13 @@ function convert(conv, parser, continuous, empty = false) {
2738
2738
  context.position = source.length;
2739
2739
  return new parser_1.List();
2740
2740
  }
2741
- if (continuous) {
2742
- context.position += source.length - position - src.length;
2743
- const result = parser(input);
2744
- context.source = source;
2745
- return result;
2746
- } else {
2747
- const {
2748
- offset,
2749
- backtracks
2750
- } = context;
2751
- const result = parser((0, parser_1.subinput)(src, context));
2752
- context.position = context.source.length;
2753
- return result;
2754
- }
2741
+ const {
2742
+ offset,
2743
+ backtracks
2744
+ } = context;
2745
+ const result = parser((0, parser_1.subinput)(src, context));
2746
+ context.position = context.source.length;
2747
+ return result;
2755
2748
  });
2756
2749
  }
2757
2750
  exports.convert = convert;
@@ -3022,11 +3015,12 @@ Object.defineProperty(exports, "__esModule", ({
3022
3015
  exports.rewrite = exports.focus = void 0;
3023
3016
  const parser_1 = __webpack_require__(605);
3024
3017
  const combinator_1 = __webpack_require__(3484);
3025
- function focus(scope, parser) {
3018
+ function focus(scope, parser, slice = true) {
3026
3019
  const match = (0, combinator_1.matcher)(scope, false);
3027
- return (0, parser_1.failsafe)(({
3028
- context
3029
- }) => {
3020
+ return (0, parser_1.failsafe)(arg => {
3021
+ const {
3022
+ context
3023
+ } = arg;
3030
3024
  const {
3031
3025
  source,
3032
3026
  position
@@ -3036,7 +3030,12 @@ function focus(scope, parser) {
3036
3030
  context
3037
3031
  })?.head?.value ?? '';
3038
3032
  if (src === '') return;
3039
- context.range = src.length;
3033
+ const range = context.range = src.length;
3034
+ if (!slice) {
3035
+ const result = parser(arg);
3036
+ context.position += result && context.position === position ? range : 0;
3037
+ return result;
3038
+ }
3040
3039
  context.offset ??= 0;
3041
3040
  context.offset += position;
3042
3041
  const result = parser((0, parser_1.input)(src, context));
@@ -3048,10 +3047,11 @@ function focus(scope, parser) {
3048
3047
  });
3049
3048
  }
3050
3049
  exports.focus = focus;
3051
- function rewrite(scope, parser) {
3052
- return (0, parser_1.failsafe)(({
3053
- context
3054
- }) => {
3050
+ function rewrite(scope, parser, slice = true) {
3051
+ return (0, parser_1.failsafe)(arg => {
3052
+ const {
3053
+ context
3054
+ } = arg;
3055
3055
  const {
3056
3056
  source,
3057
3057
  position
@@ -3061,6 +3061,13 @@ function rewrite(scope, parser) {
3061
3061
  context
3062
3062
  });
3063
3063
  if (res1 === undefined || context.position < position) return;
3064
+ const range = context.range = context.position - position;
3065
+ if (!slice) {
3066
+ context.position = position;
3067
+ const res2 = parser(arg);
3068
+ context.position += res2 && context.position === position ? range : 0;
3069
+ return res2;
3070
+ }
3064
3071
  const src = source.slice(position, context.position);
3065
3072
  context.offset ??= 0;
3066
3073
  context.offset += position;
@@ -4658,8 +4665,8 @@ exports.blockquote = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, co
4658
4665
  const opener = /(?=>>+(?:$|[ \n]))/y;
4659
4666
  const indent = (0, combinator_1.block)((0, combinator_1.open)(opener, (0, combinator_1.some)(source_1.contentline, />(?:$|[ \n])/y)), false);
4660
4667
  const unindent = source => source.replace(/(?<=^|\n)>(?: |(?=>*(?:$|[ \n])))|\n$/g, '');
4661
- const source = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.recursion)(2 /* Recursion.blockquote */, (0, combinator_1.union)([(0, combinator_1.rewrite)(indent, (0, combinator_1.convert)(unindent, source, false, true)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, (0, combinator_1.fmap)(autolink_1.autolink, ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('pre', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))])), false, true))]))), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('blockquote', (0, util_1.unwrap)(ns)))])));
4662
- const markdown = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.recursion)(2 /* Recursion.blockquote */, (0, combinator_1.union)([(0, combinator_1.rewrite)(indent, (0, combinator_1.convert)(unindent, markdown, false, true)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, ({
4668
+ const source = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.recursion)(2 /* Recursion.blockquote */, (0, combinator_1.union)([(0, combinator_1.rewrite)(indent, (0, combinator_1.convert)(unindent, source, true)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, (0, combinator_1.fmap)(autolink_1.autolink, ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('pre', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))])), true))]))), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('blockquote', (0, util_1.unwrap)(ns)))])));
4669
+ const markdown = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.recursion)(2 /* Recursion.blockquote */, (0, combinator_1.union)([(0, combinator_1.rewrite)(indent, (0, combinator_1.convert)(unindent, markdown, true)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, ({
4663
4670
  context
4664
4671
  }) => {
4665
4672
  (0, combinator_1.consume)(10, context);
@@ -4677,7 +4684,7 @@ const markdown = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combina
4677
4684
  }, context);
4678
4685
  context.position = source.length;
4679
4686
  return new parser_1.List([new parser_1.Data((0, dom_1.html)('section', [document, (0, dom_1.html)('h2', 'References'), references]))]);
4680
- }, false, true))]))), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('blockquote', (0, util_1.unwrap)(ns)))])));
4687
+ }, true))]))), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('blockquote', (0, util_1.unwrap)(ns)))])));
4681
4688
 
4682
4689
  /***/ },
4683
4690
 
@@ -4926,7 +4933,7 @@ const inline_1 = __webpack_require__(7973);
4926
4933
  exports.segment = (0, combinator_1.block)((0, combinator_1.sequence)([(0, combinator_1.line)((0, combinator_1.close)(label_1.segment, /(?!\S).*\n/y)), (0, combinator_1.union)([codeblock_1.segment, mathblock_1.segment, table_1.segment, blockquote_1.segment, placeholder_1.segment, (0, combinator_1.some)(source_1.contentline)])]));
4927
4934
  exports.fig = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.verify)((0, combinator_1.convert)((source, context) => {
4928
4935
  // Bug: TypeScript
4929
- const fence = (/^[^\n]*\n!?>+ /.test(source) && source.match(/^~{3,}(?=[^\S\n]*$)/mg) || []).reduce((max, fence) => fence > max ? fence : max, '~~') + '~';
4936
+ const fence = (/^[^\n]*\n!?>+ /.test(source) && source.match(/^~{3,}(?=[^\S\n]*$)/gm) || []).reduce((max, fence) => fence > max ? fence : max, '~~') + '~';
4930
4937
  const {
4931
4938
  position
4932
4939
  } = context;
@@ -4935,7 +4942,7 @@ exports.fig = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment,
4935
4942
  });
4936
4943
  context.position = position;
4937
4944
  return result ? `${fence}figure ${source.replace(/^(.+\n.+\n)([\S\s]+?)\n?$/, '$1\n$2')}\n${fence}` : `${fence}figure ${source}\n\n${fence}`;
4938
- }, (0, combinator_1.union)([figure_1.figure]), false), ([{
4945
+ }, (0, combinator_1.union)([figure_1.figure])), ([{
4939
4946
  value: el
4940
4947
  }]) => el.tagName === 'FIGURE')));
4941
4948
  const parser = (0, combinator_1.sequence)([(0, combinator_1.line)((0, combinator_1.close)(label_1.segment, /(?!\S).*\n/y)), (0, combinator_1.line)((0, combinator_1.union)([inline_1.media, inline_1.lineshortmedia])), (0, combinator_1.some)(source_1.contentline)]);
@@ -5001,7 +5008,7 @@ const dom_1 = __webpack_require__(394);
5001
5008
  exports.segment = (0, combinator_1.block)((0, combinator_1.match)(/(~{3,})(?:figure )?(?=\[?\$)/y, (0, memoize_1.memoize)(([, fence], closer = new RegExp(String.raw`${fence}[^\S\n]*(?:$|\n)`, 'y')) => (0, combinator_1.close)((0, combinator_1.sequence)([source_1.contentline, (0, combinator_1.inits)([
5002
5009
  // All parsers which can include closing terms.
5003
5010
  (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 - 1, [], 2 ** 4 - 1)));
5004
- 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/y)])), (0, combinator_1.inits)([(0, combinator_1.block)((0, combinator_1.union)([ulist_1.ulist, olist_1.olist, table_1.table, 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.lineshortmedia)])), source_1.emptyline, (0, combinator_1.block)((0, visibility_1.visualize)((0, visibility_1.trimBlank)((0, combinator_1.some)(inline_1.inline))))])]), false), nodes => {
5011
+ 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/y)])), (0, combinator_1.inits)([(0, combinator_1.block)((0, combinator_1.union)([ulist_1.ulist, olist_1.olist, table_1.table, 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.lineshortmedia)])), source_1.emptyline, (0, combinator_1.block)((0, visibility_1.visualize)((0, visibility_1.trimBlank)((0, combinator_1.some)(inline_1.inline))))])])), nodes => {
5005
5012
  const [label, param, content, ...caption] = (0, util_1.unwrap)(nodes);
5006
5013
  return new parser_1.List([new parser_1.Data((0, dom_1.html)('figure', attributes(label.getAttribute('data-label'), param, content, caption), [(0, dom_1.html)('figcaption', [(0, dom_1.html)('span', {
5007
5014
  class: 'figindex'
@@ -5209,7 +5216,7 @@ const align = (0, combinator_1.line)((0, combinator_1.fmap)((0, combinator_1.uni
5209
5216
  const delimiter = /[-=<>]+(?:\/[-=^v]*)?(?=[^\S\n]*\n)|[#:](?:(?!:\D|0)\d*:(?!0)\d*)?(?:!+[+]?)?(?=[ \n])/y;
5210
5217
  const head = (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.open)((0, source_1.str)(/#(?:(?!:\D|0)\d*:(?!0)\d*)?(?:!+[+]?)?(?=[ \n])/y), (0, combinator_1.rewrite)((0, combinator_1.inits)([source_1.anyline, (0, combinator_1.some)(source_1.contentline, delimiter)]), (0, combinator_1.union)([(0, combinator_1.block)((0, combinator_1.surround)(/\s/y, (0, combinator_1.union)([inline_1.medialink, inline_1.media, inline_1.lineshortmedia]), /[^\S\n]*(?:$|\n)/y)), (0, combinator_1.open)(/(?:[^\S\n]*\n|\s)/y, (0, visibility_1.visualize)((0, visibility_1.trimBlank)((0, combinator_1.some)(inline_1.inline))), true)])), true), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('th', attributes(ns.shift().value), (0, dom_1.defrag)((0, util_1.unwrap)(ns))))])), false);
5211
5218
  const data = (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.open)((0, source_1.str)(/:(?:(?!:\D|0)\d*:(?!0)\d*)?(?:!+[+]?)?(?=[ \n])/y), (0, combinator_1.rewrite)((0, combinator_1.inits)([source_1.anyline, (0, combinator_1.some)(source_1.contentline, delimiter)]), (0, combinator_1.union)([(0, combinator_1.block)((0, combinator_1.surround)(/\s/y, (0, combinator_1.union)([inline_1.medialink, inline_1.media, inline_1.lineshortmedia]), /[^\S\n]*(?:$|\n)/y)), (0, combinator_1.open)(/(?:[^\S\n]*\n|\s)/y, (0, visibility_1.visualize)((0, visibility_1.trimBlankEnd)((0, combinator_1.some)(inline_1.inline))), true)])), true), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('td', attributes(ns.shift().value), (0, dom_1.defrag)((0, util_1.unwrap)(ns))))])), false);
5212
- const dataline = (0, combinator_1.line)((0, combinator_1.rewrite)(source_1.contentline, (0, combinator_1.union)([(0, combinator_1.validate)(/!+ /y, (0, combinator_1.convert)(source => `:${source}`, data, false)), (0, combinator_1.convert)(source => `: ${source}`, data, false)])));
5219
+ const dataline = (0, combinator_1.line)((0, combinator_1.rewrite)(source_1.contentline, (0, combinator_1.union)([(0, combinator_1.validate)(/!+ /y, (0, combinator_1.convert)(source => `:${source}`, data)), (0, combinator_1.convert)(source => `: ${source}`, data)])));
5213
5220
  function attributes(source) {
5214
5221
  let [, rowspan = undefined, colspan = undefined, highlight = undefined, extension = undefined] = source.match(/^[#:](?:(\d+)?:(\d+)?)?(?:(!+)([+]?))?$/) ?? [];
5215
5222
  rowspan === '1' ? rowspan = undefined : undefined;
@@ -5434,16 +5441,17 @@ exports.segment = (0, combinator_1.block)((0, combinator_1.focus)(/#+ +\S[^\n]*(
5434
5441
  context
5435
5442
  } = input;
5436
5443
  const {
5437
- source
5444
+ source,
5445
+ range = 0
5438
5446
  } = context;
5439
5447
  const acc = new parser_1.List();
5440
- for (; context.position < source.length;) {
5448
+ for (const len = context.position + range; context.position < len;) {
5441
5449
  const line = (0, combinator_1.firstline)(source, context.position);
5442
5450
  acc.push(new parser_1.Data(line));
5443
5451
  context.position += line.length;
5444
5452
  }
5445
5453
  return acc;
5446
- }));
5454
+ }, false));
5447
5455
  exports.heading = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment,
5448
5456
  // その他の表示制御は各所のCSSで行う。
5449
5457
  (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 32 /* State.index */ | 16 /* State.label */ | 8 /* State.link */, (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.union)([(0, combinator_1.open)((0, source_1.str)(/##+/y), (0, visibility_1.visualize)((0, visibility_1.trimBlank)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline])))), true), (0, combinator_1.open)((0, source_1.str)('#'), (0, combinator_1.state)(251 /* State.linkers */, (0, visibility_1.visualize)((0, visibility_1.trimBlank)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))), true)]), (nodes, context) => {
@@ -5826,11 +5834,9 @@ const source_1 = __webpack_require__(8745);
5826
5834
  const util_1 = __webpack_require__(4992);
5827
5835
  const dom_1 = __webpack_require__(394);
5828
5836
  exports.syntax = />+ /y;
5829
- exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.some)((0, combinator_1.validate)(exports.syntax, source_1.anyline)), (0, combinator_1.convert)(
5830
- // TODO: インデント数を渡してインデント数前の行頭確認を行う実装に置き換える
5831
- source => source.replace(/(?<=^>+ )/mg, '\r'), (0, combinator_1.some)((0, combinator_1.union)([
5837
+ exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.some)((0, combinator_1.validate)(exports.syntax, source_1.anyline)), (0, combinator_1.convert)(source => source.replace(/(?<=^>+ )/gm, '\r'), (0, combinator_1.some)((0, combinator_1.union)([
5832
5838
  // quote補助関数が残した数式をパースする。
5833
- math_1.math, autolink_1.autolink, source_1.unescsource])), false)), (ns, {
5839
+ math_1.math, autolink_1.autolink, source_1.unescsource])))), (ns, {
5834
5840
  source,
5835
5841
  position
5836
5842
  }) => new parser_1.List([new parser_1.Data(source[position - 1] === '\n' ? ns.pop().value : (0, dom_1.html)('br')), new parser_1.Data((0, dom_1.html)('span', {
@@ -5863,7 +5869,7 @@ exports.sidefence = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, com
5863
5869
  }))]))));
5864
5870
  const opener = /(?=\|\|+(?:$|[ \n]))/y;
5865
5871
  const unindent = source => source.replace(/(?<=^|\n)\|(?: |(?=\|*(?:$|[ \n])))|\n$/g, '');
5866
- const source = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.recursion)(1 /* Recursion.block */, (0, combinator_1.union)([(0, combinator_1.focus)(/(?:\|\|+(?=$|[ \n])[^\n]*(?:$|\n))+/y, (0, combinator_1.convert)(unindent, source, false, true)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, (0, combinator_1.fmap)(autolink_1.autolink, ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('pre', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))])), false, true))]))), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('blockquote', (0, util_1.unwrap)(ns)))])));
5872
+ const source = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.recursion)(1 /* Recursion.block */, (0, combinator_1.union)([(0, combinator_1.focus)(/(?:\|\|+(?=$|[ \n])[^\n]*(?:$|\n))+/y, (0, combinator_1.convert)(unindent, source, true)), (0, combinator_1.rewrite)((0, combinator_1.some)(source_1.contentline, opener), (0, combinator_1.convert)(unindent, (0, combinator_1.fmap)(autolink_1.autolink, ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('pre', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))])), true))]))), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('blockquote', (0, util_1.unwrap)(ns)))])));
5867
5873
 
5868
5874
  /***/ },
5869
5875
 
@@ -5897,13 +5903,17 @@ const row = (parser, optional) => (0, combinator_1.fallback)((0, combinator_1.fm
5897
5903
  }, [(0, dom_1.html)('td', source.replace('\n', ''))]))])));
5898
5904
  const align = (0, combinator_1.fmap)((0, combinator_1.open)('|', (0, combinator_1.union)([(0, combinator_1.focus)(/:-+:?/y, ({
5899
5905
  context: {
5900
- source
5906
+ source,
5907
+ position,
5908
+ range = 0
5901
5909
  }
5902
- }) => new parser_1.List([new parser_1.Data(source.at(-1) === ':' ? 'center' : 'start')])), (0, combinator_1.focus)(/-+:?/y, ({
5910
+ }) => new parser_1.List([new parser_1.Data(source[position + range - 1] === ':' ? 'center' : 'start')]), false), (0, combinator_1.focus)(/-+:?/y, ({
5903
5911
  context: {
5904
- source
5912
+ source,
5913
+ position,
5914
+ range = 0
5905
5915
  }
5906
- }) => new parser_1.List([new parser_1.Data(source.at(-1) === ':' ? 'end' : '')]))])), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('td', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))]));
5916
+ }) => new parser_1.List([new parser_1.Data(source[position + range - 1] === ':' ? 'end' : '')]), false)])), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('td', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))]));
5907
5917
  const cell = (0, combinator_1.surround)(/\|\s*(?=\S)/y, (0, combinator_1.union)([(0, combinator_1.close)(inline_1.medialink, /\s*(?=\||$)/y), (0, combinator_1.close)(inline_1.media, /\s*(?=\||$)/y), (0, combinator_1.close)(inline_1.shortmedia, /\s*(?=\||$)/y), (0, visibility_1.trimBlank)((0, combinator_1.some)(inline_1.inline, /\|/y, [[/\|?\s*$/y, 9]]))]), /[^|]*/y, true);
5908
5918
  const head = (0, combinator_1.fmap)(cell, ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('th', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))]));
5909
5919
  const data = (0, combinator_1.fmap)(cell, ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('td', (0, dom_1.defrag)((0, util_1.unwrap)(ns))))]));
@@ -5949,11 +5959,12 @@ exports.ulist_ = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combin
5949
5959
  }, (0, dom_1.defrag)((0, util_1.unwrap)(fillFirstLine(ns)))))])))])))), ns => new parser_1.List([new parser_1.Data(format((0, dom_1.html)('ul', (0, util_1.unwrap)(ns))))]))));
5950
5960
  exports.checkbox = (0, combinator_1.focus)(/\[[xX ]\](?=$|[ \n])/y, ({
5951
5961
  context: {
5952
- source
5962
+ source,
5963
+ position
5953
5964
  }
5954
5965
  }) => new parser_1.List([new parser_1.Data((0, dom_1.html)('span', {
5955
5966
  class: 'checkbox'
5956
- }, source[1].trimStart() ? '☑' : '☐'))]));
5967
+ }, source[position + 1].trimStart() ? '☑' : '☐'))]), false);
5957
5968
  function fillFirstLine(nodes) {
5958
5969
  const node = nodes.head?.value;
5959
5970
  if (typeof node !== 'object') return nodes;
@@ -5992,11 +6003,11 @@ const normalize_1 = __webpack_require__(4490);
5992
6003
  const dom_1 = __webpack_require__(394);
5993
6004
  exports.header = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/---+ *\r?\n(?=\S)/y, (0, combinator_1.inits)([(0, combinator_1.block)((0, combinator_1.union)([(0, combinator_1.validate)(({
5994
6005
  context
5995
- }) => context.header ?? true, (0, combinator_1.focus)(/(---+) *\r?\n(?:[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*:[ \t]+\S[^\r\n]*\r?\n){1,100}\1 *(?:$|\r?\n)/y, (0, combinator_1.convert)(source => (0, normalize_1.normalize)(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))).replace(/(\S)\s+$/mg, '$1'), (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([field])), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('aside', {
6006
+ }) => context.header ?? true, (0, combinator_1.focus)(/(---+) *\r?\n(?:[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*:[ \t]+\S[^\r\n]*\r?\n){1,100}\1 *(?:$|\r?\n)/y, (0, combinator_1.convert)(source => (0, normalize_1.normalize)(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))), (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([field])), ns => new parser_1.List([new parser_1.Data((0, dom_1.html)('aside', {
5996
6007
  class: 'header'
5997
6008
  }, [(0, dom_1.html)('details', {
5998
6009
  open: ''
5999
- }, (0, dom_1.defrag)((0, util_1.unwrap)(ns.unshift(new parser_1.Data((0, dom_1.html)('summary', 'Header'))) && ns)))]))])), false))), ({
6010
+ }, (0, dom_1.defrag)((0, util_1.unwrap)(ns.unshift(new parser_1.Data((0, dom_1.html)('summary', 'Header'))) && ns)))]))]))))), ({
6000
6011
  context
6001
6012
  }) => {
6002
6013
  const {
@@ -6295,7 +6306,9 @@ exports.account = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1 /*
6295
6306
  }, {
6296
6307
  value: account
6297
6308
  }]], context) => {
6298
- if (context.source[context.position] === '#') return;
6309
+ if (context.source[context.position] === '#') {
6310
+ return void (0, combinator_1.setBacktrack)(context, [2 | 0 /* Backtrack.autolink */], context.position - context.range);
6311
+ }
6299
6312
  return new parser_1.List([new parser_1.Data((0, dom_1.define)((0, link_1.parse)(new parser_1.List([new parser_1.Data(`@${host}${account}`)]), new parser_1.List([new parser_1.Data(host ? `https://${host}@${account}` : `/@${account}`)]), context), {
6300
6313
  class: 'account'
6301
6314
  }))]);
@@ -6435,12 +6448,13 @@ exports.lineurl = (0, combinator_1.lazy)(() => (0, combinator_1.focus)(/(?<=^|[\
6435
6448
  }) => {
6436
6449
  const {
6437
6450
  source,
6438
- position
6451
+ position,
6452
+ range = 0
6439
6453
  } = context;
6440
- context.position -= source[0] === '!' ? 1 : 0;
6441
- context.position += source.length;
6442
- return new parser_1.List([new parser_1.Data((0, link_1.parse)(new parser_1.List(), new parser_1.List([new parser_1.Data(source.slice(position))]), context))]);
6443
- })), (0, combinator_1.open)((0, source_1.str)(/[^:]+/y), (0, combinator_1.some)(inline_1.inline))])])));
6454
+ context.position -= position > 0 && source[position - 1] === '!' ? 1 : 0;
6455
+ context.position += range;
6456
+ return new parser_1.List([new parser_1.Data((0, link_1.parse)(new parser_1.List(), new parser_1.List([new parser_1.Data(source.slice(position, context.position))]), context))]);
6457
+ })), (0, source_1.str)(/[^:]+/y)])]), false));
6444
6458
  const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')')), (0, source_1.str)(')'), true, [3 | 0 /* Backtrack.autolink */], undefined, () => new parser_1.List()), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ']')), (0, source_1.str)(']'), true, [3 | 0 /* Backtrack.autolink */], undefined, () => new parser_1.List()), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), '}')), (0, source_1.str)('}'), true, [3 | 0 /* Backtrack.autolink */], undefined, () => new parser_1.List()), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.recursion)(6 /* Recursion.terminal */, (0, combinator_1.some)(source_1.unescsource, '"'))), (0, source_1.str)('"'), true, [3 | 0 /* Backtrack.autolink */], undefined, () => new parser_1.List())]));
6445
6459
 
6446
6460
  /***/ },
@@ -7844,8 +7858,8 @@ exports.lineshortmedia = exports.shortmedia = void 0;
7844
7858
  const combinator_1 = __webpack_require__(3484);
7845
7859
  const url_1 = __webpack_require__(2129);
7846
7860
  const media_1 = __webpack_require__(7478);
7847
- exports.shortmedia = (0, combinator_1.constraint)(4 /* State.media */, (0, combinator_1.rewrite)((0, combinator_1.open)('!', url_1.url), (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media]), false)));
7848
- exports.lineshortmedia = (0, combinator_1.focus)(/(?<=^|[\r\n])!https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/y, (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media]), false));
7861
+ exports.shortmedia = (0, combinator_1.constraint)(4 /* State.media */, (0, combinator_1.rewrite)((0, combinator_1.open)('!', url_1.url), (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media]))));
7862
+ exports.lineshortmedia = (0, combinator_1.constraint)(4 /* State.media */, (0, combinator_1.focus)(/(?<=^|[\r\n])!https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/y, (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media]))));
7849
7863
 
7850
7864
  /***/ },
7851
7865
 
@@ -8986,20 +9000,18 @@ exports.stringify = stringify;
8986
9000
  Object.defineProperty(exports, "__esModule", ({
8987
9001
  value: true
8988
9002
  }));
8989
- exports.trimBlankNodeEnd = exports.trimBlankEnd = exports.trimBlankStart = exports.trimBlank = exports.isTightNodeStart = exports.isLooseNodeStart = exports.tightStart = exports.blankWith = exports.visualize = exports.blank = void 0;
9003
+ exports.trimBlankNodeEnd = exports.trimBlankEnd = exports.trimBlankStart = exports.trimBlank = exports.isTightNodeStart = exports.isLooseNodeStart = exports.tightStart = exports.blankWith = exports.visualize = void 0;
8990
9004
  const parser_1 = __webpack_require__(605);
8991
9005
  const combinator_1 = __webpack_require__(3484);
8992
9006
  const htmlentity_1 = __webpack_require__(470);
8993
9007
  const normalize_1 = __webpack_require__(4490);
8994
9008
  var blank;
8995
9009
  (function (blank) {
8996
- blank.line = new RegExp(
8997
- // TODO: 行全体をエスケープ
8998
- /^(\\?[^\S\r\n]|&IHN;|<wbr ?>|\\$)+$/mg.source.replace('IHN', `(?:${normalize_1.invisibleHTMLEntityNames.join('|')})`), 'gm');
8999
- blank.start = new RegExp(/(?:\\?[^\S\r\n]|&IHN;|<wbr ?>)+/y.source.replace('IHN', `(?:${normalize_1.invisibleHTMLEntityNames.join('|')})`), 'y');
9000
- })(blank || (exports.blank = blank = {}));
9010
+ blank.line = new RegExp(/((?:^|\n)[^\S\n]*(?=\S))((?:[^\S\n]|\\(?=$|\s)|&IHN;|<wbr ?>)+(?=$|\n))/g.source.replace('IHN', `(?:${normalize_1.invisibleHTMLEntityNames.join('|')})`), 'g');
9011
+ blank.start = new RegExp(/(?:[^\S\n]|\\(?=$|\s)|&IHN;|<wbr ?>)+/y.source.replace('IHN', `(?:${normalize_1.invisibleHTMLEntityNames.join('|')})`), 'y');
9012
+ })(blank || (blank = {}));
9001
9013
  function visualize(parser) {
9002
- return (0, combinator_1.convert)(source => source.replace(blank.line, `${"\u001B" /* Command.Escape */}$1`), parser, false);
9014
+ return (0, combinator_1.convert)(source => source.replace(blank.line, `$1${"\u001B" /* Command.Escape */}$2`), parser);
9003
9015
  }
9004
9016
  exports.visualize = visualize;
9005
9017
  function blankWith(starts, delimiter) {
package/markdown.d.ts CHANGED
@@ -1112,7 +1112,7 @@ export namespace MarkdownParser {
1112
1112
  SourceParser.StrParser,
1113
1113
  Parser<string | HTMLElement, Context, [
1114
1114
  Parser<HTMLAnchorElement, Context, []>,
1115
- InlineParser,
1115
+ SourceParser.StrParser,
1116
1116
  ]>,
1117
1117
  ]> {
1118
1118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.294.9",
3
+ "version": "0.294.10",
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",
@@ -1,7 +1,7 @@
1
1
  import { Parser, List, Ctx, Context, subinput, failsafe } from '../../data/parser';
2
2
 
3
- export function convert<P extends Parser<unknown>>(conv: (source: string, context: Context<P>) => string, parser: P, continuous: boolean, empty?: boolean): P;
4
- export function convert<N>(conv: (source: string, context: Ctx) => string, parser: Parser<N>, continuous: boolean, empty = false): Parser<N> {
3
+ export function convert<P extends Parser<unknown>>(conv: (source: string, context: Context<P>) => string, parser: P, empty?: boolean): P;
4
+ export function convert<N>(conv: (source: string, context: Ctx) => string, parser: Parser<N>, empty = false): Parser<N> {
5
5
  assert(parser);
6
6
  return failsafe(input => {
7
7
  const { context } = input;
@@ -14,22 +14,12 @@ export function convert<N>(conv: (source: string, context: Ctx) => string, parse
14
14
  context.position = source.length;
15
15
  return new List();
16
16
  }
17
- assert(source.endsWith(src) || src.endsWith(source, position) || !continuous);
18
- if (continuous) {
19
- context.position += source.length - position - src.length;
20
- const result = parser(input);
21
- assert(context.position > position || !result);
22
- context.source = source;
23
- return result;
24
- }
25
- else {
26
- const { offset, backtracks } = context;
27
- const result = parser(subinput(src, context));
28
- context.position = context.source.length
29
- assert(context.offset === offset);
30
- assert(context.source === source);
31
- assert(context.backtracks === backtracks);
32
- return result;
33
- }
17
+ const { offset, backtracks } = context;
18
+ const result = parser(subinput(src, context));
19
+ context.position = context.source.length
20
+ assert(context.offset === offset);
21
+ assert(context.source === source);
22
+ assert(context.backtracks === backtracks);
23
+ return result;
34
24
  });
35
25
  }
@@ -1,17 +1,24 @@
1
1
  import { Parser, Context, input, failsafe } from '../../data/parser';
2
2
  import { matcher } from '../../../combinator';
3
3
 
4
- export function focus<P extends Parser<unknown>>(scope: string | RegExp, parser: P): P;
5
- export function focus<N>(scope: string | RegExp, parser: Parser<N>): Parser<N> {
4
+ export function focus<P extends Parser<unknown>>(scope: string | RegExp, parser: P, slice?: boolean): P;
5
+ export function focus<N>(scope: string | RegExp, parser: Parser<N>, slice = true): Parser<N> {
6
6
  assert(parser);
7
7
  const match = matcher(scope, false);
8
- return failsafe(({ context }) => {
8
+ return failsafe(arg => {
9
+ const { context } = arg;
9
10
  const { source, position } = context;
10
11
  if (position === source.length) return;
11
12
  const src = match({ context })?.head?.value ?? '';
12
13
  assert(source.startsWith(src, position));
13
14
  if (src === '') return;
14
- context.range = src.length;
15
+ const range = context.range = src.length;
16
+ if (!slice) {
17
+ const result = parser(arg);
18
+ context.position += result && context.position === position ? range : 0;
19
+ assert(context.position > position || !result);
20
+ return result;
21
+ }
15
22
  context.offset ??= 0;
16
23
  context.offset += position;
17
24
  const result = parser(input(src, context));
@@ -25,16 +32,25 @@ export function focus<N>(scope: string | RegExp, parser: Parser<N>): Parser<N> {
25
32
  }
26
33
 
27
34
  //export function rewrite<N, C extends Ctx, D extends Parser<unknown, C>[]>(scope: Parser<unknown, C, D>, parser: Parser<N, C, never>): Parser<N, C, D>;
28
- export function rewrite<P extends Parser<unknown>>(scope: Parser<unknown, Context<P>>, parser: P): P;
29
- export function rewrite<N>(scope: Parser<unknown>, parser: Parser<N>): Parser<N> {
35
+ export function rewrite<P extends Parser<unknown>>(scope: Parser<unknown, Context<P>>, parser: P, slice?: boolean): P;
36
+ export function rewrite<N>(scope: Parser<unknown>, parser: Parser<N>, slice = true): Parser<N> {
30
37
  assert(scope);
31
38
  assert(parser);
32
- return failsafe(({ context }) => {
39
+ return failsafe(arg => {
40
+ const { context } = arg;
33
41
  const { source, position } = context;
34
42
  if (position === source.length) return;
35
43
  const res1 = scope({ context });
36
44
  assert(context.position > position || !res1);
37
45
  if (res1 === undefined || context.position < position) return;
46
+ const range = context.range = context.position - position;
47
+ if (!slice) {
48
+ context.position = position;
49
+ const res2 = parser(arg);
50
+ context.position += res2 && context.position === position ? range : 0;
51
+ assert(context.position > position || !res2);
52
+ return res2;
53
+ }
38
54
  const src = source.slice(position, context.position);
39
55
  assert(src !== '');
40
56
  assert(source.startsWith(src, position));
@@ -25,10 +25,10 @@ const source: BlockquoteParser.SourceParser = lazy(() => fmap(
25
25
  some(recursion(Recursion.blockquote, union([
26
26
  rewrite(
27
27
  indent,
28
- convert(unindent, source, false, true)),
28
+ convert(unindent, source, true)),
29
29
  rewrite(
30
30
  some(contentline, opener),
31
- convert(unindent, fmap(autolink, ns => new List([new Data(html('pre', defrag(unwrap(ns))))])), false, true)),
31
+ convert(unindent, fmap(autolink, ns => new List([new Data(html('pre', defrag(unwrap(ns))))])), true)),
32
32
  ]))),
33
33
  ns => new List([new Data(html('blockquote', unwrap(ns)))])));
34
34
 
@@ -36,7 +36,7 @@ const markdown: BlockquoteParser.MarkdownParser = lazy(() => fmap(
36
36
  some(recursion(Recursion.blockquote, union([
37
37
  rewrite(
38
38
  indent,
39
- convert(unindent, markdown, false, true)),
39
+ convert(unindent, markdown, true)),
40
40
  rewrite(
41
41
  some(contentline, opener),
42
42
  convert(unindent, ({ context }) => {
@@ -51,6 +51,6 @@ const markdown: BlockquoteParser.MarkdownParser = lazy(() => fmap(
51
51
  }, context);
52
52
  context.position = source.length;
53
53
  return new List([new Data(html('section', [document, html('h2', 'References'), references]))]);
54
- }, false, true)),
54
+ }, true)),
55
55
  ]))),
56
56
  ns => new List([new Data(html('blockquote', unwrap(ns)))])));
@@ -28,7 +28,7 @@ export const segment: FigParser.SegmentParser = block(
28
28
  export const fig: FigParser = block(rewrite(segment, verify(convert(
29
29
  (source, context) => {
30
30
  // Bug: TypeScript
31
- const fence = (/^[^\n]*\n!?>+ /.test(source) && source.match(/^~{3,}(?=[^\S\n]*$)/mg) as string[] || [])
31
+ const fence = (/^[^\n]*\n!?>+ /.test(source) && source.match(/^~{3,}(?=[^\S\n]*$)/gm) as string[] || [])
32
32
  .reduce((max, fence) => fence > max ? fence : max, '~~') + '~';
33
33
  const { position } = context;
34
34
  const result = parser({ context });
@@ -37,8 +37,7 @@ export const fig: FigParser = block(rewrite(segment, verify(convert(
37
37
  ? `${fence}figure ${source.replace(/^(.+\n.+\n)([\S\s]+?)\n?$/, '$1\n$2')}\n${fence}`
38
38
  : `${fence}figure ${source}\n\n${fence}`;
39
39
  },
40
- union([figure]),
41
- false),
40
+ union([figure])),
42
41
  ([{ value: el }]) => el.tagName === 'FIGURE')));
43
42
 
44
43
  const parser = sequence([
@@ -67,7 +67,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
67
67
  emptyline,
68
68
  block(visualize(trimBlank(some(inline)))),
69
69
  ]),
70
- ]), false),
70
+ ])),
71
71
  nodes => {
72
72
  const [label, param, content, ...caption] = unwrap(nodes) as [HTMLAnchorElement, string, ...HTMLElement[]];
73
73
  return new List([
@@ -133,8 +133,8 @@ const dataline: CellParser.DatalineParser = line(
133
133
  rewrite(
134
134
  contentline,
135
135
  union([
136
- validate(/!+ /y, convert(source => `:${source}`, data, false)),
137
- convert(source => `: ${source}`, data, false),
136
+ validate(/!+ /y, convert(source => `:${source}`, data)),
137
+ convert(source => `: ${source}`, data),
138
138
  ])));
139
139
 
140
140
  function attributes(source: string): Record<string, string | undefined> {
@@ -12,15 +12,15 @@ export const segment: HeadingParser.SegmentParser = block(focus(
12
12
  /#+ +\S[^\n]*(?:\n#+(?=$|[ \n])[^\n]*)*(?:$|\n)/y,
13
13
  input => {
14
14
  const { context } = input;
15
- const { source } = context;
15
+ const { source, range = 0 } = context;
16
16
  const acc = new List<Data<string>>();
17
- for (; context.position < source.length;) {
17
+ for (const len = context.position + range; context.position < len;) {
18
18
  const line = firstline(source, context.position);
19
19
  acc.push(new Data(line));
20
20
  context.position += line.length;
21
21
  }
22
22
  return acc;
23
- }));
23
+ }, false));
24
24
 
25
25
  export const heading: HeadingParser = block(rewrite(segment,
26
26
  // その他の表示制御は各所のCSSで行う。
@@ -23,7 +23,7 @@ describe('Unit: parser/block/paragraph', () => {
23
23
  assert.deepStrictEqual(inspect(parser('a\\\n'), ctx), [['<p>a</p>'], '']);
24
24
  assert.deepStrictEqual(inspect(parser('a\\\nb'), ctx), [['<p>a<br>b</p>'], '']);
25
25
  assert.deepStrictEqual(inspect(parser('a&NewLine;b'), ctx), [['<p>a b</p>'], '']);
26
- assert.deepStrictEqual(inspect(parser('&Tab;&NewLine;'), ctx), [['<p>&amp;NewLine;</p>'], '']);
26
+ assert.deepStrictEqual(inspect(parser('&Tab;&NewLine;'), ctx), [['<p>&amp;Tab;</p>'], '']);
27
27
  assert.deepStrictEqual(inspect(parser('<wbr>'), ctx), [['<p>&lt;wbr&gt;</p>'], '']);
28
28
  assert.deepStrictEqual(inspect(parser('<wbr>\n'), ctx), [['<p>&lt;wbr&gt;</p>'], '']);
29
29
  assert.deepStrictEqual(inspect(parser('<wbr>\na'), ctx), [['<p>&lt;wbr&gt;<br>a</p>'], '']);
@@ -13,15 +13,13 @@ export const quote: ReplyParser.QuoteParser = lazy(() => block(fmap(
13
13
  rewrite(
14
14
  some(validate(syntax, anyline)),
15
15
  convert(
16
- // TODO: インデント数を渡してインデント数前の行頭確認を行う実装に置き換える
17
- source => source.replace(/(?<=^>+ )/mg, '\r'),
16
+ source => source.replace(/(?<=^>+ )/gm, '\r'),
18
17
  some(union([
19
18
  // quote補助関数が残した数式をパースする。
20
19
  math,
21
20
  autolink,
22
21
  unescsource,
23
- ])),
24
- false)),
22
+ ])))),
25
23
  (ns, { source, position }) => new List([
26
24
  new Data(source[position - 1] === '\n' ? ns.pop()!.value as HTMLBRElement : html('br')),
27
25
  new Data(html('span', { class: 'quote' }, defrag(unwrap(ns)))),
@@ -24,9 +24,9 @@ const source: SidefenceParser.SourceParser = lazy(() => fmap(
24
24
  some(recursion(Recursion.block, union([
25
25
  focus(
26
26
  /(?:\|\|+(?=$|[ \n])[^\n]*(?:$|\n))+/y,
27
- convert(unindent, source, false, true)),
27
+ convert(unindent, source, true)),
28
28
  rewrite(
29
29
  some(contentline, opener),
30
- convert(unindent, fmap(autolink, ns => new List([new Data(html('pre', defrag(unwrap(ns))))])), false, true)),
30
+ convert(unindent, fmap(autolink, ns => new List([new Data(html('pre', defrag(unwrap(ns))))])), true)),
31
31
  ]))),
32
32
  ns => new List([new Data(html('blockquote', unwrap(ns)))])));
@@ -40,10 +40,10 @@ const row = <P extends CellParser | AlignParser>(parser: P, optional: boolean):
40
40
  const align: AlignParser = fmap(open(
41
41
  '|',
42
42
  union([
43
- focus(/:-+:?/y, ({ context: { source } }) =>
44
- new List([new Data(source.at(-1) === ':' ? 'center' : 'start')])),
45
- focus(/-+:?/y, ({ context: { source } }) =>
46
- new List([new Data(source.at(-1) === ':' ? 'end' : '')])),
43
+ focus(/:-+:?/y, ({ context: { source, position, range = 0 } }) =>
44
+ new List([new Data(source[position + range - 1] === ':' ? 'center' : 'start')]), false),
45
+ focus(/-+:?/y, ({ context: { source, position, range = 0 } }) =>
46
+ new List([new Data(source[position + range - 1] === ':' ? 'end' : '')]), false),
47
47
  ])),
48
48
  ns => new List([new Data(html('td', defrag(unwrap(ns))))]));
49
49
 
@@ -31,9 +31,9 @@ export const ulist_: UListParser = lazy(() => block(fmap(validate(
31
31
 
32
32
  export const checkbox = focus(
33
33
  /\[[xX ]\](?=$|[ \n])/y,
34
- ({ context: { source } }) => new List([
35
- new Data(html('span', { class: 'checkbox' }, source[1].trimStart() ? '☑' : '☐')),
36
- ]));
34
+ ({ context: { source, position } }) => new List([
35
+ new Data(html('span', { class: 'checkbox' }, source[position + 1].trimStart() ? '☑' : '☐')),
36
+ ]), false);
37
37
 
38
38
  export function fillFirstLine(nodes: List<Data<string | HTMLElement>>): List<Data<string | HTMLElement>> {
39
39
  const node = nodes.head?.value;
@@ -14,7 +14,7 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
14
14
  validate(({ context }) => context.header ?? true,
15
15
  focus(/(---+) *\r?\n(?:[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*:[ \t]+\S[^\r\n]*\r?\n){1,100}\1 *(?:$|\r?\n)/y,
16
16
  convert(source =>
17
- normalize(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))).replace(/(\S)\s+$/mg, '$1'),
17
+ normalize(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))),
18
18
  fmap(
19
19
  some(union([field])),
20
20
  ns => new List([
@@ -23,7 +23,7 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
23
23
  { open: '' },
24
24
  defrag(unwrap(ns.unshift(new Data(html('summary', 'Header'))) && ns))),
25
25
  ])),
26
- ])), false))),
26
+ ]))))),
27
27
  ({ context }) => {
28
28
  const { source, position } = context;
29
29
  context.position += source.length;
@@ -1,7 +1,7 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Backtrack } from '../../context';
3
3
  import { List, Data } from '../../../combinator/data/parser';
4
- import { some, state, constraint, verify, surround, lazy } from '../../../combinator';
4
+ import { some, state, constraint, verify, surround, setBacktrack, lazy } from '../../../combinator';
5
5
  import { parse } from '../link';
6
6
  import { emoji } from './hashtag';
7
7
  import { str } from '../../source';
@@ -45,7 +45,10 @@ export const account: AutolinkParser.AccountParser = lazy(() => constraint(State
45
45
  ]);
46
46
  },
47
47
  ([[{ value: host }, { value: account }]], context) => {
48
- if (context.source[context.position] === '#') return;
48
+ if (context.source[context.position] === '#') {
49
+ assert(context.source[context.position - context.range!] === '@');
50
+ return void setBacktrack(context, [2 | Backtrack.autolink], context.position - context.range!);
51
+ }
49
52
  return new List([
50
53
  new Data(define(
51
54
  parse(
@@ -27,19 +27,19 @@ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => focus(
27
27
  str('!'),
28
28
  union([
29
29
  constraint(State.autolink, state(State.autolink, ({ context }) => {
30
- const { source, position } = context;
31
- context.position -= source[0] === '!' ? 1 : 0;
32
- context.position += source.length;
30
+ const { source, position, range = 0 } = context;
31
+ context.position -= position > 0 && source[position - 1] === '!' ? 1 : 0;
32
+ context.position += range;
33
33
  return new List([
34
34
  new Data(parse(
35
35
  new List(),
36
- new List([new Data(source.slice(position))]),
36
+ new List([new Data(source.slice(position, context.position))]),
37
37
  context))
38
38
  ]);
39
39
  })),
40
- open(str(/[^:]+/y), some(inline)),
40
+ str(/[^:]+/y),
41
41
  ]),
42
- ])));
42
+ ]), false));
43
43
 
44
44
  const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => union([
45
45
  surround(str('('), recursion(Recursion.terminal, some(union([bracket, unescsource]), ')')), str(')'),
@@ -8,12 +8,10 @@ export const shortmedia: ShortMediaParser = constraint(State.media, rewrite(
8
8
  open('!', url),
9
9
  convert(
10
10
  source => `!{ ${source.slice(1)} }`,
11
- union([media]),
12
- false)));
11
+ union([media]))));
13
12
 
14
- export const lineshortmedia: ShortMediaParser.LineShortMediaParser = focus(
13
+ export const lineshortmedia: ShortMediaParser.LineShortMediaParser = constraint(State.media, focus(
15
14
  /(?<=^|[\r\n])!https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/y,
16
15
  convert(
17
16
  source => `!{ ${source.slice(1)} }`,
18
- union([media]),
19
- false));
17
+ union([media]))));
@@ -5,41 +5,23 @@ import { convert, fmap } from '../combinator';
5
5
  import { unsafehtmlentity } from './inline/htmlentity';
6
6
  import { invisibleHTMLEntityNames } from './api/normalize';
7
7
 
8
- export namespace blank {
8
+ namespace blank {
9
9
  export const line = new RegExp(
10
- // TODO: 行全体をエスケープ
11
- /^(\\?[^\S\r\n]|&IHN;|<wbr ?>|\\$)+$/mg.source
10
+ /((?:^|\n)[^\S\n]*(?=\S))((?:[^\S\n]|\\(?=$|\s)|&IHN;|<wbr ?>)+(?=$|\n))/g.source
12
11
  .replace('IHN', `(?:${invisibleHTMLEntityNames.join('|')})`),
13
- 'gm');
12
+ 'g');
14
13
  export const start = new RegExp(
15
- /(?:\\?[^\S\r\n]|&IHN;|<wbr ?>)+/y.source
16
- .replace('IHN', `(?:${invisibleHTMLEntityNames.join('|')})`), 'y');
14
+ /(?:[^\S\n]|\\(?=$|\s)|&IHN;|<wbr ?>)+/y.source
15
+ .replace('IHN', `(?:${invisibleHTMLEntityNames.join('|')})`),
16
+ 'y');
17
17
  }
18
18
 
19
19
  export function visualize<P extends Parser<HTMLElement | string>>(parser: P): P;
20
20
  export function visualize<N extends HTMLElement | string>(parser: Parser<N>): Parser<N> {
21
21
  return convert(
22
- source => source.replace(blank.line, `${Command.Escape}$1`),
23
- parser,
24
- false);
22
+ source => source.replace(blank.line, `$1${Command.Escape}$2`),
23
+ parser);
25
24
  }
26
- //function hasVisible(
27
- // nodes: readonly (HTMLElement | string)[],
28
- //): boolean {
29
- // for (let i = 0; i < nodes.length; ++i) {
30
- // const node = nodes[i];
31
- // if (typeof node === 'string') {
32
- // if (node && node.trimStart()) return true;
33
- // }
34
- // else {
35
- // if (node.innerText.trimStart()) return true;
36
- // if (node.classList.contains('reference')) return true;
37
- // //if (state & State.media ^ State.media &&
38
- // // (node.classList.contains('media') || node.getElementsByClassName('media')[0])) return true;
39
- // }
40
- // }
41
- // return false;
42
- //}
43
25
 
44
26
  export function blankWith(delimiter: string | RegExp): RegExp;
45
27
  export function blankWith(starts: '' | '\n', delimiter: string | RegExp): RegExp;