securemark 0.283.3 → 0.283.4

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.283.4
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.283.3
4
8
 
5
9
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.283.3 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.283.4 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"));
@@ -1031,7 +1031,7 @@ const util_1 = __webpack_require__(4992);
1031
1031
  const visibility_1 = __webpack_require__(6364);
1032
1032
  const array_1 = __webpack_require__(6876);
1033
1033
  const dom_1 = __webpack_require__(394);
1034
- exports.dlist = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.validate)(/^~[^\S\n]+(?=\S)/, (0, combinator_1.some)((0, combinator_1.inits)([(0, combinator_1.state)(256 /* State.annotation */ | 128 /* State.reference */ | 64 /* State.index */ | 32 /* State.label */ | 16 /* State.link */ | 8 /* State.media */, (0, combinator_1.some)(term)), (0, combinator_1.some)(desc)]))), es => [(0, dom_1.html)('dl', fillTrailingDescription(es))])));
1034
+ exports.dlist = (0, combinator_1.lazy)(() => (0, combinator_1.block)((0, combinator_1.fmap)((0, combinator_1.validate)(/^~[^\S\n]+(?=\S)/, (0, combinator_1.some)((0, combinator_1.inits)([(0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 32 /* State.index */ | 16 /* State.label */ | 8 /* State.link */ | 4 /* State.media */, (0, combinator_1.some)(term)), (0, combinator_1.some)(desc)]))), es => [(0, dom_1.html)('dl', fillTrailingDescription(es))])));
1035
1035
  const term = (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.open)(/^~[^\S\n]+(?=\S)/, (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline])))), true), ns => [(0, dom_1.html)('dt', {
1036
1036
  'data-index': (0, inline_1.dataindex)(ns)
1037
1037
  }, (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns)))])));
@@ -1965,9 +1965,13 @@ const combinator_1 = __webpack_require__(3484);
1965
1965
  const link_1 = __webpack_require__(3628);
1966
1966
  const source_1 = __webpack_require__(8745);
1967
1967
  const closer = /^[-+*=~^_,.;:!?]*(?=[\\"`|\[\](){}<>]|$)/;
1968
- exports.url = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['http://', 'https://'], (0, combinator_1.rewrite)((0, combinator_1.open)(/^https?:\/\/(?=[\x21-\x7E])/, (0, combinator_1.focus)(/^[\x21-\x7E]+/, (0, combinator_1.some)((0, combinator_1.union)([bracket, (0, combinator_1.some)(source_1.unescsource, closer)])))), (0, combinator_1.convert)(url => `{ ${url} }`, (0, combinator_1.union)([link_1.unsafelink])))));
1969
- exports.lineurl = (0, combinator_1.lazy)(() => (0, combinator_1.open)(source_1.linebreak, (0, combinator_1.tails)([(0, source_1.str)('!'), (0, combinator_1.focus)(/^https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/, (0, combinator_1.convert)(url => `{ ${url} }`, link_1.unsafelink))])));
1970
- const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.precedence)(1, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')'), (0, source_1.str)(')'), true, undefined, undefined, 3 | 8 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ']'), (0, source_1.str)(']'), true, undefined, undefined, 3 | 8 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), '}'), (0, source_1.str)('}'), true, undefined, undefined, 3 | 8 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.some)(source_1.unescsource, '"')), (0, source_1.str)('"'), true, undefined, undefined, 3 | 8 /* Backtrack.url */)]))));
1968
+ exports.url = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['http://', 'https://'], (0, combinator_1.rewrite)((0, combinator_1.open)(/^https?:\/\/(?=[\x21-\x7E])/, (0, combinator_1.focus)(/^[\x21-\x7E]+/, (0, combinator_1.some)((0, combinator_1.union)([bracket, (0, combinator_1.some)(source_1.unescsource, closer)])))), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.syntax)(0, 1 /* State.autolink */, (0, combinator_1.convert)(url => `{ ${url} }`, link_1.unsafelink))), ({
1969
+ source
1970
+ }) => [[source], '']]))));
1971
+ exports.lineurl = (0, combinator_1.lazy)(() => (0, combinator_1.open)(source_1.linebreak, (0, combinator_1.focus)(/^!?https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/, (0, combinator_1.tails)([(0, source_1.str)('!'), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.syntax)(0, 1 /* State.autolink */, (0, combinator_1.convert)(url => `{ ${url} }`, link_1.unsafelink))), ({
1972
+ source
1973
+ }) => [[source], '']])]))));
1974
+ const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(0, 6 /* Recursion.terminal */, (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ')')), (0, source_1.str)(')'), true, undefined, undefined, 3 | 8 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), ']')), (0, source_1.str)(']'), true, undefined, undefined, 3 | 8 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.precedence)(1, (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.unescsource]), '}')), (0, source_1.str)('}'), true, undefined, undefined, 3 | 8 /* Backtrack.url */), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(2, (0, combinator_1.some)(source_1.unescsource, '"')), (0, source_1.str)('"'), true, undefined, undefined, 3 | 8 /* Backtrack.url */)])));
1971
1975
 
1972
1976
  /***/ },
1973
1977
 
@@ -2041,7 +2045,7 @@ const source_1 = __webpack_require__(8745);
2041
2045
  const dom_1 = __webpack_require__(394);
2042
2046
  const body = (0, source_1.str)(/^\$[A-Za-z]*(?:(?:-[A-Za-z][0-9A-Za-z]*)+|-(?:(?:0|[1-9][0-9]*)\.)*(?:0|[1-9][0-9]*)(?![0-9A-Za-z]))/);
2043
2047
  exports.segment = (0, combinator_1.clear)((0, combinator_1.validate)(['[$', '$'], (0, combinator_1.union)([(0, combinator_1.surround)('[', body, ']'), body])));
2044
- exports.label = (0, combinator_1.validate)(['[$', '$'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, combinator_1.constraint)(32 /* State.label */, false, (0, combinator_1.union)([(0, combinator_1.surround)('[', body, ']'), body])), ([text]) => [(0, dom_1.html)('a', {
2048
+ exports.label = (0, combinator_1.validate)(['[$', '$'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, combinator_1.constraint)(16 /* State.label */, false, (0, combinator_1.union)([(0, combinator_1.surround)('[', body, ']'), body])), ([text]) => [(0, dom_1.html)('a', {
2045
2049
  class: 'label',
2046
2050
  'data-label': text.slice(text[1] === '-' ? 0 : 1).toLowerCase()
2047
2051
  }, text)])));
@@ -2329,7 +2333,7 @@ exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('#', (0, co
2329
2333
  }) => [[source], ''])))));
2330
2334
  exports.heading = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment,
2331
2335
  // その他の表示制御は各所のCSSで行う。
2332
- (0, combinator_1.state)(256 /* State.annotation */ | 128 /* State.reference */ | 64 /* State.index */ | 32 /* State.label */ | 16 /* State.link */ | 8 /* State.media */, (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.union)([(0, combinator_1.open)((0, source_1.str)(/^##+/), (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((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)(502 /* State.linkers */, (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))), true)]), ([h, ...ns]) => [h.length <= 6 ? (0, dom_1.html)(`h${h.length}`, {
2336
+ (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 32 /* State.index */ | 16 /* State.label */ | 8 /* State.link */ | 4 /* State.media */, (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.union)([(0, combinator_1.open)((0, source_1.str)(/^##+/), (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((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.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))), true)]), ([h, ...ns]) => [h.length <= 6 ? (0, dom_1.html)(`h${h.length}`, {
2333
2337
  'data-index': (0, inline_1.dataindex)(ns)
2334
2338
  }, (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns))) : (0, dom_1.html)(`h6`, {
2335
2339
  class: 'invalid',
@@ -3233,12 +3237,12 @@ const optspec = {
3233
3237
  rel: ['nofollow']
3234
3238
  };
3235
3239
  Object.setPrototypeOf(optspec, null);
3236
- exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['[', '{'], (0, combinator_1.union)([exports.medialink, exports.textlink])));
3237
- exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.constraint)(16 /* State.link */, false, (0, combinator_1.syntax)(1, 502 /* State.linkers */ | 8 /* State.media */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[/^\\?\n/, 9], [']', 1]])), ']', true, undefined, undefined, 1 | 4 /* Backtrack.bracket */)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/, false, undefined, undefined, 3 | 16 /* Backtrack.link */))])), ([params, content = []], rest, context) => {
3240
+ exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.union)([exports.medialink, exports.textlink]));
3241
+ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['[', '{'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.constraint)(8 /* State.link */, false, (0, combinator_1.syntax)(1, 251 /* State.linkers */ | 4 /* State.media */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[/^\\?\n/, 9], [']', 1]])), ']', true, undefined, undefined, 1 | 4 /* Backtrack.bracket */)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/, false, undefined, undefined, 3 | 16 /* Backtrack.link */))])), ([params, content = []], rest, context) => {
3238
3242
  if (content.length !== 0 && (0, visibility_1.trimNodeEnd)(content = (0, dom_1.defrag)(content)).length === 0) return;
3239
3243
  return [[parse(content, params, context)], rest];
3240
- })))));
3241
- exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.constraint)(16 /* State.link */ | 8 /* State.media */, false, (0, combinator_1.syntax)(1, 502 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => [[parse((0, dom_1.defrag)(content), params, context)], rest])))));
3244
+ }))))));
3245
+ exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['[', '{'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.constraint)(8 /* State.link */ | 4 /* State.media */, false, (0, combinator_1.syntax)(1, 251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => [[parse((0, dom_1.defrag)(content), params, context)], rest]))))));
3242
3246
  exports.linemedialink = (0, combinator_1.surround)(source_1.linebreak, (0, combinator_1.union)([exports.medialink]), /^(?=[^\S\n]*(?:$|\n))/);
3243
3247
  exports.unsafelink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.precedence)(1, (0, combinator_1.bind)((0, combinator_1.reverse)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([source_1.unescsource]), ']'), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), /^[^\S\n]*}/))])), ([params, content = []], rest, context) => [[parse((0, dom_1.defrag)(content), params, context)], rest]))));
3244
3248
  exports.uri = (0, combinator_1.union)([(0, combinator_1.open)(/^[^\S\n]+/, (0, source_1.str)(/^\S+/)), (0, source_1.str)(/^[^\s{}]+/)]);
@@ -4286,7 +4290,7 @@ const combinator_1 = __webpack_require__(3484);
4286
4290
  const inline_1 = __webpack_require__(7973);
4287
4291
  const visibility_1 = __webpack_require__(6364);
4288
4292
  const dom_1 = __webpack_require__(394);
4289
- exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('((', (0, combinator_1.constraint)(256 /* State.annotation */, false, (0, combinator_1.syntax)(1, 256 /* State.annotation */ | 8 /* State.media */, (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ')', [[/^\\?\n/, 9], [')', 1]])))), '))', false, ([, ns], rest) => [[(0, dom_1.html)('sup', {
4293
+ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('((', (0, combinator_1.constraint)(128 /* State.annotation */, false, (0, combinator_1.syntax)(1, 128 /* State.annotation */ | 4 /* State.media */, (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ')', [[/^\\?\n/, 9], [')', 1]])))), '))', false, ([, ns], rest) => [[(0, dom_1.html)('sup', {
4290
4294
  class: 'annotation'
4291
4295
  }, [(0, dom_1.html)('span', (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns)))])], rest], undefined, 1 | 4 /* Backtrack.bracket */)));
4292
4296
 
@@ -4330,9 +4334,11 @@ const link_1 = __webpack_require__(3628);
4330
4334
  const source_1 = __webpack_require__(8745);
4331
4335
  const dom_1 = __webpack_require__(394);
4332
4336
  // https://example/@user must be a user page or a redirect page going there.
4333
- exports.account = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.open)('@', (0, combinator_1.tails)([(0, source_1.str)(/^[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*\//i), (0, source_1.str)(/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*/i)]))), (0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `https://${source.slice(1).replace('/', '/@')}` : `/${source}`} }`, (0, combinator_1.union)([link_1.unsafelink]))), ([el]) => [(0, dom_1.define)(el, {
4337
+ exports.account = (0, combinator_1.lazy)(() => (0, combinator_1.rewrite)((0, combinator_1.open)('@', (0, combinator_1.tails)([(0, source_1.str)(/^[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*\//i), (0, source_1.str)(/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*/i)])), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.syntax)(0, 1 /* State.autolink */, (0, combinator_1.fmap)((0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `https://${source.slice(1).replace('/', '/@')}` : `/${source}`} }`, link_1.unsafelink), ([el]) => [(0, dom_1.define)(el, {
4334
4338
  class: 'account'
4335
- })]));
4339
+ })]))), ({
4340
+ source
4341
+ }) => [[source], '']])));
4336
4342
 
4337
4343
  /***/ },
4338
4344
 
@@ -5057,15 +5063,16 @@ const hashtag_1 = __webpack_require__(5764);
5057
5063
  const util_1 = __webpack_require__(4992);
5058
5064
  const dom_1 = __webpack_require__(394);
5059
5065
  // https://example/@user?ch=a+b must be a user channel page or a redirect page going there.
5060
- exports.channel = (0, combinator_1.validate)('@', (0, combinator_1.bind)((0, combinator_1.sequence)([account_1.account, (0, combinator_1.some)(hashtag_1.hashtag)]), (es, rest) => {
5066
+ exports.channel = (0, combinator_1.validate)('@', (0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.bind)((0, combinator_1.sequence)([account_1.account, (0, combinator_1.some)(hashtag_1.hashtag)]), (es, rest) => {
5061
5067
  const source = (0, util_1.stringify)(es);
5062
5068
  const el = es[0];
5069
+ if (typeof el === 'string') return [es, rest];
5063
5070
  const url = `${el.getAttribute('href')}?ch=${source.slice(source.indexOf('#') + 1).replace(/#/g, '+')}`;
5064
5071
  return [[(0, dom_1.define)(el, {
5065
5072
  class: 'channel',
5066
5073
  href: url
5067
5074
  }, source)], rest];
5068
- }));
5075
+ })));
5069
5076
 
5070
5077
  /***/ },
5071
5078
 
@@ -5085,7 +5092,7 @@ const indexee_1 = __webpack_require__(7610);
5085
5092
  const source_1 = __webpack_require__(8745);
5086
5093
  const visibility_1 = __webpack_require__(6364);
5087
5094
  const dom_1 = __webpack_require__(394);
5088
- exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[#', (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, indexee_1.indexee)((0, combinator_1.surround)('[#', (0, combinator_1.constraint)(64 /* State.index */, false, (0, combinator_1.syntax)(1, 502 /* State.linkers */ | 8 /* State.media */, (0, visibility_1.startTight)((0, combinator_1.some)((0, combinator_1.inits)([inline_1.inline, exports.signature]), ']', [[/^\\?\n/, 9], [']', 1]])))), ']', false, ([, ns], rest) => [[(0, dom_1.html)('a', {
5095
+ exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[#', (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, indexee_1.indexee)((0, combinator_1.surround)('[#', (0, combinator_1.constraint)(32 /* State.index */, false, (0, combinator_1.syntax)(1, 251 /* State.linkers */ | 4 /* State.media */, (0, visibility_1.startTight)((0, combinator_1.some)((0, combinator_1.inits)([inline_1.inline, exports.signature]), ']', [[/^\\?\n/, 9], [']', 1]])))), ']', false, ([, ns], rest) => [[(0, dom_1.html)('a', {
5089
5096
  'data-index': dataindex(ns)
5090
5097
  }, (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns)))], rest], undefined, 1 | 4 /* Backtrack.bracket */)), ([el]) => [(0, dom_1.define)(el, {
5091
5098
  id: el.id ? null : undefined,
@@ -5354,7 +5361,7 @@ const source_1 = __webpack_require__(8745);
5354
5361
  const visibility_1 = __webpack_require__(6364);
5355
5362
  const array_1 = __webpack_require__(6876);
5356
5363
  const dom_1 = __webpack_require__(394);
5357
- exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 4 /* Recursion.inline */, (0, combinator_1.surround)((0, source_1.str)('==', '='), (0, combinator_1.constraint)(4 /* State.mark */, false, (0, combinator_1.syntax)(0, 0 /* State.none */, (0, visibility_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, visibility_1.blankWith)('==')), (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '='), exports.mark)]))))), (0, source_1.str)('=='), false, ([, bs], rest, {
5364
+ exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 4 /* Recursion.inline */, (0, combinator_1.surround)((0, source_1.str)('==', '='), (0, combinator_1.constraint)(2 /* State.mark */, false, (0, combinator_1.syntax)(0, 0 /* State.none */, (0, visibility_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, visibility_1.blankWith)('==')), (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '='), exports.mark)]))))), (0, source_1.str)('=='), false, ([, bs], rest, {
5358
5365
  id
5359
5366
  }) => {
5360
5367
  const el = (0, dom_1.html)('mark', (0, dom_1.defrag)(bs));
@@ -5477,7 +5484,7 @@ class Delimiters {
5477
5484
  constructor() {
5478
5485
  this.registry = (0, memoize_1.memoize)(() => []);
5479
5486
  this.delimiters = [];
5480
- this.order = [];
5487
+ this.stack = [];
5481
5488
  this.states = [];
5482
5489
  }
5483
5490
  static signature(pattern) {
@@ -5494,9 +5501,9 @@ class Delimiters {
5494
5501
  const {
5495
5502
  registry,
5496
5503
  delimiters,
5497
- order
5504
+ stack
5498
5505
  } = this;
5499
- // 構文数x優先順位数以下
5506
+ // シグネチャ数以下
5500
5507
 
5501
5508
  for (let i = 0; i < delims.length; ++i) {
5502
5509
  const {
@@ -5504,9 +5511,9 @@ class Delimiters {
5504
5511
  matcher,
5505
5512
  precedence
5506
5513
  } = delims[i];
5507
- const stack = registry(signature);
5508
- const index = stack[0]?.index ?? delimiters.length;
5509
- if (stack.length === 0 || precedence > delimiters[index].precedence) {
5514
+ const memory = registry(signature);
5515
+ const index = memory[0]?.index ?? delimiters.length;
5516
+ if (memory.length === 0 || precedence > delimiters[index].precedence) {
5510
5517
  const delimiter = {
5511
5518
  index,
5512
5519
  signature,
@@ -5515,10 +5522,10 @@ class Delimiters {
5515
5522
  state: true
5516
5523
  };
5517
5524
  delimiters[index] = delimiter;
5518
- stack.push(delimiter);
5519
- order.push(index);
5525
+ memory.push(delimiter);
5526
+ stack.push(index);
5520
5527
  } else {
5521
- order.push(-1);
5528
+ stack.push(-1);
5522
5529
  }
5523
5530
  // 現状各優先順位は固定
5524
5531
  }
@@ -5527,18 +5534,18 @@ class Delimiters {
5527
5534
  const {
5528
5535
  registry,
5529
5536
  delimiters,
5530
- order
5537
+ stack
5531
5538
  } = this;
5532
5539
  for (let i = 0; i < count; ++i) {
5533
- const index = order.pop();
5540
+ const index = stack.pop();
5534
5541
  if (index === -1) continue;
5535
- const stack = registry(delimiters[index].signature);
5536
- if (stack.length === 1) {
5537
- stack.pop();
5542
+ const memory = registry(delimiters[index].signature);
5543
+ if (memory.length === 1) {
5544
+ memory.pop();
5538
5545
  delimiters.pop();
5539
5546
  } else {
5540
- stack.pop();
5541
- delimiters[index] = stack.at(-1);
5547
+ memory.pop();
5548
+ delimiters[index] = memory.at(-1);
5542
5549
  }
5543
5550
  }
5544
5551
  }
@@ -5713,14 +5720,15 @@ function precedence(precedence, parser) {
5713
5720
  delimiters,
5714
5721
  precedence: p = 0
5715
5722
  } = context;
5716
- const shift = precedence > p;
5723
+ const shift = delimiters && precedence > p;
5717
5724
  context.precedence = precedence;
5718
- shift && delimiters?.shift(precedence);
5725
+ // デリミタはシフト後に設定しなければならない
5726
+ shift && delimiters.shift(precedence);
5719
5727
  const result = parser({
5720
5728
  source,
5721
5729
  context
5722
5730
  });
5723
- shift && delimiters?.unshift();
5731
+ shift && delimiters.unshift();
5724
5732
  context.precedence = p;
5725
5733
  return result;
5726
5734
  };
@@ -5806,9 +5814,11 @@ const dom_1 = __webpack_require__(394);
5806
5814
  // https://example/hashtags/a must be a hashtag page or a redirect page going there.
5807
5815
  // https://github.com/tc39/proposal-regexp-unicode-property-escapes#matching-emoji
5808
5816
  exports.emoji = String.raw`\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F`;
5809
- exports.hashtag = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.open)('#', (0, source_1.str)(new RegExp([/^(?!['_])(?=(?:[0-9]{1,9})?(?:[^\d\p{C}\p{S}\p{P}\s]|emoji|'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|')))/u.source, /(?:[^\p{C}\p{S}\p{P}\s]|emoji|'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|'))+/u.source].join('').replace(/emoji/g, exports.emoji), 'u')))), (0, combinator_1.convert)(source => `[${source}]{ ${`/hashtags/${source.slice(1)}`} }`, (0, combinator_1.union)([link_1.unsafelink]))), ([el]) => [(0, dom_1.define)(el, {
5817
+ exports.hashtag = (0, combinator_1.lazy)(() => (0, combinator_1.rewrite)((0, combinator_1.open)('#', (0, source_1.str)(new RegExp([/^(?!['_])(?=(?:[0-9]{1,9})?(?:[^\d\p{C}\p{S}\p{P}\s]|emoji|'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|')))/u.source, /(?:[^\p{C}\p{S}\p{P}\s]|emoji|'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|'))+/u.source].join('').replace(/emoji/g, exports.emoji), 'u'))), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.syntax)(0, 1 /* State.autolink */, (0, combinator_1.fmap)((0, combinator_1.convert)(source => `[${source}]{ ${`/hashtags/${source.slice(1)}`} }`, link_1.unsafelink), ([el]) => [(0, dom_1.define)(el, {
5810
5818
  class: 'hashtag'
5811
- })]));
5819
+ })]))), ({
5820
+ source
5821
+ }) => [[source], '']])));
5812
5822
 
5813
5823
  /***/ },
5814
5824
 
@@ -5856,9 +5866,9 @@ function surround(opener, parser, closer, optional = false, f, g, log = 0) {
5856
5866
  } = context;
5857
5867
  for (let i = 0; i < source.length - mr_.length; ++i) {
5858
5868
  if (source[i] !== source[0]) break;
5859
- const j = source.length + offset - i;
5860
- if (!(j in logger)) continue;
5861
- if (logger[j] & 1 << (log >>> 2)) return;
5869
+ const pos = source.length + offset - i - 1;
5870
+ if (!(pos in logger)) continue;
5871
+ if (logger[pos] & 1 << (log >>> 2)) return;
5862
5872
  }
5863
5873
  }
5864
5874
  const res2 = mr_ !== '' ? parser({
@@ -5880,7 +5890,7 @@ function surround(opener, parser, closer, optional = false, f, g, log = 0) {
5880
5890
  logger = {},
5881
5891
  offset = 0
5882
5892
  } = context;
5883
- logger[source.length + offset] |= 1 << (log >>> 2);
5893
+ logger[source.length + offset - 1] |= 1 << (log >>> 2);
5884
5894
  }
5885
5895
  return rr ? f ? f([rl, rm, rr], rest, context) : [(0, array_1.push)((0, array_1.unshift)(rl, rm ?? []), rr), rest] : g ? g([rl, rm, mr_], rest, context) : undefined;
5886
5896
  };
@@ -5930,12 +5940,12 @@ const combinator_1 = __webpack_require__(3484);
5930
5940
  const source_1 = __webpack_require__(8745);
5931
5941
  const dom_1 = __webpack_require__(394);
5932
5942
  // https://html.spec.whatwg.org/multipage/input.html
5933
- exports.email = (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.rewrite)((0, combinator_1.verify)((0, source_1.str)(/^[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z]){0,255}@[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*(?![0-9a-z])/i), ([source]) => source.length <= 255), ({
5943
+ exports.email = (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.rewrite)((0, combinator_1.verify)((0, source_1.str)(/^[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z]){0,255}@[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*(?![0-9a-z])/i), ([source]) => source.length <= 255), (0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.syntax)(0, 1 /* State.autolink */, ({
5934
5944
  source
5935
5945
  }) => [[(0, dom_1.html)('a', {
5936
5946
  class: 'email',
5937
5947
  href: `mailto:${source}`
5938
- }, source)], '']));
5948
+ }, source)], '']))));
5939
5949
 
5940
5950
  /***/ },
5941
5951
 
@@ -6053,7 +6063,7 @@ const combinator_1 = __webpack_require__(3484);
6053
6063
  const url_1 = __webpack_require__(2129);
6054
6064
  const media_1 = __webpack_require__(7478);
6055
6065
  const source_1 = __webpack_require__(8745);
6056
- exports.shortmedia = (0, combinator_1.rewrite)((0, combinator_1.constraint)(8 /* State.media */, false, (0, combinator_1.open)('!', url_1.url)), (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media])));
6066
+ exports.shortmedia = (0, combinator_1.rewrite)((0, combinator_1.constraint)(4 /* State.media */, false, (0, combinator_1.open)('!', url_1.url)), (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media])));
6057
6067
  exports.lineshortmedia = (0, combinator_1.open)(source_1.linebreak, (0, combinator_1.focus)(/^!https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/, (0, combinator_1.convert)(source => `!{ ${source.slice(1)} }`, (0, combinator_1.union)([media_1.media]))));
6058
6068
 
6059
6069
  /***/ },
@@ -7016,7 +7026,7 @@ const source_1 = __webpack_require__(8745);
7016
7026
  const visibility_1 = __webpack_require__(6364);
7017
7027
  const array_1 = __webpack_require__(6876);
7018
7028
  const dom_1 = __webpack_require__(394);
7019
- exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[', (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.syntax)(1, -1 /* State.all */, (0, combinator_1.fmap)((0, combinator_1.sequence)([(0, combinator_1.bind)((0, combinator_1.surround)('[', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']', false, undefined, undefined, 3 | 20 /* Backtrack.ruby */), ([source], rest, context) => {
7029
+ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[', (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.fmap)((0, combinator_1.syntax)(1, -1 /* State.all */, (0, combinator_1.sequence)([(0, combinator_1.bind)((0, combinator_1.surround)('[', (0, source_1.str)(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']', false, undefined, undefined, 3 | 20 /* Backtrack.ruby */), ([source], rest, context) => {
7020
7030
  const ns = (0, parser_1.eval)(text({
7021
7031
  source,
7022
7032
  context
@@ -7029,7 +7039,7 @@ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[', (0,
7029
7039
  context
7030
7040
  }), [undefined])[0];
7031
7041
  return ns && [[ns], rest];
7032
- })]), ([texts, rubies]) => {
7042
+ })])), ([texts, rubies]) => {
7033
7043
  switch (true) {
7034
7044
  case rubies.length <= texts.length:
7035
7045
  return [(0, dom_1.html)('ruby', attributes(texts, rubies), (0, dom_1.defrag)(texts.reduce((acc, _, i) => (0, array_1.push)(acc, (0, array_1.unshift)([texts[i]], i < rubies.length && rubies[i] ? [(0, dom_1.html)('rp', '('), (0, dom_1.html)('rt', rubies[i]), (0, dom_1.html)('rp', ')')] : [(0, dom_1.html)('rt')])), [])))];
@@ -7038,7 +7048,7 @@ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[', (0,
7038
7048
  default:
7039
7049
  return [(0, dom_1.html)('ruby', attributes(texts, rubies), (0, dom_1.defrag)((0, array_1.unshift)([texts.join(' ')], [(0, dom_1.html)('rp', '('), (0, dom_1.html)('rt', rubies.join(' ').trim()), (0, dom_1.html)('rp', ')')])))];
7040
7050
  }
7041
- })))));
7051
+ }))));
7042
7052
  const text = (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, ({
7043
7053
  source,
7044
7054
  context
@@ -7176,7 +7186,7 @@ const optspec = {
7176
7186
  rel: undefined
7177
7187
  };
7178
7188
  Object.setPrototypeOf(optspec, null);
7179
- exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['![', '!{'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.open)('!', (0, combinator_1.constraint)(8 /* State.media */, false, (0, combinator_1.syntax)(1, ~16 /* State.link */, (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']', [[/^\\?\n/, 9]]), ']', true, undefined, undefined, 1 | 12 /* Backtrack.media */)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), /^[^\S\n]*}/, false, undefined, undefined, 3 | 16 /* Backtrack.link */))]), ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
7189
+ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['![', '!{'], (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.open)('!', (0, combinator_1.constraint)(4 /* State.media */, false, (0, combinator_1.syntax)(1, ~8 /* State.link */, (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.tails)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, bracket, source_1.txt]), ']', [[/^\\?\n/, 9]]), ']', true, undefined, undefined, 1 | 12 /* Backtrack.media */)), (0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), /^[^\S\n]*}/, false, undefined, undefined, 3 | 16 /* Backtrack.link */))]), ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
7180
7190
  const INSECURE_URI = params.shift();
7181
7191
  const url = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, context.host ?? location, context.url ?? context.host ?? location), context.host?.href || location.href);
7182
7192
  let cache;
@@ -7192,7 +7202,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(['![', '
7192
7202
  if (el.hasAttribute('aspect-ratio')) {
7193
7203
  el.style.aspectRatio = el.getAttribute('aspect-ratio');
7194
7204
  }
7195
- if (context.state & 16 /* State.link */) return [[el], rest];
7205
+ if (context.state & 8 /* State.link */) return [[el], rest];
7196
7206
  if (cache && cache.tagName !== 'IMG') return [[el], rest];
7197
7207
  return (0, combinator_1.fmap)(link_1.unsafelink, ([link]) => [(0, dom_1.define)(link, {
7198
7208
  class: null,
@@ -7974,7 +7984,7 @@ const hashnum_1 = __webpack_require__(8684);
7974
7984
  const anchor_1 = __webpack_require__(8535);
7975
7985
  const source_1 = __webpack_require__(8745);
7976
7986
  const util_1 = __webpack_require__(4992);
7977
- exports.autolink = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/^(?:[@#>0-9a-z]|\S[#>]|[\r\n]!?https?:\/\/)/iu, (0, combinator_1.constraint)(2 /* State.autolink */, false, (0, combinator_1.syntax)(0, ~1 /* State.shortcut */, (0, combinator_1.union)([(0, combinator_1.some)((0, combinator_1.union)([url_1.lineurl])), (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([url_1.url, email_1.email,
7987
+ exports.autolink = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/^(?:[@#>0-9a-z]|\S[#>]|[\r\n]!?https?:\/\/)/iu, (0, combinator_1.syntax)(0, ~1 /* State.autolink */, (0, combinator_1.union)([(0, combinator_1.some)((0, combinator_1.union)([url_1.lineurl])), (0, combinator_1.fmap)((0, combinator_1.some)((0, combinator_1.union)([url_1.url, email_1.email,
7978
7988
  // Escape unmatched email-like strings.
7979
7989
  (0, source_1.str)(/^[0-9a-z]+(?:[_.+-][0-9a-z]+)*(?:@(?:[0-9a-z]+(?:[.-][0-9a-z]+)*)?)*/i), channel_1.channel, account_1.account,
7980
7990
  // Escape unmatched account-like strings.
@@ -7984,7 +7994,7 @@ exports.autolink = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/^(?:
7984
7994
  // Escape unmatched hashtag-like strings.
7985
7995
  (0, source_1.str)(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|['_])*/u.source.replace('emoji', hashtag_1.emoji), 'u')),
7986
7996
  // Escape invalid leading characters.
7987
- (0, source_1.str)(/^[0-9a-z](?=>)/iu), anchor_1.anchor])), ns => ns.length === 1 ? ns : [(0, util_1.stringify)(ns)])])))));
7997
+ (0, source_1.str)(/^[0-9a-z](?=>)/iu), anchor_1.anchor])), ns => ns.length === 1 ? ns : [(0, util_1.stringify)(ns)])]))));
7988
7998
 
7989
7999
  /***/ },
7990
8000
 
@@ -8188,9 +8198,11 @@ const dom_1 = __webpack_require__(394);
8188
8198
  // cid: YYYY-MMDD-HHMM-SSmmm
8189
8199
  // 内部表現はUnixTimeに統一する(時系列順)
8190
8200
  // 外部表現は投稿ごとに投稿者の投稿時のタイムゾーンに統一する(非時系列順)
8191
- exports.anchor = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('>>', (0, combinator_1.fmap)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.focus)(/^>>(?:[a-z][0-9a-z]*(?:-[0-9a-z]+)*\/)?[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9a-z@#:])/i, (0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `/@${source.slice(2).replace('/', '/timeline?at=')}` : `?at=${source.slice(2)}`} }`, (0, combinator_1.union)([link_1.unsafelink])))), ([el]) => [(0, dom_1.define)(el, {
8201
+ exports.anchor = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('>>', (0, combinator_1.focus)(/^>>(?:[a-z][0-9a-z]*(?:-[0-9a-z]+)*\/)?[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9a-z@#:])/i, (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.syntax)(0, 1 /* State.autolink */, (0, combinator_1.fmap)((0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `/@${source.slice(2).replace('/', '/timeline?at=')}` : `?at=${source.slice(2)}`} }`, link_1.unsafelink), ([el]) => [(0, dom_1.define)(el, {
8192
8202
  class: 'anchor'
8193
- })])));
8203
+ })]))), ({
8204
+ source
8205
+ }) => [[source], '']]))));
8194
8206
 
8195
8207
  /***/ },
8196
8208
 
@@ -8478,10 +8490,12 @@ const link_1 = __webpack_require__(3628);
8478
8490
  const hashtag_1 = __webpack_require__(5764);
8479
8491
  const source_1 = __webpack_require__(8745);
8480
8492
  const dom_1 = __webpack_require__(394);
8481
- exports.hashnum = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.open)('#', (0, source_1.str)(new RegExp(/^[0-9]{1,9}(?![^\p{C}\p{S}\p{P}\s]|emoji|['_])/u.source.replace(/emoji/, hashtag_1.emoji), 'u')))), (0, combinator_1.convert)(source => `[${source}]{ ${source.slice(1)} }`, (0, combinator_1.union)([link_1.unsafelink]))), ([el]) => [(0, dom_1.define)(el, {
8493
+ exports.hashnum = (0, combinator_1.lazy)(() => (0, combinator_1.rewrite)((0, combinator_1.open)('#', (0, source_1.str)(new RegExp(/^[0-9]{1,9}(?![^\p{C}\p{S}\p{P}\s]|emoji|['_])/u.source.replace(/emoji/, hashtag_1.emoji), 'u'))), (0, combinator_1.union)([(0, combinator_1.constraint)(1 /* State.autolink */, false, (0, combinator_1.syntax)(0, 1 /* State.autolink */, (0, combinator_1.fmap)((0, combinator_1.convert)(source => `[${source}]{ ${source.slice(1)} }`, link_1.unsafelink), ([el]) => [(0, dom_1.define)(el, {
8482
8494
  class: 'hashnum',
8483
8495
  href: null
8484
- })]));
8496
+ })]))), ({
8497
+ source
8498
+ }) => [[source], '']])));
8485
8499
 
8486
8500
  /***/ },
8487
8501
 
@@ -8677,11 +8691,11 @@ const source_1 = __webpack_require__(8745);
8677
8691
  const memoize_1 = __webpack_require__(6925);
8678
8692
  const array_1 = __webpack_require__(6876);
8679
8693
  const dom_1 = __webpack_require__(394);
8680
- exports.remark = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[%', (0, combinator_1.creation)(1, 4 /* Recursion.inline */, (0, combinator_1.syntax)(4, 0 /* State.none */, (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}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]]), (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', {
8694
+ exports.remark = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[%', (0, combinator_1.creation)(1, 4 /* Recursion.inline */, (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.syntax)(4, 0 /* State.none */, (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]])), (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', {
8681
8695
  class: 'remark'
8682
8696
  }, [(0, dom_1.html)('input', {
8683
8697
  type: 'checkbox'
8684
- }), (0, dom_1.html)('span', (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))])], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), ([, fence]) => fence.length, {}))))));
8698
+ }), (0, dom_1.html)('span', (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))])], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), ([, fence]) => fence.length, {})))));
8685
8699
 
8686
8700
  /***/ },
8687
8701
 
@@ -8700,7 +8714,7 @@ const inline_1 = __webpack_require__(7973);
8700
8714
  const source_1 = __webpack_require__(8745);
8701
8715
  const visibility_1 = __webpack_require__(6364);
8702
8716
  const dom_1 = __webpack_require__(394);
8703
- exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('[[', (0, combinator_1.constraint)(128 /* State.reference */, false, (0, combinator_1.syntax)(1, 256 /* State.annotation */ | 128 /* State.reference */ | 8 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns)))])], rest], undefined, 1 | 4 /* Backtrack.bracket */)));
8717
+ exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('[[', (0, combinator_1.constraint)(64 /* State.reference */, false, (0, combinator_1.syntax)(1, 128 /* State.annotation */ | 64 /* State.reference */ | 4 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns)))])], rest], undefined, 1 | 4 /* Backtrack.bracket */)));
8704
8718
  // Chicago-Style
8705
8719
  const abbr = (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.surround)('^', (0, combinator_1.union)([(0, source_1.str)(/^(?=[A-Z])(?:[0-9A-Za-z]'?|(?:[-.:]|\.?\??,? ?)(?!['\-.:?, ]))+/)]), /^\|?(?=]])|^\|[^\S\n]*/, true, ([, ns], rest) => ns ? [['\n', ns[0].trimEnd()], rest.replace(visibility_1.blank.start, '')] : [[''], `^${rest}`], ([,, rest]) => [[''], `^${rest}`]));
8706
8720
  function attributes(ns) {
package/markdown.d.ts CHANGED
@@ -603,7 +603,7 @@ export namespace MarkdownParser {
603
603
  Block<'reply/cite'>,
604
604
  Parser<HTMLSpanElement | HTMLBRElement, Context, [
605
605
  SourceParser.StrParser,
606
- Parser<HTMLAnchorElement, Context, [
606
+ Parser<string | HTMLAnchorElement, Context, [
607
607
  InlineParser.AutolinkParser.AnchorParser,
608
608
  Parser<HTMLAnchorElement, Context, []>,
609
609
  Parser<HTMLAnchorElement, Context, []>,
@@ -1147,8 +1147,9 @@ export namespace MarkdownParser {
1147
1147
  export interface UrlParser extends
1148
1148
  // https://host
1149
1149
  Inline<'url'>,
1150
- Parser<HTMLAnchorElement, Context, [
1150
+ Parser<string | HTMLAnchorElement, Context, [
1151
1151
  LinkParser.UnsafeLinkParser,
1152
+ Parser<string, Context, []>,
1152
1153
  ]> {
1153
1154
  }
1154
1155
  export namespace UrlParser {
@@ -1156,7 +1157,10 @@ export namespace MarkdownParser {
1156
1157
  Inline<'url/lineurl'>,
1157
1158
  Parser<string | HTMLElement, Context, [
1158
1159
  SourceParser.StrParser,
1159
- InlineParser.LinkParser.UnsafeLinkParser,
1160
+ Parser<string | HTMLElement, Context, [
1161
+ InlineParser.LinkParser.UnsafeLinkParser,
1162
+ Parser<string, Context, []>,
1163
+ ]>,
1160
1164
  ]> {
1161
1165
  }
1162
1166
  export interface BracketParser extends
@@ -1188,7 +1192,7 @@ export namespace MarkdownParser {
1188
1192
  export interface ChannelParser extends
1189
1193
  // @user#tag
1190
1194
  Inline<'channel'>,
1191
- Parser<HTMLAnchorElement, Context, [
1195
+ Parser<string | HTMLAnchorElement, Context, [
1192
1196
  InlineParser.AutolinkParser.AccountParser,
1193
1197
  InlineParser.AutolinkParser.HashtagParser,
1194
1198
  ]> {
@@ -1196,29 +1200,33 @@ export namespace MarkdownParser {
1196
1200
  export interface AccountParser extends
1197
1201
  // @user
1198
1202
  Inline<'account'>,
1199
- Parser<HTMLAnchorElement, Context, [
1203
+ Parser<string | HTMLAnchorElement, Context, [
1200
1204
  LinkParser.UnsafeLinkParser,
1205
+ Parser<string, Context, []>,
1201
1206
  ]> {
1202
1207
  }
1203
1208
  export interface HashtagParser extends
1204
1209
  // #tag
1205
1210
  Inline<'hashtag'>,
1206
- Parser<HTMLAnchorElement, Context, [
1211
+ Parser<string | HTMLAnchorElement, Context, [
1207
1212
  LinkParser.UnsafeLinkParser,
1213
+ Parser<string, Context, []>,
1208
1214
  ]> {
1209
1215
  }
1210
1216
  export interface HashnumParser extends
1211
1217
  // #1
1212
1218
  Inline<'hashnum'>,
1213
- Parser<HTMLAnchorElement, Context, [
1219
+ Parser<string | HTMLAnchorElement, Context, [
1214
1220
  LinkParser.UnsafeLinkParser,
1221
+ Parser<string, Context, []>,
1215
1222
  ]> {
1216
1223
  }
1217
1224
  export interface AnchorParser extends
1218
1225
  // >>1
1219
1226
  Inline<'anchor'>,
1220
- Parser<HTMLAnchorElement, Context, [
1227
+ Parser<string | HTMLAnchorElement, Context, [
1221
1228
  LinkParser.UnsafeLinkParser,
1229
+ Parser<string, Context, []>,
1222
1230
  ]> {
1223
1231
  }
1224
1232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.283.3",
3
+ "version": "0.283.4",
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",
@@ -59,10 +59,10 @@ export function surround<T>(
59
59
  const { logger = {}, offset = 0 } = context;
60
60
  for (let i = 0; i < source.length - mr_.length; ++i) {
61
61
  if (source[i] !== source[0]) break;
62
- const j = source.length + offset - i;
63
- if (!(j in logger)) continue;
62
+ const pos = source.length + offset - i - 1;
63
+ if (!(pos in logger)) continue;
64
64
  assert(log >>> 2);
65
- if (logger[j] & 1 << (log >>> 2)) return;
65
+ if (logger[pos] & 1 << (log >>> 2)) return;
66
66
  }
67
67
  }
68
68
  const res2 = mr_ !== '' ? parser({ source: mr_, context }) : undefined;
@@ -77,7 +77,7 @@ export function surround<T>(
77
77
  if (rest.length === lmr_.length) return;
78
78
  if (log & 2 && rr === undefined) {
79
79
  const { logger = {}, offset = 0 } = context;
80
- logger[source.length + offset] |= 1 << (log >>> 2);
80
+ logger[source.length + offset - 1] |= 1 << (log >>> 2);
81
81
  }
82
82
  return rr
83
83
  ? f
@@ -33,7 +33,7 @@ export class Delimiters {
33
33
  this.signature);
34
34
  private readonly registry = memoize<(signature: string) => Delimiter[]>(() => []);
35
35
  private readonly delimiters: Delimiter[] = [];
36
- private readonly order: number[] = [];
36
+ private readonly stack: number[] = [];
37
37
  private readonly states: (readonly number[])[] = [];
38
38
  public push(
39
39
  delims: readonly {
@@ -42,14 +42,14 @@ export class Delimiters {
42
42
  readonly precedence: number;
43
43
  }[]
44
44
  ): void {
45
- const { registry, delimiters, order } = this;
46
- // 構文数x優先順位数以下
45
+ const { registry, delimiters, stack } = this;
46
+ // シグネチャ数以下
47
47
  assert(delimiters.length < 100);
48
48
  for (let i = 0; i < delims.length; ++i) {
49
49
  const { signature, matcher, precedence } = delims[i];
50
- const stack = registry(signature);
51
- const index = stack[0]?.index ?? delimiters.length;
52
- if (stack.length === 0 || precedence > delimiters[index].precedence) {
50
+ const memory = registry(signature);
51
+ const index = memory[0]?.index ?? delimiters.length;
52
+ if (memory.length === 0 || precedence > delimiters[index].precedence) {
53
53
  const delimiter: Delimiter = {
54
54
  index,
55
55
  signature,
@@ -58,34 +58,34 @@ export class Delimiters {
58
58
  state: true,
59
59
  };
60
60
  delimiters[index] = delimiter;
61
- stack.push(delimiter);
62
- order.push(index);
61
+ memory.push(delimiter);
62
+ stack.push(index);
63
63
  }
64
64
  else {
65
- order.push(-1);
65
+ stack.push(-1);
66
66
  }
67
67
  // 現状各優先順位は固定
68
- assert(stack.length === 1);
68
+ assert(memory.length === 1);
69
69
  }
70
70
  }
71
71
  public pop(count: number): void {
72
72
  assert(count > 0);
73
- const { registry, delimiters, order } = this;
73
+ const { registry, delimiters, stack } = this;
74
74
  for (let i = 0; i < count; ++i) {
75
- assert(this.order.length > 0);
76
- const index = order.pop()!;
75
+ assert(this.stack.length > 0);
76
+ const index = stack.pop()!;
77
77
  if (index === -1) continue;
78
- const stack = registry(delimiters[index].signature);
79
- assert(stack.length > 0);
80
- if (stack.length === 1) {
78
+ const memory = registry(delimiters[index].signature);
79
+ assert(memory.length > 0);
80
+ if (memory.length === 1) {
81
81
  assert(index === delimiters.length - 1);
82
- assert(stack[0] === delimiters.at(-1));
83
- stack.pop();
82
+ assert(memory[0] === delimiters.at(-1));
83
+ memory.pop();
84
84
  delimiters.pop();
85
85
  }
86
86
  else {
87
- stack.pop();
88
- delimiters[index] = stack.at(-1)!;
87
+ memory.pop();
88
+ delimiters[index] = memory.at(-1)!;
89
89
  }
90
90
  }
91
91
  }
@@ -96,11 +96,12 @@ export function precedence<T>(precedence: number, parser: Parser<T>): Parser<T>
96
96
  assert(precedence >= 0);
97
97
  return ({ source, context }) => {
98
98
  const { delimiters, precedence: p = 0 } = context;
99
- const shift = precedence > p;
99
+ const shift = delimiters && precedence > p;
100
100
  context.precedence = precedence;
101
- shift && delimiters?.shift(precedence);
101
+ // デリミタはシフト後に設定しなければならない
102
+ shift && delimiters.shift(precedence);
102
103
  const result = parser({ source, context });
103
- shift && delimiters?.unshift();
104
+ shift && delimiters.unshift();
104
105
  context.precedence = p;
105
106
  return result;
106
107
  };
@@ -1,13 +1,12 @@
1
1
  export const enum State {
2
- annotation = 1 << 8,
3
- reference = 1 << 7,
4
- index = 1 << 6,
5
- label = 1 << 5,
6
- link = 1 << 4,
7
- media = 1 << 3,
8
- mark = 1 << 2,
9
- autolink = 1 << 1,
10
- shortcut = 1 << 0,
2
+ annotation = 1 << 7,
3
+ reference = 1 << 6,
4
+ index = 1 << 5,
5
+ label = 1 << 4,
6
+ link = 1 << 3,
7
+ media = 1 << 2,
8
+ mark = 1 << 1,
9
+ autolink = 1 << 0,
11
10
  none = 0,
12
11
  all = ~0,
13
12
  linkers = 0
@@ -1,5 +1,5 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, tails, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
2
+ import { union, tails, syntax, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
3
3
  import { unsafelink } from '../link';
4
4
  import { str } from '../../source';
5
5
  import { State } from '../../context';
@@ -7,20 +7,21 @@ import { define } from 'typed-dom/dom';
7
7
 
8
8
  // https://example/@user must be a user page or a redirect page going there.
9
9
 
10
- export const account: AutolinkParser.AccountParser = lazy(() => fmap(rewrite(
11
- constraint(State.shortcut, false,
10
+ export const account: AutolinkParser.AccountParser = lazy(() => rewrite(
12
11
  open(
13
12
  '@',
14
13
  tails([
15
14
  str(/^[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*\//i),
16
15
  str(/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*/i),
17
- ]))),
18
- convert(
19
- source =>
20
- `[${source}]{ ${
21
- source.includes('/')
22
- ? `https://${source.slice(1).replace('/', '/@')}`
23
- : `/${source}`
24
- } }`,
25
- union([unsafelink]))),
26
- ([el]) => [define(el, { class: 'account' })]));
16
+ ])),
17
+ union([
18
+ constraint(State.autolink, false, syntax(0, State.autolink, fmap(convert(
19
+ source =>
20
+ `[${source}]{ ${source.includes('/')
21
+ ? `https://${source.slice(1).replace('/', '/@')}`
22
+ : `/${source}`
23
+ } }`,
24
+ unsafelink),
25
+ ([el]) => [define(el, { class: 'account' })]))),
26
+ ({ source }) => [[source], ''],
27
+ ])));
@@ -1,5 +1,5 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, constraint, validate, focus, convert, fmap, lazy } from '../../../combinator';
2
+ import { union, syntax, constraint, validate, focus, convert, fmap, lazy } from '../../../combinator';
3
3
  import { unsafelink } from '../link';
4
4
  import { State } from '../../context';
5
5
  import { define } from 'typed-dom/dom';
@@ -14,16 +14,17 @@ import { define } from 'typed-dom/dom';
14
14
  // 内部表現はUnixTimeに統一する(時系列順)
15
15
  // 外部表現は投稿ごとに投稿者の投稿時のタイムゾーンに統一する(非時系列順)
16
16
 
17
- export const anchor: AutolinkParser.AnchorParser = lazy(() => validate('>>', fmap(
18
- constraint(State.shortcut, false,
17
+ export const anchor: AutolinkParser.AnchorParser = lazy(() => validate('>>',
19
18
  focus(
20
19
  /^>>(?:[a-z][0-9a-z]*(?:-[0-9a-z]+)*\/)?[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9a-z@#:])/i,
21
- convert(
22
- source =>
23
- `[${source}]{ ${
24
- source.includes('/')
25
- ? `/@${source.slice(2).replace('/', '/timeline?at=')}`
26
- : `?at=${source.slice(2)}`
27
- } }`,
28
- union([unsafelink])))),
29
- ([el]) => [define(el, { class: 'anchor' })])));
20
+ union([
21
+ constraint(State.autolink, false, syntax(0, State.autolink, fmap(convert(
22
+ source =>
23
+ `[${source}]{ ${source.includes('/')
24
+ ? `/@${source.slice(2).replace('/', '/timeline?at=')}`
25
+ : `?at=${source.slice(2)}`
26
+ } }`,
27
+ unsafelink),
28
+ ([el]) => [define(el, { class: 'anchor' })]))),
29
+ ({ source }) => [[source], ''],
30
+ ]))));
@@ -1,13 +1,15 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { sequence, some, validate, bind } from '../../../combinator';
2
+ import { sequence, some, constraint, validate, bind } from '../../../combinator';
3
3
  import { account } from './account';
4
4
  import { hashtag } from './hashtag';
5
+ import { State } from '../../context';
5
6
  import { stringify } from '../../util';
6
7
  import { define } from 'typed-dom/dom';
7
8
 
8
9
  // https://example/@user?ch=a+b must be a user channel page or a redirect page going there.
9
10
 
10
- export const channel: AutolinkParser.ChannelParser = validate('@', bind(
11
+ export const channel: AutolinkParser.ChannelParser = validate('@',
12
+ constraint(State.autolink, false, bind(
11
13
  sequence([
12
14
  account,
13
15
  some(hashtag),
@@ -15,6 +17,7 @@ export const channel: AutolinkParser.ChannelParser = validate('@', bind(
15
17
  (es, rest) => {
16
18
  const source = stringify(es);
17
19
  const el = es[0];
20
+ if (typeof el === 'string') return [es, rest];
18
21
  const url = `${el.getAttribute('href')}?ch=${source.slice(source.indexOf('#') + 1).replace(/#/g, '+')}`;
19
22
  return [[define(el, { class: 'channel', href: url }, source)], rest];
20
- }));
23
+ })));
@@ -1,7 +1,7 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { creation, verify, rewrite } from '../../../combinator';
2
+ import { syntax, creation, constraint, verify, rewrite } from '../../../combinator';
3
3
  import { str } from '../../source';
4
- import { Recursion } from '../../context';
4
+ import { State, Recursion } from '../../context';
5
5
  import { html } from 'typed-dom/dom';
6
6
 
7
7
  // https://html.spec.whatwg.org/multipage/input.html
@@ -9,4 +9,5 @@ import { html } from 'typed-dom/dom';
9
9
  export const email: AutolinkParser.EmailParser = creation(1, Recursion.ignore, rewrite(verify(
10
10
  str(/^[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z]){0,255}@[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*(?![0-9a-z])/i),
11
11
  ([source]) => source.length <= 255),
12
- ({ source }) => [[html('a', { class: 'email', href: `mailto:${source}` }, source)], '']));
12
+ constraint(State.autolink, false, syntax(0, State.autolink,
13
+ ({ source }) => [[html('a', { class: 'email', href: `mailto:${source}` }, source)], '']))));
@@ -1,15 +1,17 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
2
+ import { union, syntax, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
3
3
  import { unsafelink } from '../link';
4
4
  import { emoji } from './hashtag';
5
5
  import { str } from '../../source';
6
6
  import { State } from '../../context';
7
7
  import { define } from 'typed-dom/dom';
8
8
 
9
- export const hashnum: AutolinkParser.HashnumParser = lazy(() => fmap(rewrite(
10
- constraint(State.shortcut, false,
11
- open('#', str(new RegExp(/^[0-9]{1,9}(?![^\p{C}\p{S}\p{P}\s]|emoji|['_])/u.source.replace(/emoji/, emoji), 'u')))),
12
- convert(
13
- source => `[${source}]{ ${source.slice(1)} }`,
14
- union([unsafelink]))),
15
- ([el]) => [define(el, { class: 'hashnum', href: null })]));
9
+ export const hashnum: AutolinkParser.HashnumParser = lazy(() => rewrite(
10
+ open('#', str(new RegExp(/^[0-9]{1,9}(?![^\p{C}\p{S}\p{P}\s]|emoji|['_])/u.source.replace(/emoji/, emoji), 'u'))),
11
+ union([
12
+ constraint(State.autolink, false, syntax(0, State.autolink, fmap(convert(
13
+ source => `[${source}]{ ${source.slice(1)} }`,
14
+ unsafelink),
15
+ ([el]) => [define(el, { class: 'hashnum', href: null })]))),
16
+ ({ source }) => [[source], ''],
17
+ ])));
@@ -1,5 +1,5 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
2
+ import { union, syntax, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
3
3
  import { unsafelink } from '../link';
4
4
  import { str } from '../../source';
5
5
  import { State } from '../../context';
@@ -10,15 +10,17 @@ import { define } from 'typed-dom/dom';
10
10
  // https://github.com/tc39/proposal-regexp-unicode-property-escapes#matching-emoji
11
11
  export const emoji = String.raw`\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F`;
12
12
 
13
- export const hashtag: AutolinkParser.HashtagParser = lazy(() => fmap(rewrite(
14
- constraint(State.shortcut, false,
13
+ export const hashtag: AutolinkParser.HashtagParser = lazy(() => rewrite(
15
14
  open(
16
15
  '#',
17
16
  str(new RegExp([
18
17
  /^(?!['_])(?=(?:[0-9]{1,9})?(?:[^\d\p{C}\p{S}\p{P}\s]|emoji|'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|')))/u.source,
19
18
  /(?:[^\p{C}\p{S}\p{P}\s]|emoji|'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|'))+/u.source,
20
- ].join('').replace(/emoji/g, emoji), 'u')))),
21
- convert(
22
- source => `[${source}]{ ${`/hashtags/${source.slice(1)}`} }`,
23
- union([unsafelink]))),
24
- ([el]) => [define(el, { class: 'hashtag' })]));
19
+ ].join('').replace(/emoji/g, emoji), 'u'))),
20
+ union([
21
+ constraint(State.autolink, false, syntax(0, State.autolink, fmap(convert(
22
+ source => `[${source}]{ ${`/hashtags/${source.slice(1)}`} }`,
23
+ unsafelink),
24
+ ([el]) => [define(el, { class: 'hashtag' })]))),
25
+ ({ source }) => [[source], ''],
26
+ ])));
@@ -1,8 +1,8 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, tails, some, creation, precedence, validate, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
2
+ import { union, tails, some, syntax, creation, precedence, constraint, validate, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
3
3
  import { unsafelink } from '../link';
4
4
  import { linebreak, unescsource, str } from '../../source';
5
- import { Backtrack, Recursion } from '../../context';
5
+ import { State, Recursion, Backtrack } from '../../context';
6
6
 
7
7
  const closer = /^[-+*=~^_,.;:!?]*(?=[\\"`|\[\](){}<>]|$)/;
8
8
 
@@ -10,24 +10,30 @@ export const url: AutolinkParser.UrlParser = lazy(() => validate(['http://', 'ht
10
10
  open(
11
11
  /^https?:\/\/(?=[\x21-\x7E])/,
12
12
  focus(/^[\x21-\x7E]+/, some(union([bracket, some(unescsource, closer)])))),
13
- convert(
14
- url => `{ ${url} }`,
15
- union([unsafelink])))));
13
+ union([
14
+ constraint(State.autolink, false, syntax(0, State.autolink, convert(
15
+ url => `{ ${url} }`,
16
+ unsafelink))),
17
+ ({ source }) => [[source], ''],
18
+ ]))));
16
19
 
17
20
  export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => open(
18
21
  linebreak,
19
- tails([
20
- str('!'),
21
- focus(
22
- /^https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/,
23
- convert(
24
- url => `{ ${url} }`,
25
- unsafelink)),
26
- ])));
22
+ focus(
23
+ /^!?https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/,
24
+ tails([
25
+ str('!'),
26
+ union([
27
+ constraint(State.autolink, false, syntax(0, State.autolink, convert(
28
+ url => `{ ${url} }`,
29
+ unsafelink))),
30
+ ({ source }) => [[source], ''],
31
+ ]),
32
+ ]))));
27
33
 
28
- const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => creation(0, Recursion.terminal, precedence(1, union([
29
- surround(str('('), some(union([bracket, unescsource]), ')'), str(')'), true, undefined, undefined, 3 | Backtrack.url),
30
- surround(str('['), some(union([bracket, unescsource]), ']'), str(']'), true, undefined, undefined, 3 | Backtrack.url),
31
- surround(str('{'), some(union([bracket, unescsource]), '}'), str('}'), true, undefined, undefined, 3 | Backtrack.url),
34
+ const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
35
+ surround(str('('), precedence(1, some(union([bracket, unescsource]), ')')), str(')'), true, undefined, undefined, 3 | Backtrack.url),
36
+ surround(str('['), precedence(1, some(union([bracket, unescsource]), ']')), str(']'), true, undefined, undefined, 3 | Backtrack.url),
37
+ surround(str('{'), precedence(1, some(union([bracket, unescsource]), '}')), str('}'), true, undefined, undefined, 3 | Backtrack.url),
32
38
  surround(str('"'), precedence(2, some(unescsource, '"')), str('"'), true, undefined, undefined, 3 | Backtrack.url),
33
- ]))));
39
+ ])));
@@ -1,5 +1,5 @@
1
1
  import { AutolinkParser } from '../inline';
2
- import { union, some, syntax, constraint, validate, lazy, fmap } from '../../combinator';
2
+ import { union, some, syntax, validate, lazy, fmap } from '../../combinator';
3
3
  import { url, lineurl } from './autolink/url';
4
4
  import { email } from './autolink/email';
5
5
  import { channel } from './autolink/channel';
@@ -13,8 +13,7 @@ import { stringify } from '../util';
13
13
 
14
14
  export const autolink: AutolinkParser = lazy(() =>
15
15
  validate(/^(?:[@#>0-9a-z]|\S[#>]|[\r\n]!?https?:\/\/)/iu,
16
- constraint(State.autolink, false,
17
- syntax(0, ~State.shortcut,
16
+ syntax(0, ~State.autolink,
18
17
  union([
19
18
  some(union([lineurl])),
20
19
  fmap(some(union([
@@ -37,4 +36,4 @@ export const autolink: AutolinkParser = lazy(() =>
37
36
  anchor,
38
37
  ])),
39
38
  ns => ns.length === 1 ? ns : [stringify(ns)]),
40
- ])))));
39
+ ]))));
@@ -18,48 +18,50 @@ const attrspecs = {
18
18
  Object.setPrototypeOf(attrspecs, null);
19
19
  Object.values(attrspecs).forEach(o => Object.setPrototypeOf(o, null));
20
20
 
21
- export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^\S\n]|>)/i, creation(1, Recursion.inline, syntax(3, State.none, union([
22
- focus(
23
- /^<wbr[^\S\n]*>/i,
24
- () => [[h('wbr')], '']),
25
- surround(
26
- // https://html.spec.whatwg.org/multipage/syntax.html#void-elements
27
- str(/^<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[^\S\n]|>)/i), some(union([attribute])), str(/^[^\S\n]*>/), true,
28
- ([as, bs = [], cs], rest) =>
29
- [[elem(as[0].slice(1), push(unshift(as, bs), cs), [], [])], rest]),
30
- match(
31
- new RegExp(String.raw`^<(${TAGS.join('|')})(?=[^\S\n]|>)`),
32
- memoize(
33
- ([, tag]) =>
34
- surround<HTMLParser.TagParser, string>(surround(
35
- str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
36
- subsequence([
37
- focus(/^[^\S\n]*\n/, some(inline)),
38
- some(open(/^\n?/, some(inline, blankWith('\n', `</${tag}>`), [[blankWith('\n', `</${tag}>`), 3]]), true)),
39
- ]),
40
- str(`</${tag}>`), true,
41
- ([as, bs = [], cs], rest) =>
42
- [[elem(tag, as, bs, cs)], rest],
43
- ([as, bs = []], rest) =>
44
- [[elem(tag, as, bs, [])], rest]))),
45
- match(
46
- /^<([a-z]+)(?=[^\S\n]|>)/i,
47
- memoize(
48
- ([, tag]) =>
49
- surround<HTMLParser.TagParser, string>(surround(
50
- str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
51
- subsequence([
52
- focus(/^[^\S\n]*\n/, some(inline)),
53
- some(inline, `</${tag}>`, [[`</${tag}>`, 3]]),
54
- ]),
55
- str(`</${tag}>`), true,
56
- ([as, bs = [], cs], rest) =>
57
- [[elem(tag, as, bs, cs)], rest],
58
- ([as, bs = []], rest) =>
59
- [[elem(tag, as, bs, [])], rest]),
60
- ([, tag]) => tag,
61
- new Clock(10000))),
62
- ]))))));
21
+ export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^\S\n]|>)/i, creation(1, Recursion.inline,
22
+ syntax(3, State.none,
23
+ union([
24
+ focus(
25
+ /^<wbr[^\S\n]*>/i,
26
+ () => [[h('wbr')], '']),
27
+ surround(
28
+ // https://html.spec.whatwg.org/multipage/syntax.html#void-elements
29
+ str(/^<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[^\S\n]|>)/i), some(union([attribute])), str(/^[^\S\n]*>/), true,
30
+ ([as, bs = [], cs], rest) =>
31
+ [[elem(as[0].slice(1), push(unshift(as, bs), cs), [], [])], rest]),
32
+ match(
33
+ new RegExp(String.raw`^<(${TAGS.join('|')})(?=[^\S\n]|>)`),
34
+ memoize(
35
+ ([, tag]) =>
36
+ surround<HTMLParser.TagParser, string>(surround(
37
+ str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
38
+ subsequence([
39
+ focus(/^[^\S\n]*\n/, some(inline)),
40
+ some(open(/^\n?/, some(inline, blankWith('\n', `</${tag}>`), [[blankWith('\n', `</${tag}>`), 3]]), true)),
41
+ ]),
42
+ str(`</${tag}>`), true,
43
+ ([as, bs = [], cs], rest) =>
44
+ [[elem(tag, as, bs, cs)], rest],
45
+ ([as, bs = []], rest) =>
46
+ [[elem(tag, as, bs, [])], rest]))),
47
+ match(
48
+ /^<([a-z]+)(?=[^\S\n]|>)/i,
49
+ memoize(
50
+ ([, tag]) =>
51
+ surround<HTMLParser.TagParser, string>(surround(
52
+ str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
53
+ subsequence([
54
+ focus(/^[^\S\n]*\n/, some(inline)),
55
+ some(inline, `</${tag}>`, [[`</${tag}>`, 3]]),
56
+ ]),
57
+ str(`</${tag}>`), true,
58
+ ([as, bs = [], cs], rest) =>
59
+ [[elem(tag, as, bs, cs)], rest],
60
+ ([as, bs = []], rest) =>
61
+ [[elem(tag, as, bs, [])], rest]),
62
+ ([, tag]) => tag,
63
+ new Clock(10000))),
64
+ ]))))));
63
65
 
64
66
  export const attribute: HTMLParser.AttributeParser = union([
65
67
  str(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="[^"\n]*")?(?=[^\S\n]|>)/i),
@@ -15,12 +15,12 @@ const optspec = {
15
15
  } as const;
16
16
  Object.setPrototypeOf(optspec, null);
17
17
 
18
- export const link: LinkParser = lazy(() => validate(['[', '{'], union([
18
+ export const link: LinkParser = lazy(() => union([
19
19
  medialink,
20
20
  textlink,
21
- ])));
21
+ ]));
22
22
 
23
- export const textlink: LinkParser.TextLinkParser = lazy(() => creation(1, Recursion.ignore,
23
+ export const textlink: LinkParser.TextLinkParser = lazy(() => validate(['[', '{'], creation(1, Recursion.ignore,
24
24
  constraint(State.link, false,
25
25
  syntax(1, State.linkers | State.media,
26
26
  bind(reverse(tails([
@@ -40,9 +40,9 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => creation(1, Recurs
40
40
  assert(content[0] !== '');
41
41
  if (content.length !== 0 && trimNodeEnd(content = defrag(content)).length === 0) return;
42
42
  return [[parse(content, params, context)], rest];
43
- })))));
43
+ }))))));
44
44
 
45
- export const medialink: LinkParser.MediaLinkParser = lazy(() => creation(1, Recursion.ignore,
45
+ export const medialink: LinkParser.MediaLinkParser = lazy(() => validate(['[', '{'], creation(1, Recursion.ignore,
46
46
  constraint(State.link | State.media, false,
47
47
  syntax(1, State.linkers,
48
48
  bind(reverse(sequence([
@@ -53,7 +53,7 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() => creation(1, Recu
53
53
  dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]*}/)),
54
54
  ])),
55
55
  ([params, content = []]: [string[], (HTMLElement | string)[]], rest, context) =>
56
- [[parse(defrag(content), params, context)], rest])))));
56
+ [[parse(defrag(content), params, context)], rest]))))));
57
57
 
58
58
  export const linemedialink: LinkParser.LineMediaLinkParser = surround(
59
59
  linebreak,
@@ -61,7 +61,8 @@ export const linemedialink: LinkParser.LineMediaLinkParser = surround(
61
61
  /^(?=[^\S\n]*(?:$|\n))/);
62
62
 
63
63
  export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
64
- creation(1, Recursion.ignore, precedence(1,
64
+ creation(1, Recursion.ignore,
65
+ precedence(1,
65
66
  bind(reverse(tails([
66
67
  dup(surround(
67
68
  '[',
@@ -7,13 +7,13 @@ import { memoize } from 'spica/memoize';
7
7
  import { unshift, push } from 'spica/array';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
- export const remark: RemarkParser = lazy(() => validate('[%', creation(1, Recursion.inline, syntax(4, State.none, match(
10
+ export const remark: RemarkParser = lazy(() => validate('[%', creation(1, Recursion.inline, match(
11
11
  /^\[(%+)\s/,
12
12
  memoize(
13
13
  ([, fence]) =>
14
14
  surround(
15
15
  open(str(`[${fence}`), some(text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true),
16
- some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]]),
16
+ syntax(4, State.none, some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]])),
17
17
  close(some(text, /^\S/), str(`${fence}]`)), true,
18
18
  ([as, bs = [], cs], rest) => [[
19
19
  html('span', { class: 'remark' }, [
@@ -22,4 +22,4 @@ export const remark: RemarkParser = lazy(() => validate('[%', creation(1, Recurs
22
22
  ]),
23
23
  ], rest],
24
24
  ([as, bs = []], rest) => [unshift(as, bs), rest]),
25
- ([, fence]) => fence.length, {}))))));
25
+ ([, fence]) => fence.length, {})))));
@@ -8,7 +8,8 @@ import { isStartTightNodes } from '../visibility';
8
8
  import { unshift, push } from 'spica/array';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
 
11
- export const ruby: RubyParser = lazy(() => validate('[', creation(1, Recursion.ignore, syntax(1, State.all, fmap(
11
+ export const ruby: RubyParser = lazy(() => validate('[', creation(1, Recursion.ignore, fmap(
12
+ syntax(1, State.all,
12
13
  sequence([
13
14
  bind(surround('[', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']', false, undefined, undefined, 3 | Backtrack.ruby), ([source], rest, context) => {
14
15
  const ns = eval(text({ source, context }), [undefined])[0];
@@ -19,7 +20,7 @@ export const ruby: RubyParser = lazy(() => validate('[', creation(1, Recursion.i
19
20
  const ns = eval(text({ source, context }), [undefined])[0];
20
21
  return ns && [[ns], rest];
21
22
  }),
22
- ]),
23
+ ])),
23
24
  ([texts, rubies]) => {
24
25
  switch (true) {
25
26
  case rubies.length <= texts.length:
@@ -50,7 +51,7 @@ export const ruby: RubyParser = lazy(() => validate('[', creation(1, Recursion.i
50
51
  [html('rp', '('), html('rt', rubies.join(' ').trim()), html('rp', ')')]))),
51
52
  ];
52
53
  }
53
- })))));
54
+ }))));
54
55
 
55
56
  const text: RubyParser.TextParser = creation(1, Recursion.ignore, ({ source, context }) => {
56
57
  const acc = [''];
@@ -173,6 +173,7 @@ describe('Unit: parser/inline', () => {
173
173
  assert.deepStrictEqual(inspect(parser('"[% *"*"*')), [['"', '[%', ' ', '*', '"', '*', '"', '*'], '']);
174
174
  assert.deepStrictEqual(inspect(parser('"[% "*"* %]')), [['"', '<span class="remark"><input type="checkbox"><span>[% "*"* %]</span></span>'], '']);
175
175
  assert.deepStrictEqual(inspect(parser('"{{""}}')), [['"', '{', '{', '"', '"', '}', '}'], '']);
176
+ assert.deepStrictEqual(inspect(parser('[#http://a/(<bdi>)]</bdi>')), [['<a class="index" href="#index::http://a/(&lt;bdi&gt;)">http://a/(&lt;bdi&gt;)</a>', '<', '/', 'bdi', '>'], '']);
176
177
  });
177
178
 
178
179
  it('uri', () => {