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 +4 -0
- package/dist/index.js +74 -60
- package/markdown.d.ts +16 -8
- package/package.json +1 -1
- package/src/combinator/control/manipulation/surround.ts +4 -4
- package/src/combinator/data/parser/context/delimiter.ts +20 -20
- package/src/combinator/data/parser/context.ts +4 -3
- package/src/parser/context.ts +8 -9
- package/src/parser/inline/autolink/account.ts +14 -13
- package/src/parser/inline/autolink/anchor.ts +13 -12
- package/src/parser/inline/autolink/channel.ts +6 -3
- package/src/parser/inline/autolink/email.ts +4 -3
- package/src/parser/inline/autolink/hashnum.ts +10 -8
- package/src/parser/inline/autolink/hashtag.ts +10 -8
- package/src/parser/inline/autolink/url.ts +24 -18
- package/src/parser/inline/autolink.ts +3 -4
- package/src/parser/inline/html.ts +44 -42
- package/src/parser/inline/link.ts +8 -7
- package/src/parser/inline/remark.ts +3 -3
- package/src/parser/inline/ruby.ts +4 -3
- package/src/parser/inline.test.ts +1 -0
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.283.
|
|
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)(
|
|
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} }`,
|
|
1969
|
-
|
|
1970
|
-
|
|
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)(
|
|
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)(
|
|
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.
|
|
3237
|
-
exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, 0 /* Recursion.ignore */, (0, combinator_1.constraint)(
|
|
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)(
|
|
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)(
|
|
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.
|
|
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)(
|
|
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)(
|
|
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.
|
|
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
|
-
|
|
5504
|
+
stack
|
|
5498
5505
|
} = this;
|
|
5499
|
-
//
|
|
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
|
|
5508
|
-
const index =
|
|
5509
|
-
if (
|
|
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
|
-
|
|
5519
|
-
|
|
5525
|
+
memory.push(delimiter);
|
|
5526
|
+
stack.push(index);
|
|
5520
5527
|
} else {
|
|
5521
|
-
|
|
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
|
-
|
|
5537
|
+
stack
|
|
5531
5538
|
} = this;
|
|
5532
5539
|
for (let i = 0; i < count; ++i) {
|
|
5533
|
-
const index =
|
|
5540
|
+
const index = stack.pop();
|
|
5534
5541
|
if (index === -1) continue;
|
|
5535
|
-
const
|
|
5536
|
-
if (
|
|
5537
|
-
|
|
5542
|
+
const memory = registry(delimiters[index].signature);
|
|
5543
|
+
if (memory.length === 1) {
|
|
5544
|
+
memory.pop();
|
|
5538
5545
|
delimiters.pop();
|
|
5539
5546
|
} else {
|
|
5540
|
-
|
|
5541
|
-
delimiters[index] =
|
|
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
|
-
|
|
5725
|
+
// デリミタはシフト後に設定しなければならない
|
|
5726
|
+
shift && delimiters.shift(precedence);
|
|
5719
5727
|
const result = parser({
|
|
5720
5728
|
source,
|
|
5721
5729
|
context
|
|
5722
5730
|
});
|
|
5723
|
-
shift && delimiters
|
|
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.
|
|
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
|
|
5860
|
-
if (!(
|
|
5861
|
-
if (logger[
|
|
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)(
|
|
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.
|
|
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)(
|
|
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 &
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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)(
|
|
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
|
-
|
|
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
|
@@ -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
|
|
63
|
-
if (!(
|
|
62
|
+
const pos = source.length + offset - i - 1;
|
|
63
|
+
if (!(pos in logger)) continue;
|
|
64
64
|
assert(log >>> 2);
|
|
65
|
-
if (logger[
|
|
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
|
|
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,
|
|
46
|
-
//
|
|
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
|
|
51
|
-
const index =
|
|
52
|
-
if (
|
|
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
|
-
|
|
62
|
-
|
|
61
|
+
memory.push(delimiter);
|
|
62
|
+
stack.push(index);
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
|
-
|
|
65
|
+
stack.push(-1);
|
|
66
66
|
}
|
|
67
67
|
// 現状各優先順位は固定
|
|
68
|
-
assert(
|
|
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,
|
|
73
|
+
const { registry, delimiters, stack } = this;
|
|
74
74
|
for (let i = 0; i < count; ++i) {
|
|
75
|
-
assert(this.
|
|
76
|
-
const index =
|
|
75
|
+
assert(this.stack.length > 0);
|
|
76
|
+
const index = stack.pop()!;
|
|
77
77
|
if (index === -1) continue;
|
|
78
|
-
const
|
|
79
|
-
assert(
|
|
80
|
-
if (
|
|
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(
|
|
83
|
-
|
|
82
|
+
assert(memory[0] === delimiters.at(-1));
|
|
83
|
+
memory.pop();
|
|
84
84
|
delimiters.pop();
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
|
|
88
|
-
delimiters[index] =
|
|
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
|
-
|
|
101
|
+
// デリミタはシフト後に設定しなければならない
|
|
102
|
+
shift && delimiters.shift(precedence);
|
|
102
103
|
const result = parser({ source, context });
|
|
103
|
-
shift && delimiters
|
|
104
|
+
shift && delimiters.unshift();
|
|
104
105
|
context.precedence = p;
|
|
105
106
|
return result;
|
|
106
107
|
};
|
package/src/parser/context.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
export const enum State {
|
|
2
|
-
annotation = 1 <<
|
|
3
|
-
reference = 1 <<
|
|
4
|
-
index = 1 <<
|
|
5
|
-
label = 1 <<
|
|
6
|
-
link = 1 <<
|
|
7
|
-
media = 1 <<
|
|
8
|
-
mark = 1 <<
|
|
9
|
-
autolink = 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(() =>
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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('>>',
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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('@',
|
|
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
|
-
(
|
|
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(() =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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(() =>
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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 {
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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(() =>
|
|
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,
|
|
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,
|
|
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,
|
|
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/(<bdi>)">http://a/(<bdi>)</a>', '<', '/', 'bdi', '>'], '']);
|
|
176
177
|
});
|
|
177
178
|
|
|
178
179
|
it('uri', () => {
|