securemark 0.222.0 → 0.223.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -1
- package/dist/securemark.js +72 -35
- package/package-lock.json +1 -1
- package/package.json +1 -1
- package/src/parser/inline/annotation.test.ts +2 -2
- package/src/parser/inline/annotation.ts +4 -4
- package/src/parser/inline/emphasis.ts +2 -2
- package/src/parser/inline/emstrong.ts +4 -4
- package/src/parser/inline/extension/index.ts +2 -2
- package/src/parser/inline/html.test.ts +2 -2
- package/src/parser/inline/html.ts +4 -4
- package/src/parser/inline/link.test.ts +4 -4
- package/src/parser/inline/link.ts +4 -4
- package/src/parser/inline/mark.ts +2 -2
- package/src/parser/inline/math.ts +2 -2
- package/src/parser/inline/media.test.ts +3 -2
- package/src/parser/inline/media.ts +5 -6
- package/src/parser/inline/reference.test.ts +2 -2
- package/src/parser/inline/reference.ts +4 -4
- package/src/parser/inline/ruby.ts +2 -2
- package/src/parser/inline/strong.ts +2 -2
- package/src/parser/util.ts +55 -7
package/CHANGELOG.md
CHANGED
package/dist/securemark.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.
|
|
1
|
+
/*! securemark v0.223.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
|
|
2
2
|
require = function () {
|
|
3
3
|
function r(e, n, t) {
|
|
4
4
|
function o(i, f) {
|
|
@@ -6625,7 +6625,7 @@ require = function () {
|
|
|
6625
6625
|
exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('((', '))', '\n', (0, combinator_1.fmap)((0, combinator_1.surround)('((', (0, combinator_1.guard)(context => {
|
|
6626
6626
|
var _a, _b, _c;
|
|
6627
6627
|
return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.annotation) !== null && _c !== void 0 ? _c : true;
|
|
6628
|
-
}, (0, util_1.
|
|
6628
|
+
}, (0, util_1.startLoose)((0, util_1.visible)((0, combinator_1.context)({
|
|
6629
6629
|
syntax: {
|
|
6630
6630
|
inline: {
|
|
6631
6631
|
annotation: false,
|
|
@@ -6633,7 +6633,7 @@ require = function () {
|
|
|
6633
6633
|
}
|
|
6634
6634
|
},
|
|
6635
6635
|
state: global_1.undefined
|
|
6636
|
-
}, (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, ')', /^\\?\n/)])))), '))'), ns => [(0, typed_dom_1.html)('sup', { class: 'annotation' }, (0, util_1.
|
|
6636
|
+
}, (0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, ')', /^\\?\n/)]))))), '))'), ns => [(0, typed_dom_1.html)('sup', { class: 'annotation' }, (0, util_1.trimNode)((0, typed_dom_1.defrag)(ns)))]))));
|
|
6637
6637
|
},
|
|
6638
6638
|
{
|
|
6639
6639
|
'../../combinator': 30,
|
|
@@ -7064,7 +7064,7 @@ require = function () {
|
|
|
7064
7064
|
exports.emphasis = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, combinator_1.close)((0, source_1.str)('*'), /^(?!\*)/), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
|
|
7065
7065
|
strong_1.strong,
|
|
7066
7066
|
(0, combinator_1.some)(inline_1.inline, '*')
|
|
7067
|
-
]))), (0, source_1.str)('*'), false, ([as, bs, cs], rest) => (0, util_1.
|
|
7067
|
+
]))), (0, source_1.str)('*'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
|
|
7068
7068
|
[(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
|
|
7069
7069
|
rest
|
|
7070
7070
|
] : [
|
|
@@ -7098,14 +7098,14 @@ require = function () {
|
|
|
7098
7098
|
const array_1 = _dereq_('spica/array');
|
|
7099
7099
|
exports.emstrong = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('***'), (0, util_1.startTight)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '*')])), (0, source_1.str)(/^\*{1,3}/), false, ([as, bs, cs], rest, context) => {
|
|
7100
7100
|
var _a, _b;
|
|
7101
|
-
if (!(0, util_1.
|
|
7101
|
+
if (!(0, util_1.isEndTightNodes)(bs))
|
|
7102
7102
|
return [
|
|
7103
7103
|
(0, array_1.unshift)(as, bs),
|
|
7104
7104
|
cs[0] + rest
|
|
7105
7105
|
];
|
|
7106
7106
|
switch (cs[0]) {
|
|
7107
7107
|
case '*':
|
|
7108
|
-
return (_a = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '**')]), (ds, rest) => rest.slice(0, 2) === '**' && (0, util_1.
|
|
7108
|
+
return (_a = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '**')]), (ds, rest) => rest.slice(0, 2) === '**' && (0, util_1.isEndTightNodes)(ds) ? [
|
|
7109
7109
|
[(0, typed_dom_1.html)('strong', (0, array_1.unshift)([(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))], (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(ds))))],
|
|
7110
7110
|
rest.slice(2)
|
|
7111
7111
|
] : [
|
|
@@ -7122,7 +7122,7 @@ require = function () {
|
|
|
7122
7122
|
rest
|
|
7123
7123
|
];
|
|
7124
7124
|
case '**':
|
|
7125
|
-
return (_b = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '*')]), (ds, rest) => rest.slice(0, 1) === '*' && (0, util_1.
|
|
7125
|
+
return (_b = (0, combinator_1.bind)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '*')]), (ds, rest) => rest.slice(0, 1) === '*' && (0, util_1.isEndTightNodes)(ds) ? [
|
|
7126
7126
|
[(0, typed_dom_1.html)('em', (0, array_1.unshift)([(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))], (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(ds))))],
|
|
7127
7127
|
rest.slice(1)
|
|
7128
7128
|
] : [
|
|
@@ -7246,7 +7246,7 @@ require = function () {
|
|
|
7246
7246
|
}, (0, combinator_1.open)((0, source_1.str)(/^\|?/, false), (0, combinator_1.some)((0, combinator_1.union)([
|
|
7247
7247
|
signature,
|
|
7248
7248
|
inline_1.inline
|
|
7249
|
-
]), ']', /^\\?\n/), true)))), ']'), ns => [(0, typed_dom_1.html)('a', (0, util_1.
|
|
7249
|
+
]), ']', /^\\?\n/), true)))), ']'), ns => [(0, typed_dom_1.html)('a', (0, util_1.trimNodeEnd)((0, typed_dom_1.defrag)(ns)))])), ([el]) => [(0, typed_dom_1.define)(el, {
|
|
7250
7250
|
id: el.id ? null : global_1.undefined,
|
|
7251
7251
|
class: 'index',
|
|
7252
7252
|
href: el.id ? `#${ el.id }` : global_1.undefined
|
|
@@ -7485,7 +7485,7 @@ require = function () {
|
|
|
7485
7485
|
[(0, typed_dom_1.html)(tag, attributes('html', [], attrspec[tag], as))],
|
|
7486
7486
|
rest
|
|
7487
7487
|
]), ([, tag]) => tag)),
|
|
7488
|
-
(0, combinator_1.match)(/^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.
|
|
7488
|
+
(0, combinator_1.match)(/^(?=<(sup|sub|small|bdo|bdi)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.startLoose)((0, util_1.visible)((0, combinator_1.context)((() => {
|
|
7489
7489
|
switch (tag) {
|
|
7490
7490
|
case 'sup':
|
|
7491
7491
|
case 'sub':
|
|
@@ -7507,11 +7507,11 @@ require = function () {
|
|
|
7507
7507
|
default:
|
|
7508
7508
|
return {};
|
|
7509
7509
|
}
|
|
7510
|
-
})(), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`))), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
|
|
7510
|
+
})(), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`)))), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest, context) => [
|
|
7511
7511
|
[elem(tag, as, (0, util_1.trimEndBR)((0, typed_dom_1.defrag)(bs)), cs, context)],
|
|
7512
7512
|
rest
|
|
7513
7513
|
])), ([, tag]) => tag)),
|
|
7514
|
-
(0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.
|
|
7514
|
+
(0, combinator_1.match)(/^(?=<([a-z]+)(?=[^\S\n]|>))/, (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.validate)(`<${ tag }`, `</${ tag }>`, (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${ tag }`), (0, combinator_1.some)(exports.attribute), (0, source_1.str)('>'), true), (0, util_1.startLoose)((0, util_1.visible)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), `</${ tag }>`))), (0, source_1.str)(`</${ tag }>`), false, ([as, bs, cs], rest) => [
|
|
7515
7515
|
[elem(tag, as, (0, util_1.trimEndBR)((0, typed_dom_1.defrag)(bs)), cs, {})],
|
|
7516
7516
|
rest
|
|
7517
7517
|
], ([as, bs], rest) => as.length === 1 ? [
|
|
@@ -7672,7 +7672,7 @@ require = function () {
|
|
|
7672
7672
|
(0, combinator_1.context)({ syntax: { inline: { link: false } } }, (0, combinator_1.dup)((0, combinator_1.union)([
|
|
7673
7673
|
(0, combinator_1.surround)('[', inline_1.media, ']'),
|
|
7674
7674
|
(0, combinator_1.surround)('[', inline_1.shortmedia, ']'),
|
|
7675
|
-
(0, combinator_1.surround)('[', (0, util_1.
|
|
7675
|
+
(0, combinator_1.surround)('[', (0, util_1.startLoose)((0, util_1.visible)((0, combinator_1.context)({
|
|
7676
7676
|
syntax: {
|
|
7677
7677
|
inline: {
|
|
7678
7678
|
annotation: false,
|
|
@@ -7683,7 +7683,7 @@ require = function () {
|
|
|
7683
7683
|
autolink: false
|
|
7684
7684
|
}
|
|
7685
7685
|
}
|
|
7686
|
-
}, (0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/))), ']', true)
|
|
7686
|
+
}, (0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/)))), ']', true)
|
|
7687
7687
|
]))),
|
|
7688
7688
|
(0, combinator_1.dup)((0, combinator_1.surround)(/^{(?![{}])/, (0, combinator_1.inits)([
|
|
7689
7689
|
exports.uri,
|
|
@@ -7694,7 +7694,7 @@ require = function () {
|
|
|
7694
7694
|
if ((0, parser_1.eval)((0, combinator_1.some)(autolink_1.autolink)((0, util_1.stringify)(content), context), []).some(node => typeof node === 'object'))
|
|
7695
7695
|
return;
|
|
7696
7696
|
const INSECURE_URI = params.shift();
|
|
7697
|
-
const el = create(INSECURE_URI, (0, util_1.
|
|
7697
|
+
const el = create(INSECURE_URI, (0, util_1.trimNode)((0, typed_dom_1.defrag)(content)), new url_1.ReadonlyURL(resolve(INSECURE_URI, context.host || global_1.location, context.url || global_1.location), ((_a = context.host) === null || _a === void 0 ? void 0 : _a.href) || global_1.location.href), ((_b = context.host) === null || _b === void 0 ? void 0 : _b.origin) || global_1.location.origin);
|
|
7698
7698
|
if (el.classList.contains('invalid'))
|
|
7699
7699
|
return [
|
|
7700
7700
|
[el],
|
|
@@ -7798,7 +7798,7 @@ require = function () {
|
|
|
7798
7798
|
const util_1 = _dereq_('../util');
|
|
7799
7799
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
7800
7800
|
const array_1 = _dereq_('spica/array');
|
|
7801
|
-
exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('=='), (0, util_1.startTight)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '==')])), (0, source_1.str)('=='), false, ([as, bs, cs], rest) => (0, util_1.
|
|
7801
|
+
exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('=='), (0, util_1.startTight)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '==')])), (0, source_1.str)('=='), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
|
|
7802
7802
|
[(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
|
|
7803
7803
|
rest
|
|
7804
7804
|
] : [
|
|
@@ -7830,7 +7830,7 @@ require = function () {
|
|
|
7830
7830
|
const disallowedCommand = /\\(?:begin|tiny|huge|large)(?![0-9a-z])/i;
|
|
7831
7831
|
exports.math = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('$', '$', '\n', (0, combinator_1.rewrite)((0, combinator_1.union)([
|
|
7832
7832
|
(0, combinator_1.surround)('$', bracket, '$'),
|
|
7833
|
-
(0, combinator_1.surround)('$', (0, combinator_1.verify)((0, source_1.str)(/^(?=[\\^_[(|]|[A-Za-z][0-9A-Za-z]*'*[ ~]?(?:\$|([\\^_(|:=<>])(?!\1)))(?:\\\$|[\x20-\x23\x25-\x7E])*/), util_1.
|
|
7833
|
+
(0, combinator_1.surround)('$', (0, combinator_1.verify)((0, source_1.str)(/^(?=[\\^_[(|]|[A-Za-z][0-9A-Za-z]*'*[ ~]?(?:\$|([\\^_(|:=<>])(?!\1)))(?:\\\$|[\x20-\x23\x25-\x7E])*/), util_1.isEndTightNodes), /^\$(?![0-9A-Za-z])/)
|
|
7834
7834
|
]), (source, {
|
|
7835
7835
|
caches: {math: cache} = {}
|
|
7836
7836
|
}) => {
|
|
@@ -7874,7 +7874,6 @@ require = function () {
|
|
|
7874
7874
|
const html_1 = _dereq_('./html');
|
|
7875
7875
|
const htmlentity_1 = _dereq_('./htmlentity');
|
|
7876
7876
|
const source_1 = _dereq_('../source');
|
|
7877
|
-
const util_1 = _dereq_('../util');
|
|
7878
7877
|
const typed_dom_1 = _dereq_('typed-dom');
|
|
7879
7878
|
const url_1 = _dereq_('spica/url');
|
|
7880
7879
|
const array_1 = _dereq_('spica/array');
|
|
@@ -7892,7 +7891,7 @@ require = function () {
|
|
|
7892
7891
|
var _a, _b, _c;
|
|
7893
7892
|
return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.media) !== null && _c !== void 0 ? _c : true;
|
|
7894
7893
|
}, (0, combinator_1.tails)([
|
|
7895
|
-
(0, combinator_1.dup)((0, combinator_1.surround)(/^\[(
|
|
7894
|
+
(0, combinator_1.dup)((0, combinator_1.surround)(/^\[(?!\s*\\\s)/, (0, combinator_1.some)((0, combinator_1.union)([
|
|
7896
7895
|
htmlentity_1.htmlentity,
|
|
7897
7896
|
bracket,
|
|
7898
7897
|
source_1.txt
|
|
@@ -7902,12 +7901,12 @@ require = function () {
|
|
|
7902
7901
|
(0, combinator_1.some)(option)
|
|
7903
7902
|
]), /^[^\S\n]?}/))
|
|
7904
7903
|
])))), ([as, bs]) => bs ? [
|
|
7905
|
-
[(0, array_1.join)(as)],
|
|
7904
|
+
[(0, array_1.join)(as).trim() || (0, array_1.join)(as)],
|
|
7906
7905
|
bs
|
|
7907
7906
|
] : [
|
|
7908
7907
|
[''],
|
|
7909
7908
|
as
|
|
7910
|
-
]), ([[text]]) =>
|
|
7909
|
+
]), ([[text]]) => text === '' || text.trim() !== ''), ([[text], params], rest, context) => {
|
|
7911
7910
|
var _a, _b, _c, _d;
|
|
7912
7911
|
const INSECURE_URI = params.shift();
|
|
7913
7912
|
const url = new url_1.ReadonlyURL((0, link_1.resolve)(INSECURE_URI, context.host || global_1.location, context.url || global_1.location), ((_a = context.host) === null || _a === void 0 ? void 0 : _a.href) || global_1.location.href);
|
|
@@ -7916,14 +7915,14 @@ require = function () {
|
|
|
7916
7915
|
const el = cache && cached ? cache.get(url.href).cloneNode(true) : (0, typed_dom_1.html)('img', {
|
|
7917
7916
|
class: 'media',
|
|
7918
7917
|
'data-src': url.source,
|
|
7919
|
-
alt: text
|
|
7918
|
+
alt: text
|
|
7920
7919
|
});
|
|
7921
7920
|
if (!cached && !sanitize(url, el))
|
|
7922
7921
|
return [
|
|
7923
7922
|
[el],
|
|
7924
7923
|
rest
|
|
7925
7924
|
];
|
|
7926
|
-
cached && el.hasAttribute('alt') && el.setAttribute('alt', text
|
|
7925
|
+
cached && el.hasAttribute('alt') && el.setAttribute('alt', text);
|
|
7927
7926
|
(0, typed_dom_1.define)(el, (0, html_1.attributes)('media', (0, array_1.push)([], el.classList), optspec, params));
|
|
7928
7927
|
if (((_d = (_c = context.syntax) === null || _c === void 0 ? void 0 : _c.inline) === null || _d === void 0 ? void 0 : _d.link) === false || cached && el.tagName !== 'IMG')
|
|
7929
7928
|
return [
|
|
@@ -7988,7 +7987,6 @@ require = function () {
|
|
|
7988
7987
|
{
|
|
7989
7988
|
'../../combinator': 30,
|
|
7990
7989
|
'../source': 131,
|
|
7991
|
-
'../util': 137,
|
|
7992
7990
|
'./html': 114,
|
|
7993
7991
|
'./htmlentity': 115,
|
|
7994
7992
|
'./link': 117,
|
|
@@ -8013,7 +8011,7 @@ require = function () {
|
|
|
8013
8011
|
exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[[', ']]', '\n', (0, combinator_1.fmap)((0, combinator_1.surround)('[[', (0, combinator_1.guard)(context => {
|
|
8014
8012
|
var _a, _b, _c;
|
|
8015
8013
|
return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.reference) !== null && _c !== void 0 ? _c : true;
|
|
8016
|
-
}, (0, util_1.
|
|
8014
|
+
}, (0, util_1.startLoose)((0, util_1.visible)((0, combinator_1.context)({
|
|
8017
8015
|
syntax: {
|
|
8018
8016
|
inline: {
|
|
8019
8017
|
annotation: false,
|
|
@@ -8032,7 +8030,7 @@ require = function () {
|
|
|
8032
8030
|
''
|
|
8033
8031
|
]),
|
|
8034
8032
|
(0, combinator_1.some)(inline_1.inline, ']', /^\\?\n/)
|
|
8035
|
-
])))), ']]'), ns => [(0, typed_dom_1.html)('sup', attributes(ns), (0, util_1.
|
|
8033
|
+
]))))), ']]'), ns => [(0, typed_dom_1.html)('sup', attributes(ns), (0, util_1.trimNode)((0, typed_dom_1.defrag)(ns)))]))));
|
|
8036
8034
|
const abbr = (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.verify)((0, combinator_1.surround)('^', (0, combinator_1.union)([(0, source_1.str)(/^(?![0-9]+\s?[|\]])[0-9A-Za-z]+(?:(?:-|(?=\W)(?!'\d)'?(?!\.\d)\.?(?!,\S),? ?)[0-9A-Za-z]+)*(?:-|'?\.?,? ?)?/)]), /^\|?(?=]])|^\|[^\S\n]+/), (_, rest, context) => (0, util_1.isStartTight)(rest, context)), ([source]) => [(0, typed_dom_1.html)('abbr', source)]));
|
|
8037
8035
|
function attributes(ns) {
|
|
8038
8036
|
return typeof ns[0] === 'object' && ns[0].tagName === 'ABBR' ? {
|
|
@@ -8071,7 +8069,7 @@ require = function () {
|
|
|
8071
8069
|
exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.validate)('[', ')', '\n', (0, combinator_1.sequence)([
|
|
8072
8070
|
(0, combinator_1.surround)('[', (0, combinator_1.focus)(/^(?:\\[^\n]|[^\[\]\n])+(?=]\()/, text), ']'),
|
|
8073
8071
|
(0, combinator_1.surround)('(', (0, combinator_1.focus)(/^(?:\\[^\n]|[^\(\)\n])+(?=\))/, text), ')')
|
|
8074
|
-
])), ([texts]) => (0, util_1.
|
|
8072
|
+
])), ([texts]) => (0, util_1.isStartTightNodes)(texts)), ([texts, rubies], rest) => {
|
|
8075
8073
|
const tail = typeof texts[texts.length - 1] === 'object' ? [texts.pop()] : [];
|
|
8076
8074
|
tail.length === 0 && texts[texts.length - 1] === '' && texts.pop();
|
|
8077
8075
|
switch (true) {
|
|
@@ -8180,7 +8178,7 @@ require = function () {
|
|
|
8180
8178
|
emphasis_1.emphasis,
|
|
8181
8179
|
(0, combinator_1.some)(inline_1.inline, '*'),
|
|
8182
8180
|
(0, source_1.str)('*')
|
|
8183
|
-
]), '**')), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.
|
|
8181
|
+
]), '**')), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
|
|
8184
8182
|
[(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)((0, util_1.trimEndBR)(bs)))],
|
|
8185
8183
|
rest
|
|
8186
8184
|
] : [
|
|
@@ -8944,7 +8942,7 @@ require = function () {
|
|
|
8944
8942
|
function (_dereq_, module, exports) {
|
|
8945
8943
|
'use strict';
|
|
8946
8944
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
8947
|
-
exports.stringify = exports.trimEndBR = exports.
|
|
8945
|
+
exports.stringify = exports.trimEndBR = exports.trimNodeEnd = exports.trimNode = exports.visible = exports.isEndTightNodes = exports.isStartTightNodes = exports.isStartTight = exports.startTight = exports.startLoose = exports.visualize = void 0;
|
|
8948
8946
|
const global_1 = _dereq_('spica/global');
|
|
8949
8947
|
const parser_1 = _dereq_('../combinator/data/parser');
|
|
8950
8948
|
const combinator_1 = _dereq_('../combinator');
|
|
@@ -9019,6 +9017,15 @@ require = function () {
|
|
|
9019
9017
|
}
|
|
9020
9018
|
return false;
|
|
9021
9019
|
}
|
|
9020
|
+
function startLoose(parser) {
|
|
9021
|
+
return (source, context) => isStartLoose(source, context) ? parser(source, context) : global_1.undefined;
|
|
9022
|
+
}
|
|
9023
|
+
exports.startLoose = startLoose;
|
|
9024
|
+
function isStartLoose(source, context) {
|
|
9025
|
+
if (source === '')
|
|
9026
|
+
return true;
|
|
9027
|
+
return isStartTight(source.replace(/^[^\S\n]+/, ''), context);
|
|
9028
|
+
}
|
|
9022
9029
|
function startTight(parser) {
|
|
9023
9030
|
return (source, context) => isStartTight(source, context) ? parser(source, context) : global_1.undefined;
|
|
9024
9031
|
}
|
|
@@ -9058,25 +9065,37 @@ require = function () {
|
|
|
9058
9065
|
}
|
|
9059
9066
|
}
|
|
9060
9067
|
exports.isStartTight = isStartTight;
|
|
9061
|
-
function
|
|
9068
|
+
function isStartTightNodes(nodes) {
|
|
9062
9069
|
if (nodes.length === 0)
|
|
9063
9070
|
return true;
|
|
9064
9071
|
return isVisible(nodes[0], 0);
|
|
9065
9072
|
}
|
|
9066
|
-
exports.
|
|
9067
|
-
function
|
|
9073
|
+
exports.isStartTightNodes = isStartTightNodes;
|
|
9074
|
+
function isEndTightNodes(nodes) {
|
|
9068
9075
|
if (nodes.length === 0)
|
|
9069
9076
|
return true;
|
|
9070
9077
|
const last = nodes.length - 1;
|
|
9071
9078
|
return typeof nodes[last] === 'string' && nodes[last].length > 1 ? isVisible(nodes[last], -1) || isVisible(nodes[last], -2) : isVisible(nodes[last], -1) || last === 0 || isVisible(nodes[last - 1], -1);
|
|
9072
9079
|
}
|
|
9073
|
-
exports.
|
|
9080
|
+
exports.isEndTightNodes = isEndTightNodes;
|
|
9081
|
+
function visible(parser) {
|
|
9082
|
+
return (0, combinator_1.verify)(parser, nodes => {
|
|
9083
|
+
if (nodes.length === 0)
|
|
9084
|
+
return true;
|
|
9085
|
+
for (let i = 0; i < nodes.length; ++i) {
|
|
9086
|
+
if (isVisible(nodes[i]))
|
|
9087
|
+
return true;
|
|
9088
|
+
}
|
|
9089
|
+
return false;
|
|
9090
|
+
});
|
|
9091
|
+
}
|
|
9092
|
+
exports.visible = visible;
|
|
9074
9093
|
function isVisible(node, position) {
|
|
9075
9094
|
if (!node)
|
|
9076
9095
|
return false;
|
|
9077
9096
|
switch (typeof node) {
|
|
9078
9097
|
case 'string':
|
|
9079
|
-
const char = node[position >= 0 ? position : node.length + position];
|
|
9098
|
+
const char = position === global_1.undefined ? node : node[position >= 0 ? position : node.length + position];
|
|
9080
9099
|
switch (char) {
|
|
9081
9100
|
case ' ':
|
|
9082
9101
|
case '\t':
|
|
@@ -9099,7 +9118,25 @@ require = function () {
|
|
|
9099
9118
|
}
|
|
9100
9119
|
}
|
|
9101
9120
|
}
|
|
9102
|
-
function
|
|
9121
|
+
function trimNode(nodes) {
|
|
9122
|
+
return trimNodeStart(trimNodeEnd(nodes));
|
|
9123
|
+
}
|
|
9124
|
+
exports.trimNode = trimNode;
|
|
9125
|
+
function trimNodeStart(nodes) {
|
|
9126
|
+
const skip = nodes.length > 0 && typeof nodes[nodes.length - 1] === 'object' && nodes[nodes.length - 1]['className'] === 'indexer' ? [nodes.pop()] : [];
|
|
9127
|
+
for (let first = nodes[0]; nodes.length > 0 && !isVisible(first, 0) && !(typeof first === 'object' && first.className === 'comment');) {
|
|
9128
|
+
if (typeof first === 'string') {
|
|
9129
|
+
const pos = first.length - first.trimStart().length;
|
|
9130
|
+
if (pos > 0) {
|
|
9131
|
+
nodes[0] = first.slice(pos);
|
|
9132
|
+
break;
|
|
9133
|
+
}
|
|
9134
|
+
}
|
|
9135
|
+
nodes.pop();
|
|
9136
|
+
}
|
|
9137
|
+
return (0, array_1.push)(nodes, skip);
|
|
9138
|
+
}
|
|
9139
|
+
function trimNodeEnd(nodes) {
|
|
9103
9140
|
const skip = nodes.length > 0 && typeof nodes[nodes.length - 1] === 'object' && nodes[nodes.length - 1]['className'] === 'indexer' ? [nodes.pop()] : [];
|
|
9104
9141
|
for (let last = nodes[0]; nodes.length > 0 && !isVisible(last = nodes[nodes.length - 1], -1) && !(typeof last === 'object' && last.className === 'comment');) {
|
|
9105
9142
|
if (typeof last === 'string') {
|
|
@@ -9113,7 +9150,7 @@ require = function () {
|
|
|
9113
9150
|
}
|
|
9114
9151
|
return (0, array_1.push)(nodes, skip);
|
|
9115
9152
|
}
|
|
9116
|
-
exports.
|
|
9153
|
+
exports.trimNodeEnd = trimNodeEnd;
|
|
9117
9154
|
function trimEndBR(nodes) {
|
|
9118
9155
|
if (nodes.length === 0)
|
|
9119
9156
|
return nodes;
|
package/package-lock.json
CHANGED
package/package.json
CHANGED
|
@@ -14,8 +14,6 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('(())')), undefined);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('(()))')), undefined);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('(( ))')), undefined);
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('(( a))')), undefined);
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('(( a ))')), undefined);
|
|
19
17
|
assert.deepStrictEqual(inspect(parser('((\n))')), undefined);
|
|
20
18
|
assert.deepStrictEqual(inspect(parser('((\na))')), undefined);
|
|
21
19
|
assert.deepStrictEqual(inspect(parser('((\\ a))')), undefined);
|
|
@@ -34,6 +32,8 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
34
32
|
});
|
|
35
33
|
|
|
36
34
|
it('basic', () => {
|
|
35
|
+
assert.deepStrictEqual(inspect(parser('(( a))')), [['<sup class="annotation">a</sup>'], '']);
|
|
36
|
+
assert.deepStrictEqual(inspect(parser('(( a ))')), [['<sup class="annotation">a</sup>'], '']);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('((a))')), [['<sup class="annotation">a</sup>'], '']);
|
|
38
38
|
assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a</sup>'], '']);
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a</sup>'], '']);
|
|
@@ -2,13 +2,13 @@ import { undefined } from 'spica/global';
|
|
|
2
2
|
import { AnnotationParser } from '../inline';
|
|
3
3
|
import { union, some, validate, guard, context, creator, surround, lazy, fmap } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import {
|
|
5
|
+
import { startLoose, visible, trimNode } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
|
|
8
8
|
export const annotation: AnnotationParser = lazy(() => creator(validate('((', '))', '\n', fmap(surround(
|
|
9
9
|
'((',
|
|
10
10
|
guard(context => context.syntax?.inline?.annotation ?? true,
|
|
11
|
-
|
|
11
|
+
startLoose(visible(
|
|
12
12
|
context({ syntax: { inline: {
|
|
13
13
|
annotation: false,
|
|
14
14
|
// Redundant
|
|
@@ -20,6 +20,6 @@ export const annotation: AnnotationParser = lazy(() => creator(validate('((', ')
|
|
|
20
20
|
//link: true,
|
|
21
21
|
//autolink: true,
|
|
22
22
|
}}, state: undefined },
|
|
23
|
-
union([some(inline, ')', /^\\?\n/)])))),
|
|
23
|
+
union([some(inline, ')', /^\\?\n/)]))))),
|
|
24
24
|
'))'),
|
|
25
|
-
ns => [html('sup', { class: 'annotation' },
|
|
25
|
+
ns => [html('sup', { class: 'annotation' }, trimNode(defrag(ns)))]))));
|
|
@@ -3,7 +3,7 @@ import { union, some, creator, surround, close, lazy } from '../../combinator';
|
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { strong } from './strong';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import { startTight,
|
|
6
|
+
import { startTight, isEndTightNodes, trimEndBR } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
|
|
@@ -12,7 +12,7 @@ export const emphasis: EmphasisParser = lazy(() => creator(surround(close(
|
|
|
12
12
|
startTight(some(union([strong, some(inline, '*')]))),
|
|
13
13
|
str('*'), false,
|
|
14
14
|
([as, bs, cs], rest) =>
|
|
15
|
-
|
|
15
|
+
isEndTightNodes(bs)
|
|
16
16
|
? [[html('em', defrag(trimEndBR(bs)))], rest]
|
|
17
17
|
: [unshift(as, bs), cs[0] + rest],
|
|
18
18
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -2,7 +2,7 @@ import { EmStrongParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy, bind } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import { startTight,
|
|
5
|
+
import { startTight, isEndTightNodes, trimEndBR } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
@@ -11,13 +11,13 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
|
11
11
|
startTight(union([some(inline, '*')])),
|
|
12
12
|
str(/^\*{1,3}/), false,
|
|
13
13
|
([as, bs, cs], rest, context) => {
|
|
14
|
-
if (!
|
|
14
|
+
if (!isEndTightNodes(bs)) return [unshift(as, bs), cs[0] + rest];
|
|
15
15
|
switch (cs[0]) {
|
|
16
16
|
case '*':
|
|
17
17
|
return bind<EmStrongParser>(
|
|
18
18
|
union([some(inline, '**')]),
|
|
19
19
|
(ds, rest) =>
|
|
20
|
-
rest.slice(0, 2) === '**' &&
|
|
20
|
+
rest.slice(0, 2) === '**' && isEndTightNodes(ds)
|
|
21
21
|
? [[html('strong', unshift([html('em', defrag(trimEndBR(bs)))], defrag(trimEndBR(ds))))], rest.slice(2)]
|
|
22
22
|
: [unshift(['**', html('em', defrag(trimEndBR(bs)))], ds), rest])
|
|
23
23
|
(rest, context) ?? [['**', html('em', defrag(trimEndBR(bs)))], rest];
|
|
@@ -25,7 +25,7 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
|
25
25
|
return bind<EmStrongParser>(
|
|
26
26
|
union([some(inline, '*')]),
|
|
27
27
|
(ds, rest) =>
|
|
28
|
-
rest.slice(0, 1) === '*' &&
|
|
28
|
+
rest.slice(0, 1) === '*' && isEndTightNodes(ds)
|
|
29
29
|
? [[html('em', unshift([html('strong', defrag(trimEndBR(bs)))], defrag(trimEndBR(ds))))], rest.slice(1)]
|
|
30
30
|
: [unshift(['*', html('strong', defrag(trimEndBR(bs)))], ds), rest])
|
|
31
31
|
(rest, context) ?? [['*', html('strong', defrag(trimEndBR(bs)))], rest];
|
|
@@ -4,7 +4,7 @@ import { union, some, validate, guard, context, creator, surround, open, lazy, f
|
|
|
4
4
|
import { inline } from '../../inline';
|
|
5
5
|
import { indexee, identify } from './indexee';
|
|
6
6
|
import { txt, str } from '../../source';
|
|
7
|
-
import { startTight,
|
|
7
|
+
import { startTight, trimNodeEnd } from '../../util';
|
|
8
8
|
import { html, define, defrag } from 'typed-dom';
|
|
9
9
|
import { join } from 'spica/array';
|
|
10
10
|
|
|
@@ -29,7 +29,7 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
|
|
|
29
29
|
inline,
|
|
30
30
|
]), ']', /^\\?\n/), true)))),
|
|
31
31
|
']'),
|
|
32
|
-
ns => [html('a',
|
|
32
|
+
ns => [html('a', trimNodeEnd(defrag(ns)))])),
|
|
33
33
|
([el]: [HTMLAnchorElement]) => [
|
|
34
34
|
define(el,
|
|
35
35
|
{
|
|
@@ -29,8 +29,6 @@ describe('Unit: parser/inline/html', () => {
|
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('<small>z')), undefined);
|
|
30
30
|
assert.deepStrictEqual(inspect(parser('<small></small>')), undefined);
|
|
31
31
|
assert.deepStrictEqual(inspect(parser('<small> </small>')), undefined);
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('<small> a</small>')), undefined);
|
|
33
|
-
assert.deepStrictEqual(inspect(parser('<small> a </small>')), undefined);
|
|
34
32
|
assert.deepStrictEqual(inspect(parser('<small>\n</small>')), undefined);
|
|
35
33
|
assert.deepStrictEqual(inspect(parser('<small>\na</small>')), undefined);
|
|
36
34
|
assert.deepStrictEqual(inspect(parser('<small>\\ a</small>')), undefined);
|
|
@@ -59,6 +57,8 @@ describe('Unit: parser/inline/html', () => {
|
|
|
59
57
|
});
|
|
60
58
|
|
|
61
59
|
it('basic', () => {
|
|
60
|
+
assert.deepStrictEqual(inspect(parser('<small> a</small>')), [['<small> a</small>'], '']);
|
|
61
|
+
assert.deepStrictEqual(inspect(parser('<small> a </small>')), [['<small> a </small>'], '']);
|
|
62
62
|
assert.deepStrictEqual(inspect(parser('<small>a</small>')), [['<small>a</small>'], '']);
|
|
63
63
|
assert.deepStrictEqual(inspect(parser('<small>a</small>a')), [['<small>a</small>'], 'a']);
|
|
64
64
|
assert.deepStrictEqual(inspect(parser('<small>a </small>')), [['<small>a </small>'], '']);
|
|
@@ -5,7 +5,7 @@ import { HTMLParser } from '../inline';
|
|
|
5
5
|
import { union, some, validate, context, creator, surround, match, lazy } from '../../combinator';
|
|
6
6
|
import { inline } from '../inline';
|
|
7
7
|
import { str } from '../source';
|
|
8
|
-
import {
|
|
8
|
+
import { startLoose, visible, trimEndBR } from '../util';
|
|
9
9
|
import { html as h, defrag } from 'typed-dom';
|
|
10
10
|
import { memoize } from 'spica/memoize';
|
|
11
11
|
import { Cache } from 'spica/cache';
|
|
@@ -39,7 +39,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
39
39
|
validate(`<${tag}`, `</${tag}>`,
|
|
40
40
|
surround<HTMLParser.TagParser, string>(surround(
|
|
41
41
|
str(`<${tag}`), some(attribute), str('>'), true),
|
|
42
|
-
|
|
42
|
+
startLoose(visible(
|
|
43
43
|
context((() => {
|
|
44
44
|
switch (tag) {
|
|
45
45
|
case 'sup':
|
|
@@ -63,7 +63,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
63
63
|
return {};
|
|
64
64
|
}
|
|
65
65
|
})(),
|
|
66
|
-
some(union([inline]), `</${tag}>`))),
|
|
66
|
+
some(union([inline]), `</${tag}>`)))),
|
|
67
67
|
str(`</${tag}>`), false,
|
|
68
68
|
([as, bs, cs], rest, context) =>
|
|
69
69
|
[[elem(tag, as, trimEndBR(defrag(bs)), cs, context)], rest])),
|
|
@@ -75,7 +75,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', '>', '\n', vali
|
|
|
75
75
|
validate(`<${tag}`, `</${tag}>`,
|
|
76
76
|
surround<HTMLParser.TagParser, string>(surround(
|
|
77
77
|
str(`<${tag}`), some(attribute), str('>'), true),
|
|
78
|
-
|
|
78
|
+
startLoose(visible(some(union([inline]), `</${tag}>`))),
|
|
79
79
|
str(`</${tag}>`), false,
|
|
80
80
|
([as, bs, cs], rest) =>
|
|
81
81
|
[[elem(tag, as, trimEndBR(defrag(bs)), cs, {})], rest],
|
|
@@ -65,8 +65,6 @@ describe('Unit: parser/inline/link', () => {
|
|
|
65
65
|
assert.deepStrictEqual(inspect(parser('[[]{}')), undefined);
|
|
66
66
|
assert.deepStrictEqual(inspect(parser('[]]{}')), undefined);
|
|
67
67
|
assert.deepStrictEqual(inspect(parser('[a]{}')), undefined);
|
|
68
|
-
assert.deepStrictEqual(inspect(parser('[ a]{b}')), undefined);
|
|
69
|
-
assert.deepStrictEqual(inspect(parser('[ a ]{b}')), undefined);
|
|
70
68
|
assert.deepStrictEqual(inspect(parser('[a\nb]{#}')), undefined);
|
|
71
69
|
assert.deepStrictEqual(inspect(parser('[a\\\nb]{#}')), undefined);
|
|
72
70
|
assert.deepStrictEqual(inspect(parser('[<wbr>]{/}')), undefined);
|
|
@@ -95,11 +93,13 @@ describe('Unit: parser/inline/link', () => {
|
|
|
95
93
|
assert.deepStrictEqual(inspect(parser('[]{^/b}')), [[`<a href="/b">^/b</a>`], '']);
|
|
96
94
|
assert.deepStrictEqual(inspect(parser('[]{#}')), [['<a href="#">#</a>'], '']);
|
|
97
95
|
assert.deepStrictEqual(inspect(parser('[]{#b}')), [['<a href="#b">#b</a>'], '']);
|
|
96
|
+
assert.deepStrictEqual(inspect(parser('[ a]{b}')), [['<a href="b">a</a>'], '']);
|
|
97
|
+
assert.deepStrictEqual(inspect(parser('[ a ]{b}')), [['<a href="b">a</a>'], '']);
|
|
98
|
+
assert.deepStrictEqual(inspect(parser('[a ]{b}')), [['<a href="b">a</a>'], '']);
|
|
99
|
+
assert.deepStrictEqual(inspect(parser('[a ]{b}')), [['<a href="b">a</a>'], '']);
|
|
98
100
|
assert.deepStrictEqual(inspect(parser('[a]{b}')), [['<a href="b">a</a>'], '']);
|
|
99
101
|
assert.deepStrictEqual(inspect(parser('[a]{#}')), [['<a href="#">a</a>'], '']);
|
|
100
102
|
assert.deepStrictEqual(inspect(parser('[a]{#b}')), [['<a href="#b">a</a>'], '']);
|
|
101
|
-
assert.deepStrictEqual(inspect(parser('[a ]{b}')), [['<a href="b">a</a>'], '']);
|
|
102
|
-
assert.deepStrictEqual(inspect(parser('[a ]{b}')), [['<a href="b">a</a>'], '']);
|
|
103
103
|
assert.deepStrictEqual(inspect(parser('[a b]{c}')), [['<a href="c">a b</a>'], '']);
|
|
104
104
|
assert.deepStrictEqual(inspect(parser(`[]{?#${encodeURIComponent(':/[]{}<>?#=& ')}}`)), [['<a href="?#%3A%2F%5B%5D%7B%7D%3C%3E%3F%23%3D%26%20">?#%3A%2F[]{}<>%3F%23%3D%26%20</a>'], '']);
|
|
105
105
|
assert.deepStrictEqual(inspect(parser('{b}')), [['<a href="b">b</a>'], '']);
|
|
@@ -7,7 +7,7 @@ import { inline, media, shortmedia } from '../inline';
|
|
|
7
7
|
import { attributes } from './html';
|
|
8
8
|
import { autolink } from '../autolink';
|
|
9
9
|
import { str } from '../source';
|
|
10
|
-
import {
|
|
10
|
+
import { startLoose, visible, trimNode, stringify } from '../util';
|
|
11
11
|
import { html, define, defrag } from 'typed-dom';
|
|
12
12
|
import { ReadonlyURL } from 'spica/url';
|
|
13
13
|
|
|
@@ -28,7 +28,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(reverse(
|
|
|
28
28
|
surround('[', shortmedia, ']'),
|
|
29
29
|
surround(
|
|
30
30
|
'[',
|
|
31
|
-
|
|
31
|
+
startLoose(visible(
|
|
32
32
|
context({ syntax: { inline: {
|
|
33
33
|
annotation: false,
|
|
34
34
|
reference: false,
|
|
@@ -39,7 +39,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(reverse(
|
|
|
39
39
|
media: false,
|
|
40
40
|
autolink: false,
|
|
41
41
|
}}},
|
|
42
|
-
some(inline, ']', /^\\?\n/))),
|
|
42
|
+
some(inline, ']', /^\\?\n/)))),
|
|
43
43
|
']',
|
|
44
44
|
true),
|
|
45
45
|
]))),
|
|
@@ -54,7 +54,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(reverse(
|
|
|
54
54
|
assert(!INSECURE_URI.match(/\s/));
|
|
55
55
|
const el = create(
|
|
56
56
|
INSECURE_URI,
|
|
57
|
-
|
|
57
|
+
trimNode(defrag(content)),
|
|
58
58
|
new ReadonlyURL(
|
|
59
59
|
resolve(INSECURE_URI, context.host || location, context.url || location),
|
|
60
60
|
context.host?.href || location.href),
|
|
@@ -2,7 +2,7 @@ import { MarkParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import { startTight,
|
|
5
|
+
import { startTight, isEndTightNodes, trimEndBR } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@ export const mark: MarkParser = lazy(() => creator(surround(
|
|
|
11
11
|
startTight(union([some(inline, '==')])),
|
|
12
12
|
str('=='), false,
|
|
13
13
|
([as, bs, cs], rest) =>
|
|
14
|
-
|
|
14
|
+
isEndTightNodes(bs)
|
|
15
15
|
? [[html('mark', defrag(trimEndBR(bs)))], rest]
|
|
16
16
|
: [unshift(as, bs), cs[0] + rest],
|
|
17
17
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MathParser } from '../inline';
|
|
2
2
|
import { union, some, validate, verify, rewrite, creator, surround, lazy } from '../../combinator';
|
|
3
3
|
import { escsource, str } from '../source';
|
|
4
|
-
import {
|
|
4
|
+
import { isEndTightNodes } from '../util';
|
|
5
5
|
import { html } from 'typed-dom';
|
|
6
6
|
|
|
7
7
|
const disallowedCommand = /\\(?:begin|tiny|huge|large)(?![0-9a-z])/i;
|
|
@@ -21,7 +21,7 @@ export const math: MathParser = lazy(() => creator(validate('$', '$', '\n', rewr
|
|
|
21
21
|
// $[A-z]*[,.!?()] : Incomplete syntax before texts
|
|
22
22
|
// $[A-z]*\s?[!@#&*+~=`$[]{<] : Incomplete syntax in or around another syntax
|
|
23
23
|
str(/^(?=[\\^_[(|]|[A-Za-z][0-9A-Za-z]*'*[ ~]?(?:\$|([\\^_(|:=<>])(?!\1)))(?:\\\$|[\x20-\x23\x25-\x7E])*/),
|
|
24
|
-
|
|
24
|
+
isEndTightNodes),
|
|
25
25
|
/^\$(?![0-9A-Za-z])/),
|
|
26
26
|
]),
|
|
27
27
|
(source, { caches: { math: cache } = {} }) => [[
|
|
@@ -39,9 +39,8 @@ describe('Unit: parser/inline/media', () => {
|
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('![\\ ]{#}')), undefined);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('![	]{#}')), undefined);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('![a]{}')), undefined);
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('![ a]{#}')), undefined);
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('![ a ]{#}')), undefined);
|
|
44
42
|
assert.deepStrictEqual(inspect(parser('![\\ a ]{#}')), undefined);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('![ \\ a ]{#}')), undefined);
|
|
45
44
|
assert.deepStrictEqual(inspect(parser('![a\nb]{#}')), undefined);
|
|
46
45
|
assert.deepStrictEqual(inspect(parser('![a\\\nb]{#}')), undefined);
|
|
47
46
|
assert.deepStrictEqual(inspect(parser('![]{ttp://host}')), [['<img class="media invalid" data-src="ttp://host" alt="">'], '']);
|
|
@@ -63,6 +62,8 @@ describe('Unit: parser/inline/media', () => {
|
|
|
63
62
|
assert.deepStrictEqual(inspect(parser('![]{\\b}')), [['<a href="\\b" target="_blank"><img class="media" data-src="\\b" alt=""></a>'], '']);
|
|
64
63
|
assert.deepStrictEqual(inspect(parser('![]{./b}')), [['<a href="./b" target="_blank"><img class="media" data-src="./b" alt=""></a>'], '']);
|
|
65
64
|
assert.deepStrictEqual(inspect(parser('![]{^/b}')), [[`<a href="/b" target="_blank"><img class="media" data-src="/b" alt=""></a>`], '']);
|
|
65
|
+
assert.deepStrictEqual(inspect(parser('![ a]{b}')), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="a"></a>'], '']);
|
|
66
|
+
assert.deepStrictEqual(inspect(parser('![ a ]{b}')), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="a"></a>'], '']);
|
|
66
67
|
assert.deepStrictEqual(inspect(parser('![a ]{b}')), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="a"></a>'], '']);
|
|
67
68
|
assert.deepStrictEqual(inspect(parser('![a ]{b}')), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="a"></a>'], '']);
|
|
68
69
|
assert.deepStrictEqual(inspect(parser('![a b]{c}')), [['<a href="c" target="_blank"><img class="media" data-src="c" alt="a b"></a>'], '']);
|
|
@@ -6,7 +6,6 @@ import { link, uri, option as linkoption, resolve } from './link';
|
|
|
6
6
|
import { attributes } from './html';
|
|
7
7
|
import { htmlentity } from './htmlentity';
|
|
8
8
|
import { txt, str } from '../source';
|
|
9
|
-
import { verifyStartTight } from '../util';
|
|
10
9
|
import { html, define } from 'typed-dom';
|
|
11
10
|
import { ReadonlyURL } from 'spica/url';
|
|
12
11
|
import { unshift, push, join } from 'spica/array';
|
|
@@ -24,11 +23,11 @@ export const media: MediaParser = lazy(() => creator(10, bind(verify(fmap(open(
|
|
|
24
23
|
validate(['[', '{'], '}', '\n',
|
|
25
24
|
guard(context => context.syntax?.inline?.media ?? true,
|
|
26
25
|
tails([
|
|
27
|
-
dup(surround(/^\[(
|
|
26
|
+
dup(surround(/^\[(?!\s*\\\s)/, some(union([htmlentity, bracket, txt]), ']', /^\\?\n/), ']', true)),
|
|
28
27
|
dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]?}/)),
|
|
29
28
|
])))),
|
|
30
|
-
([as, bs]) => bs ? [[join(as)], bs] : [[''], as]),
|
|
31
|
-
([[text]]) =>
|
|
29
|
+
([as, bs]) => bs ? [[join(as).trim() || join(as)], bs] : [[''], as]),
|
|
30
|
+
([[text]]) => text === '' || text.trim() !== ''),
|
|
32
31
|
([[text], params], rest, context) => {
|
|
33
32
|
const INSECURE_URI = params.shift()!;
|
|
34
33
|
assert(INSECURE_URI === INSECURE_URI.trim());
|
|
@@ -40,9 +39,9 @@ export const media: MediaParser = lazy(() => creator(10, bind(verify(fmap(open(
|
|
|
40
39
|
const cached = cache?.has(url.href);
|
|
41
40
|
const el = cache && cached
|
|
42
41
|
? cache.get(url.href)!.cloneNode(true)
|
|
43
|
-
: html('img', { class: 'media', 'data-src': url.source, alt: text
|
|
42
|
+
: html('img', { class: 'media', 'data-src': url.source, alt: text });
|
|
44
43
|
if (!cached && !sanitize(url, el)) return [[el], rest];
|
|
45
|
-
cached && el.hasAttribute('alt') && el.setAttribute('alt', text
|
|
44
|
+
cached && el.hasAttribute('alt') && el.setAttribute('alt', text);
|
|
46
45
|
define(el, attributes('media', push([], el.classList), optspec, params));
|
|
47
46
|
assert(el.matches('img') || !el.matches('.invalid'));
|
|
48
47
|
if (context.syntax?.inline?.link === false || cached && el.tagName !== 'IMG') return [[el], rest];
|
|
@@ -14,8 +14,6 @@ describe('Unit: parser/inline/reference', () => {
|
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('[[]]')), undefined);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('[[]]]')), undefined);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('[[ ]]')), undefined);
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('[[ a]]')), undefined);
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('[[ a ]]')), undefined);
|
|
19
17
|
assert.deepStrictEqual(inspect(parser('[[\n]]')), undefined);
|
|
20
18
|
assert.deepStrictEqual(inspect(parser('[[\na]]')), undefined);
|
|
21
19
|
assert.deepStrictEqual(inspect(parser('[[\\ a]]')), undefined);
|
|
@@ -34,6 +32,8 @@ describe('Unit: parser/inline/reference', () => {
|
|
|
34
32
|
});
|
|
35
33
|
|
|
36
34
|
it('basic', () => {
|
|
35
|
+
assert.deepStrictEqual(inspect(parser('[[ a]]')), [['<sup class="reference">a</sup>'], '']);
|
|
36
|
+
assert.deepStrictEqual(inspect(parser('[[ a ]]')), [['<sup class="reference">a</sup>'], '']);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('[[a]]')), [['<sup class="reference">a</sup>'], '']);
|
|
38
38
|
assert.deepStrictEqual(inspect(parser('[[a ]]')), [['<sup class="reference">a</sup>'], '']);
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('[[a ]]')), [['<sup class="reference">a</sup>'], '']);
|
|
@@ -3,13 +3,13 @@ import { ReferenceParser } from '../inline';
|
|
|
3
3
|
import { union, subsequence, some, validate, verify, focus, guard, context, creator, surround, lazy, fmap } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import {
|
|
6
|
+
import { startLoose, isStartTight, visible, trimNode, stringify } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
|
|
9
9
|
export const reference: ReferenceParser = lazy(() => creator(validate('[[', ']]', '\n', fmap(surround(
|
|
10
10
|
'[[',
|
|
11
11
|
guard(context => context.syntax?.inline?.reference ?? true,
|
|
12
|
-
|
|
12
|
+
startLoose(visible(
|
|
13
13
|
context({ syntax: { inline: {
|
|
14
14
|
annotation: false,
|
|
15
15
|
reference: false,
|
|
@@ -24,9 +24,9 @@ export const reference: ReferenceParser = lazy(() => creator(validate('[[', ']]'
|
|
|
24
24
|
abbr,
|
|
25
25
|
focus('^', c => [['', c], '']),
|
|
26
26
|
some(inline, ']', /^\\?\n/),
|
|
27
|
-
])))),
|
|
27
|
+
]))))),
|
|
28
28
|
']]'),
|
|
29
|
-
ns => [html('sup', attributes(ns),
|
|
29
|
+
ns => [html('sup', attributes(ns), trimNode(defrag(ns)))]))));
|
|
30
30
|
|
|
31
31
|
const abbr: ReferenceParser.AbbrParser = creator(fmap(verify(surround(
|
|
32
32
|
'^',
|
|
@@ -4,7 +4,7 @@ import { eval, exec } from '../../combinator/data/parser';
|
|
|
4
4
|
import { sequence, validate, verify, focus, creator, surround, lazy, bind } from '../../combinator';
|
|
5
5
|
import { htmlentity } from './htmlentity';
|
|
6
6
|
import { text as txt } from '../source';
|
|
7
|
-
import {
|
|
7
|
+
import { isStartTightNodes } from '../util';
|
|
8
8
|
import { html, defrag } from 'typed-dom';
|
|
9
9
|
import { unshift, push, join } from 'spica/array';
|
|
10
10
|
|
|
@@ -14,7 +14,7 @@ export const ruby: RubyParser = lazy(() => creator(bind(verify(
|
|
|
14
14
|
surround('[', focus(/^(?:\\[^\n]|[^\[\]\n])+(?=]\()/, text), ']'),
|
|
15
15
|
surround('(', focus(/^(?:\\[^\n]|[^\(\)\n])+(?=\))/, text), ')'),
|
|
16
16
|
])),
|
|
17
|
-
([texts]) =>
|
|
17
|
+
([texts]) => isStartTightNodes(texts)),
|
|
18
18
|
([texts, rubies], rest) => {
|
|
19
19
|
const tail = typeof texts[texts.length - 1] === 'object'
|
|
20
20
|
? [texts.pop()!]
|
|
@@ -3,7 +3,7 @@ import { union, some, creator, surround, close, lazy } from '../../combinator';
|
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { emphasis } from './emphasis';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import { startTight,
|
|
6
|
+
import { startTight, isEndTightNodes, trimEndBR } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
|
|
@@ -12,7 +12,7 @@ export const strong: StrongParser = lazy(() => creator(surround(close(
|
|
|
12
12
|
startTight(some(union([emphasis, some(inline, '*'), str('*')]), '**')),
|
|
13
13
|
str('**'), false,
|
|
14
14
|
([as, bs, cs], rest) =>
|
|
15
|
-
|
|
15
|
+
isEndTightNodes(bs)
|
|
16
16
|
? [[html('strong', defrag(trimEndBR(bs)))], rest]
|
|
17
17
|
: [unshift(as, bs), cs[0] + rest],
|
|
18
18
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
package/src/parser/util.ts
CHANGED
|
@@ -70,6 +70,17 @@ function hasVisible(
|
|
|
70
70
|
return false;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
export function startLoose<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
74
|
+
export function startLoose<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
|
|
75
|
+
return (source, context) =>
|
|
76
|
+
isStartLoose(source, context)
|
|
77
|
+
? parser(source, context)
|
|
78
|
+
: undefined;
|
|
79
|
+
}
|
|
80
|
+
function isStartLoose(source: string, context: MarkdownParser.Context): boolean {
|
|
81
|
+
if (source === '') return true;
|
|
82
|
+
return isStartTight(source.replace(/^[^\S\n]+/, ''), context);
|
|
83
|
+
}
|
|
73
84
|
export function startTight<P extends Parser<unknown>>(parser: P): P;
|
|
74
85
|
export function startTight<T>(parser: Parser<T>): Parser<T> {
|
|
75
86
|
return (source, context) =>
|
|
@@ -116,11 +127,11 @@ export function isStartTight(source: string, context: MarkdownParser.Context): b
|
|
|
116
127
|
return source[0].trimStart() !== '';
|
|
117
128
|
}
|
|
118
129
|
}
|
|
119
|
-
export function
|
|
130
|
+
export function isStartTightNodes(nodes: readonly (HTMLElement | string)[]): boolean {
|
|
120
131
|
if (nodes.length === 0) return true;
|
|
121
132
|
return isVisible(nodes[0], 0);
|
|
122
133
|
}
|
|
123
|
-
export function
|
|
134
|
+
export function isEndTightNodes(nodes: readonly (HTMLElement | string)[]): boolean {
|
|
124
135
|
if (nodes.length === 0) return true;
|
|
125
136
|
const last = nodes.length - 1;
|
|
126
137
|
return typeof nodes[last] === 'string' && (nodes[last] as string).length > 1
|
|
@@ -129,12 +140,23 @@ export function verifyEndTight(nodes: readonly (HTMLElement | string)[]): boolea
|
|
|
129
140
|
: isVisible(nodes[last], -1) || last === 0 ||
|
|
130
141
|
isVisible(nodes[last - 1], -1);
|
|
131
142
|
}
|
|
132
|
-
function
|
|
143
|
+
export function visible<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
144
|
+
export function visible<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
|
|
145
|
+
return verify(parser, nodes => {
|
|
146
|
+
if (nodes.length === 0) return true;
|
|
147
|
+
for (let i = 0; i < nodes.length; ++i) {
|
|
148
|
+
if (isVisible(nodes[i])) return true;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function isVisible(node: HTMLElement | string, position?: number): boolean {
|
|
133
154
|
if (!node) return false;
|
|
134
155
|
switch (typeof node) {
|
|
135
156
|
case 'string':
|
|
136
|
-
|
|
137
|
-
|
|
157
|
+
const char = position === undefined
|
|
158
|
+
? node
|
|
159
|
+
: node[position >= 0 ? position : node.length + position];
|
|
138
160
|
assert(char);
|
|
139
161
|
switch (char) {
|
|
140
162
|
case ' ':
|
|
@@ -159,8 +181,34 @@ function isVisible(node: HTMLElement | string, position: number): boolean {
|
|
|
159
181
|
}
|
|
160
182
|
}
|
|
161
183
|
|
|
162
|
-
export function
|
|
163
|
-
|
|
184
|
+
export function trimNode(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
185
|
+
return trimNodeStart(trimNodeEnd(nodes));
|
|
186
|
+
}
|
|
187
|
+
function trimNodeStart(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
188
|
+
const skip = nodes.length > 0 &&
|
|
189
|
+
typeof nodes[nodes.length - 1] === 'object' &&
|
|
190
|
+
nodes[nodes.length - 1]['className'] === 'indexer'
|
|
191
|
+
? [nodes.pop()!]
|
|
192
|
+
: [];
|
|
193
|
+
for (
|
|
194
|
+
let first = nodes[0];
|
|
195
|
+
nodes.length > 0 &&
|
|
196
|
+
!isVisible(first, 0) &&
|
|
197
|
+
!(typeof first === 'object' && first.className === 'comment');
|
|
198
|
+
) {
|
|
199
|
+
assert(nodes.length > 0);
|
|
200
|
+
if (typeof first === 'string') {
|
|
201
|
+
const pos = first.length - first.trimStart().length;
|
|
202
|
+
if (pos > 0) {
|
|
203
|
+
nodes[0] = first.slice(pos);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
nodes.pop();
|
|
208
|
+
}
|
|
209
|
+
return push(nodes, skip);
|
|
210
|
+
}
|
|
211
|
+
export function trimNodeEnd(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
164
212
|
const skip = nodes.length > 0 &&
|
|
165
213
|
typeof nodes[nodes.length - 1] === 'object' &&
|
|
166
214
|
nodes[nodes.length - 1]['className'] === 'indexer'
|