@lvce-editor/extension-detail-view 3.15.0 → 3.16.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/dist/extensionDetailViewWorkerMain.js +98 -3069
- package/package.json +1 -1
|
@@ -82,12 +82,6 @@ const getType = value => {
|
|
|
82
82
|
return 'unknown';
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
-
const array = value => {
|
|
86
|
-
const type = getType(value);
|
|
87
|
-
if (type !== 'array') {
|
|
88
|
-
throw new AssertionError('expected value to be of type array');
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
85
|
const string = value => {
|
|
92
86
|
const type = getType(value);
|
|
93
87
|
if (type !== 'string') {
|
|
@@ -896,7 +890,7 @@ const create = (uid, uri, width, height, platform, assetDir$1) => {
|
|
|
896
890
|
const AdditionalDetails = 'AdditionalDetails';
|
|
897
891
|
const AdditionalDetailsEntry = 'AdditionalDetailsEntry';
|
|
898
892
|
const AdditionalDetailsTitle = 'AdditionalDetailsTitle';
|
|
899
|
-
const Aside
|
|
893
|
+
const Aside = 'Aside';
|
|
900
894
|
const Button$1 = 'Button';
|
|
901
895
|
const ButtonPrimary = 'ButtonPrimary';
|
|
902
896
|
const Categories = 'Categories';
|
|
@@ -922,7 +916,6 @@ const Features$1 = 'Features';
|
|
|
922
916
|
const FeaturesList = 'FeaturesList';
|
|
923
917
|
const FeatureWebView = 'FeatureWebView';
|
|
924
918
|
const Large$1 = 'Large';
|
|
925
|
-
const Markdown = 'Markdown';
|
|
926
919
|
const MoreInfo = 'MoreInfo';
|
|
927
920
|
const MoreInfoEntry = 'MoreInfoEntry';
|
|
928
921
|
const MoreInfoEntryKey = 'MoreInfoEntryKey';
|
|
@@ -1009,49 +1002,24 @@ const getDisplaySize = size => {
|
|
|
1009
1002
|
});
|
|
1010
1003
|
};
|
|
1011
1004
|
|
|
1012
|
-
const A
|
|
1013
|
-
const Abbr$1 = 54;
|
|
1014
|
-
const Article$1 = 27;
|
|
1015
|
-
const Aside$1 = 28;
|
|
1016
|
-
const Br$1 = 55;
|
|
1005
|
+
const A = 53;
|
|
1017
1006
|
const Button = 1;
|
|
1018
|
-
const
|
|
1019
|
-
const
|
|
1020
|
-
const
|
|
1021
|
-
const
|
|
1022
|
-
const
|
|
1023
|
-
const Figcaption$1 = 45;
|
|
1024
|
-
const Figure$1 = 46;
|
|
1025
|
-
const Footer$1 = 29;
|
|
1026
|
-
const H1$1 = 5;
|
|
1027
|
-
const H2$1 = 22;
|
|
1028
|
-
const H3$1 = 23;
|
|
1029
|
-
const H4$1 = 24;
|
|
1030
|
-
const H5$1 = 25;
|
|
1031
|
-
const Header$1 = 30;
|
|
1032
|
-
const Hr$1 = 47;
|
|
1033
|
-
const Img$1 = 17;
|
|
1034
|
-
const Li$1 = 48;
|
|
1035
|
-
const Nav$1 = 40;
|
|
1036
|
-
const Ol$1 = 49;
|
|
1037
|
-
const P$1 = 50;
|
|
1038
|
-
const Pre$1 = 51;
|
|
1039
|
-
const Search$1 = 42;
|
|
1040
|
-
const Section$1 = 41;
|
|
1041
|
-
const Span$1 = 8;
|
|
1007
|
+
const Div = 4;
|
|
1008
|
+
const H1 = 5;
|
|
1009
|
+
const H2 = 22;
|
|
1010
|
+
const Img = 17;
|
|
1011
|
+
const Pre = 51;
|
|
1042
1012
|
const Table = 9;
|
|
1043
1013
|
const TBody = 10;
|
|
1044
1014
|
const Td = 11;
|
|
1045
|
-
const Text$
|
|
1046
|
-
const Tfoot$1 = 59;
|
|
1015
|
+
const Text$1 = 12;
|
|
1047
1016
|
const Th = 13;
|
|
1048
1017
|
const THead = 14;
|
|
1049
|
-
const Time$1 = 58;
|
|
1050
1018
|
const Tr = 15;
|
|
1051
1019
|
|
|
1052
1020
|
const text = data => {
|
|
1053
1021
|
return {
|
|
1054
|
-
type: Text$
|
|
1022
|
+
type: Text$1,
|
|
1055
1023
|
text: data,
|
|
1056
1024
|
childCount: 0
|
|
1057
1025
|
};
|
|
@@ -1060,24 +1028,23 @@ const text = data => {
|
|
|
1060
1028
|
const getChangelogVirtualDom = () => {
|
|
1061
1029
|
// TODO set tabpanel role
|
|
1062
1030
|
return [{
|
|
1063
|
-
type: Div
|
|
1031
|
+
type: Div,
|
|
1064
1032
|
className: Changelog$1,
|
|
1065
1033
|
childCount: 1
|
|
1066
1034
|
}, text('Not Implemented')];
|
|
1067
1035
|
};
|
|
1068
1036
|
|
|
1069
|
-
const Document = 'document';
|
|
1070
1037
|
const TabList = 'tablist';
|
|
1071
1038
|
const Tab = 'tab';
|
|
1072
1039
|
const Panel = 'panel';
|
|
1073
1040
|
|
|
1074
1041
|
const getAdditionalDetailsEntryVirtualDom = (heading, items, renderer) => {
|
|
1075
1042
|
return [{
|
|
1076
|
-
type: Div
|
|
1043
|
+
type: Div,
|
|
1077
1044
|
className: AdditionalDetailsEntry,
|
|
1078
1045
|
childCount: 2
|
|
1079
1046
|
}, {
|
|
1080
|
-
type: Div
|
|
1047
|
+
type: Div,
|
|
1081
1048
|
className: AdditionalDetailsTitle,
|
|
1082
1049
|
childCount: 1
|
|
1083
1050
|
}, text(heading), ...renderer(items)];
|
|
@@ -1088,7 +1055,7 @@ const getCategoryVirtualDom = category => {
|
|
|
1088
1055
|
label
|
|
1089
1056
|
} = category;
|
|
1090
1057
|
return [{
|
|
1091
|
-
type: Div
|
|
1058
|
+
type: Div,
|
|
1092
1059
|
className: Category,
|
|
1093
1060
|
childCount: 1
|
|
1094
1061
|
}, text(label)];
|
|
@@ -1096,7 +1063,7 @@ const getCategoryVirtualDom = category => {
|
|
|
1096
1063
|
|
|
1097
1064
|
const getCategoriesDom = categories => {
|
|
1098
1065
|
return [{
|
|
1099
|
-
type: Div
|
|
1066
|
+
type: Div,
|
|
1100
1067
|
className: Categories,
|
|
1101
1068
|
childCount: categories.length
|
|
1102
1069
|
}, ...categories.flatMap(getCategoryVirtualDom)];
|
|
@@ -1107,7 +1074,7 @@ const getMoreInfoEntryKeyVirtualDom = item => {
|
|
|
1107
1074
|
key
|
|
1108
1075
|
} = item;
|
|
1109
1076
|
return [{
|
|
1110
|
-
type: Div
|
|
1077
|
+
type: Div,
|
|
1111
1078
|
className: MoreInfoEntryKey,
|
|
1112
1079
|
childCount: 1
|
|
1113
1080
|
}, text(key)];
|
|
@@ -1115,13 +1082,13 @@ const getMoreInfoEntryKeyVirtualDom = item => {
|
|
|
1115
1082
|
|
|
1116
1083
|
const getTag = (onClick, code) => {
|
|
1117
1084
|
if (onClick) {
|
|
1118
|
-
return A
|
|
1085
|
+
return A;
|
|
1119
1086
|
}
|
|
1120
1087
|
if (code) {
|
|
1121
1088
|
// TODO use code tag
|
|
1122
|
-
return Div
|
|
1089
|
+
return Div;
|
|
1123
1090
|
}
|
|
1124
|
-
return Div
|
|
1091
|
+
return Div;
|
|
1125
1092
|
};
|
|
1126
1093
|
const getClassName = (onClick, code) => {
|
|
1127
1094
|
if (onClick) {
|
|
@@ -1149,12 +1116,12 @@ const getMoreInfoEntryValueVirtualDom = item => {
|
|
|
1149
1116
|
};
|
|
1150
1117
|
|
|
1151
1118
|
const parentNodeEven = {
|
|
1152
|
-
type: Div
|
|
1119
|
+
type: Div,
|
|
1153
1120
|
className: MoreInfoEntry,
|
|
1154
1121
|
childCount: 2
|
|
1155
1122
|
};
|
|
1156
1123
|
const parentNodeOdd = {
|
|
1157
|
-
type: Div
|
|
1124
|
+
type: Div,
|
|
1158
1125
|
className: MoreInfoEntry + ' ' + MoreInfoEntryOdd,
|
|
1159
1126
|
childCount: 2
|
|
1160
1127
|
};
|
|
@@ -1168,7 +1135,7 @@ const getMoreInfoEntryVirtualDom = item => {
|
|
|
1168
1135
|
|
|
1169
1136
|
const getMoreInfoVirtualDom = items => {
|
|
1170
1137
|
return [{
|
|
1171
|
-
type: Div
|
|
1138
|
+
type: Div,
|
|
1172
1139
|
className: MoreInfo,
|
|
1173
1140
|
childCount: items.length
|
|
1174
1141
|
}, ...items.flatMap(getMoreInfoEntryVirtualDom)];
|
|
@@ -1176,7 +1143,7 @@ const getMoreInfoVirtualDom = items => {
|
|
|
1176
1143
|
|
|
1177
1144
|
const resourceNode = {
|
|
1178
1145
|
// TODO use link with url
|
|
1179
|
-
type: Div
|
|
1146
|
+
type: Div,
|
|
1180
1147
|
className: Resource,
|
|
1181
1148
|
childCount: 1
|
|
1182
1149
|
};
|
|
@@ -1189,7 +1156,7 @@ const getResourceVirtualDom = resource => {
|
|
|
1189
1156
|
|
|
1190
1157
|
const getResourcesVirtualDom = resources => {
|
|
1191
1158
|
return [{
|
|
1192
|
-
type: Div
|
|
1159
|
+
type: Div,
|
|
1193
1160
|
className: Resources,
|
|
1194
1161
|
childCount: resources.length
|
|
1195
1162
|
}, ...resources.flatMap(getResourceVirtualDom)];
|
|
@@ -1200,11 +1167,11 @@ const getAdditionalDetailsVirtualDom = (showAdditionalDetails, firstHeading, ent
|
|
|
1200
1167
|
return [];
|
|
1201
1168
|
}
|
|
1202
1169
|
return [{
|
|
1203
|
-
type: Div
|
|
1204
|
-
className: Aside
|
|
1170
|
+
type: Div,
|
|
1171
|
+
className: Aside,
|
|
1205
1172
|
childCount: 1
|
|
1206
1173
|
}, {
|
|
1207
|
-
type: Div
|
|
1174
|
+
type: Div,
|
|
1208
1175
|
className: AdditionalDetails,
|
|
1209
1176
|
tabIndex: 0,
|
|
1210
1177
|
childCount: 4
|
|
@@ -1241,475 +1208,27 @@ const getInstallationEntries = (displaySize, extensionId, extensionVersion) => {
|
|
|
1241
1208
|
return entries;
|
|
1242
1209
|
};
|
|
1243
1210
|
|
|
1244
|
-
const
|
|
1245
|
-
|
|
1246
|
-
const getVirtualDomChildCount = markdownDom => {
|
|
1247
|
-
const max = markdownDom.length - 1;
|
|
1248
|
-
let stack = [];
|
|
1249
|
-
for (let i = max; i >= 0; i--) {
|
|
1250
|
-
const element = markdownDom[i];
|
|
1251
|
-
if (element.childCount > 0) {
|
|
1252
|
-
stack = stack.slice(element.childCount);
|
|
1253
|
-
}
|
|
1254
|
-
stack.unshift(element);
|
|
1255
|
-
}
|
|
1256
|
-
return stack.length;
|
|
1257
|
-
};
|
|
1258
|
-
|
|
1259
|
-
const Div = 'div';
|
|
1260
|
-
const H1 = 'h1';
|
|
1261
|
-
const H2 = 'h2';
|
|
1262
|
-
const H3 = 'h3';
|
|
1263
|
-
const H4 = 'h4';
|
|
1264
|
-
const H5 = 'h5';
|
|
1265
|
-
const Img = 'img';
|
|
1266
|
-
const Span = 'span';
|
|
1267
|
-
const Article = 'article';
|
|
1268
|
-
const Aside = 'aside';
|
|
1269
|
-
const Footer = 'footer';
|
|
1270
|
-
const Header = 'header';
|
|
1271
|
-
const Nav = 'nav';
|
|
1272
|
-
const Section = 'section';
|
|
1273
|
-
const Search = 'search';
|
|
1274
|
-
const Dd = 'dd';
|
|
1275
|
-
const Dl = 'dl';
|
|
1276
|
-
const Figcaption = 'figcaption';
|
|
1277
|
-
const Figure = 'figure';
|
|
1278
|
-
const Hr = 'hr';
|
|
1279
|
-
const Li = 'li';
|
|
1280
|
-
const Ol = 'ol';
|
|
1281
|
-
const P = 'p';
|
|
1282
|
-
const Pre = 'pre';
|
|
1283
|
-
const A = 'a';
|
|
1284
|
-
const Abbr = 'abbr';
|
|
1285
|
-
const Br = 'br';
|
|
1286
|
-
const Cite = 'cite';
|
|
1287
|
-
const Data = 'data';
|
|
1288
|
-
const Time = 'time';
|
|
1289
|
-
const Tfoot = 'tfoot';
|
|
1290
|
-
|
|
1291
|
-
const getVirtualDomTag = text => {
|
|
1292
|
-
switch (text) {
|
|
1293
|
-
case H1:
|
|
1294
|
-
return H1$1;
|
|
1295
|
-
case H2:
|
|
1296
|
-
return H2$1;
|
|
1297
|
-
case H3:
|
|
1298
|
-
return H3$1;
|
|
1299
|
-
case H4:
|
|
1300
|
-
return H4$1;
|
|
1301
|
-
case H5:
|
|
1302
|
-
return H5$1;
|
|
1303
|
-
case Div:
|
|
1304
|
-
return Div$1;
|
|
1305
|
-
case Article:
|
|
1306
|
-
return Article$1;
|
|
1307
|
-
case Aside:
|
|
1308
|
-
return Aside$1;
|
|
1309
|
-
case Footer:
|
|
1310
|
-
return Footer$1;
|
|
1311
|
-
case Header:
|
|
1312
|
-
return Header$1;
|
|
1313
|
-
case Nav:
|
|
1314
|
-
return Nav$1;
|
|
1315
|
-
case Section:
|
|
1316
|
-
return Section$1;
|
|
1317
|
-
case Search:
|
|
1318
|
-
return Search$1;
|
|
1319
|
-
case Dd:
|
|
1320
|
-
return Dd$1;
|
|
1321
|
-
case Dl:
|
|
1322
|
-
return Dl$1;
|
|
1323
|
-
case Figcaption:
|
|
1324
|
-
return Figcaption$1;
|
|
1325
|
-
case Figure:
|
|
1326
|
-
return Figure$1;
|
|
1327
|
-
case Hr:
|
|
1328
|
-
return Hr$1;
|
|
1329
|
-
case Li:
|
|
1330
|
-
return Li$1;
|
|
1331
|
-
case Ol:
|
|
1332
|
-
return Ol$1;
|
|
1333
|
-
case P:
|
|
1334
|
-
return P$1;
|
|
1335
|
-
case Pre:
|
|
1336
|
-
return Pre$1;
|
|
1337
|
-
case A:
|
|
1338
|
-
return A$1;
|
|
1339
|
-
case Abbr:
|
|
1340
|
-
return Abbr$1;
|
|
1341
|
-
case Br:
|
|
1342
|
-
return Br$1;
|
|
1343
|
-
case Cite:
|
|
1344
|
-
return Cite$1;
|
|
1345
|
-
case Data:
|
|
1346
|
-
return Data$1;
|
|
1347
|
-
case Time:
|
|
1348
|
-
return Time$1;
|
|
1349
|
-
case Tfoot:
|
|
1350
|
-
return Tfoot$1;
|
|
1351
|
-
case Img:
|
|
1352
|
-
return Img$1;
|
|
1353
|
-
case Span:
|
|
1354
|
-
return Span$1;
|
|
1355
|
-
default:
|
|
1356
|
-
return Div$1;
|
|
1357
|
-
}
|
|
1358
|
-
};
|
|
1211
|
+
const RendererWorker = 1;
|
|
1359
1212
|
|
|
1360
|
-
const
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
const TagNameStart = 3;
|
|
1364
|
-
const TagNameEnd = 4;
|
|
1365
|
-
const Content = 5;
|
|
1366
|
-
const ClosingTagSlash = 6;
|
|
1367
|
-
const WhitespaceInsideOpeningTag = 7;
|
|
1368
|
-
const AttributeName = 8;
|
|
1369
|
-
const AttributeEqualSign = 9;
|
|
1370
|
-
const AttributeQuoteStart = 10;
|
|
1371
|
-
const AttributeValue = 11;
|
|
1372
|
-
const AttributeQuoteEnd = 12;
|
|
1373
|
-
const WhitespaceAfterClosingTagSlash = 13;
|
|
1374
|
-
const WhitespaceAfterOpeningTagOpenAngleBracket = 14;
|
|
1375
|
-
const ExclamationMark = 15;
|
|
1376
|
-
const Doctype = 16;
|
|
1377
|
-
const StartCommentDashes = 17;
|
|
1378
|
-
const Comment = 18;
|
|
1379
|
-
const EndCommentTag = 19;
|
|
1380
|
-
const Text$1 = 20;
|
|
1381
|
-
const CommentStart = 21;
|
|
1382
|
-
|
|
1383
|
-
const isSelfClosingTag = tag => {
|
|
1384
|
-
switch (tag) {
|
|
1385
|
-
case Img:
|
|
1386
|
-
return true;
|
|
1387
|
-
default:
|
|
1388
|
-
return false;
|
|
1389
|
-
}
|
|
1213
|
+
const rpcs = Object.create(null);
|
|
1214
|
+
const set = (id, rpc) => {
|
|
1215
|
+
rpcs[id] = rpc;
|
|
1390
1216
|
};
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
return text.replaceAll('>', '>').replaceAll('<', '<').replaceAll('&', '&');
|
|
1217
|
+
const get = id => {
|
|
1218
|
+
return rpcs[id];
|
|
1394
1219
|
};
|
|
1395
1220
|
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
this.name = 'UnexpectedTokenError';
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
const State = {
|
|
1404
|
-
TopLevelContent: 1,
|
|
1405
|
-
AfterOpeningAngleBracket: 2,
|
|
1406
|
-
InsideOpeningTag: 3,
|
|
1407
|
-
AfterClosingTagSlash: 4,
|
|
1408
|
-
AfterClosingTagName: 5,
|
|
1409
|
-
InsideOpeningTagAfterWhitespace: 6,
|
|
1410
|
-
AfterAttributeName: 7,
|
|
1411
|
-
AfterAttributeEqualSign: 8,
|
|
1412
|
-
InsideAttributeAfterDoubleQuote: 9,
|
|
1413
|
-
AfterAttributeValueInsideDoubleQuote: 10,
|
|
1414
|
-
AfterAttributeValueClosingQuote: 11,
|
|
1415
|
-
AfterExclamationMark: 16,
|
|
1416
|
-
InsideComment: 17
|
|
1417
|
-
};
|
|
1418
|
-
const RE_ANGLE_BRACKET_OPEN = /^</;
|
|
1419
|
-
const RE_ANGLE_BRACKET_OPEN_TAG = /^<(?![\s!%])/;
|
|
1420
|
-
const RE_ANGLE_BRACKET_CLOSE = /^>/;
|
|
1421
|
-
const RE_SLASH = /^\//;
|
|
1422
|
-
const RE_TAGNAME = /^[a-zA-Z\d$]+/;
|
|
1423
|
-
const RE_CONTENT = /^[^<>]+/;
|
|
1424
|
-
const RE_WHITESPACE = /^\s+/;
|
|
1425
|
-
const RE_ATTRIBUTE_NAME = /^[a-zA-Z\d-]+/;
|
|
1426
|
-
const RE_EQUAL_SIGN = /^=/;
|
|
1427
|
-
const RE_DOUBLE_QUOTE = /^"/;
|
|
1428
|
-
const RE_ATTRIBUTE_VALUE_INSIDE_DOUBLE_QUOTE = /^[^"\n]+/;
|
|
1429
|
-
const RE_TEXT = /^[^<>]+/;
|
|
1430
|
-
const RE_EXCLAMATION_MARK = /^!/;
|
|
1431
|
-
const RE_DASH_DASH = /^--/;
|
|
1432
|
-
const RE_DOCTYPE = /^doctype/i;
|
|
1433
|
-
const RE_BLOCK_COMMENT_CONTENT = /^[a-zA-Z\s]+/;
|
|
1434
|
-
const RE_COMMENT_END = /^-->/;
|
|
1435
|
-
const RE_TAG_TEXT = /^[^\s>]+/;
|
|
1436
|
-
const RE_ANY_TEXT = /^[^\n]+/;
|
|
1437
|
-
const RE_BLOCK_COMMENT_START = /^<!--/;
|
|
1438
|
-
const RE_SELF_CLOSING = /^\/>/;
|
|
1439
|
-
const tokenizeHtml = text => {
|
|
1440
|
-
string(text);
|
|
1441
|
-
let state = State.TopLevelContent;
|
|
1442
|
-
let index = 0;
|
|
1443
|
-
let next;
|
|
1444
|
-
const tokens = [];
|
|
1445
|
-
let token = None$1;
|
|
1446
|
-
while (index < text.length) {
|
|
1447
|
-
const part = text.slice(index);
|
|
1448
|
-
switch (state) {
|
|
1449
|
-
case State.TopLevelContent:
|
|
1450
|
-
if (next = part.match(RE_ANGLE_BRACKET_OPEN_TAG)) {
|
|
1451
|
-
token = OpeningAngleBracket;
|
|
1452
|
-
state = State.AfterOpeningAngleBracket;
|
|
1453
|
-
} else if (next = part.match(RE_CONTENT)) {
|
|
1454
|
-
token = Content;
|
|
1455
|
-
state = State.TopLevelContent;
|
|
1456
|
-
} else if (next = part.match(RE_BLOCK_COMMENT_START)) {
|
|
1457
|
-
token = CommentStart;
|
|
1458
|
-
state = State.InsideComment;
|
|
1459
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1460
|
-
token = Content;
|
|
1461
|
-
state = State.TopLevelContent;
|
|
1462
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_OPEN)) {
|
|
1463
|
-
token = Text$1;
|
|
1464
|
-
state = State.TopLevelContent;
|
|
1465
|
-
} else {
|
|
1466
|
-
throw new UnexpectedTokenError();
|
|
1467
|
-
}
|
|
1468
|
-
break;
|
|
1469
|
-
case State.AfterOpeningAngleBracket:
|
|
1470
|
-
if (next = part.match(RE_TAGNAME)) {
|
|
1471
|
-
token = TagNameStart;
|
|
1472
|
-
state = State.InsideOpeningTag;
|
|
1473
|
-
} else if (next = part.match(RE_SLASH)) {
|
|
1474
|
-
token = ClosingTagSlash;
|
|
1475
|
-
state = State.AfterClosingTagSlash;
|
|
1476
|
-
} else if (next = part.match(RE_WHITESPACE)) {
|
|
1477
|
-
token = WhitespaceAfterOpeningTagOpenAngleBracket;
|
|
1478
|
-
state = State.TopLevelContent;
|
|
1479
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1480
|
-
token = ClosingAngleBracket;
|
|
1481
|
-
state = State.TopLevelContent;
|
|
1482
|
-
} else if (next = part.match(RE_EXCLAMATION_MARK)) {
|
|
1483
|
-
token = ExclamationMark;
|
|
1484
|
-
state = State.AfterExclamationMark;
|
|
1485
|
-
} else if (next = part.match(RE_ANY_TEXT)) {
|
|
1486
|
-
token = Text$1;
|
|
1487
|
-
state = State.TopLevelContent;
|
|
1488
|
-
} else {
|
|
1489
|
-
text.slice(index); // ?
|
|
1490
|
-
throw new UnexpectedTokenError();
|
|
1491
|
-
}
|
|
1492
|
-
break;
|
|
1493
|
-
case State.AfterExclamationMark:
|
|
1494
|
-
if (next = part.match(RE_DASH_DASH)) {
|
|
1495
|
-
token = StartCommentDashes;
|
|
1496
|
-
state = State.InsideComment;
|
|
1497
|
-
} else if (next = part.match(RE_DOCTYPE)) {
|
|
1498
|
-
token = Doctype;
|
|
1499
|
-
state = State.InsideOpeningTag;
|
|
1500
|
-
} else {
|
|
1501
|
-
text.slice(index); // ?
|
|
1502
|
-
throw new UnexpectedTokenError();
|
|
1503
|
-
}
|
|
1504
|
-
break;
|
|
1505
|
-
case State.InsideComment:
|
|
1506
|
-
if (next = part.match(RE_BLOCK_COMMENT_CONTENT)) {
|
|
1507
|
-
token = Comment;
|
|
1508
|
-
state = State.InsideComment;
|
|
1509
|
-
} else if (next = part.match(RE_COMMENT_END)) {
|
|
1510
|
-
token = EndCommentTag;
|
|
1511
|
-
state = State.TopLevelContent;
|
|
1512
|
-
} else {
|
|
1513
|
-
text.slice(index); // ?
|
|
1514
|
-
throw new UnexpectedTokenError();
|
|
1515
|
-
}
|
|
1516
|
-
break;
|
|
1517
|
-
case State.InsideOpeningTag:
|
|
1518
|
-
if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1519
|
-
token = ClosingAngleBracket;
|
|
1520
|
-
state = State.TopLevelContent;
|
|
1521
|
-
} else if (next = part.match(RE_WHITESPACE)) {
|
|
1522
|
-
token = WhitespaceInsideOpeningTag;
|
|
1523
|
-
state = State.InsideOpeningTagAfterWhitespace;
|
|
1524
|
-
} else if (next = part.match(RE_TAG_TEXT)) {
|
|
1525
|
-
token = Text$1;
|
|
1526
|
-
state = State.TopLevelContent;
|
|
1527
|
-
} else {
|
|
1528
|
-
throw new UnexpectedTokenError();
|
|
1529
|
-
}
|
|
1530
|
-
break;
|
|
1531
|
-
case State.InsideOpeningTagAfterWhitespace:
|
|
1532
|
-
if (next = part.match(RE_ATTRIBUTE_NAME)) {
|
|
1533
|
-
token = AttributeName;
|
|
1534
|
-
state = State.AfterAttributeName;
|
|
1535
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1536
|
-
token = ClosingAngleBracket;
|
|
1537
|
-
state = State.TopLevelContent;
|
|
1538
|
-
} else if (next = part.match(RE_SELF_CLOSING)) {
|
|
1539
|
-
token = ClosingAngleBracket;
|
|
1540
|
-
state = State.TopLevelContent;
|
|
1541
|
-
} else if (next = part.match(RE_TEXT)) {
|
|
1542
|
-
token = AttributeName;
|
|
1543
|
-
state = State.AfterAttributeName;
|
|
1544
|
-
} else {
|
|
1545
|
-
text.slice(index).match(RE_TEXT); // ?
|
|
1546
|
-
text.slice(index); // ?
|
|
1547
|
-
throw new UnexpectedTokenError();
|
|
1548
|
-
}
|
|
1549
|
-
break;
|
|
1550
|
-
case State.AfterAttributeName:
|
|
1551
|
-
if (next = part.match(RE_EQUAL_SIGN)) {
|
|
1552
|
-
token = AttributeEqualSign;
|
|
1553
|
-
state = State.AfterAttributeEqualSign;
|
|
1554
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1555
|
-
token = ClosingAngleBracket;
|
|
1556
|
-
state = State.TopLevelContent;
|
|
1557
|
-
} else if (next = part.match(RE_WHITESPACE)) {
|
|
1558
|
-
token = WhitespaceInsideOpeningTag;
|
|
1559
|
-
state = State.InsideOpeningTagAfterWhitespace;
|
|
1560
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_OPEN)) {
|
|
1561
|
-
token = OpeningAngleBracket;
|
|
1562
|
-
state = State.AfterOpeningAngleBracket;
|
|
1563
|
-
} else {
|
|
1564
|
-
text.slice(index); // ?
|
|
1565
|
-
throw new UnexpectedTokenError();
|
|
1566
|
-
}
|
|
1567
|
-
break;
|
|
1568
|
-
case State.AfterAttributeEqualSign:
|
|
1569
|
-
if (next = part.match(RE_DOUBLE_QUOTE)) {
|
|
1570
|
-
token = AttributeQuoteStart;
|
|
1571
|
-
state = State.InsideAttributeAfterDoubleQuote;
|
|
1572
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1573
|
-
token = ClosingAngleBracket;
|
|
1574
|
-
state = State.TopLevelContent;
|
|
1575
|
-
} else {
|
|
1576
|
-
throw new UnexpectedTokenError();
|
|
1577
|
-
}
|
|
1578
|
-
break;
|
|
1579
|
-
case State.InsideAttributeAfterDoubleQuote:
|
|
1580
|
-
if (next = text.slice(index).match(RE_ATTRIBUTE_VALUE_INSIDE_DOUBLE_QUOTE)) {
|
|
1581
|
-
token = AttributeValue;
|
|
1582
|
-
state = State.AfterAttributeValueInsideDoubleQuote;
|
|
1583
|
-
} else if (next = part.match(RE_DOUBLE_QUOTE)) {
|
|
1584
|
-
token = AttributeQuoteEnd;
|
|
1585
|
-
state = State.AfterAttributeValueClosingQuote;
|
|
1586
|
-
} else {
|
|
1587
|
-
throw new UnexpectedTokenError();
|
|
1588
|
-
}
|
|
1589
|
-
break;
|
|
1590
|
-
case State.AfterAttributeValueInsideDoubleQuote:
|
|
1591
|
-
if (next = part.match(RE_DOUBLE_QUOTE)) {
|
|
1592
|
-
token = AttributeQuoteEnd;
|
|
1593
|
-
state = State.AfterAttributeValueClosingQuote;
|
|
1594
|
-
} else {
|
|
1595
|
-
throw new UnexpectedTokenError();
|
|
1596
|
-
}
|
|
1597
|
-
break;
|
|
1598
|
-
case State.AfterAttributeValueClosingQuote:
|
|
1599
|
-
if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1600
|
-
token = ClosingAngleBracket;
|
|
1601
|
-
state = State.TopLevelContent;
|
|
1602
|
-
} else if (next = part.match(RE_WHITESPACE)) {
|
|
1603
|
-
token = WhitespaceInsideOpeningTag;
|
|
1604
|
-
state = State.InsideOpeningTagAfterWhitespace;
|
|
1605
|
-
} else if (next = part.match(RE_SELF_CLOSING)) {
|
|
1606
|
-
token = ClosingAngleBracket;
|
|
1607
|
-
state = State.TopLevelContent;
|
|
1608
|
-
} else {
|
|
1609
|
-
throw new UnexpectedTokenError();
|
|
1610
|
-
}
|
|
1611
|
-
break;
|
|
1612
|
-
case State.AfterClosingTagSlash:
|
|
1613
|
-
if (next = part.match(RE_TAGNAME)) {
|
|
1614
|
-
token = TagNameEnd;
|
|
1615
|
-
state = State.AfterClosingTagName;
|
|
1616
|
-
} else if (next = part.match(RE_WHITESPACE)) {
|
|
1617
|
-
token = WhitespaceAfterClosingTagSlash;
|
|
1618
|
-
state = State.TopLevelContent;
|
|
1619
|
-
} else if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1620
|
-
token = ClosingAngleBracket;
|
|
1621
|
-
state = State.TopLevelContent;
|
|
1622
|
-
} else {
|
|
1623
|
-
throw new UnexpectedTokenError();
|
|
1624
|
-
}
|
|
1625
|
-
break;
|
|
1626
|
-
case State.AfterClosingTagName:
|
|
1627
|
-
if (next = part.match(RE_ANGLE_BRACKET_CLOSE)) {
|
|
1628
|
-
token = ClosingAngleBracket;
|
|
1629
|
-
state = State.TopLevelContent;
|
|
1630
|
-
} else if (next = part.match(RE_WHITESPACE)) {
|
|
1631
|
-
token = Content;
|
|
1632
|
-
state = State.TopLevelContent;
|
|
1633
|
-
} else {
|
|
1634
|
-
throw new UnexpectedTokenError();
|
|
1635
|
-
}
|
|
1636
|
-
break;
|
|
1637
|
-
default:
|
|
1638
|
-
throw new UnexpectedTokenError();
|
|
1639
|
-
}
|
|
1640
|
-
const tokenText = next[0];
|
|
1641
|
-
tokens.push({
|
|
1642
|
-
type: token,
|
|
1643
|
-
text: tokenText
|
|
1644
|
-
});
|
|
1645
|
-
index += tokenText.length;
|
|
1646
|
-
}
|
|
1647
|
-
return tokens;
|
|
1221
|
+
const invoke = (method, ...params) => {
|
|
1222
|
+
const rpc = get(RendererWorker);
|
|
1223
|
+
return rpc.invoke(method, ...params);
|
|
1648
1224
|
};
|
|
1649
1225
|
|
|
1650
|
-
const
|
|
1226
|
+
const getMarkdownVirtualDom = async html => {
|
|
1651
1227
|
string(html);
|
|
1652
|
-
|
|
1653
|
-
const tokens = tokenizeHtml(html);
|
|
1654
|
-
const dom = [];
|
|
1655
|
-
const root = {
|
|
1656
|
-
type: 0,
|
|
1657
|
-
childCount: 0
|
|
1658
|
-
};
|
|
1659
|
-
let current = root;
|
|
1660
|
-
const stack = [root];
|
|
1661
|
-
let attributeName = '';
|
|
1662
|
-
for (const token of tokens) {
|
|
1663
|
-
switch (token.type) {
|
|
1664
|
-
case TagNameStart:
|
|
1665
|
-
current.childCount++;
|
|
1666
|
-
current = {
|
|
1667
|
-
type: getVirtualDomTag(token.text),
|
|
1668
|
-
childCount: 0
|
|
1669
|
-
};
|
|
1670
|
-
dom.push(current);
|
|
1671
|
-
if (!isSelfClosingTag(token.text)) {
|
|
1672
|
-
stack.push(current);
|
|
1673
|
-
}
|
|
1674
|
-
break;
|
|
1675
|
-
case TagNameEnd:
|
|
1676
|
-
stack.pop();
|
|
1677
|
-
current = stack.at(-1) || root;
|
|
1678
|
-
break;
|
|
1679
|
-
case Content:
|
|
1680
|
-
current.childCount++;
|
|
1681
|
-
dom.push(text(parseText(token.text)));
|
|
1682
|
-
break;
|
|
1683
|
-
case AttributeName:
|
|
1684
|
-
attributeName = token.text;
|
|
1685
|
-
if (attributeName === 'class') {
|
|
1686
|
-
attributeName = 'className';
|
|
1687
|
-
}
|
|
1688
|
-
break;
|
|
1689
|
-
case AttributeValue:
|
|
1690
|
-
if (allowedAttributes.includes(attributeName)) {
|
|
1691
|
-
current[attributeName] = token.text;
|
|
1692
|
-
}
|
|
1693
|
-
attributeName = '';
|
|
1694
|
-
break;
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1228
|
+
const dom = await invoke('Markdown.getVirtualDom', html);
|
|
1697
1229
|
return dom;
|
|
1698
1230
|
};
|
|
1699
1231
|
|
|
1700
|
-
const getMarkdownVirtualDom = html => {
|
|
1701
|
-
string(html);
|
|
1702
|
-
const childDom = parseHtml(html, allowedMarkdownAttributes);
|
|
1703
|
-
const markdownChildCount = getVirtualDomChildCount(childDom);
|
|
1704
|
-
return [{
|
|
1705
|
-
type: Div$1,
|
|
1706
|
-
className: Markdown,
|
|
1707
|
-
role: Document,
|
|
1708
|
-
onContextMenu: HandleReadmeContextMenu,
|
|
1709
|
-
childCount: markdownChildCount
|
|
1710
|
-
}, ...childDom];
|
|
1711
|
-
};
|
|
1712
|
-
|
|
1713
1232
|
const getMarketplaceEntries = () => {
|
|
1714
1233
|
return [{
|
|
1715
1234
|
key: 'Published',
|
|
@@ -1721,7 +1240,7 @@ const getMarketplaceEntries = () => {
|
|
|
1721
1240
|
}];
|
|
1722
1241
|
};
|
|
1723
1242
|
|
|
1724
|
-
const getDetailsVirtualDom = (sanitizedReadmeHtml, displaySize, extensionId, extensionVersion, width) => {
|
|
1243
|
+
const getDetailsVirtualDom = async (sanitizedReadmeHtml, displaySize, extensionId, extensionVersion, width) => {
|
|
1725
1244
|
const firstHeading = 'Installation';
|
|
1726
1245
|
const entries = getInstallationEntries(displaySize, extensionId, extensionVersion);
|
|
1727
1246
|
const secondHeading = 'Marketplace';
|
|
@@ -1749,11 +1268,11 @@ const getDetailsVirtualDom = (sanitizedReadmeHtml, displaySize, extensionId, ext
|
|
|
1749
1268
|
const showAdditionalDetails = width > showAdditionalDetailsBreakpoint;
|
|
1750
1269
|
const childCount = showAdditionalDetails ? 2 : 1;
|
|
1751
1270
|
const dom = [{
|
|
1752
|
-
type: Div
|
|
1271
|
+
type: Div,
|
|
1753
1272
|
className: ExtensionDetailPanel,
|
|
1754
1273
|
childCount: childCount,
|
|
1755
1274
|
role: Panel
|
|
1756
|
-
}, ...getMarkdownVirtualDom(sanitizedReadmeHtml), ...getAdditionalDetailsVirtualDom(showAdditionalDetails, firstHeading, entries, secondHeading, secondEntries, thirdHeading, categories, fourthHeading, resources)];
|
|
1275
|
+
}, ...(await getMarkdownVirtualDom(sanitizedReadmeHtml)), ...getAdditionalDetailsVirtualDom(showAdditionalDetails, firstHeading, entries, secondHeading, secondEntries, thirdHeading, categories, fourthHeading, resources)];
|
|
1757
1276
|
return dom;
|
|
1758
1277
|
};
|
|
1759
1278
|
|
|
@@ -1868,7 +1387,7 @@ const getCommandTableEntries = extension => {
|
|
|
1868
1387
|
|
|
1869
1388
|
const getFeatureContentHeadingVirtualDom = heading => {
|
|
1870
1389
|
return [{
|
|
1871
|
-
type: H1
|
|
1390
|
+
type: H1,
|
|
1872
1391
|
childCount: 1
|
|
1873
1392
|
}, text(heading)];
|
|
1874
1393
|
};
|
|
@@ -1887,7 +1406,7 @@ const getCellCodeVirtualDom = value => {
|
|
|
1887
1406
|
className: TableCell,
|
|
1888
1407
|
childCount: 1
|
|
1889
1408
|
}, {
|
|
1890
|
-
type: Div
|
|
1409
|
+
type: Div,
|
|
1891
1410
|
// TODO use code tag
|
|
1892
1411
|
childCount: 1
|
|
1893
1412
|
}, text(value)];
|
|
@@ -1954,7 +1473,7 @@ const getFeatureCommandsVirtualDom = extension => {
|
|
|
1954
1473
|
const heading = commands();
|
|
1955
1474
|
const tableInfo = getCommandTableEntries(extension);
|
|
1956
1475
|
return [{
|
|
1957
|
-
type: Div
|
|
1476
|
+
type: Div,
|
|
1958
1477
|
className: FeatureContent,
|
|
1959
1478
|
childCount: 2
|
|
1960
1479
|
}, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
@@ -1987,7 +1506,7 @@ const getFeatureJsonValidationVirtualDom = extension => {
|
|
|
1987
1506
|
const heading = jsonValidation();
|
|
1988
1507
|
const tableInfo = getJsonValidationTableEntries(extension);
|
|
1989
1508
|
return [{
|
|
1990
|
-
type: Div
|
|
1509
|
+
type: Div,
|
|
1991
1510
|
className: FeatureContent,
|
|
1992
1511
|
childCount: 2
|
|
1993
1512
|
}, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
@@ -1996,11 +1515,11 @@ const getFeatureJsonValidationVirtualDom = extension => {
|
|
|
1996
1515
|
const getFeatureNotImplementedVirtualDom = () => {
|
|
1997
1516
|
const heading = 'Not implemented';
|
|
1998
1517
|
return [{
|
|
1999
|
-
type: Div
|
|
1518
|
+
type: Div,
|
|
2000
1519
|
className: FeatureContent,
|
|
2001
1520
|
childCount: 1
|
|
2002
1521
|
}, {
|
|
2003
|
-
type: H1
|
|
1522
|
+
type: H1,
|
|
2004
1523
|
childCount: 1
|
|
2005
1524
|
}, text(heading)];
|
|
2006
1525
|
};
|
|
@@ -2009,7 +1528,7 @@ const getFeatureProgrammingLanguagesVirtualDom = () => {
|
|
|
2009
1528
|
const heading = programmingLanguages();
|
|
2010
1529
|
// TODO
|
|
2011
1530
|
return [{
|
|
2012
|
-
type: Div
|
|
1531
|
+
type: Div,
|
|
2013
1532
|
className: FeatureContent,
|
|
2014
1533
|
childCount: 1
|
|
2015
1534
|
}, ...getFeatureContentHeadingVirtualDom(heading)];
|
|
@@ -2045,22 +1564,35 @@ const getFeatureSettingsVirtualDom = extension => {
|
|
|
2045
1564
|
const heading = settings();
|
|
2046
1565
|
const tableInfo = getSettingsTableEntries(extension);
|
|
2047
1566
|
return [{
|
|
2048
|
-
type: Div
|
|
1567
|
+
type: Div,
|
|
2049
1568
|
className: FeatureContent,
|
|
2050
1569
|
childCount: 2
|
|
2051
1570
|
}, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
2052
1571
|
};
|
|
2053
1572
|
|
|
2054
|
-
const
|
|
2055
|
-
const
|
|
1573
|
+
const getVirtualDomChildCount = markdownDom => {
|
|
1574
|
+
const max = markdownDom.length - 1;
|
|
1575
|
+
let stack = [];
|
|
1576
|
+
for (let i = max; i >= 0; i--) {
|
|
1577
|
+
const element = markdownDom[i];
|
|
1578
|
+
if (element.childCount > 0) {
|
|
1579
|
+
stack = stack.slice(element.childCount);
|
|
1580
|
+
}
|
|
1581
|
+
stack.unshift(element);
|
|
1582
|
+
}
|
|
1583
|
+
return stack.length;
|
|
1584
|
+
};
|
|
1585
|
+
|
|
1586
|
+
const getFeatureThemesVirtualDom = async themesHtml => {
|
|
1587
|
+
const markdownDom = await getMarkdownVirtualDom(themesHtml);
|
|
2056
1588
|
const childCount = getVirtualDomChildCount(markdownDom);
|
|
2057
1589
|
const heading = theme();
|
|
2058
1590
|
return [{
|
|
2059
|
-
type: Div
|
|
1591
|
+
type: Div,
|
|
2060
1592
|
className: FeatureContent,
|
|
2061
1593
|
childCount: 2
|
|
2062
1594
|
}, ...getFeatureContentHeadingVirtualDom(heading), {
|
|
2063
|
-
type: Div
|
|
1595
|
+
type: Div,
|
|
2064
1596
|
className: 'DefaultMarkdown',
|
|
2065
1597
|
childCount
|
|
2066
1598
|
}, ...markdownDom];
|
|
@@ -2086,18 +1618,18 @@ const getWebViews = extension => {
|
|
|
2086
1618
|
return rawWebViews.map(toWebView);
|
|
2087
1619
|
};
|
|
2088
1620
|
|
|
2089
|
-
const heading
|
|
2090
|
-
type: H2
|
|
1621
|
+
const heading = {
|
|
1622
|
+
type: H2,
|
|
2091
1623
|
className: DefinitionListItemHeading,
|
|
2092
1624
|
childCount: 1
|
|
2093
1625
|
};
|
|
2094
1626
|
const pre = {
|
|
2095
|
-
type: Pre
|
|
1627
|
+
type: Pre,
|
|
2096
1628
|
className: DefinitionListItemValue,
|
|
2097
1629
|
childCount: 1
|
|
2098
1630
|
};
|
|
2099
1631
|
const item = {
|
|
2100
|
-
type: Div
|
|
1632
|
+
type: Div,
|
|
2101
1633
|
className: DefinitionListItem,
|
|
2102
1634
|
childCount: 2
|
|
2103
1635
|
};
|
|
@@ -2113,21 +1645,21 @@ const getWebViewVirtualDom = webView => {
|
|
|
2113
1645
|
const textContentSecurityPolicy = contentSecurityPolicy();
|
|
2114
1646
|
const textElements = elements();
|
|
2115
1647
|
return [{
|
|
2116
|
-
type: Div
|
|
1648
|
+
type: Div,
|
|
2117
1649
|
className: FeatureWebView,
|
|
2118
1650
|
childCount: 5
|
|
2119
|
-
}, item, heading
|
|
1651
|
+
}, item, heading, text(textId), pre, text(id$1), item, heading, text(textSelector), pre, text(selectorString), item, heading, text(textContentSecurityPolicy), pre, text(contentSecurityPolicyString), item, heading, text(textElements), pre, text(elementsString)];
|
|
2120
1652
|
};
|
|
2121
1653
|
|
|
2122
1654
|
const getFeatureWebViewsVirtualDom = extension => {
|
|
2123
1655
|
const webViews$1 = getWebViews(extension);
|
|
2124
1656
|
const heading = webViews();
|
|
2125
1657
|
return [{
|
|
2126
|
-
type: Div
|
|
1658
|
+
type: Div,
|
|
2127
1659
|
className: FeatureContent,
|
|
2128
1660
|
childCount: 2
|
|
2129
1661
|
}, ...getFeatureContentHeadingVirtualDom(heading), {
|
|
2130
|
-
type: Div
|
|
1662
|
+
type: Div,
|
|
2131
1663
|
childCount: webViews$1.length
|
|
2132
1664
|
}, ...webViews$1.flatMap(getWebViewVirtualDom)];
|
|
2133
1665
|
};
|
|
@@ -2142,10 +1674,10 @@ const Settings = 'Settings';
|
|
|
2142
1674
|
const WebViews = 'WebViews';
|
|
2143
1675
|
const Theme = 'Theme';
|
|
2144
1676
|
|
|
2145
|
-
const getFeatureContentVirtualDom = (features, themesHtml, selectedFeature, extension) => {
|
|
1677
|
+
const getFeatureContentVirtualDom = async (features, themesHtml, selectedFeature, extension) => {
|
|
2146
1678
|
switch (selectedFeature) {
|
|
2147
1679
|
case Theme:
|
|
2148
|
-
return getFeatureThemesVirtualDom(themesHtml);
|
|
1680
|
+
return await getFeatureThemesVirtualDom(themesHtml);
|
|
2149
1681
|
case Commands:
|
|
2150
1682
|
return getFeatureCommandsVirtualDom(extension);
|
|
2151
1683
|
case JsonValidation:
|
|
@@ -2180,38 +1712,38 @@ const getFeatureListItemVirtualDom = feature => {
|
|
|
2180
1712
|
const getFeatureListVirtualDom = features => {
|
|
2181
1713
|
return [{
|
|
2182
1714
|
// TODO use either list or tabs role
|
|
2183
|
-
type: Div
|
|
1715
|
+
type: Div,
|
|
2184
1716
|
className: FeaturesList,
|
|
2185
1717
|
childCount: features.length,
|
|
2186
1718
|
onClick: HandleFeaturesClick
|
|
2187
1719
|
}, ...features.flatMap(getFeatureListItemVirtualDom)];
|
|
2188
1720
|
};
|
|
2189
1721
|
|
|
2190
|
-
const getFeaturesVirtualDom = (features, themesHtml, selectedFeature, extension) => {
|
|
1722
|
+
const getFeaturesVirtualDom = async (features, themesHtml, selectedFeature, extension) => {
|
|
2191
1723
|
if (features.length === 0) {
|
|
2192
1724
|
return [{
|
|
2193
|
-
type: Div
|
|
1725
|
+
type: Div,
|
|
2194
1726
|
className: Features$1,
|
|
2195
1727
|
childCount: 3
|
|
2196
1728
|
}, text('None')];
|
|
2197
1729
|
}
|
|
2198
1730
|
return [{
|
|
2199
|
-
type: Div
|
|
1731
|
+
type: Div,
|
|
2200
1732
|
className: Features$1,
|
|
2201
1733
|
childCount: 3
|
|
2202
1734
|
}, ...getFeatureListVirtualDom(features), {
|
|
2203
|
-
type: Div
|
|
1735
|
+
type: Div,
|
|
2204
1736
|
className: 'Sash SashVertical',
|
|
2205
1737
|
childCount: 0
|
|
2206
|
-
}, ...getFeatureContentVirtualDom(features, themesHtml, selectedFeature, extension)];
|
|
1738
|
+
}, ...(await getFeatureContentVirtualDom(features, themesHtml, selectedFeature, extension))];
|
|
2207
1739
|
};
|
|
2208
1740
|
|
|
2209
|
-
const getExtensionDetailContentVirtualDom = (sanitizedReadmeHtml, themesHtml, selectedTab, features, displaySize, extensionId, extensionVersion, selectedFeature, extension, width) => {
|
|
1741
|
+
const getExtensionDetailContentVirtualDom = async (sanitizedReadmeHtml, themesHtml, selectedTab, features, displaySize, extensionId, extensionVersion, selectedFeature, extension, width) => {
|
|
2210
1742
|
switch (selectedTab) {
|
|
2211
1743
|
case Details:
|
|
2212
|
-
return getDetailsVirtualDom(sanitizedReadmeHtml, displaySize, extensionId, extensionVersion, width);
|
|
1744
|
+
return await getDetailsVirtualDom(sanitizedReadmeHtml, displaySize, extensionId, extensionVersion, width);
|
|
2213
1745
|
case Features:
|
|
2214
|
-
return getFeaturesVirtualDom(features, themesHtml, selectedFeature, extension);
|
|
1746
|
+
return await getFeaturesVirtualDom(features, themesHtml, selectedFeature, extension);
|
|
2215
1747
|
case Changelog:
|
|
2216
1748
|
return getChangelogVirtualDom();
|
|
2217
1749
|
default:
|
|
@@ -2230,7 +1762,7 @@ const getButtonVirtualDom = (message, onClick) => {
|
|
|
2230
1762
|
|
|
2231
1763
|
const getExtensionDetailHeaderActionsVirtualDom = () => {
|
|
2232
1764
|
const dom = [{
|
|
2233
|
-
type: Div
|
|
1765
|
+
type: Div,
|
|
2234
1766
|
className: ExtensionDetailHeaderActions,
|
|
2235
1767
|
childCount: 2
|
|
2236
1768
|
}, ...getButtonVirtualDom('Disable', HandleClickDisable), ...getButtonVirtualDom('Uninstall', HandleClickUninstall)];
|
|
@@ -2244,26 +1776,26 @@ const getExtensionDetailHeaderVirtualDom = extensionDetail => {
|
|
|
2244
1776
|
description
|
|
2245
1777
|
} = extensionDetail;
|
|
2246
1778
|
const dom = [{
|
|
2247
|
-
type: Div
|
|
1779
|
+
type: Div,
|
|
2248
1780
|
className: ExtensionDetailHeader,
|
|
2249
1781
|
childCount: 2
|
|
2250
1782
|
}, {
|
|
2251
|
-
type: Img
|
|
1783
|
+
type: Img,
|
|
2252
1784
|
className: ExtensionDetailIcon,
|
|
2253
1785
|
alt: '',
|
|
2254
1786
|
draggable: false,
|
|
2255
1787
|
childCount: 0,
|
|
2256
1788
|
src: iconSrc
|
|
2257
1789
|
}, {
|
|
2258
|
-
type: Div
|
|
1790
|
+
type: Div,
|
|
2259
1791
|
className: ExtensionDetailHeaderDetails,
|
|
2260
1792
|
childCount: 3
|
|
2261
1793
|
}, {
|
|
2262
|
-
type: Div
|
|
1794
|
+
type: Div,
|
|
2263
1795
|
className: ExtensionDetailName,
|
|
2264
1796
|
childCount: 1
|
|
2265
1797
|
}, text(name), {
|
|
2266
|
-
type: Div
|
|
1798
|
+
type: Div,
|
|
2267
1799
|
className: ExtensionDetailDescription,
|
|
2268
1800
|
childCount: 1
|
|
2269
1801
|
}, text(description), ...getExtensionDetailHeaderActionsVirtualDom()];
|
|
@@ -2360,7 +1892,7 @@ const getTabVirtualDom = tab => {
|
|
|
2360
1892
|
|
|
2361
1893
|
const getTabsVirtualDom = tabs => {
|
|
2362
1894
|
return [{
|
|
2363
|
-
type: Div
|
|
1895
|
+
type: Div,
|
|
2364
1896
|
className: ExtensionDetailTabs,
|
|
2365
1897
|
childCount: tabs.length,
|
|
2366
1898
|
role: TabList,
|
|
@@ -2396,7 +1928,7 @@ const getClassNames = size => {
|
|
|
2396
1928
|
}
|
|
2397
1929
|
};
|
|
2398
1930
|
|
|
2399
|
-
const getExtensionDetailVirtualDom = (extensionDetail, sanitizedReadmeHtml, selectedTab, newState) => {
|
|
1931
|
+
const getExtensionDetailVirtualDom = async (extensionDetail, sanitizedReadmeHtml, selectedTab, newState) => {
|
|
2400
1932
|
// TODO move this to view model so that rendering occurs like
|
|
2401
1933
|
// 1. state
|
|
2402
1934
|
// 2. view model
|
|
@@ -2415,18 +1947,18 @@ const getExtensionDetailVirtualDom = (extensionDetail, sanitizedReadmeHtml, sele
|
|
|
2415
1947
|
const sizeValue = getViewletSize(newState?.width || 0);
|
|
2416
1948
|
const sizeClass = getClassNames(sizeValue);
|
|
2417
1949
|
const dom = [{
|
|
2418
|
-
type: Div
|
|
1950
|
+
type: Div,
|
|
2419
1951
|
className: mergeClassNames(Viewlet, ExtensionDetail, sizeClass),
|
|
2420
1952
|
childCount: 3
|
|
2421
|
-
}, ...getExtensionDetailHeaderVirtualDom(extensionDetail), ...getTabsVirtualDom(tabs), ...getExtensionDetailContentVirtualDom(sanitizedReadmeHtml, themesHtml, selectedTab, features, displaySize, extensionId, extensionVersion, selectedFeature, extension, width)];
|
|
1953
|
+
}, ...getExtensionDetailHeaderVirtualDom(extensionDetail), ...getTabsVirtualDom(tabs), ...(await getExtensionDetailContentVirtualDom(sanitizedReadmeHtml, themesHtml, selectedTab, features, displaySize, extensionId, extensionVersion, selectedFeature, extension, width))];
|
|
2422
1954
|
return dom;
|
|
2423
1955
|
};
|
|
2424
1956
|
|
|
2425
|
-
const getExtensionDetailVirtualDom2 = uid => {
|
|
1957
|
+
const getExtensionDetailVirtualDom2 = async uid => {
|
|
2426
1958
|
const {
|
|
2427
1959
|
newState
|
|
2428
1960
|
} = get$1(uid);
|
|
2429
|
-
return getExtensionDetailVirtualDom(newState, newState.sanitizedReadmeHtml, newState.selectedTab, newState);
|
|
1961
|
+
return await getExtensionDetailVirtualDom(newState, newState.sanitizedReadmeHtml, newState.selectedTab, newState);
|
|
2430
1962
|
};
|
|
2431
1963
|
|
|
2432
1964
|
const None = 0;
|
|
@@ -2506,21 +2038,6 @@ const handleClickFeatures = async (state, name) => {
|
|
|
2506
2038
|
return selectFeature(state, name);
|
|
2507
2039
|
};
|
|
2508
2040
|
|
|
2509
|
-
const RendererWorker = 1;
|
|
2510
|
-
|
|
2511
|
-
const rpcs = Object.create(null);
|
|
2512
|
-
const set = (id, rpc) => {
|
|
2513
|
-
rpcs[id] = rpc;
|
|
2514
|
-
};
|
|
2515
|
-
const get = id => {
|
|
2516
|
-
return rpcs[id];
|
|
2517
|
-
};
|
|
2518
|
-
|
|
2519
|
-
const invoke = (method, ...params) => {
|
|
2520
|
-
const rpc = get(RendererWorker);
|
|
2521
|
-
return rpc.invoke(method, ...params);
|
|
2522
|
-
};
|
|
2523
|
-
|
|
2524
2041
|
const handleClickSize = async state => {
|
|
2525
2042
|
const {
|
|
2526
2043
|
uri
|
|
@@ -2609,2492 +2126,8 @@ const getThemeMarkdown = (themes, iconThemes, productIconThemes) => {
|
|
|
2609
2126
|
return markdown;
|
|
2610
2127
|
};
|
|
2611
2128
|
|
|
2612
|
-
/**
|
|
2613
|
-
* marked v15.0.6 - a markdown parser
|
|
2614
|
-
* Copyright (c) 2011-2025, Christopher Jeffrey. (MIT Licensed)
|
|
2615
|
-
* https://github.com/markedjs/marked
|
|
2616
|
-
*/
|
|
2617
|
-
|
|
2618
|
-
/**
|
|
2619
|
-
* DO NOT EDIT THIS FILE
|
|
2620
|
-
* The code in this file is generated from files in ./src/
|
|
2621
|
-
*/
|
|
2622
|
-
|
|
2623
|
-
/**
|
|
2624
|
-
* Gets the original marked default options.
|
|
2625
|
-
*/
|
|
2626
|
-
function _getDefaults() {
|
|
2627
|
-
return {
|
|
2628
|
-
async: false,
|
|
2629
|
-
breaks: false,
|
|
2630
|
-
extensions: null,
|
|
2631
|
-
gfm: true,
|
|
2632
|
-
hooks: null,
|
|
2633
|
-
pedantic: false,
|
|
2634
|
-
renderer: null,
|
|
2635
|
-
silent: false,
|
|
2636
|
-
tokenizer: null,
|
|
2637
|
-
walkTokens: null
|
|
2638
|
-
};
|
|
2639
|
-
}
|
|
2640
|
-
let _defaults = _getDefaults();
|
|
2641
|
-
function changeDefaults(newDefaults) {
|
|
2642
|
-
_defaults = newDefaults;
|
|
2643
|
-
}
|
|
2644
|
-
const noopTest = {
|
|
2645
|
-
exec: () => null
|
|
2646
|
-
};
|
|
2647
|
-
function edit(regex, opt = '') {
|
|
2648
|
-
let source = typeof regex === 'string' ? regex : regex.source;
|
|
2649
|
-
const obj = {
|
|
2650
|
-
replace: (name, val) => {
|
|
2651
|
-
let valSource = typeof val === 'string' ? val : val.source;
|
|
2652
|
-
valSource = valSource.replace(other.caret, '$1');
|
|
2653
|
-
source = source.replace(name, valSource);
|
|
2654
|
-
return obj;
|
|
2655
|
-
},
|
|
2656
|
-
getRegex: () => {
|
|
2657
|
-
return new RegExp(source, opt);
|
|
2658
|
-
}
|
|
2659
|
-
};
|
|
2660
|
-
return obj;
|
|
2661
|
-
}
|
|
2662
|
-
const other = {
|
|
2663
|
-
codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm,
|
|
2664
|
-
outputLinkReplace: /\\([\[\]])/g,
|
|
2665
|
-
indentCodeCompensation: /^(\s+)(?:```)/,
|
|
2666
|
-
beginningSpace: /^\s+/,
|
|
2667
|
-
endingHash: /#$/,
|
|
2668
|
-
startingSpaceChar: /^ /,
|
|
2669
|
-
endingSpaceChar: / $/,
|
|
2670
|
-
nonSpaceChar: /[^ ]/,
|
|
2671
|
-
newLineCharGlobal: /\n/g,
|
|
2672
|
-
tabCharGlobal: /\t/g,
|
|
2673
|
-
multipleSpaceGlobal: /\s+/g,
|
|
2674
|
-
blankLine: /^[ \t]*$/,
|
|
2675
|
-
doubleBlankLine: /\n[ \t]*\n[ \t]*$/,
|
|
2676
|
-
blockquoteStart: /^ {0,3}>/,
|
|
2677
|
-
blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g,
|
|
2678
|
-
blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm,
|
|
2679
|
-
listReplaceTabs: /^\t+/,
|
|
2680
|
-
listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g,
|
|
2681
|
-
listIsTask: /^\[[ xX]\] /,
|
|
2682
|
-
listReplaceTask: /^\[[ xX]\] +/,
|
|
2683
|
-
anyLine: /\n.*\n/,
|
|
2684
|
-
hrefBrackets: /^<(.*)>$/,
|
|
2685
|
-
tableDelimiter: /[:|]/,
|
|
2686
|
-
tableAlignChars: /^\||\| *$/g,
|
|
2687
|
-
tableRowBlankLine: /\n[ \t]*$/,
|
|
2688
|
-
tableAlignRight: /^ *-+: *$/,
|
|
2689
|
-
tableAlignCenter: /^ *:-+: *$/,
|
|
2690
|
-
tableAlignLeft: /^ *:-+ *$/,
|
|
2691
|
-
startATag: /^<a /i,
|
|
2692
|
-
endATag: /^<\/a>/i,
|
|
2693
|
-
startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i,
|
|
2694
|
-
endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i,
|
|
2695
|
-
startAngleBracket: /^</,
|
|
2696
|
-
endAngleBracket: />$/,
|
|
2697
|
-
pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/,
|
|
2698
|
-
unicodeAlphaNumeric: /[\p{L}\p{N}]/u,
|
|
2699
|
-
escapeTest: /[&<>"']/,
|
|
2700
|
-
escapeReplace: /[&<>"']/g,
|
|
2701
|
-
escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,
|
|
2702
|
-
escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,
|
|
2703
|
-
unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,
|
|
2704
|
-
caret: /(^|[^\[])\^/g,
|
|
2705
|
-
percentDecode: /%25/g,
|
|
2706
|
-
findPipe: /\|/g,
|
|
2707
|
-
splitPipe: / \|/,
|
|
2708
|
-
slashPipe: /\\\|/g,
|
|
2709
|
-
carriageReturn: /\r\n|\r/g,
|
|
2710
|
-
spaceLine: /^ +$/gm,
|
|
2711
|
-
notSpaceStart: /^\S*/,
|
|
2712
|
-
endingNewline: /\n$/,
|
|
2713
|
-
listItemRegex: bull => new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`),
|
|
2714
|
-
nextBulletRegex: indent => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),
|
|
2715
|
-
hrRegex: indent => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),
|
|
2716
|
-
fencesBeginRegex: indent => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`),
|
|
2717
|
-
headingBeginRegex: indent => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),
|
|
2718
|
-
htmlBeginRegex: indent => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, 'i')
|
|
2719
|
-
};
|
|
2720
|
-
/**
|
|
2721
|
-
* Block-Level Grammar
|
|
2722
|
-
*/
|
|
2723
|
-
const newline = /^(?:[ \t]*(?:\n|$))+/;
|
|
2724
|
-
const blockCode = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
|
|
2725
|
-
const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
|
|
2726
|
-
const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
|
|
2727
|
-
const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
|
|
2728
|
-
const bullet = /(?:[*+-]|\d{1,9}[.)])/;
|
|
2729
|
-
const lheading = edit(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g, bullet) // lists can interrupt
|
|
2730
|
-
.replace(/blockCode/g, /(?: {4}| {0,3}\t)/) // indented code blocks can interrupt
|
|
2731
|
-
.replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt
|
|
2732
|
-
.replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt
|
|
2733
|
-
.replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt
|
|
2734
|
-
.replace(/html/g, / {0,3}<[^\n>]+>\n/) // block html can interrupt
|
|
2735
|
-
.getRegex();
|
|
2736
|
-
const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
|
|
2737
|
-
const blockText = /^[^\n]+/;
|
|
2738
|
-
const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
|
|
2739
|
-
const def = edit(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace('label', _blockLabel).replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
|
|
2740
|
-
const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, bullet).getRegex();
|
|
2741
|
-
const _tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title' + '|tr|track|ul';
|
|
2742
|
-
const _comment = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
|
|
2743
|
-
const html = edit('^ {0,3}(?:' // optional indentation
|
|
2744
|
-
+ '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
|
|
2745
|
-
+ '|comment[^\\n]*(\\n+|$)' // (2)
|
|
2746
|
-
+ '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
|
|
2747
|
-
+ '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
|
|
2748
|
-
+ '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
|
|
2749
|
-
+ '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (6)
|
|
2750
|
-
+ '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) open tag
|
|
2751
|
-
+ '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) closing tag
|
|
2752
|
-
+ ')', 'i').replace('comment', _comment).replace('tag', _tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
|
|
2753
|
-
const paragraph = edit(_paragraph).replace('hr', hr).replace('heading', ' {0,3}#{1,6}(?:\\s|$)').replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
|
|
2754
|
-
.replace('|table', '').replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
2755
|
-
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', _tag) // pars can be interrupted by type (6) html blocks
|
|
2756
|
-
.getRegex();
|
|
2757
|
-
const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace('paragraph', paragraph).getRegex();
|
|
2758
|
-
/**
|
|
2759
|
-
* Normal Block Grammar
|
|
2760
|
-
*/
|
|
2761
|
-
const blockNormal = {
|
|
2762
|
-
blockquote,
|
|
2763
|
-
code: blockCode,
|
|
2764
|
-
def,
|
|
2765
|
-
fences,
|
|
2766
|
-
heading,
|
|
2767
|
-
hr,
|
|
2768
|
-
html,
|
|
2769
|
-
lheading,
|
|
2770
|
-
list,
|
|
2771
|
-
newline,
|
|
2772
|
-
paragraph,
|
|
2773
|
-
table: noopTest,
|
|
2774
|
-
text: blockText
|
|
2775
|
-
};
|
|
2776
|
-
/**
|
|
2777
|
-
* GFM Block Grammar
|
|
2778
|
-
*/
|
|
2779
|
-
const gfmTable = edit('^ *([^\\n ].*)\\n' // Header
|
|
2780
|
-
+ ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align
|
|
2781
|
-
+ '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells
|
|
2782
|
-
.replace('hr', hr).replace('heading', ' {0,3}#{1,6}(?:\\s|$)').replace('blockquote', ' {0,3}>').replace('code', '(?: {4}| {0,3}\t)[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
2783
|
-
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', _tag) // tables can be interrupted by type (6) html blocks
|
|
2784
|
-
.getRegex();
|
|
2785
|
-
const blockGfm = {
|
|
2786
|
-
...blockNormal,
|
|
2787
|
-
table: gfmTable,
|
|
2788
|
-
paragraph: edit(_paragraph).replace('hr', hr).replace('heading', ' {0,3}#{1,6}(?:\\s|$)').replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
|
|
2789
|
-
.replace('table', gfmTable) // interrupt paragraphs with table
|
|
2790
|
-
.replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
2791
|
-
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', _tag) // pars can be interrupted by type (6) html blocks
|
|
2792
|
-
.getRegex()
|
|
2793
|
-
};
|
|
2794
|
-
/**
|
|
2795
|
-
* Pedantic grammar (original John Gruber's loose markdown specification)
|
|
2796
|
-
*/
|
|
2797
|
-
const blockPedantic = {
|
|
2798
|
-
...blockNormal,
|
|
2799
|
-
html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
|
|
2800
|
-
+ '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', _comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(),
|
|
2801
|
-
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
|
|
2802
|
-
heading: /^(#{1,6})(.*)(?:\n+|$)/,
|
|
2803
|
-
fences: noopTest,
|
|
2804
|
-
// fences not supported
|
|
2805
|
-
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
2806
|
-
paragraph: edit(_paragraph).replace('hr', hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', lheading).replace('|table', '').replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').replace('|tag', '').getRegex()
|
|
2807
|
-
};
|
|
2808
|
-
/**
|
|
2809
|
-
* Inline-Level Grammar
|
|
2810
|
-
*/
|
|
2811
|
-
const escape$1 = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
|
|
2812
|
-
const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
|
|
2813
|
-
const br = /^( {2,}|\\)\n(?!\s*$)/;
|
|
2814
|
-
const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
|
|
2815
|
-
// list of unicode punctuation marks, plus any missing characters from CommonMark spec
|
|
2816
|
-
const _punctuation = /[\p{P}\p{S}]/u;
|
|
2817
|
-
const _punctuationOrSpace = /[\s\p{P}\p{S}]/u;
|
|
2818
|
-
const _notPunctuationOrSpace = /[^\s\p{P}\p{S}]/u;
|
|
2819
|
-
const punctuation = edit(/^((?![*_])punctSpace)/, 'u').replace(/punctSpace/g, _punctuationOrSpace).getRegex();
|
|
2820
|
-
// GFM allows ~ inside strong and em for strikethrough
|
|
2821
|
-
const _punctuationGfmStrongEm = /(?!~)[\p{P}\p{S}]/u;
|
|
2822
|
-
const _punctuationOrSpaceGfmStrongEm = /(?!~)[\s\p{P}\p{S}]/u;
|
|
2823
|
-
const _notPunctuationOrSpaceGfmStrongEm = /(?:[^\s\p{P}\p{S}]|~)/u;
|
|
2824
|
-
// sequences em should skip over [title](link), `code`, <html>
|
|
2825
|
-
const blockSkip = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g;
|
|
2826
|
-
const emStrongLDelimCore = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
|
|
2827
|
-
const emStrongLDelim = edit(emStrongLDelimCore, 'u').replace(/punct/g, _punctuation).getRegex();
|
|
2828
|
-
const emStrongLDelimGfm = edit(emStrongLDelimCore, 'u').replace(/punct/g, _punctuationGfmStrongEm).getRegex();
|
|
2829
|
-
const emStrongRDelimAstCore = '^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
|
|
2830
|
-
+ '|[^*]+(?=[^*])' // Consume to delim
|
|
2831
|
-
+ '|(?!\\*)punct(\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter
|
|
2832
|
-
+ '|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter
|
|
2833
|
-
+ '|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)' // (3) #***a, ***a can only be Left Delimiter
|
|
2834
|
-
+ '|[\\s](\\*+)(?!\\*)(?=punct)' // (4) ***# can only be Left Delimiter
|
|
2835
|
-
+ '|(?!\\*)punct(\\*+)(?!\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter
|
|
2836
|
-
+ '|notPunctSpace(\\*+)(?=notPunctSpace)'; // (6) a***a can be either Left or Right Delimiter
|
|
2837
|
-
const emStrongRDelimAst = edit(emStrongRDelimAstCore, 'gu').replace(/notPunctSpace/g, _notPunctuationOrSpace).replace(/punctSpace/g, _punctuationOrSpace).replace(/punct/g, _punctuation).getRegex();
|
|
2838
|
-
const emStrongRDelimAstGfm = edit(emStrongRDelimAstCore, 'gu').replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmStrongEm).replace(/punctSpace/g, _punctuationOrSpaceGfmStrongEm).replace(/punct/g, _punctuationGfmStrongEm).getRegex();
|
|
2839
|
-
// (6) Not allowed for _
|
|
2840
|
-
const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong
|
|
2841
|
-
+ '|[^_]+(?=[^_])' // Consume to delim
|
|
2842
|
-
+ '|(?!_)punct(_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter
|
|
2843
|
-
+ '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter
|
|
2844
|
-
+ '|(?!_)punctSpace(_+)(?=notPunctSpace)' // (3) #___a, ___a can only be Left Delimiter
|
|
2845
|
-
+ '|[\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter
|
|
2846
|
-
+ '|(?!_)punct(_+)(?!_)(?=punct)', 'gu') // (5) #___# can be either Left or Right Delimiter
|
|
2847
|
-
.replace(/notPunctSpace/g, _notPunctuationOrSpace).replace(/punctSpace/g, _punctuationOrSpace).replace(/punct/g, _punctuation).getRegex();
|
|
2848
|
-
const anyPunctuation = edit(/\\(punct)/, 'gu').replace(/punct/g, _punctuation).getRegex();
|
|
2849
|
-
const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
|
|
2850
|
-
const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();
|
|
2851
|
-
const tag = edit('^comment' + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
|
|
2852
|
-
+ '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
|
|
2853
|
-
+ '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
|
|
2854
|
-
+ '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
|
|
2855
|
-
+ '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>') // CDATA section
|
|
2856
|
-
.replace('comment', _inlineComment).replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
|
|
2857
|
-
const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
|
|
2858
|
-
const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace('label', _inlineLabel).replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
|
|
2859
|
-
const reflink = edit(/^!?\[(label)\]\[(ref)\]/).replace('label', _inlineLabel).replace('ref', _blockLabel).getRegex();
|
|
2860
|
-
const nolink = edit(/^!?\[(ref)\](?:\[\])?/).replace('ref', _blockLabel).getRegex();
|
|
2861
|
-
const reflinkSearch = edit('reflink|nolink(?!\\()', 'g').replace('reflink', reflink).replace('nolink', nolink).getRegex();
|
|
2862
|
-
/**
|
|
2863
|
-
* Normal Inline Grammar
|
|
2864
|
-
*/
|
|
2865
|
-
const inlineNormal = {
|
|
2866
|
-
_backpedal: noopTest,
|
|
2867
|
-
// only used for GFM url
|
|
2868
|
-
anyPunctuation,
|
|
2869
|
-
autolink,
|
|
2870
|
-
blockSkip,
|
|
2871
|
-
br,
|
|
2872
|
-
code: inlineCode,
|
|
2873
|
-
del: noopTest,
|
|
2874
|
-
emStrongLDelim,
|
|
2875
|
-
emStrongRDelimAst,
|
|
2876
|
-
emStrongRDelimUnd,
|
|
2877
|
-
escape: escape$1,
|
|
2878
|
-
link,
|
|
2879
|
-
nolink,
|
|
2880
|
-
punctuation,
|
|
2881
|
-
reflink,
|
|
2882
|
-
reflinkSearch,
|
|
2883
|
-
tag,
|
|
2884
|
-
text: inlineText,
|
|
2885
|
-
url: noopTest
|
|
2886
|
-
};
|
|
2887
|
-
/**
|
|
2888
|
-
* Pedantic Inline Grammar
|
|
2889
|
-
*/
|
|
2890
|
-
const inlinePedantic = {
|
|
2891
|
-
...inlineNormal,
|
|
2892
|
-
link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', _inlineLabel).getRegex(),
|
|
2893
|
-
reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', _inlineLabel).getRegex()
|
|
2894
|
-
};
|
|
2895
|
-
/**
|
|
2896
|
-
* GFM Inline Grammar
|
|
2897
|
-
*/
|
|
2898
|
-
const inlineGfm = {
|
|
2899
|
-
...inlineNormal,
|
|
2900
|
-
emStrongRDelimAst: emStrongRDelimAstGfm,
|
|
2901
|
-
emStrongLDelim: emStrongLDelimGfm,
|
|
2902
|
-
url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i').replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),
|
|
2903
|
-
_backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
|
|
2904
|
-
del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,
|
|
2905
|
-
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
|
|
2906
|
-
};
|
|
2907
|
-
/**
|
|
2908
|
-
* GFM + Line Breaks Inline Grammar
|
|
2909
|
-
*/
|
|
2910
|
-
const inlineBreaks = {
|
|
2911
|
-
...inlineGfm,
|
|
2912
|
-
br: edit(br).replace('{2,}', '*').getRegex(),
|
|
2913
|
-
text: edit(inlineGfm.text).replace('\\b_', '\\b_| {2,}\\n').replace(/\{2,\}/g, '*').getRegex()
|
|
2914
|
-
};
|
|
2915
|
-
/**
|
|
2916
|
-
* exports
|
|
2917
|
-
*/
|
|
2918
|
-
const block = {
|
|
2919
|
-
normal: blockNormal,
|
|
2920
|
-
gfm: blockGfm,
|
|
2921
|
-
pedantic: blockPedantic
|
|
2922
|
-
};
|
|
2923
|
-
const inline = {
|
|
2924
|
-
normal: inlineNormal,
|
|
2925
|
-
gfm: inlineGfm,
|
|
2926
|
-
breaks: inlineBreaks,
|
|
2927
|
-
pedantic: inlinePedantic
|
|
2928
|
-
};
|
|
2929
|
-
|
|
2930
|
-
/**
|
|
2931
|
-
* Helpers
|
|
2932
|
-
*/
|
|
2933
|
-
const escapeReplacements = {
|
|
2934
|
-
'&': '&',
|
|
2935
|
-
'<': '<',
|
|
2936
|
-
'>': '>',
|
|
2937
|
-
'"': '"',
|
|
2938
|
-
"'": '''
|
|
2939
|
-
};
|
|
2940
|
-
const getEscapeReplacement = ch => escapeReplacements[ch];
|
|
2941
|
-
function escape(html, encode) {
|
|
2942
|
-
if (encode) {
|
|
2943
|
-
if (other.escapeTest.test(html)) {
|
|
2944
|
-
return html.replace(other.escapeReplace, getEscapeReplacement);
|
|
2945
|
-
}
|
|
2946
|
-
} else {
|
|
2947
|
-
if (other.escapeTestNoEncode.test(html)) {
|
|
2948
|
-
return html.replace(other.escapeReplaceNoEncode, getEscapeReplacement);
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
return html;
|
|
2952
|
-
}
|
|
2953
|
-
function cleanUrl(href) {
|
|
2954
|
-
try {
|
|
2955
|
-
href = encodeURI(href).replace(other.percentDecode, '%');
|
|
2956
|
-
} catch {
|
|
2957
|
-
return null;
|
|
2958
|
-
}
|
|
2959
|
-
return href;
|
|
2960
|
-
}
|
|
2961
|
-
function splitCells(tableRow, count) {
|
|
2962
|
-
// ensure that every cell-delimiting pipe has a space
|
|
2963
|
-
// before it to distinguish it from an escaped pipe
|
|
2964
|
-
const row = tableRow.replace(other.findPipe, (match, offset, str) => {
|
|
2965
|
-
let escaped = false;
|
|
2966
|
-
let curr = offset;
|
|
2967
|
-
while (--curr >= 0 && str[curr] === '\\') escaped = !escaped;
|
|
2968
|
-
if (escaped) {
|
|
2969
|
-
// odd number of slashes means | is escaped
|
|
2970
|
-
// so we leave it alone
|
|
2971
|
-
return '|';
|
|
2972
|
-
} else {
|
|
2973
|
-
// add space before unescaped |
|
|
2974
|
-
return ' |';
|
|
2975
|
-
}
|
|
2976
|
-
}),
|
|
2977
|
-
cells = row.split(other.splitPipe);
|
|
2978
|
-
let i = 0;
|
|
2979
|
-
// First/last cell in a row cannot be empty if it has no leading/trailing pipe
|
|
2980
|
-
if (!cells[0].trim()) {
|
|
2981
|
-
cells.shift();
|
|
2982
|
-
}
|
|
2983
|
-
if (cells.length > 0 && !cells.at(-1)?.trim()) {
|
|
2984
|
-
cells.pop();
|
|
2985
|
-
}
|
|
2986
|
-
if (count) {
|
|
2987
|
-
if (cells.length > count) {
|
|
2988
|
-
cells.splice(count);
|
|
2989
|
-
} else {
|
|
2990
|
-
while (cells.length < count) cells.push('');
|
|
2991
|
-
}
|
|
2992
|
-
}
|
|
2993
|
-
for (; i < cells.length; i++) {
|
|
2994
|
-
// leading or trailing whitespace is ignored per the gfm spec
|
|
2995
|
-
cells[i] = cells[i].trim().replace(other.slashPipe, '|');
|
|
2996
|
-
}
|
|
2997
|
-
return cells;
|
|
2998
|
-
}
|
|
2999
|
-
/**
|
|
3000
|
-
* Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
|
|
3001
|
-
* /c*$/ is vulnerable to REDOS.
|
|
3002
|
-
*
|
|
3003
|
-
* @param str
|
|
3004
|
-
* @param c
|
|
3005
|
-
* @param invert Remove suffix of non-c chars instead. Default falsey.
|
|
3006
|
-
*/
|
|
3007
|
-
function rtrim(str, c, invert) {
|
|
3008
|
-
const l = str.length;
|
|
3009
|
-
if (l === 0) {
|
|
3010
|
-
return '';
|
|
3011
|
-
}
|
|
3012
|
-
// Length of suffix matching the invert condition.
|
|
3013
|
-
let suffLen = 0;
|
|
3014
|
-
// Step left until we fail to match the invert condition.
|
|
3015
|
-
while (suffLen < l) {
|
|
3016
|
-
const currChar = str.charAt(l - suffLen - 1);
|
|
3017
|
-
if (currChar === c && true) {
|
|
3018
|
-
suffLen++;
|
|
3019
|
-
} else {
|
|
3020
|
-
break;
|
|
3021
|
-
}
|
|
3022
|
-
}
|
|
3023
|
-
return str.slice(0, l - suffLen);
|
|
3024
|
-
}
|
|
3025
|
-
function findClosingBracket(str, b) {
|
|
3026
|
-
if (str.indexOf(b[1]) === -1) {
|
|
3027
|
-
return -1;
|
|
3028
|
-
}
|
|
3029
|
-
let level = 0;
|
|
3030
|
-
for (let i = 0; i < str.length; i++) {
|
|
3031
|
-
if (str[i] === '\\') {
|
|
3032
|
-
i++;
|
|
3033
|
-
} else if (str[i] === b[0]) {
|
|
3034
|
-
level++;
|
|
3035
|
-
} else if (str[i] === b[1]) {
|
|
3036
|
-
level--;
|
|
3037
|
-
if (level < 0) {
|
|
3038
|
-
return i;
|
|
3039
|
-
}
|
|
3040
|
-
}
|
|
3041
|
-
}
|
|
3042
|
-
return -1;
|
|
3043
|
-
}
|
|
3044
|
-
function outputLink(cap, link, raw, lexer, rules) {
|
|
3045
|
-
const href = link.href;
|
|
3046
|
-
const title = link.title || null;
|
|
3047
|
-
const text = cap[1].replace(rules.other.outputLinkReplace, '$1');
|
|
3048
|
-
if (cap[0].charAt(0) !== '!') {
|
|
3049
|
-
lexer.state.inLink = true;
|
|
3050
|
-
const token = {
|
|
3051
|
-
type: 'link',
|
|
3052
|
-
raw,
|
|
3053
|
-
href,
|
|
3054
|
-
title,
|
|
3055
|
-
text,
|
|
3056
|
-
tokens: lexer.inlineTokens(text)
|
|
3057
|
-
};
|
|
3058
|
-
lexer.state.inLink = false;
|
|
3059
|
-
return token;
|
|
3060
|
-
}
|
|
3061
|
-
return {
|
|
3062
|
-
type: 'image',
|
|
3063
|
-
raw,
|
|
3064
|
-
href,
|
|
3065
|
-
title,
|
|
3066
|
-
text
|
|
3067
|
-
};
|
|
3068
|
-
}
|
|
3069
|
-
function indentCodeCompensation(raw, text, rules) {
|
|
3070
|
-
const matchIndentToCode = raw.match(rules.other.indentCodeCompensation);
|
|
3071
|
-
if (matchIndentToCode === null) {
|
|
3072
|
-
return text;
|
|
3073
|
-
}
|
|
3074
|
-
const indentToCode = matchIndentToCode[1];
|
|
3075
|
-
return text.split('\n').map(node => {
|
|
3076
|
-
const matchIndentInNode = node.match(rules.other.beginningSpace);
|
|
3077
|
-
if (matchIndentInNode === null) {
|
|
3078
|
-
return node;
|
|
3079
|
-
}
|
|
3080
|
-
const [indentInNode] = matchIndentInNode;
|
|
3081
|
-
if (indentInNode.length >= indentToCode.length) {
|
|
3082
|
-
return node.slice(indentToCode.length);
|
|
3083
|
-
}
|
|
3084
|
-
return node;
|
|
3085
|
-
}).join('\n');
|
|
3086
|
-
}
|
|
3087
|
-
/**
|
|
3088
|
-
* Tokenizer
|
|
3089
|
-
*/
|
|
3090
|
-
class _Tokenizer {
|
|
3091
|
-
options;
|
|
3092
|
-
rules; // set by the lexer
|
|
3093
|
-
lexer; // set by the lexer
|
|
3094
|
-
constructor(options) {
|
|
3095
|
-
this.options = options || _defaults;
|
|
3096
|
-
}
|
|
3097
|
-
space(src) {
|
|
3098
|
-
const cap = this.rules.block.newline.exec(src);
|
|
3099
|
-
if (cap && cap[0].length > 0) {
|
|
3100
|
-
return {
|
|
3101
|
-
type: 'space',
|
|
3102
|
-
raw: cap[0]
|
|
3103
|
-
};
|
|
3104
|
-
}
|
|
3105
|
-
}
|
|
3106
|
-
code(src) {
|
|
3107
|
-
const cap = this.rules.block.code.exec(src);
|
|
3108
|
-
if (cap) {
|
|
3109
|
-
const text = cap[0].replace(this.rules.other.codeRemoveIndent, '');
|
|
3110
|
-
return {
|
|
3111
|
-
type: 'code',
|
|
3112
|
-
raw: cap[0],
|
|
3113
|
-
codeBlockStyle: 'indented',
|
|
3114
|
-
text: !this.options.pedantic ? rtrim(text, '\n') : text
|
|
3115
|
-
};
|
|
3116
|
-
}
|
|
3117
|
-
}
|
|
3118
|
-
fences(src) {
|
|
3119
|
-
const cap = this.rules.block.fences.exec(src);
|
|
3120
|
-
if (cap) {
|
|
3121
|
-
const raw = cap[0];
|
|
3122
|
-
const text = indentCodeCompensation(raw, cap[3] || '', this.rules);
|
|
3123
|
-
return {
|
|
3124
|
-
type: 'code',
|
|
3125
|
-
raw,
|
|
3126
|
-
lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],
|
|
3127
|
-
text
|
|
3128
|
-
};
|
|
3129
|
-
}
|
|
3130
|
-
}
|
|
3131
|
-
heading(src) {
|
|
3132
|
-
const cap = this.rules.block.heading.exec(src);
|
|
3133
|
-
if (cap) {
|
|
3134
|
-
let text = cap[2].trim();
|
|
3135
|
-
// remove trailing #s
|
|
3136
|
-
if (this.rules.other.endingHash.test(text)) {
|
|
3137
|
-
const trimmed = rtrim(text, '#');
|
|
3138
|
-
if (this.options.pedantic) {
|
|
3139
|
-
text = trimmed.trim();
|
|
3140
|
-
} else if (!trimmed || this.rules.other.endingSpaceChar.test(trimmed)) {
|
|
3141
|
-
// CommonMark requires space before trailing #s
|
|
3142
|
-
text = trimmed.trim();
|
|
3143
|
-
}
|
|
3144
|
-
}
|
|
3145
|
-
return {
|
|
3146
|
-
type: 'heading',
|
|
3147
|
-
raw: cap[0],
|
|
3148
|
-
depth: cap[1].length,
|
|
3149
|
-
text,
|
|
3150
|
-
tokens: this.lexer.inline(text)
|
|
3151
|
-
};
|
|
3152
|
-
}
|
|
3153
|
-
}
|
|
3154
|
-
hr(src) {
|
|
3155
|
-
const cap = this.rules.block.hr.exec(src);
|
|
3156
|
-
if (cap) {
|
|
3157
|
-
return {
|
|
3158
|
-
type: 'hr',
|
|
3159
|
-
raw: rtrim(cap[0], '\n')
|
|
3160
|
-
};
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
blockquote(src) {
|
|
3164
|
-
const cap = this.rules.block.blockquote.exec(src);
|
|
3165
|
-
if (cap) {
|
|
3166
|
-
let lines = rtrim(cap[0], '\n').split('\n');
|
|
3167
|
-
let raw = '';
|
|
3168
|
-
let text = '';
|
|
3169
|
-
const tokens = [];
|
|
3170
|
-
while (lines.length > 0) {
|
|
3171
|
-
let inBlockquote = false;
|
|
3172
|
-
const currentLines = [];
|
|
3173
|
-
let i;
|
|
3174
|
-
for (i = 0; i < lines.length; i++) {
|
|
3175
|
-
// get lines up to a continuation
|
|
3176
|
-
if (this.rules.other.blockquoteStart.test(lines[i])) {
|
|
3177
|
-
currentLines.push(lines[i]);
|
|
3178
|
-
inBlockquote = true;
|
|
3179
|
-
} else if (!inBlockquote) {
|
|
3180
|
-
currentLines.push(lines[i]);
|
|
3181
|
-
} else {
|
|
3182
|
-
break;
|
|
3183
|
-
}
|
|
3184
|
-
}
|
|
3185
|
-
lines = lines.slice(i);
|
|
3186
|
-
const currentRaw = currentLines.join('\n');
|
|
3187
|
-
const currentText = currentRaw
|
|
3188
|
-
// precede setext continuation with 4 spaces so it isn't a setext
|
|
3189
|
-
.replace(this.rules.other.blockquoteSetextReplace, '\n $1').replace(this.rules.other.blockquoteSetextReplace2, '');
|
|
3190
|
-
raw = raw ? `${raw}\n${currentRaw}` : currentRaw;
|
|
3191
|
-
text = text ? `${text}\n${currentText}` : currentText;
|
|
3192
|
-
// parse blockquote lines as top level tokens
|
|
3193
|
-
// merge paragraphs if this is a continuation
|
|
3194
|
-
const top = this.lexer.state.top;
|
|
3195
|
-
this.lexer.state.top = true;
|
|
3196
|
-
this.lexer.blockTokens(currentText, tokens, true);
|
|
3197
|
-
this.lexer.state.top = top;
|
|
3198
|
-
// if there is no continuation then we are done
|
|
3199
|
-
if (lines.length === 0) {
|
|
3200
|
-
break;
|
|
3201
|
-
}
|
|
3202
|
-
const lastToken = tokens.at(-1);
|
|
3203
|
-
if (lastToken?.type === 'code') {
|
|
3204
|
-
// blockquote continuation cannot be preceded by a code block
|
|
3205
|
-
break;
|
|
3206
|
-
} else if (lastToken?.type === 'blockquote') {
|
|
3207
|
-
// include continuation in nested blockquote
|
|
3208
|
-
const oldToken = lastToken;
|
|
3209
|
-
const newText = oldToken.raw + '\n' + lines.join('\n');
|
|
3210
|
-
const newToken = this.blockquote(newText);
|
|
3211
|
-
tokens[tokens.length - 1] = newToken;
|
|
3212
|
-
raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;
|
|
3213
|
-
text = text.substring(0, text.length - oldToken.text.length) + newToken.text;
|
|
3214
|
-
break;
|
|
3215
|
-
} else if (lastToken?.type === 'list') {
|
|
3216
|
-
// include continuation in nested list
|
|
3217
|
-
const oldToken = lastToken;
|
|
3218
|
-
const newText = oldToken.raw + '\n' + lines.join('\n');
|
|
3219
|
-
const newToken = this.list(newText);
|
|
3220
|
-
tokens[tokens.length - 1] = newToken;
|
|
3221
|
-
raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
|
|
3222
|
-
text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
|
|
3223
|
-
lines = newText.substring(tokens.at(-1).raw.length).split('\n');
|
|
3224
|
-
continue;
|
|
3225
|
-
}
|
|
3226
|
-
}
|
|
3227
|
-
return {
|
|
3228
|
-
type: 'blockquote',
|
|
3229
|
-
raw,
|
|
3230
|
-
tokens,
|
|
3231
|
-
text
|
|
3232
|
-
};
|
|
3233
|
-
}
|
|
3234
|
-
}
|
|
3235
|
-
list(src) {
|
|
3236
|
-
let cap = this.rules.block.list.exec(src);
|
|
3237
|
-
if (cap) {
|
|
3238
|
-
let bull = cap[1].trim();
|
|
3239
|
-
const isordered = bull.length > 1;
|
|
3240
|
-
const list = {
|
|
3241
|
-
type: 'list',
|
|
3242
|
-
raw: '',
|
|
3243
|
-
ordered: isordered,
|
|
3244
|
-
start: isordered ? +bull.slice(0, -1) : '',
|
|
3245
|
-
loose: false,
|
|
3246
|
-
items: []
|
|
3247
|
-
};
|
|
3248
|
-
bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
|
|
3249
|
-
if (this.options.pedantic) {
|
|
3250
|
-
bull = isordered ? bull : '[*+-]';
|
|
3251
|
-
}
|
|
3252
|
-
// Get next list item
|
|
3253
|
-
const itemRegex = this.rules.other.listItemRegex(bull);
|
|
3254
|
-
let endsWithBlankLine = false;
|
|
3255
|
-
// Check if current bullet point can start a new List Item
|
|
3256
|
-
while (src) {
|
|
3257
|
-
let endEarly = false;
|
|
3258
|
-
let raw = '';
|
|
3259
|
-
let itemContents = '';
|
|
3260
|
-
if (!(cap = itemRegex.exec(src))) {
|
|
3261
|
-
break;
|
|
3262
|
-
}
|
|
3263
|
-
if (this.rules.block.hr.test(src)) {
|
|
3264
|
-
// End list if bullet was actually HR (possibly move into itemRegex?)
|
|
3265
|
-
break;
|
|
3266
|
-
}
|
|
3267
|
-
raw = cap[0];
|
|
3268
|
-
src = src.substring(raw.length);
|
|
3269
|
-
let line = cap[2].split('\n', 1)[0].replace(this.rules.other.listReplaceTabs, t => ' '.repeat(3 * t.length));
|
|
3270
|
-
let nextLine = src.split('\n', 1)[0];
|
|
3271
|
-
let blankLine = !line.trim();
|
|
3272
|
-
let indent = 0;
|
|
3273
|
-
if (this.options.pedantic) {
|
|
3274
|
-
indent = 2;
|
|
3275
|
-
itemContents = line.trimStart();
|
|
3276
|
-
} else if (blankLine) {
|
|
3277
|
-
indent = cap[1].length + 1;
|
|
3278
|
-
} else {
|
|
3279
|
-
indent = cap[2].search(this.rules.other.nonSpaceChar); // Find first non-space char
|
|
3280
|
-
indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
|
|
3281
|
-
itemContents = line.slice(indent);
|
|
3282
|
-
indent += cap[1].length;
|
|
3283
|
-
}
|
|
3284
|
-
if (blankLine && this.rules.other.blankLine.test(nextLine)) {
|
|
3285
|
-
// Items begin with at most one blank line
|
|
3286
|
-
raw += nextLine + '\n';
|
|
3287
|
-
src = src.substring(nextLine.length + 1);
|
|
3288
|
-
endEarly = true;
|
|
3289
|
-
}
|
|
3290
|
-
if (!endEarly) {
|
|
3291
|
-
const nextBulletRegex = this.rules.other.nextBulletRegex(indent);
|
|
3292
|
-
const hrRegex = this.rules.other.hrRegex(indent);
|
|
3293
|
-
const fencesBeginRegex = this.rules.other.fencesBeginRegex(indent);
|
|
3294
|
-
const headingBeginRegex = this.rules.other.headingBeginRegex(indent);
|
|
3295
|
-
const htmlBeginRegex = this.rules.other.htmlBeginRegex(indent);
|
|
3296
|
-
// Check if following lines should be included in List Item
|
|
3297
|
-
while (src) {
|
|
3298
|
-
const rawLine = src.split('\n', 1)[0];
|
|
3299
|
-
let nextLineWithoutTabs;
|
|
3300
|
-
nextLine = rawLine;
|
|
3301
|
-
// Re-align to follow commonmark nesting rules
|
|
3302
|
-
if (this.options.pedantic) {
|
|
3303
|
-
nextLine = nextLine.replace(this.rules.other.listReplaceNesting, ' ');
|
|
3304
|
-
nextLineWithoutTabs = nextLine;
|
|
3305
|
-
} else {
|
|
3306
|
-
nextLineWithoutTabs = nextLine.replace(this.rules.other.tabCharGlobal, ' ');
|
|
3307
|
-
}
|
|
3308
|
-
// End list item if found code fences
|
|
3309
|
-
if (fencesBeginRegex.test(nextLine)) {
|
|
3310
|
-
break;
|
|
3311
|
-
}
|
|
3312
|
-
// End list item if found start of new heading
|
|
3313
|
-
if (headingBeginRegex.test(nextLine)) {
|
|
3314
|
-
break;
|
|
3315
|
-
}
|
|
3316
|
-
// End list item if found start of html block
|
|
3317
|
-
if (htmlBeginRegex.test(nextLine)) {
|
|
3318
|
-
break;
|
|
3319
|
-
}
|
|
3320
|
-
// End list item if found start of new bullet
|
|
3321
|
-
if (nextBulletRegex.test(nextLine)) {
|
|
3322
|
-
break;
|
|
3323
|
-
}
|
|
3324
|
-
// Horizontal rule found
|
|
3325
|
-
if (hrRegex.test(nextLine)) {
|
|
3326
|
-
break;
|
|
3327
|
-
}
|
|
3328
|
-
if (nextLineWithoutTabs.search(this.rules.other.nonSpaceChar) >= indent || !nextLine.trim()) {
|
|
3329
|
-
// Dedent if possible
|
|
3330
|
-
itemContents += '\n' + nextLineWithoutTabs.slice(indent);
|
|
3331
|
-
} else {
|
|
3332
|
-
// not enough indentation
|
|
3333
|
-
if (blankLine) {
|
|
3334
|
-
break;
|
|
3335
|
-
}
|
|
3336
|
-
// paragraph continuation unless last line was a different block level element
|
|
3337
|
-
if (line.replace(this.rules.other.tabCharGlobal, ' ').search(this.rules.other.nonSpaceChar) >= 4) {
|
|
3338
|
-
// indented code block
|
|
3339
|
-
break;
|
|
3340
|
-
}
|
|
3341
|
-
if (fencesBeginRegex.test(line)) {
|
|
3342
|
-
break;
|
|
3343
|
-
}
|
|
3344
|
-
if (headingBeginRegex.test(line)) {
|
|
3345
|
-
break;
|
|
3346
|
-
}
|
|
3347
|
-
if (hrRegex.test(line)) {
|
|
3348
|
-
break;
|
|
3349
|
-
}
|
|
3350
|
-
itemContents += '\n' + nextLine;
|
|
3351
|
-
}
|
|
3352
|
-
if (!blankLine && !nextLine.trim()) {
|
|
3353
|
-
// Check if current line is blank
|
|
3354
|
-
blankLine = true;
|
|
3355
|
-
}
|
|
3356
|
-
raw += rawLine + '\n';
|
|
3357
|
-
src = src.substring(rawLine.length + 1);
|
|
3358
|
-
line = nextLineWithoutTabs.slice(indent);
|
|
3359
|
-
}
|
|
3360
|
-
}
|
|
3361
|
-
if (!list.loose) {
|
|
3362
|
-
// If the previous item ended with a blank line, the list is loose
|
|
3363
|
-
if (endsWithBlankLine) {
|
|
3364
|
-
list.loose = true;
|
|
3365
|
-
} else if (this.rules.other.doubleBlankLine.test(raw)) {
|
|
3366
|
-
endsWithBlankLine = true;
|
|
3367
|
-
}
|
|
3368
|
-
}
|
|
3369
|
-
let istask = null;
|
|
3370
|
-
let ischecked;
|
|
3371
|
-
// Check for task list items
|
|
3372
|
-
if (this.options.gfm) {
|
|
3373
|
-
istask = this.rules.other.listIsTask.exec(itemContents);
|
|
3374
|
-
if (istask) {
|
|
3375
|
-
ischecked = istask[0] !== '[ ] ';
|
|
3376
|
-
itemContents = itemContents.replace(this.rules.other.listReplaceTask, '');
|
|
3377
|
-
}
|
|
3378
|
-
}
|
|
3379
|
-
list.items.push({
|
|
3380
|
-
type: 'list_item',
|
|
3381
|
-
raw,
|
|
3382
|
-
task: !!istask,
|
|
3383
|
-
checked: ischecked,
|
|
3384
|
-
loose: false,
|
|
3385
|
-
text: itemContents,
|
|
3386
|
-
tokens: []
|
|
3387
|
-
});
|
|
3388
|
-
list.raw += raw;
|
|
3389
|
-
}
|
|
3390
|
-
// Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
|
|
3391
|
-
const lastItem = list.items.at(-1);
|
|
3392
|
-
if (lastItem) {
|
|
3393
|
-
lastItem.raw = lastItem.raw.trimEnd();
|
|
3394
|
-
lastItem.text = lastItem.text.trimEnd();
|
|
3395
|
-
} else {
|
|
3396
|
-
// not a list since there were no items
|
|
3397
|
-
return;
|
|
3398
|
-
}
|
|
3399
|
-
list.raw = list.raw.trimEnd();
|
|
3400
|
-
// Item child tokens handled here at end because we needed to have the final item to trim it first
|
|
3401
|
-
for (let i = 0; i < list.items.length; i++) {
|
|
3402
|
-
this.lexer.state.top = false;
|
|
3403
|
-
list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
|
|
3404
|
-
if (!list.loose) {
|
|
3405
|
-
// Check if list should be loose
|
|
3406
|
-
const spacers = list.items[i].tokens.filter(t => t.type === 'space');
|
|
3407
|
-
const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => this.rules.other.anyLine.test(t.raw));
|
|
3408
|
-
list.loose = hasMultipleLineBreaks;
|
|
3409
|
-
}
|
|
3410
|
-
}
|
|
3411
|
-
// Set all items to loose if list is loose
|
|
3412
|
-
if (list.loose) {
|
|
3413
|
-
for (let i = 0; i < list.items.length; i++) {
|
|
3414
|
-
list.items[i].loose = true;
|
|
3415
|
-
}
|
|
3416
|
-
}
|
|
3417
|
-
return list;
|
|
3418
|
-
}
|
|
3419
|
-
}
|
|
3420
|
-
html(src) {
|
|
3421
|
-
const cap = this.rules.block.html.exec(src);
|
|
3422
|
-
if (cap) {
|
|
3423
|
-
const token = {
|
|
3424
|
-
type: 'html',
|
|
3425
|
-
block: true,
|
|
3426
|
-
raw: cap[0],
|
|
3427
|
-
pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
|
|
3428
|
-
text: cap[0]
|
|
3429
|
-
};
|
|
3430
|
-
return token;
|
|
3431
|
-
}
|
|
3432
|
-
}
|
|
3433
|
-
def(src) {
|
|
3434
|
-
const cap = this.rules.block.def.exec(src);
|
|
3435
|
-
if (cap) {
|
|
3436
|
-
const tag = cap[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, ' ');
|
|
3437
|
-
const href = cap[2] ? cap[2].replace(this.rules.other.hrefBrackets, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';
|
|
3438
|
-
const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];
|
|
3439
|
-
return {
|
|
3440
|
-
type: 'def',
|
|
3441
|
-
tag,
|
|
3442
|
-
raw: cap[0],
|
|
3443
|
-
href,
|
|
3444
|
-
title
|
|
3445
|
-
};
|
|
3446
|
-
}
|
|
3447
|
-
}
|
|
3448
|
-
table(src) {
|
|
3449
|
-
const cap = this.rules.block.table.exec(src);
|
|
3450
|
-
if (!cap) {
|
|
3451
|
-
return;
|
|
3452
|
-
}
|
|
3453
|
-
if (!this.rules.other.tableDelimiter.test(cap[2])) {
|
|
3454
|
-
// delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading
|
|
3455
|
-
return;
|
|
3456
|
-
}
|
|
3457
|
-
const headers = splitCells(cap[1]);
|
|
3458
|
-
const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');
|
|
3459
|
-
const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\n') : [];
|
|
3460
|
-
const item = {
|
|
3461
|
-
type: 'table',
|
|
3462
|
-
raw: cap[0],
|
|
3463
|
-
header: [],
|
|
3464
|
-
align: [],
|
|
3465
|
-
rows: []
|
|
3466
|
-
};
|
|
3467
|
-
if (headers.length !== aligns.length) {
|
|
3468
|
-
// header and align columns must be equal, rows can be different.
|
|
3469
|
-
return;
|
|
3470
|
-
}
|
|
3471
|
-
for (const align of aligns) {
|
|
3472
|
-
if (this.rules.other.tableAlignRight.test(align)) {
|
|
3473
|
-
item.align.push('right');
|
|
3474
|
-
} else if (this.rules.other.tableAlignCenter.test(align)) {
|
|
3475
|
-
item.align.push('center');
|
|
3476
|
-
} else if (this.rules.other.tableAlignLeft.test(align)) {
|
|
3477
|
-
item.align.push('left');
|
|
3478
|
-
} else {
|
|
3479
|
-
item.align.push(null);
|
|
3480
|
-
}
|
|
3481
|
-
}
|
|
3482
|
-
for (let i = 0; i < headers.length; i++) {
|
|
3483
|
-
item.header.push({
|
|
3484
|
-
text: headers[i],
|
|
3485
|
-
tokens: this.lexer.inline(headers[i]),
|
|
3486
|
-
header: true,
|
|
3487
|
-
align: item.align[i]
|
|
3488
|
-
});
|
|
3489
|
-
}
|
|
3490
|
-
for (const row of rows) {
|
|
3491
|
-
item.rows.push(splitCells(row, item.header.length).map((cell, i) => {
|
|
3492
|
-
return {
|
|
3493
|
-
text: cell,
|
|
3494
|
-
tokens: this.lexer.inline(cell),
|
|
3495
|
-
header: false,
|
|
3496
|
-
align: item.align[i]
|
|
3497
|
-
};
|
|
3498
|
-
}));
|
|
3499
|
-
}
|
|
3500
|
-
return item;
|
|
3501
|
-
}
|
|
3502
|
-
lheading(src) {
|
|
3503
|
-
const cap = this.rules.block.lheading.exec(src);
|
|
3504
|
-
if (cap) {
|
|
3505
|
-
return {
|
|
3506
|
-
type: 'heading',
|
|
3507
|
-
raw: cap[0],
|
|
3508
|
-
depth: cap[2].charAt(0) === '=' ? 1 : 2,
|
|
3509
|
-
text: cap[1],
|
|
3510
|
-
tokens: this.lexer.inline(cap[1])
|
|
3511
|
-
};
|
|
3512
|
-
}
|
|
3513
|
-
}
|
|
3514
|
-
paragraph(src) {
|
|
3515
|
-
const cap = this.rules.block.paragraph.exec(src);
|
|
3516
|
-
if (cap) {
|
|
3517
|
-
const text = cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1];
|
|
3518
|
-
return {
|
|
3519
|
-
type: 'paragraph',
|
|
3520
|
-
raw: cap[0],
|
|
3521
|
-
text,
|
|
3522
|
-
tokens: this.lexer.inline(text)
|
|
3523
|
-
};
|
|
3524
|
-
}
|
|
3525
|
-
}
|
|
3526
|
-
text(src) {
|
|
3527
|
-
const cap = this.rules.block.text.exec(src);
|
|
3528
|
-
if (cap) {
|
|
3529
|
-
return {
|
|
3530
|
-
type: 'text',
|
|
3531
|
-
raw: cap[0],
|
|
3532
|
-
text: cap[0],
|
|
3533
|
-
tokens: this.lexer.inline(cap[0])
|
|
3534
|
-
};
|
|
3535
|
-
}
|
|
3536
|
-
}
|
|
3537
|
-
escape(src) {
|
|
3538
|
-
const cap = this.rules.inline.escape.exec(src);
|
|
3539
|
-
if (cap) {
|
|
3540
|
-
return {
|
|
3541
|
-
type: 'escape',
|
|
3542
|
-
raw: cap[0],
|
|
3543
|
-
text: cap[1]
|
|
3544
|
-
};
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
tag(src) {
|
|
3548
|
-
const cap = this.rules.inline.tag.exec(src);
|
|
3549
|
-
if (cap) {
|
|
3550
|
-
if (!this.lexer.state.inLink && this.rules.other.startATag.test(cap[0])) {
|
|
3551
|
-
this.lexer.state.inLink = true;
|
|
3552
|
-
} else if (this.lexer.state.inLink && this.rules.other.endATag.test(cap[0])) {
|
|
3553
|
-
this.lexer.state.inLink = false;
|
|
3554
|
-
}
|
|
3555
|
-
if (!this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(cap[0])) {
|
|
3556
|
-
this.lexer.state.inRawBlock = true;
|
|
3557
|
-
} else if (this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(cap[0])) {
|
|
3558
|
-
this.lexer.state.inRawBlock = false;
|
|
3559
|
-
}
|
|
3560
|
-
return {
|
|
3561
|
-
type: 'html',
|
|
3562
|
-
raw: cap[0],
|
|
3563
|
-
inLink: this.lexer.state.inLink,
|
|
3564
|
-
inRawBlock: this.lexer.state.inRawBlock,
|
|
3565
|
-
block: false,
|
|
3566
|
-
text: cap[0]
|
|
3567
|
-
};
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
link(src) {
|
|
3571
|
-
const cap = this.rules.inline.link.exec(src);
|
|
3572
|
-
if (cap) {
|
|
3573
|
-
const trimmedUrl = cap[2].trim();
|
|
3574
|
-
if (!this.options.pedantic && this.rules.other.startAngleBracket.test(trimmedUrl)) {
|
|
3575
|
-
// commonmark requires matching angle brackets
|
|
3576
|
-
if (!this.rules.other.endAngleBracket.test(trimmedUrl)) {
|
|
3577
|
-
return;
|
|
3578
|
-
}
|
|
3579
|
-
// ending angle bracket cannot be escaped
|
|
3580
|
-
const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
|
|
3581
|
-
if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
|
|
3582
|
-
return;
|
|
3583
|
-
}
|
|
3584
|
-
} else {
|
|
3585
|
-
// find closing parenthesis
|
|
3586
|
-
const lastParenIndex = findClosingBracket(cap[2], '()');
|
|
3587
|
-
if (lastParenIndex > -1) {
|
|
3588
|
-
const start = cap[0].indexOf('!') === 0 ? 5 : 4;
|
|
3589
|
-
const linkLen = start + cap[1].length + lastParenIndex;
|
|
3590
|
-
cap[2] = cap[2].substring(0, lastParenIndex);
|
|
3591
|
-
cap[0] = cap[0].substring(0, linkLen).trim();
|
|
3592
|
-
cap[3] = '';
|
|
3593
|
-
}
|
|
3594
|
-
}
|
|
3595
|
-
let href = cap[2];
|
|
3596
|
-
let title = '';
|
|
3597
|
-
if (this.options.pedantic) {
|
|
3598
|
-
// split pedantic href and title
|
|
3599
|
-
const link = this.rules.other.pedanticHrefTitle.exec(href);
|
|
3600
|
-
if (link) {
|
|
3601
|
-
href = link[1];
|
|
3602
|
-
title = link[3];
|
|
3603
|
-
}
|
|
3604
|
-
} else {
|
|
3605
|
-
title = cap[3] ? cap[3].slice(1, -1) : '';
|
|
3606
|
-
}
|
|
3607
|
-
href = href.trim();
|
|
3608
|
-
if (this.rules.other.startAngleBracket.test(href)) {
|
|
3609
|
-
if (this.options.pedantic && !this.rules.other.endAngleBracket.test(trimmedUrl)) {
|
|
3610
|
-
// pedantic allows starting angle bracket without ending angle bracket
|
|
3611
|
-
href = href.slice(1);
|
|
3612
|
-
} else {
|
|
3613
|
-
href = href.slice(1, -1);
|
|
3614
|
-
}
|
|
3615
|
-
}
|
|
3616
|
-
return outputLink(cap, {
|
|
3617
|
-
href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,
|
|
3618
|
-
title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title
|
|
3619
|
-
}, cap[0], this.lexer, this.rules);
|
|
3620
|
-
}
|
|
3621
|
-
}
|
|
3622
|
-
reflink(src, links) {
|
|
3623
|
-
let cap;
|
|
3624
|
-
if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
|
|
3625
|
-
const linkString = (cap[2] || cap[1]).replace(this.rules.other.multipleSpaceGlobal, ' ');
|
|
3626
|
-
const link = links[linkString.toLowerCase()];
|
|
3627
|
-
if (!link) {
|
|
3628
|
-
const text = cap[0].charAt(0);
|
|
3629
|
-
return {
|
|
3630
|
-
type: 'text',
|
|
3631
|
-
raw: text,
|
|
3632
|
-
text
|
|
3633
|
-
};
|
|
3634
|
-
}
|
|
3635
|
-
return outputLink(cap, link, cap[0], this.lexer, this.rules);
|
|
3636
|
-
}
|
|
3637
|
-
}
|
|
3638
|
-
emStrong(src, maskedSrc, prevChar = '') {
|
|
3639
|
-
let match = this.rules.inline.emStrongLDelim.exec(src);
|
|
3640
|
-
if (!match) return;
|
|
3641
|
-
// _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
|
|
3642
|
-
if (match[3] && prevChar.match(this.rules.other.unicodeAlphaNumeric)) return;
|
|
3643
|
-
const nextChar = match[1] || match[2] || '';
|
|
3644
|
-
if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
|
|
3645
|
-
// unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
|
|
3646
|
-
const lLength = [...match[0]].length - 1;
|
|
3647
|
-
let rDelim,
|
|
3648
|
-
rLength,
|
|
3649
|
-
delimTotal = lLength,
|
|
3650
|
-
midDelimTotal = 0;
|
|
3651
|
-
const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
|
|
3652
|
-
endReg.lastIndex = 0;
|
|
3653
|
-
// Clip maskedSrc to same section of string as src (move to lexer?)
|
|
3654
|
-
maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
|
|
3655
|
-
while ((match = endReg.exec(maskedSrc)) != null) {
|
|
3656
|
-
rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
|
|
3657
|
-
if (!rDelim) continue; // skip single * in __abc*abc__
|
|
3658
|
-
rLength = [...rDelim].length;
|
|
3659
|
-
if (match[3] || match[4]) {
|
|
3660
|
-
// found another Left Delim
|
|
3661
|
-
delimTotal += rLength;
|
|
3662
|
-
continue;
|
|
3663
|
-
} else if (match[5] || match[6]) {
|
|
3664
|
-
// either Left or Right Delim
|
|
3665
|
-
if (lLength % 3 && !((lLength + rLength) % 3)) {
|
|
3666
|
-
midDelimTotal += rLength;
|
|
3667
|
-
continue; // CommonMark Emphasis Rules 9-10
|
|
3668
|
-
}
|
|
3669
|
-
}
|
|
3670
|
-
delimTotal -= rLength;
|
|
3671
|
-
if (delimTotal > 0) continue; // Haven't found enough closing delimiters
|
|
3672
|
-
// Remove extra characters. *a*** -> *a*
|
|
3673
|
-
rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
|
|
3674
|
-
// char length can be >1 for unicode characters;
|
|
3675
|
-
const lastCharLength = [...match[0]][0].length;
|
|
3676
|
-
const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);
|
|
3677
|
-
// Create `em` if smallest delimiter has odd char count. *a***
|
|
3678
|
-
if (Math.min(lLength, rLength) % 2) {
|
|
3679
|
-
const text = raw.slice(1, -1);
|
|
3680
|
-
return {
|
|
3681
|
-
type: 'em',
|
|
3682
|
-
raw,
|
|
3683
|
-
text,
|
|
3684
|
-
tokens: this.lexer.inlineTokens(text)
|
|
3685
|
-
};
|
|
3686
|
-
}
|
|
3687
|
-
// Create 'strong' if smallest delimiter has even char count. **a***
|
|
3688
|
-
const text = raw.slice(2, -2);
|
|
3689
|
-
return {
|
|
3690
|
-
type: 'strong',
|
|
3691
|
-
raw,
|
|
3692
|
-
text,
|
|
3693
|
-
tokens: this.lexer.inlineTokens(text)
|
|
3694
|
-
};
|
|
3695
|
-
}
|
|
3696
|
-
}
|
|
3697
|
-
}
|
|
3698
|
-
codespan(src) {
|
|
3699
|
-
const cap = this.rules.inline.code.exec(src);
|
|
3700
|
-
if (cap) {
|
|
3701
|
-
let text = cap[2].replace(this.rules.other.newLineCharGlobal, ' ');
|
|
3702
|
-
const hasNonSpaceChars = this.rules.other.nonSpaceChar.test(text);
|
|
3703
|
-
const hasSpaceCharsOnBothEnds = this.rules.other.startingSpaceChar.test(text) && this.rules.other.endingSpaceChar.test(text);
|
|
3704
|
-
if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
|
|
3705
|
-
text = text.substring(1, text.length - 1);
|
|
3706
|
-
}
|
|
3707
|
-
return {
|
|
3708
|
-
type: 'codespan',
|
|
3709
|
-
raw: cap[0],
|
|
3710
|
-
text
|
|
3711
|
-
};
|
|
3712
|
-
}
|
|
3713
|
-
}
|
|
3714
|
-
br(src) {
|
|
3715
|
-
const cap = this.rules.inline.br.exec(src);
|
|
3716
|
-
if (cap) {
|
|
3717
|
-
return {
|
|
3718
|
-
type: 'br',
|
|
3719
|
-
raw: cap[0]
|
|
3720
|
-
};
|
|
3721
|
-
}
|
|
3722
|
-
}
|
|
3723
|
-
del(src) {
|
|
3724
|
-
const cap = this.rules.inline.del.exec(src);
|
|
3725
|
-
if (cap) {
|
|
3726
|
-
return {
|
|
3727
|
-
type: 'del',
|
|
3728
|
-
raw: cap[0],
|
|
3729
|
-
text: cap[2],
|
|
3730
|
-
tokens: this.lexer.inlineTokens(cap[2])
|
|
3731
|
-
};
|
|
3732
|
-
}
|
|
3733
|
-
}
|
|
3734
|
-
autolink(src) {
|
|
3735
|
-
const cap = this.rules.inline.autolink.exec(src);
|
|
3736
|
-
if (cap) {
|
|
3737
|
-
let text, href;
|
|
3738
|
-
if (cap[2] === '@') {
|
|
3739
|
-
text = cap[1];
|
|
3740
|
-
href = 'mailto:' + text;
|
|
3741
|
-
} else {
|
|
3742
|
-
text = cap[1];
|
|
3743
|
-
href = text;
|
|
3744
|
-
}
|
|
3745
|
-
return {
|
|
3746
|
-
type: 'link',
|
|
3747
|
-
raw: cap[0],
|
|
3748
|
-
text,
|
|
3749
|
-
href,
|
|
3750
|
-
tokens: [{
|
|
3751
|
-
type: 'text',
|
|
3752
|
-
raw: text,
|
|
3753
|
-
text
|
|
3754
|
-
}]
|
|
3755
|
-
};
|
|
3756
|
-
}
|
|
3757
|
-
}
|
|
3758
|
-
url(src) {
|
|
3759
|
-
let cap;
|
|
3760
|
-
if (cap = this.rules.inline.url.exec(src)) {
|
|
3761
|
-
let text, href;
|
|
3762
|
-
if (cap[2] === '@') {
|
|
3763
|
-
text = cap[0];
|
|
3764
|
-
href = 'mailto:' + text;
|
|
3765
|
-
} else {
|
|
3766
|
-
// do extended autolink path validation
|
|
3767
|
-
let prevCapZero;
|
|
3768
|
-
do {
|
|
3769
|
-
prevCapZero = cap[0];
|
|
3770
|
-
cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';
|
|
3771
|
-
} while (prevCapZero !== cap[0]);
|
|
3772
|
-
text = cap[0];
|
|
3773
|
-
if (cap[1] === 'www.') {
|
|
3774
|
-
href = 'http://' + cap[0];
|
|
3775
|
-
} else {
|
|
3776
|
-
href = cap[0];
|
|
3777
|
-
}
|
|
3778
|
-
}
|
|
3779
|
-
return {
|
|
3780
|
-
type: 'link',
|
|
3781
|
-
raw: cap[0],
|
|
3782
|
-
text,
|
|
3783
|
-
href,
|
|
3784
|
-
tokens: [{
|
|
3785
|
-
type: 'text',
|
|
3786
|
-
raw: text,
|
|
3787
|
-
text
|
|
3788
|
-
}]
|
|
3789
|
-
};
|
|
3790
|
-
}
|
|
3791
|
-
}
|
|
3792
|
-
inlineText(src) {
|
|
3793
|
-
const cap = this.rules.inline.text.exec(src);
|
|
3794
|
-
if (cap) {
|
|
3795
|
-
const escaped = this.lexer.state.inRawBlock;
|
|
3796
|
-
return {
|
|
3797
|
-
type: 'text',
|
|
3798
|
-
raw: cap[0],
|
|
3799
|
-
text: cap[0],
|
|
3800
|
-
escaped
|
|
3801
|
-
};
|
|
3802
|
-
}
|
|
3803
|
-
}
|
|
3804
|
-
}
|
|
3805
|
-
|
|
3806
|
-
/**
|
|
3807
|
-
* Block Lexer
|
|
3808
|
-
*/
|
|
3809
|
-
class _Lexer {
|
|
3810
|
-
tokens;
|
|
3811
|
-
options;
|
|
3812
|
-
state;
|
|
3813
|
-
tokenizer;
|
|
3814
|
-
inlineQueue;
|
|
3815
|
-
constructor(options) {
|
|
3816
|
-
// TokenList cannot be created in one go
|
|
3817
|
-
this.tokens = [];
|
|
3818
|
-
this.tokens.links = Object.create(null);
|
|
3819
|
-
this.options = options || _defaults;
|
|
3820
|
-
this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
|
|
3821
|
-
this.tokenizer = this.options.tokenizer;
|
|
3822
|
-
this.tokenizer.options = this.options;
|
|
3823
|
-
this.tokenizer.lexer = this;
|
|
3824
|
-
this.inlineQueue = [];
|
|
3825
|
-
this.state = {
|
|
3826
|
-
inLink: false,
|
|
3827
|
-
inRawBlock: false,
|
|
3828
|
-
top: true
|
|
3829
|
-
};
|
|
3830
|
-
const rules = {
|
|
3831
|
-
other,
|
|
3832
|
-
block: block.normal,
|
|
3833
|
-
inline: inline.normal
|
|
3834
|
-
};
|
|
3835
|
-
if (this.options.pedantic) {
|
|
3836
|
-
rules.block = block.pedantic;
|
|
3837
|
-
rules.inline = inline.pedantic;
|
|
3838
|
-
} else if (this.options.gfm) {
|
|
3839
|
-
rules.block = block.gfm;
|
|
3840
|
-
if (this.options.breaks) {
|
|
3841
|
-
rules.inline = inline.breaks;
|
|
3842
|
-
} else {
|
|
3843
|
-
rules.inline = inline.gfm;
|
|
3844
|
-
}
|
|
3845
|
-
}
|
|
3846
|
-
this.tokenizer.rules = rules;
|
|
3847
|
-
}
|
|
3848
|
-
/**
|
|
3849
|
-
* Expose Rules
|
|
3850
|
-
*/
|
|
3851
|
-
static get rules() {
|
|
3852
|
-
return {
|
|
3853
|
-
block,
|
|
3854
|
-
inline
|
|
3855
|
-
};
|
|
3856
|
-
}
|
|
3857
|
-
/**
|
|
3858
|
-
* Static Lex Method
|
|
3859
|
-
*/
|
|
3860
|
-
static lex(src, options) {
|
|
3861
|
-
const lexer = new _Lexer(options);
|
|
3862
|
-
return lexer.lex(src);
|
|
3863
|
-
}
|
|
3864
|
-
/**
|
|
3865
|
-
* Static Lex Inline Method
|
|
3866
|
-
*/
|
|
3867
|
-
static lexInline(src, options) {
|
|
3868
|
-
const lexer = new _Lexer(options);
|
|
3869
|
-
return lexer.inlineTokens(src);
|
|
3870
|
-
}
|
|
3871
|
-
/**
|
|
3872
|
-
* Preprocessing
|
|
3873
|
-
*/
|
|
3874
|
-
lex(src) {
|
|
3875
|
-
src = src.replace(other.carriageReturn, '\n');
|
|
3876
|
-
this.blockTokens(src, this.tokens);
|
|
3877
|
-
for (let i = 0; i < this.inlineQueue.length; i++) {
|
|
3878
|
-
const next = this.inlineQueue[i];
|
|
3879
|
-
this.inlineTokens(next.src, next.tokens);
|
|
3880
|
-
}
|
|
3881
|
-
this.inlineQueue = [];
|
|
3882
|
-
return this.tokens;
|
|
3883
|
-
}
|
|
3884
|
-
blockTokens(src, tokens = [], lastParagraphClipped = false) {
|
|
3885
|
-
if (this.options.pedantic) {
|
|
3886
|
-
src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');
|
|
3887
|
-
}
|
|
3888
|
-
while (src) {
|
|
3889
|
-
let token;
|
|
3890
|
-
if (this.options.extensions?.block?.some(extTokenizer => {
|
|
3891
|
-
if (token = extTokenizer.call({
|
|
3892
|
-
lexer: this
|
|
3893
|
-
}, src, tokens)) {
|
|
3894
|
-
src = src.substring(token.raw.length);
|
|
3895
|
-
tokens.push(token);
|
|
3896
|
-
return true;
|
|
3897
|
-
}
|
|
3898
|
-
return false;
|
|
3899
|
-
})) {
|
|
3900
|
-
continue;
|
|
3901
|
-
}
|
|
3902
|
-
// newline
|
|
3903
|
-
if (token = this.tokenizer.space(src)) {
|
|
3904
|
-
src = src.substring(token.raw.length);
|
|
3905
|
-
const lastToken = tokens.at(-1);
|
|
3906
|
-
if (token.raw.length === 1 && lastToken !== undefined) {
|
|
3907
|
-
// if there's a single \n as a spacer, it's terminating the last line,
|
|
3908
|
-
// so move it there so that we don't get unnecessary paragraph tags
|
|
3909
|
-
lastToken.raw += '\n';
|
|
3910
|
-
} else {
|
|
3911
|
-
tokens.push(token);
|
|
3912
|
-
}
|
|
3913
|
-
continue;
|
|
3914
|
-
}
|
|
3915
|
-
// code
|
|
3916
|
-
if (token = this.tokenizer.code(src)) {
|
|
3917
|
-
src = src.substring(token.raw.length);
|
|
3918
|
-
const lastToken = tokens.at(-1);
|
|
3919
|
-
// An indented code block cannot interrupt a paragraph.
|
|
3920
|
-
if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
|
|
3921
|
-
lastToken.raw += '\n' + token.raw;
|
|
3922
|
-
lastToken.text += '\n' + token.text;
|
|
3923
|
-
this.inlineQueue.at(-1).src = lastToken.text;
|
|
3924
|
-
} else {
|
|
3925
|
-
tokens.push(token);
|
|
3926
|
-
}
|
|
3927
|
-
continue;
|
|
3928
|
-
}
|
|
3929
|
-
// fences
|
|
3930
|
-
if (token = this.tokenizer.fences(src)) {
|
|
3931
|
-
src = src.substring(token.raw.length);
|
|
3932
|
-
tokens.push(token);
|
|
3933
|
-
continue;
|
|
3934
|
-
}
|
|
3935
|
-
// heading
|
|
3936
|
-
if (token = this.tokenizer.heading(src)) {
|
|
3937
|
-
src = src.substring(token.raw.length);
|
|
3938
|
-
tokens.push(token);
|
|
3939
|
-
continue;
|
|
3940
|
-
}
|
|
3941
|
-
// hr
|
|
3942
|
-
if (token = this.tokenizer.hr(src)) {
|
|
3943
|
-
src = src.substring(token.raw.length);
|
|
3944
|
-
tokens.push(token);
|
|
3945
|
-
continue;
|
|
3946
|
-
}
|
|
3947
|
-
// blockquote
|
|
3948
|
-
if (token = this.tokenizer.blockquote(src)) {
|
|
3949
|
-
src = src.substring(token.raw.length);
|
|
3950
|
-
tokens.push(token);
|
|
3951
|
-
continue;
|
|
3952
|
-
}
|
|
3953
|
-
// list
|
|
3954
|
-
if (token = this.tokenizer.list(src)) {
|
|
3955
|
-
src = src.substring(token.raw.length);
|
|
3956
|
-
tokens.push(token);
|
|
3957
|
-
continue;
|
|
3958
|
-
}
|
|
3959
|
-
// html
|
|
3960
|
-
if (token = this.tokenizer.html(src)) {
|
|
3961
|
-
src = src.substring(token.raw.length);
|
|
3962
|
-
tokens.push(token);
|
|
3963
|
-
continue;
|
|
3964
|
-
}
|
|
3965
|
-
// def
|
|
3966
|
-
if (token = this.tokenizer.def(src)) {
|
|
3967
|
-
src = src.substring(token.raw.length);
|
|
3968
|
-
const lastToken = tokens.at(-1);
|
|
3969
|
-
if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
|
|
3970
|
-
lastToken.raw += '\n' + token.raw;
|
|
3971
|
-
lastToken.text += '\n' + token.raw;
|
|
3972
|
-
this.inlineQueue.at(-1).src = lastToken.text;
|
|
3973
|
-
} else if (!this.tokens.links[token.tag]) {
|
|
3974
|
-
this.tokens.links[token.tag] = {
|
|
3975
|
-
href: token.href,
|
|
3976
|
-
title: token.title
|
|
3977
|
-
};
|
|
3978
|
-
}
|
|
3979
|
-
continue;
|
|
3980
|
-
}
|
|
3981
|
-
// table (gfm)
|
|
3982
|
-
if (token = this.tokenizer.table(src)) {
|
|
3983
|
-
src = src.substring(token.raw.length);
|
|
3984
|
-
tokens.push(token);
|
|
3985
|
-
continue;
|
|
3986
|
-
}
|
|
3987
|
-
// lheading
|
|
3988
|
-
if (token = this.tokenizer.lheading(src)) {
|
|
3989
|
-
src = src.substring(token.raw.length);
|
|
3990
|
-
tokens.push(token);
|
|
3991
|
-
continue;
|
|
3992
|
-
}
|
|
3993
|
-
// top-level paragraph
|
|
3994
|
-
// prevent paragraph consuming extensions by clipping 'src' to extension start
|
|
3995
|
-
let cutSrc = src;
|
|
3996
|
-
if (this.options.extensions?.startBlock) {
|
|
3997
|
-
let startIndex = Infinity;
|
|
3998
|
-
const tempSrc = src.slice(1);
|
|
3999
|
-
let tempStart;
|
|
4000
|
-
this.options.extensions.startBlock.forEach(getStartIndex => {
|
|
4001
|
-
tempStart = getStartIndex.call({
|
|
4002
|
-
lexer: this
|
|
4003
|
-
}, tempSrc);
|
|
4004
|
-
if (typeof tempStart === 'number' && tempStart >= 0) {
|
|
4005
|
-
startIndex = Math.min(startIndex, tempStart);
|
|
4006
|
-
}
|
|
4007
|
-
});
|
|
4008
|
-
if (startIndex < Infinity && startIndex >= 0) {
|
|
4009
|
-
cutSrc = src.substring(0, startIndex + 1);
|
|
4010
|
-
}
|
|
4011
|
-
}
|
|
4012
|
-
if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
|
|
4013
|
-
const lastToken = tokens.at(-1);
|
|
4014
|
-
if (lastParagraphClipped && lastToken?.type === 'paragraph') {
|
|
4015
|
-
lastToken.raw += '\n' + token.raw;
|
|
4016
|
-
lastToken.text += '\n' + token.text;
|
|
4017
|
-
this.inlineQueue.pop();
|
|
4018
|
-
this.inlineQueue.at(-1).src = lastToken.text;
|
|
4019
|
-
} else {
|
|
4020
|
-
tokens.push(token);
|
|
4021
|
-
}
|
|
4022
|
-
lastParagraphClipped = cutSrc.length !== src.length;
|
|
4023
|
-
src = src.substring(token.raw.length);
|
|
4024
|
-
continue;
|
|
4025
|
-
}
|
|
4026
|
-
// text
|
|
4027
|
-
if (token = this.tokenizer.text(src)) {
|
|
4028
|
-
src = src.substring(token.raw.length);
|
|
4029
|
-
const lastToken = tokens.at(-1);
|
|
4030
|
-
if (lastToken?.type === 'text') {
|
|
4031
|
-
lastToken.raw += '\n' + token.raw;
|
|
4032
|
-
lastToken.text += '\n' + token.text;
|
|
4033
|
-
this.inlineQueue.pop();
|
|
4034
|
-
this.inlineQueue.at(-1).src = lastToken.text;
|
|
4035
|
-
} else {
|
|
4036
|
-
tokens.push(token);
|
|
4037
|
-
}
|
|
4038
|
-
continue;
|
|
4039
|
-
}
|
|
4040
|
-
if (src) {
|
|
4041
|
-
const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
|
|
4042
|
-
if (this.options.silent) {
|
|
4043
|
-
console.error(errMsg);
|
|
4044
|
-
break;
|
|
4045
|
-
} else {
|
|
4046
|
-
throw new Error(errMsg);
|
|
4047
|
-
}
|
|
4048
|
-
}
|
|
4049
|
-
}
|
|
4050
|
-
this.state.top = true;
|
|
4051
|
-
return tokens;
|
|
4052
|
-
}
|
|
4053
|
-
inline(src, tokens = []) {
|
|
4054
|
-
this.inlineQueue.push({
|
|
4055
|
-
src,
|
|
4056
|
-
tokens
|
|
4057
|
-
});
|
|
4058
|
-
return tokens;
|
|
4059
|
-
}
|
|
4060
|
-
/**
|
|
4061
|
-
* Lexing/Compiling
|
|
4062
|
-
*/
|
|
4063
|
-
inlineTokens(src, tokens = []) {
|
|
4064
|
-
// String with links masked to avoid interference with em and strong
|
|
4065
|
-
let maskedSrc = src;
|
|
4066
|
-
let match = null;
|
|
4067
|
-
// Mask out reflinks
|
|
4068
|
-
if (this.tokens.links) {
|
|
4069
|
-
const links = Object.keys(this.tokens.links);
|
|
4070
|
-
if (links.length > 0) {
|
|
4071
|
-
while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
|
|
4072
|
-
if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
|
|
4073
|
-
maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
|
|
4074
|
-
}
|
|
4075
|
-
}
|
|
4076
|
-
}
|
|
4077
|
-
}
|
|
4078
|
-
// Mask out other blocks
|
|
4079
|
-
while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
|
|
4080
|
-
maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
|
|
4081
|
-
}
|
|
4082
|
-
// Mask out escaped characters
|
|
4083
|
-
while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
|
|
4084
|
-
maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
|
|
4085
|
-
}
|
|
4086
|
-
let keepPrevChar = false;
|
|
4087
|
-
let prevChar = '';
|
|
4088
|
-
while (src) {
|
|
4089
|
-
if (!keepPrevChar) {
|
|
4090
|
-
prevChar = '';
|
|
4091
|
-
}
|
|
4092
|
-
keepPrevChar = false;
|
|
4093
|
-
let token;
|
|
4094
|
-
// extensions
|
|
4095
|
-
if (this.options.extensions?.inline?.some(extTokenizer => {
|
|
4096
|
-
if (token = extTokenizer.call({
|
|
4097
|
-
lexer: this
|
|
4098
|
-
}, src, tokens)) {
|
|
4099
|
-
src = src.substring(token.raw.length);
|
|
4100
|
-
tokens.push(token);
|
|
4101
|
-
return true;
|
|
4102
|
-
}
|
|
4103
|
-
return false;
|
|
4104
|
-
})) {
|
|
4105
|
-
continue;
|
|
4106
|
-
}
|
|
4107
|
-
// escape
|
|
4108
|
-
if (token = this.tokenizer.escape(src)) {
|
|
4109
|
-
src = src.substring(token.raw.length);
|
|
4110
|
-
tokens.push(token);
|
|
4111
|
-
continue;
|
|
4112
|
-
}
|
|
4113
|
-
// tag
|
|
4114
|
-
if (token = this.tokenizer.tag(src)) {
|
|
4115
|
-
src = src.substring(token.raw.length);
|
|
4116
|
-
tokens.push(token);
|
|
4117
|
-
continue;
|
|
4118
|
-
}
|
|
4119
|
-
// link
|
|
4120
|
-
if (token = this.tokenizer.link(src)) {
|
|
4121
|
-
src = src.substring(token.raw.length);
|
|
4122
|
-
tokens.push(token);
|
|
4123
|
-
continue;
|
|
4124
|
-
}
|
|
4125
|
-
// reflink, nolink
|
|
4126
|
-
if (token = this.tokenizer.reflink(src, this.tokens.links)) {
|
|
4127
|
-
src = src.substring(token.raw.length);
|
|
4128
|
-
const lastToken = tokens.at(-1);
|
|
4129
|
-
if (token.type === 'text' && lastToken?.type === 'text') {
|
|
4130
|
-
lastToken.raw += token.raw;
|
|
4131
|
-
lastToken.text += token.text;
|
|
4132
|
-
} else {
|
|
4133
|
-
tokens.push(token);
|
|
4134
|
-
}
|
|
4135
|
-
continue;
|
|
4136
|
-
}
|
|
4137
|
-
// em & strong
|
|
4138
|
-
if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
|
|
4139
|
-
src = src.substring(token.raw.length);
|
|
4140
|
-
tokens.push(token);
|
|
4141
|
-
continue;
|
|
4142
|
-
}
|
|
4143
|
-
// code
|
|
4144
|
-
if (token = this.tokenizer.codespan(src)) {
|
|
4145
|
-
src = src.substring(token.raw.length);
|
|
4146
|
-
tokens.push(token);
|
|
4147
|
-
continue;
|
|
4148
|
-
}
|
|
4149
|
-
// br
|
|
4150
|
-
if (token = this.tokenizer.br(src)) {
|
|
4151
|
-
src = src.substring(token.raw.length);
|
|
4152
|
-
tokens.push(token);
|
|
4153
|
-
continue;
|
|
4154
|
-
}
|
|
4155
|
-
// del (gfm)
|
|
4156
|
-
if (token = this.tokenizer.del(src)) {
|
|
4157
|
-
src = src.substring(token.raw.length);
|
|
4158
|
-
tokens.push(token);
|
|
4159
|
-
continue;
|
|
4160
|
-
}
|
|
4161
|
-
// autolink
|
|
4162
|
-
if (token = this.tokenizer.autolink(src)) {
|
|
4163
|
-
src = src.substring(token.raw.length);
|
|
4164
|
-
tokens.push(token);
|
|
4165
|
-
continue;
|
|
4166
|
-
}
|
|
4167
|
-
// url (gfm)
|
|
4168
|
-
if (!this.state.inLink && (token = this.tokenizer.url(src))) {
|
|
4169
|
-
src = src.substring(token.raw.length);
|
|
4170
|
-
tokens.push(token);
|
|
4171
|
-
continue;
|
|
4172
|
-
}
|
|
4173
|
-
// text
|
|
4174
|
-
// prevent inlineText consuming extensions by clipping 'src' to extension start
|
|
4175
|
-
let cutSrc = src;
|
|
4176
|
-
if (this.options.extensions?.startInline) {
|
|
4177
|
-
let startIndex = Infinity;
|
|
4178
|
-
const tempSrc = src.slice(1);
|
|
4179
|
-
let tempStart;
|
|
4180
|
-
this.options.extensions.startInline.forEach(getStartIndex => {
|
|
4181
|
-
tempStart = getStartIndex.call({
|
|
4182
|
-
lexer: this
|
|
4183
|
-
}, tempSrc);
|
|
4184
|
-
if (typeof tempStart === 'number' && tempStart >= 0) {
|
|
4185
|
-
startIndex = Math.min(startIndex, tempStart);
|
|
4186
|
-
}
|
|
4187
|
-
});
|
|
4188
|
-
if (startIndex < Infinity && startIndex >= 0) {
|
|
4189
|
-
cutSrc = src.substring(0, startIndex + 1);
|
|
4190
|
-
}
|
|
4191
|
-
}
|
|
4192
|
-
if (token = this.tokenizer.inlineText(cutSrc)) {
|
|
4193
|
-
src = src.substring(token.raw.length);
|
|
4194
|
-
if (token.raw.slice(-1) !== '_') {
|
|
4195
|
-
// Track prevChar before string of ____ started
|
|
4196
|
-
prevChar = token.raw.slice(-1);
|
|
4197
|
-
}
|
|
4198
|
-
keepPrevChar = true;
|
|
4199
|
-
const lastToken = tokens.at(-1);
|
|
4200
|
-
if (lastToken?.type === 'text') {
|
|
4201
|
-
lastToken.raw += token.raw;
|
|
4202
|
-
lastToken.text += token.text;
|
|
4203
|
-
} else {
|
|
4204
|
-
tokens.push(token);
|
|
4205
|
-
}
|
|
4206
|
-
continue;
|
|
4207
|
-
}
|
|
4208
|
-
if (src) {
|
|
4209
|
-
const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
|
|
4210
|
-
if (this.options.silent) {
|
|
4211
|
-
console.error(errMsg);
|
|
4212
|
-
break;
|
|
4213
|
-
} else {
|
|
4214
|
-
throw new Error(errMsg);
|
|
4215
|
-
}
|
|
4216
|
-
}
|
|
4217
|
-
}
|
|
4218
|
-
return tokens;
|
|
4219
|
-
}
|
|
4220
|
-
}
|
|
4221
|
-
|
|
4222
|
-
/**
|
|
4223
|
-
* Renderer
|
|
4224
|
-
*/
|
|
4225
|
-
class _Renderer {
|
|
4226
|
-
options;
|
|
4227
|
-
parser; // set by the parser
|
|
4228
|
-
constructor(options) {
|
|
4229
|
-
this.options = options || _defaults;
|
|
4230
|
-
}
|
|
4231
|
-
space(token) {
|
|
4232
|
-
return '';
|
|
4233
|
-
}
|
|
4234
|
-
code({
|
|
4235
|
-
text,
|
|
4236
|
-
lang,
|
|
4237
|
-
escaped
|
|
4238
|
-
}) {
|
|
4239
|
-
const langString = (lang || '').match(other.notSpaceStart)?.[0];
|
|
4240
|
-
const code = text.replace(other.endingNewline, '') + '\n';
|
|
4241
|
-
if (!langString) {
|
|
4242
|
-
return '<pre><code>' + (escaped ? code : escape(code, true)) + '</code></pre>\n';
|
|
4243
|
-
}
|
|
4244
|
-
return '<pre><code class="language-' + escape(langString) + '">' + (escaped ? code : escape(code, true)) + '</code></pre>\n';
|
|
4245
|
-
}
|
|
4246
|
-
blockquote({
|
|
4247
|
-
tokens
|
|
4248
|
-
}) {
|
|
4249
|
-
const body = this.parser.parse(tokens);
|
|
4250
|
-
return `<blockquote>\n${body}</blockquote>\n`;
|
|
4251
|
-
}
|
|
4252
|
-
html({
|
|
4253
|
-
text
|
|
4254
|
-
}) {
|
|
4255
|
-
return text;
|
|
4256
|
-
}
|
|
4257
|
-
heading({
|
|
4258
|
-
tokens,
|
|
4259
|
-
depth
|
|
4260
|
-
}) {
|
|
4261
|
-
return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\n`;
|
|
4262
|
-
}
|
|
4263
|
-
hr(token) {
|
|
4264
|
-
return '<hr>\n';
|
|
4265
|
-
}
|
|
4266
|
-
list(token) {
|
|
4267
|
-
const ordered = token.ordered;
|
|
4268
|
-
const start = token.start;
|
|
4269
|
-
let body = '';
|
|
4270
|
-
for (let j = 0; j < token.items.length; j++) {
|
|
4271
|
-
const item = token.items[j];
|
|
4272
|
-
body += this.listitem(item);
|
|
4273
|
-
}
|
|
4274
|
-
const type = ordered ? 'ol' : 'ul';
|
|
4275
|
-
const startAttr = ordered && start !== 1 ? ' start="' + start + '"' : '';
|
|
4276
|
-
return '<' + type + startAttr + '>\n' + body + '</' + type + '>\n';
|
|
4277
|
-
}
|
|
4278
|
-
listitem(item) {
|
|
4279
|
-
let itemBody = '';
|
|
4280
|
-
if (item.task) {
|
|
4281
|
-
const checkbox = this.checkbox({
|
|
4282
|
-
checked: !!item.checked
|
|
4283
|
-
});
|
|
4284
|
-
if (item.loose) {
|
|
4285
|
-
if (item.tokens[0]?.type === 'paragraph') {
|
|
4286
|
-
item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
|
|
4287
|
-
if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
|
|
4288
|
-
item.tokens[0].tokens[0].text = checkbox + ' ' + escape(item.tokens[0].tokens[0].text);
|
|
4289
|
-
item.tokens[0].tokens[0].escaped = true;
|
|
4290
|
-
}
|
|
4291
|
-
} else {
|
|
4292
|
-
item.tokens.unshift({
|
|
4293
|
-
type: 'text',
|
|
4294
|
-
raw: checkbox + ' ',
|
|
4295
|
-
text: checkbox + ' ',
|
|
4296
|
-
escaped: true
|
|
4297
|
-
});
|
|
4298
|
-
}
|
|
4299
|
-
} else {
|
|
4300
|
-
itemBody += checkbox + ' ';
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
itemBody += this.parser.parse(item.tokens, !!item.loose);
|
|
4304
|
-
return `<li>${itemBody}</li>\n`;
|
|
4305
|
-
}
|
|
4306
|
-
checkbox({
|
|
4307
|
-
checked
|
|
4308
|
-
}) {
|
|
4309
|
-
return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox">';
|
|
4310
|
-
}
|
|
4311
|
-
paragraph({
|
|
4312
|
-
tokens
|
|
4313
|
-
}) {
|
|
4314
|
-
return `<p>${this.parser.parseInline(tokens)}</p>\n`;
|
|
4315
|
-
}
|
|
4316
|
-
table(token) {
|
|
4317
|
-
let header = '';
|
|
4318
|
-
// header
|
|
4319
|
-
let cell = '';
|
|
4320
|
-
for (let j = 0; j < token.header.length; j++) {
|
|
4321
|
-
cell += this.tablecell(token.header[j]);
|
|
4322
|
-
}
|
|
4323
|
-
header += this.tablerow({
|
|
4324
|
-
text: cell
|
|
4325
|
-
});
|
|
4326
|
-
let body = '';
|
|
4327
|
-
for (let j = 0; j < token.rows.length; j++) {
|
|
4328
|
-
const row = token.rows[j];
|
|
4329
|
-
cell = '';
|
|
4330
|
-
for (let k = 0; k < row.length; k++) {
|
|
4331
|
-
cell += this.tablecell(row[k]);
|
|
4332
|
-
}
|
|
4333
|
-
body += this.tablerow({
|
|
4334
|
-
text: cell
|
|
4335
|
-
});
|
|
4336
|
-
}
|
|
4337
|
-
if (body) body = `<tbody>${body}</tbody>`;
|
|
4338
|
-
return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n';
|
|
4339
|
-
}
|
|
4340
|
-
tablerow({
|
|
4341
|
-
text
|
|
4342
|
-
}) {
|
|
4343
|
-
return `<tr>\n${text}</tr>\n`;
|
|
4344
|
-
}
|
|
4345
|
-
tablecell(token) {
|
|
4346
|
-
const content = this.parser.parseInline(token.tokens);
|
|
4347
|
-
const type = token.header ? 'th' : 'td';
|
|
4348
|
-
const tag = token.align ? `<${type} align="${token.align}">` : `<${type}>`;
|
|
4349
|
-
return tag + content + `</${type}>\n`;
|
|
4350
|
-
}
|
|
4351
|
-
/**
|
|
4352
|
-
* span level renderer
|
|
4353
|
-
*/
|
|
4354
|
-
strong({
|
|
4355
|
-
tokens
|
|
4356
|
-
}) {
|
|
4357
|
-
return `<strong>${this.parser.parseInline(tokens)}</strong>`;
|
|
4358
|
-
}
|
|
4359
|
-
em({
|
|
4360
|
-
tokens
|
|
4361
|
-
}) {
|
|
4362
|
-
return `<em>${this.parser.parseInline(tokens)}</em>`;
|
|
4363
|
-
}
|
|
4364
|
-
codespan({
|
|
4365
|
-
text
|
|
4366
|
-
}) {
|
|
4367
|
-
return `<code>${escape(text, true)}</code>`;
|
|
4368
|
-
}
|
|
4369
|
-
br(token) {
|
|
4370
|
-
return '<br>';
|
|
4371
|
-
}
|
|
4372
|
-
del({
|
|
4373
|
-
tokens
|
|
4374
|
-
}) {
|
|
4375
|
-
return `<del>${this.parser.parseInline(tokens)}</del>`;
|
|
4376
|
-
}
|
|
4377
|
-
link({
|
|
4378
|
-
href,
|
|
4379
|
-
title,
|
|
4380
|
-
tokens
|
|
4381
|
-
}) {
|
|
4382
|
-
const text = this.parser.parseInline(tokens);
|
|
4383
|
-
const cleanHref = cleanUrl(href);
|
|
4384
|
-
if (cleanHref === null) {
|
|
4385
|
-
return text;
|
|
4386
|
-
}
|
|
4387
|
-
href = cleanHref;
|
|
4388
|
-
let out = '<a href="' + href + '"';
|
|
4389
|
-
if (title) {
|
|
4390
|
-
out += ' title="' + escape(title) + '"';
|
|
4391
|
-
}
|
|
4392
|
-
out += '>' + text + '</a>';
|
|
4393
|
-
return out;
|
|
4394
|
-
}
|
|
4395
|
-
image({
|
|
4396
|
-
href,
|
|
4397
|
-
title,
|
|
4398
|
-
text
|
|
4399
|
-
}) {
|
|
4400
|
-
const cleanHref = cleanUrl(href);
|
|
4401
|
-
if (cleanHref === null) {
|
|
4402
|
-
return escape(text);
|
|
4403
|
-
}
|
|
4404
|
-
href = cleanHref;
|
|
4405
|
-
let out = `<img src="${href}" alt="${text}"`;
|
|
4406
|
-
if (title) {
|
|
4407
|
-
out += ` title="${escape(title)}"`;
|
|
4408
|
-
}
|
|
4409
|
-
out += '>';
|
|
4410
|
-
return out;
|
|
4411
|
-
}
|
|
4412
|
-
text(token) {
|
|
4413
|
-
return 'tokens' in token && token.tokens ? this.parser.parseInline(token.tokens) : 'escaped' in token && token.escaped ? token.text : escape(token.text);
|
|
4414
|
-
}
|
|
4415
|
-
}
|
|
4416
|
-
|
|
4417
|
-
/**
|
|
4418
|
-
* TextRenderer
|
|
4419
|
-
* returns only the textual part of the token
|
|
4420
|
-
*/
|
|
4421
|
-
class _TextRenderer {
|
|
4422
|
-
// no need for block level renderers
|
|
4423
|
-
strong({
|
|
4424
|
-
text
|
|
4425
|
-
}) {
|
|
4426
|
-
return text;
|
|
4427
|
-
}
|
|
4428
|
-
em({
|
|
4429
|
-
text
|
|
4430
|
-
}) {
|
|
4431
|
-
return text;
|
|
4432
|
-
}
|
|
4433
|
-
codespan({
|
|
4434
|
-
text
|
|
4435
|
-
}) {
|
|
4436
|
-
return text;
|
|
4437
|
-
}
|
|
4438
|
-
del({
|
|
4439
|
-
text
|
|
4440
|
-
}) {
|
|
4441
|
-
return text;
|
|
4442
|
-
}
|
|
4443
|
-
html({
|
|
4444
|
-
text
|
|
4445
|
-
}) {
|
|
4446
|
-
return text;
|
|
4447
|
-
}
|
|
4448
|
-
text({
|
|
4449
|
-
text
|
|
4450
|
-
}) {
|
|
4451
|
-
return text;
|
|
4452
|
-
}
|
|
4453
|
-
link({
|
|
4454
|
-
text
|
|
4455
|
-
}) {
|
|
4456
|
-
return '' + text;
|
|
4457
|
-
}
|
|
4458
|
-
image({
|
|
4459
|
-
text
|
|
4460
|
-
}) {
|
|
4461
|
-
return '' + text;
|
|
4462
|
-
}
|
|
4463
|
-
br() {
|
|
4464
|
-
return '';
|
|
4465
|
-
}
|
|
4466
|
-
}
|
|
4467
|
-
|
|
4468
|
-
/**
|
|
4469
|
-
* Parsing & Compiling
|
|
4470
|
-
*/
|
|
4471
|
-
class _Parser {
|
|
4472
|
-
options;
|
|
4473
|
-
renderer;
|
|
4474
|
-
textRenderer;
|
|
4475
|
-
constructor(options) {
|
|
4476
|
-
this.options = options || _defaults;
|
|
4477
|
-
this.options.renderer = this.options.renderer || new _Renderer();
|
|
4478
|
-
this.renderer = this.options.renderer;
|
|
4479
|
-
this.renderer.options = this.options;
|
|
4480
|
-
this.renderer.parser = this;
|
|
4481
|
-
this.textRenderer = new _TextRenderer();
|
|
4482
|
-
}
|
|
4483
|
-
/**
|
|
4484
|
-
* Static Parse Method
|
|
4485
|
-
*/
|
|
4486
|
-
static parse(tokens, options) {
|
|
4487
|
-
const parser = new _Parser(options);
|
|
4488
|
-
return parser.parse(tokens);
|
|
4489
|
-
}
|
|
4490
|
-
/**
|
|
4491
|
-
* Static Parse Inline Method
|
|
4492
|
-
*/
|
|
4493
|
-
static parseInline(tokens, options) {
|
|
4494
|
-
const parser = new _Parser(options);
|
|
4495
|
-
return parser.parseInline(tokens);
|
|
4496
|
-
}
|
|
4497
|
-
/**
|
|
4498
|
-
* Parse Loop
|
|
4499
|
-
*/
|
|
4500
|
-
parse(tokens, top = true) {
|
|
4501
|
-
let out = '';
|
|
4502
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
4503
|
-
const anyToken = tokens[i];
|
|
4504
|
-
// Run any renderer extensions
|
|
4505
|
-
if (this.options.extensions?.renderers?.[anyToken.type]) {
|
|
4506
|
-
const genericToken = anyToken;
|
|
4507
|
-
const ret = this.options.extensions.renderers[genericToken.type].call({
|
|
4508
|
-
parser: this
|
|
4509
|
-
}, genericToken);
|
|
4510
|
-
if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
|
|
4511
|
-
out += ret || '';
|
|
4512
|
-
continue;
|
|
4513
|
-
}
|
|
4514
|
-
}
|
|
4515
|
-
const token = anyToken;
|
|
4516
|
-
switch (token.type) {
|
|
4517
|
-
case 'space':
|
|
4518
|
-
{
|
|
4519
|
-
out += this.renderer.space(token);
|
|
4520
|
-
continue;
|
|
4521
|
-
}
|
|
4522
|
-
case 'hr':
|
|
4523
|
-
{
|
|
4524
|
-
out += this.renderer.hr(token);
|
|
4525
|
-
continue;
|
|
4526
|
-
}
|
|
4527
|
-
case 'heading':
|
|
4528
|
-
{
|
|
4529
|
-
out += this.renderer.heading(token);
|
|
4530
|
-
continue;
|
|
4531
|
-
}
|
|
4532
|
-
case 'code':
|
|
4533
|
-
{
|
|
4534
|
-
out += this.renderer.code(token);
|
|
4535
|
-
continue;
|
|
4536
|
-
}
|
|
4537
|
-
case 'table':
|
|
4538
|
-
{
|
|
4539
|
-
out += this.renderer.table(token);
|
|
4540
|
-
continue;
|
|
4541
|
-
}
|
|
4542
|
-
case 'blockquote':
|
|
4543
|
-
{
|
|
4544
|
-
out += this.renderer.blockquote(token);
|
|
4545
|
-
continue;
|
|
4546
|
-
}
|
|
4547
|
-
case 'list':
|
|
4548
|
-
{
|
|
4549
|
-
out += this.renderer.list(token);
|
|
4550
|
-
continue;
|
|
4551
|
-
}
|
|
4552
|
-
case 'html':
|
|
4553
|
-
{
|
|
4554
|
-
out += this.renderer.html(token);
|
|
4555
|
-
continue;
|
|
4556
|
-
}
|
|
4557
|
-
case 'paragraph':
|
|
4558
|
-
{
|
|
4559
|
-
out += this.renderer.paragraph(token);
|
|
4560
|
-
continue;
|
|
4561
|
-
}
|
|
4562
|
-
case 'text':
|
|
4563
|
-
{
|
|
4564
|
-
let textToken = token;
|
|
4565
|
-
let body = this.renderer.text(textToken);
|
|
4566
|
-
while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
|
|
4567
|
-
textToken = tokens[++i];
|
|
4568
|
-
body += '\n' + this.renderer.text(textToken);
|
|
4569
|
-
}
|
|
4570
|
-
if (top) {
|
|
4571
|
-
out += this.renderer.paragraph({
|
|
4572
|
-
type: 'paragraph',
|
|
4573
|
-
raw: body,
|
|
4574
|
-
text: body,
|
|
4575
|
-
tokens: [{
|
|
4576
|
-
type: 'text',
|
|
4577
|
-
raw: body,
|
|
4578
|
-
text: body,
|
|
4579
|
-
escaped: true
|
|
4580
|
-
}]
|
|
4581
|
-
});
|
|
4582
|
-
} else {
|
|
4583
|
-
out += body;
|
|
4584
|
-
}
|
|
4585
|
-
continue;
|
|
4586
|
-
}
|
|
4587
|
-
default:
|
|
4588
|
-
{
|
|
4589
|
-
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
4590
|
-
if (this.options.silent) {
|
|
4591
|
-
console.error(errMsg);
|
|
4592
|
-
return '';
|
|
4593
|
-
} else {
|
|
4594
|
-
throw new Error(errMsg);
|
|
4595
|
-
}
|
|
4596
|
-
}
|
|
4597
|
-
}
|
|
4598
|
-
}
|
|
4599
|
-
return out;
|
|
4600
|
-
}
|
|
4601
|
-
/**
|
|
4602
|
-
* Parse Inline Tokens
|
|
4603
|
-
*/
|
|
4604
|
-
parseInline(tokens, renderer = this.renderer) {
|
|
4605
|
-
let out = '';
|
|
4606
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
4607
|
-
const anyToken = tokens[i];
|
|
4608
|
-
// Run any renderer extensions
|
|
4609
|
-
if (this.options.extensions?.renderers?.[anyToken.type]) {
|
|
4610
|
-
const ret = this.options.extensions.renderers[anyToken.type].call({
|
|
4611
|
-
parser: this
|
|
4612
|
-
}, anyToken);
|
|
4613
|
-
if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {
|
|
4614
|
-
out += ret || '';
|
|
4615
|
-
continue;
|
|
4616
|
-
}
|
|
4617
|
-
}
|
|
4618
|
-
const token = anyToken;
|
|
4619
|
-
switch (token.type) {
|
|
4620
|
-
case 'escape':
|
|
4621
|
-
{
|
|
4622
|
-
out += renderer.text(token);
|
|
4623
|
-
break;
|
|
4624
|
-
}
|
|
4625
|
-
case 'html':
|
|
4626
|
-
{
|
|
4627
|
-
out += renderer.html(token);
|
|
4628
|
-
break;
|
|
4629
|
-
}
|
|
4630
|
-
case 'link':
|
|
4631
|
-
{
|
|
4632
|
-
out += renderer.link(token);
|
|
4633
|
-
break;
|
|
4634
|
-
}
|
|
4635
|
-
case 'image':
|
|
4636
|
-
{
|
|
4637
|
-
out += renderer.image(token);
|
|
4638
|
-
break;
|
|
4639
|
-
}
|
|
4640
|
-
case 'strong':
|
|
4641
|
-
{
|
|
4642
|
-
out += renderer.strong(token);
|
|
4643
|
-
break;
|
|
4644
|
-
}
|
|
4645
|
-
case 'em':
|
|
4646
|
-
{
|
|
4647
|
-
out += renderer.em(token);
|
|
4648
|
-
break;
|
|
4649
|
-
}
|
|
4650
|
-
case 'codespan':
|
|
4651
|
-
{
|
|
4652
|
-
out += renderer.codespan(token);
|
|
4653
|
-
break;
|
|
4654
|
-
}
|
|
4655
|
-
case 'br':
|
|
4656
|
-
{
|
|
4657
|
-
out += renderer.br(token);
|
|
4658
|
-
break;
|
|
4659
|
-
}
|
|
4660
|
-
case 'del':
|
|
4661
|
-
{
|
|
4662
|
-
out += renderer.del(token);
|
|
4663
|
-
break;
|
|
4664
|
-
}
|
|
4665
|
-
case 'text':
|
|
4666
|
-
{
|
|
4667
|
-
out += renderer.text(token);
|
|
4668
|
-
break;
|
|
4669
|
-
}
|
|
4670
|
-
default:
|
|
4671
|
-
{
|
|
4672
|
-
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
4673
|
-
if (this.options.silent) {
|
|
4674
|
-
console.error(errMsg);
|
|
4675
|
-
return '';
|
|
4676
|
-
} else {
|
|
4677
|
-
throw new Error(errMsg);
|
|
4678
|
-
}
|
|
4679
|
-
}
|
|
4680
|
-
}
|
|
4681
|
-
}
|
|
4682
|
-
return out;
|
|
4683
|
-
}
|
|
4684
|
-
}
|
|
4685
|
-
class _Hooks {
|
|
4686
|
-
options;
|
|
4687
|
-
block;
|
|
4688
|
-
constructor(options) {
|
|
4689
|
-
this.options = options || _defaults;
|
|
4690
|
-
}
|
|
4691
|
-
static passThroughHooks = new Set(['preprocess', 'postprocess', 'processAllTokens']);
|
|
4692
|
-
/**
|
|
4693
|
-
* Process markdown before marked
|
|
4694
|
-
*/
|
|
4695
|
-
preprocess(markdown) {
|
|
4696
|
-
return markdown;
|
|
4697
|
-
}
|
|
4698
|
-
/**
|
|
4699
|
-
* Process HTML after marked is finished
|
|
4700
|
-
*/
|
|
4701
|
-
postprocess(html) {
|
|
4702
|
-
return html;
|
|
4703
|
-
}
|
|
4704
|
-
/**
|
|
4705
|
-
* Process all tokens before walk tokens
|
|
4706
|
-
*/
|
|
4707
|
-
processAllTokens(tokens) {
|
|
4708
|
-
return tokens;
|
|
4709
|
-
}
|
|
4710
|
-
/**
|
|
4711
|
-
* Provide function to tokenize markdown
|
|
4712
|
-
*/
|
|
4713
|
-
provideLexer() {
|
|
4714
|
-
return this.block ? _Lexer.lex : _Lexer.lexInline;
|
|
4715
|
-
}
|
|
4716
|
-
/**
|
|
4717
|
-
* Provide function to parse tokens
|
|
4718
|
-
*/
|
|
4719
|
-
provideParser() {
|
|
4720
|
-
return this.block ? _Parser.parse : _Parser.parseInline;
|
|
4721
|
-
}
|
|
4722
|
-
}
|
|
4723
|
-
class Marked {
|
|
4724
|
-
defaults = _getDefaults();
|
|
4725
|
-
options = this.setOptions;
|
|
4726
|
-
parse = this.parseMarkdown(true);
|
|
4727
|
-
parseInline = this.parseMarkdown(false);
|
|
4728
|
-
Parser = _Parser;
|
|
4729
|
-
Renderer = _Renderer;
|
|
4730
|
-
TextRenderer = _TextRenderer;
|
|
4731
|
-
Lexer = _Lexer;
|
|
4732
|
-
Tokenizer = _Tokenizer;
|
|
4733
|
-
Hooks = _Hooks;
|
|
4734
|
-
constructor(...args) {
|
|
4735
|
-
this.use(...args);
|
|
4736
|
-
}
|
|
4737
|
-
/**
|
|
4738
|
-
* Run callback for every token
|
|
4739
|
-
*/
|
|
4740
|
-
walkTokens(tokens, callback) {
|
|
4741
|
-
let values = [];
|
|
4742
|
-
for (const token of tokens) {
|
|
4743
|
-
values = values.concat(callback.call(this, token));
|
|
4744
|
-
switch (token.type) {
|
|
4745
|
-
case 'table':
|
|
4746
|
-
{
|
|
4747
|
-
const tableToken = token;
|
|
4748
|
-
for (const cell of tableToken.header) {
|
|
4749
|
-
values = values.concat(this.walkTokens(cell.tokens, callback));
|
|
4750
|
-
}
|
|
4751
|
-
for (const row of tableToken.rows) {
|
|
4752
|
-
for (const cell of row) {
|
|
4753
|
-
values = values.concat(this.walkTokens(cell.tokens, callback));
|
|
4754
|
-
}
|
|
4755
|
-
}
|
|
4756
|
-
break;
|
|
4757
|
-
}
|
|
4758
|
-
case 'list':
|
|
4759
|
-
{
|
|
4760
|
-
const listToken = token;
|
|
4761
|
-
values = values.concat(this.walkTokens(listToken.items, callback));
|
|
4762
|
-
break;
|
|
4763
|
-
}
|
|
4764
|
-
default:
|
|
4765
|
-
{
|
|
4766
|
-
const genericToken = token;
|
|
4767
|
-
if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
|
|
4768
|
-
this.defaults.extensions.childTokens[genericToken.type].forEach(childTokens => {
|
|
4769
|
-
const tokens = genericToken[childTokens].flat(Infinity);
|
|
4770
|
-
values = values.concat(this.walkTokens(tokens, callback));
|
|
4771
|
-
});
|
|
4772
|
-
} else if (genericToken.tokens) {
|
|
4773
|
-
values = values.concat(this.walkTokens(genericToken.tokens, callback));
|
|
4774
|
-
}
|
|
4775
|
-
}
|
|
4776
|
-
}
|
|
4777
|
-
}
|
|
4778
|
-
return values;
|
|
4779
|
-
}
|
|
4780
|
-
use(...args) {
|
|
4781
|
-
const extensions = this.defaults.extensions || {
|
|
4782
|
-
renderers: {},
|
|
4783
|
-
childTokens: {}
|
|
4784
|
-
};
|
|
4785
|
-
args.forEach(pack => {
|
|
4786
|
-
// copy options to new object
|
|
4787
|
-
const opts = {
|
|
4788
|
-
...pack
|
|
4789
|
-
};
|
|
4790
|
-
// set async to true if it was set to true before
|
|
4791
|
-
opts.async = this.defaults.async || opts.async || false;
|
|
4792
|
-
// ==-- Parse "addon" extensions --== //
|
|
4793
|
-
if (pack.extensions) {
|
|
4794
|
-
pack.extensions.forEach(ext => {
|
|
4795
|
-
if (!ext.name) {
|
|
4796
|
-
throw new Error('extension name required');
|
|
4797
|
-
}
|
|
4798
|
-
if ('renderer' in ext) {
|
|
4799
|
-
// Renderer extensions
|
|
4800
|
-
const prevRenderer = extensions.renderers[ext.name];
|
|
4801
|
-
if (prevRenderer) {
|
|
4802
|
-
// Replace extension with func to run new extension but fall back if false
|
|
4803
|
-
extensions.renderers[ext.name] = function (...args) {
|
|
4804
|
-
let ret = ext.renderer.apply(this, args);
|
|
4805
|
-
if (ret === false) {
|
|
4806
|
-
ret = prevRenderer.apply(this, args);
|
|
4807
|
-
}
|
|
4808
|
-
return ret;
|
|
4809
|
-
};
|
|
4810
|
-
} else {
|
|
4811
|
-
extensions.renderers[ext.name] = ext.renderer;
|
|
4812
|
-
}
|
|
4813
|
-
}
|
|
4814
|
-
if ('tokenizer' in ext) {
|
|
4815
|
-
// Tokenizer Extensions
|
|
4816
|
-
if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') {
|
|
4817
|
-
throw new Error("extension level must be 'block' or 'inline'");
|
|
4818
|
-
}
|
|
4819
|
-
const extLevel = extensions[ext.level];
|
|
4820
|
-
if (extLevel) {
|
|
4821
|
-
extLevel.unshift(ext.tokenizer);
|
|
4822
|
-
} else {
|
|
4823
|
-
extensions[ext.level] = [ext.tokenizer];
|
|
4824
|
-
}
|
|
4825
|
-
if (ext.start) {
|
|
4826
|
-
// Function to check for start of token
|
|
4827
|
-
if (ext.level === 'block') {
|
|
4828
|
-
if (extensions.startBlock) {
|
|
4829
|
-
extensions.startBlock.push(ext.start);
|
|
4830
|
-
} else {
|
|
4831
|
-
extensions.startBlock = [ext.start];
|
|
4832
|
-
}
|
|
4833
|
-
} else if (ext.level === 'inline') {
|
|
4834
|
-
if (extensions.startInline) {
|
|
4835
|
-
extensions.startInline.push(ext.start);
|
|
4836
|
-
} else {
|
|
4837
|
-
extensions.startInline = [ext.start];
|
|
4838
|
-
}
|
|
4839
|
-
}
|
|
4840
|
-
}
|
|
4841
|
-
}
|
|
4842
|
-
if ('childTokens' in ext && ext.childTokens) {
|
|
4843
|
-
// Child tokens to be visited by walkTokens
|
|
4844
|
-
extensions.childTokens[ext.name] = ext.childTokens;
|
|
4845
|
-
}
|
|
4846
|
-
});
|
|
4847
|
-
opts.extensions = extensions;
|
|
4848
|
-
}
|
|
4849
|
-
// ==-- Parse "overwrite" extensions --== //
|
|
4850
|
-
if (pack.renderer) {
|
|
4851
|
-
const renderer = this.defaults.renderer || new _Renderer(this.defaults);
|
|
4852
|
-
for (const prop in pack.renderer) {
|
|
4853
|
-
if (!(prop in renderer)) {
|
|
4854
|
-
throw new Error(`renderer '${prop}' does not exist`);
|
|
4855
|
-
}
|
|
4856
|
-
if (['options', 'parser'].includes(prop)) {
|
|
4857
|
-
// ignore options property
|
|
4858
|
-
continue;
|
|
4859
|
-
}
|
|
4860
|
-
const rendererProp = prop;
|
|
4861
|
-
const rendererFunc = pack.renderer[rendererProp];
|
|
4862
|
-
const prevRenderer = renderer[rendererProp];
|
|
4863
|
-
// Replace renderer with func to run extension, but fall back if false
|
|
4864
|
-
renderer[rendererProp] = (...args) => {
|
|
4865
|
-
let ret = rendererFunc.apply(renderer, args);
|
|
4866
|
-
if (ret === false) {
|
|
4867
|
-
ret = prevRenderer.apply(renderer, args);
|
|
4868
|
-
}
|
|
4869
|
-
return ret || '';
|
|
4870
|
-
};
|
|
4871
|
-
}
|
|
4872
|
-
opts.renderer = renderer;
|
|
4873
|
-
}
|
|
4874
|
-
if (pack.tokenizer) {
|
|
4875
|
-
const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
|
|
4876
|
-
for (const prop in pack.tokenizer) {
|
|
4877
|
-
if (!(prop in tokenizer)) {
|
|
4878
|
-
throw new Error(`tokenizer '${prop}' does not exist`);
|
|
4879
|
-
}
|
|
4880
|
-
if (['options', 'rules', 'lexer'].includes(prop)) {
|
|
4881
|
-
// ignore options, rules, and lexer properties
|
|
4882
|
-
continue;
|
|
4883
|
-
}
|
|
4884
|
-
const tokenizerProp = prop;
|
|
4885
|
-
const tokenizerFunc = pack.tokenizer[tokenizerProp];
|
|
4886
|
-
const prevTokenizer = tokenizer[tokenizerProp];
|
|
4887
|
-
// Replace tokenizer with func to run extension, but fall back if false
|
|
4888
|
-
// @ts-expect-error cannot type tokenizer function dynamically
|
|
4889
|
-
tokenizer[tokenizerProp] = (...args) => {
|
|
4890
|
-
let ret = tokenizerFunc.apply(tokenizer, args);
|
|
4891
|
-
if (ret === false) {
|
|
4892
|
-
ret = prevTokenizer.apply(tokenizer, args);
|
|
4893
|
-
}
|
|
4894
|
-
return ret;
|
|
4895
|
-
};
|
|
4896
|
-
}
|
|
4897
|
-
opts.tokenizer = tokenizer;
|
|
4898
|
-
}
|
|
4899
|
-
// ==-- Parse Hooks extensions --== //
|
|
4900
|
-
if (pack.hooks) {
|
|
4901
|
-
const hooks = this.defaults.hooks || new _Hooks();
|
|
4902
|
-
for (const prop in pack.hooks) {
|
|
4903
|
-
if (!(prop in hooks)) {
|
|
4904
|
-
throw new Error(`hook '${prop}' does not exist`);
|
|
4905
|
-
}
|
|
4906
|
-
if (['options', 'block'].includes(prop)) {
|
|
4907
|
-
// ignore options and block properties
|
|
4908
|
-
continue;
|
|
4909
|
-
}
|
|
4910
|
-
const hooksProp = prop;
|
|
4911
|
-
const hooksFunc = pack.hooks[hooksProp];
|
|
4912
|
-
const prevHook = hooks[hooksProp];
|
|
4913
|
-
if (_Hooks.passThroughHooks.has(prop)) {
|
|
4914
|
-
// @ts-expect-error cannot type hook function dynamically
|
|
4915
|
-
hooks[hooksProp] = arg => {
|
|
4916
|
-
if (this.defaults.async) {
|
|
4917
|
-
return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {
|
|
4918
|
-
return prevHook.call(hooks, ret);
|
|
4919
|
-
});
|
|
4920
|
-
}
|
|
4921
|
-
const ret = hooksFunc.call(hooks, arg);
|
|
4922
|
-
return prevHook.call(hooks, ret);
|
|
4923
|
-
};
|
|
4924
|
-
} else {
|
|
4925
|
-
// @ts-expect-error cannot type hook function dynamically
|
|
4926
|
-
hooks[hooksProp] = (...args) => {
|
|
4927
|
-
let ret = hooksFunc.apply(hooks, args);
|
|
4928
|
-
if (ret === false) {
|
|
4929
|
-
ret = prevHook.apply(hooks, args);
|
|
4930
|
-
}
|
|
4931
|
-
return ret;
|
|
4932
|
-
};
|
|
4933
|
-
}
|
|
4934
|
-
}
|
|
4935
|
-
opts.hooks = hooks;
|
|
4936
|
-
}
|
|
4937
|
-
// ==-- Parse WalkTokens extensions --== //
|
|
4938
|
-
if (pack.walkTokens) {
|
|
4939
|
-
const walkTokens = this.defaults.walkTokens;
|
|
4940
|
-
const packWalktokens = pack.walkTokens;
|
|
4941
|
-
opts.walkTokens = function (token) {
|
|
4942
|
-
let values = [];
|
|
4943
|
-
values.push(packWalktokens.call(this, token));
|
|
4944
|
-
if (walkTokens) {
|
|
4945
|
-
values = values.concat(walkTokens.call(this, token));
|
|
4946
|
-
}
|
|
4947
|
-
return values;
|
|
4948
|
-
};
|
|
4949
|
-
}
|
|
4950
|
-
this.defaults = {
|
|
4951
|
-
...this.defaults,
|
|
4952
|
-
...opts
|
|
4953
|
-
};
|
|
4954
|
-
});
|
|
4955
|
-
return this;
|
|
4956
|
-
}
|
|
4957
|
-
setOptions(opt) {
|
|
4958
|
-
this.defaults = {
|
|
4959
|
-
...this.defaults,
|
|
4960
|
-
...opt
|
|
4961
|
-
};
|
|
4962
|
-
return this;
|
|
4963
|
-
}
|
|
4964
|
-
lexer(src, options) {
|
|
4965
|
-
return _Lexer.lex(src, options ?? this.defaults);
|
|
4966
|
-
}
|
|
4967
|
-
parser(tokens, options) {
|
|
4968
|
-
return _Parser.parse(tokens, options ?? this.defaults);
|
|
4969
|
-
}
|
|
4970
|
-
parseMarkdown(blockType) {
|
|
4971
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4972
|
-
const parse = (src, options) => {
|
|
4973
|
-
const origOpt = {
|
|
4974
|
-
...options
|
|
4975
|
-
};
|
|
4976
|
-
const opt = {
|
|
4977
|
-
...this.defaults,
|
|
4978
|
-
...origOpt
|
|
4979
|
-
};
|
|
4980
|
-
const throwError = this.onError(!!opt.silent, !!opt.async);
|
|
4981
|
-
// throw error if an extension set async to true but parse was called with async: false
|
|
4982
|
-
if (this.defaults.async === true && origOpt.async === false) {
|
|
4983
|
-
return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));
|
|
4984
|
-
}
|
|
4985
|
-
// throw error in case of non string input
|
|
4986
|
-
if (typeof src === 'undefined' || src === null) {
|
|
4987
|
-
return throwError(new Error('marked(): input parameter is undefined or null'));
|
|
4988
|
-
}
|
|
4989
|
-
if (typeof src !== 'string') {
|
|
4990
|
-
return throwError(new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected'));
|
|
4991
|
-
}
|
|
4992
|
-
if (opt.hooks) {
|
|
4993
|
-
opt.hooks.options = opt;
|
|
4994
|
-
opt.hooks.block = blockType;
|
|
4995
|
-
}
|
|
4996
|
-
const lexer = opt.hooks ? opt.hooks.provideLexer() : blockType ? _Lexer.lex : _Lexer.lexInline;
|
|
4997
|
-
const parser = opt.hooks ? opt.hooks.provideParser() : blockType ? _Parser.parse : _Parser.parseInline;
|
|
4998
|
-
if (opt.async) {
|
|
4999
|
-
return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then(src => lexer(src, opt)).then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens).then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then(tokens => parser(tokens, opt)).then(html => opt.hooks ? opt.hooks.postprocess(html) : html).catch(throwError);
|
|
5000
|
-
}
|
|
5001
|
-
try {
|
|
5002
|
-
if (opt.hooks) {
|
|
5003
|
-
src = opt.hooks.preprocess(src);
|
|
5004
|
-
}
|
|
5005
|
-
let tokens = lexer(src, opt);
|
|
5006
|
-
if (opt.hooks) {
|
|
5007
|
-
tokens = opt.hooks.processAllTokens(tokens);
|
|
5008
|
-
}
|
|
5009
|
-
if (opt.walkTokens) {
|
|
5010
|
-
this.walkTokens(tokens, opt.walkTokens);
|
|
5011
|
-
}
|
|
5012
|
-
let html = parser(tokens, opt);
|
|
5013
|
-
if (opt.hooks) {
|
|
5014
|
-
html = opt.hooks.postprocess(html);
|
|
5015
|
-
}
|
|
5016
|
-
return html;
|
|
5017
|
-
} catch (e) {
|
|
5018
|
-
return throwError(e);
|
|
5019
|
-
}
|
|
5020
|
-
};
|
|
5021
|
-
return parse;
|
|
5022
|
-
}
|
|
5023
|
-
onError(silent, async) {
|
|
5024
|
-
return e => {
|
|
5025
|
-
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
|
5026
|
-
if (silent) {
|
|
5027
|
-
const msg = '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
|
|
5028
|
-
if (async) {
|
|
5029
|
-
return Promise.resolve(msg);
|
|
5030
|
-
}
|
|
5031
|
-
return msg;
|
|
5032
|
-
}
|
|
5033
|
-
if (async) {
|
|
5034
|
-
return Promise.reject(e);
|
|
5035
|
-
}
|
|
5036
|
-
throw e;
|
|
5037
|
-
};
|
|
5038
|
-
}
|
|
5039
|
-
}
|
|
5040
|
-
const markedInstance = new Marked();
|
|
5041
|
-
function marked(src, opt) {
|
|
5042
|
-
return markedInstance.parse(src, opt);
|
|
5043
|
-
}
|
|
5044
|
-
/**
|
|
5045
|
-
* Sets the default options.
|
|
5046
|
-
*
|
|
5047
|
-
* @param options Hash of options
|
|
5048
|
-
*/
|
|
5049
|
-
marked.options = marked.setOptions = function (options) {
|
|
5050
|
-
markedInstance.setOptions(options);
|
|
5051
|
-
marked.defaults = markedInstance.defaults;
|
|
5052
|
-
changeDefaults(marked.defaults);
|
|
5053
|
-
return marked;
|
|
5054
|
-
};
|
|
5055
|
-
/**
|
|
5056
|
-
* Gets the original marked default options.
|
|
5057
|
-
*/
|
|
5058
|
-
marked.getDefaults = _getDefaults;
|
|
5059
|
-
marked.defaults = _defaults;
|
|
5060
|
-
/**
|
|
5061
|
-
* Use Extension
|
|
5062
|
-
*/
|
|
5063
|
-
marked.use = function (...args) {
|
|
5064
|
-
markedInstance.use(...args);
|
|
5065
|
-
marked.defaults = markedInstance.defaults;
|
|
5066
|
-
changeDefaults(marked.defaults);
|
|
5067
|
-
return marked;
|
|
5068
|
-
};
|
|
5069
|
-
/**
|
|
5070
|
-
* Run callback for every token
|
|
5071
|
-
*/
|
|
5072
|
-
marked.walkTokens = function (tokens, callback) {
|
|
5073
|
-
return markedInstance.walkTokens(tokens, callback);
|
|
5074
|
-
};
|
|
5075
|
-
/**
|
|
5076
|
-
* Compiles markdown to HTML without enclosing `p` tag.
|
|
5077
|
-
*
|
|
5078
|
-
* @param src String of markdown source to be compiled
|
|
5079
|
-
* @param options Hash of options
|
|
5080
|
-
* @return String of compiled HTML
|
|
5081
|
-
*/
|
|
5082
|
-
marked.parseInline = markedInstance.parseInline;
|
|
5083
|
-
/**
|
|
5084
|
-
* Expose
|
|
5085
|
-
*/
|
|
5086
|
-
marked.Parser = _Parser;
|
|
5087
|
-
marked.parser = _Parser.parse;
|
|
5088
|
-
marked.Renderer = _Renderer;
|
|
5089
|
-
marked.TextRenderer = _TextRenderer;
|
|
5090
|
-
marked.Lexer = _Lexer;
|
|
5091
|
-
marked.lexer = _Lexer.lex;
|
|
5092
|
-
marked.Tokenizer = _Tokenizer;
|
|
5093
|
-
marked.Hooks = _Hooks;
|
|
5094
|
-
marked.parse = marked;
|
|
5095
|
-
|
|
5096
2129
|
const renderMarkdown = async (markdown, options = {}) => {
|
|
5097
|
-
const html = await
|
|
2130
|
+
const html = await invoke('Markdown.renderMarkdown', markdown, options);
|
|
5098
2131
|
return html;
|
|
5099
2132
|
};
|
|
5100
2133
|
|
|
@@ -5444,11 +2477,7 @@ const commandMap = {
|
|
|
5444
2477
|
'ExtensionDetail.resize': resize,
|
|
5445
2478
|
'ExtensionDetail.saveState': saveState,
|
|
5446
2479
|
'ExtensionDetail.selectTab': wrapCommand(selectTab),
|
|
5447
|
-
'ExtensionDetail.terminate': terminate
|
|
5448
|
-
// deprecated
|
|
5449
|
-
'ExtensionDetail.getVirtualDom': wrapCommand(getExtensionDetailVirtualDom),
|
|
5450
|
-
'HandleIconError.handleIconError': handleIconError,
|
|
5451
|
-
'RenderMarkdown.renderMarkdown': renderMarkdown
|
|
2480
|
+
'ExtensionDetail.terminate': terminate
|
|
5452
2481
|
};
|
|
5453
2482
|
|
|
5454
2483
|
const listen = async () => {
|