@changerawr/markdown 1.1.7 → 1.1.9
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/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +153 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +153 -14
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +153 -14
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +153 -14
- package/dist/react/index.mjs.map +1 -1
- package/dist/standalone.browser.js +178 -26
- package/dist/standalone.js +153 -14
- package/dist/standalone.js.map +1 -1
- package/dist/standalone.mjs +153 -14
- package/dist/standalone.mjs.map +1 -1
- package/package.json +1 -1
package/dist/standalone.mjs
CHANGED
|
@@ -485,20 +485,59 @@ var MarkdownRenderer = class {
|
|
|
485
485
|
format: this.config.format
|
|
486
486
|
}
|
|
487
487
|
}));
|
|
488
|
-
const
|
|
488
|
+
const groupedTokens = this.groupListItems(tokensWithFormat);
|
|
489
|
+
const htmlParts = groupedTokens.map((token) => this.renderToken(token));
|
|
489
490
|
const combinedHtml = htmlParts.join("");
|
|
490
491
|
if (this.config.sanitize && !this.config.allowUnsafeHtml) {
|
|
491
492
|
return sanitizeHtml(combinedHtml);
|
|
492
493
|
}
|
|
493
494
|
return combinedHtml;
|
|
494
495
|
}
|
|
496
|
+
groupListItems(tokens) {
|
|
497
|
+
const result = [];
|
|
498
|
+
let i = 0;
|
|
499
|
+
while (i < tokens.length) {
|
|
500
|
+
const token = tokens[i];
|
|
501
|
+
const isListItem = token?.type === "list-item" || token?.type === "ordered-list-item" || token?.type === "task-item";
|
|
502
|
+
if (isListItem) {
|
|
503
|
+
const listItems = [];
|
|
504
|
+
const firstItemType = token.type;
|
|
505
|
+
const isOrdered = firstItemType === "ordered-list-item";
|
|
506
|
+
while (i < tokens.length) {
|
|
507
|
+
const item = tokens[i];
|
|
508
|
+
if (!item) break;
|
|
509
|
+
const itemType = item.type;
|
|
510
|
+
const isSameListType = isOrdered && itemType === "ordered-list-item" || !isOrdered && (itemType === "list-item" || itemType === "task-item");
|
|
511
|
+
if (isSameListType) {
|
|
512
|
+
listItems.push(item);
|
|
513
|
+
i++;
|
|
514
|
+
} else {
|
|
515
|
+
break;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
const wrappedList = {
|
|
519
|
+
type: isOrdered ? "ol" : "ul",
|
|
520
|
+
content: "",
|
|
521
|
+
raw: "",
|
|
522
|
+
children: listItems,
|
|
523
|
+
attributes: { format: this.config.format }
|
|
524
|
+
};
|
|
525
|
+
wrappedList._isWrapped = true;
|
|
526
|
+
result.push(wrappedList);
|
|
527
|
+
} else {
|
|
528
|
+
result.push(token);
|
|
529
|
+
i++;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return result;
|
|
533
|
+
}
|
|
495
534
|
renderToken(token) {
|
|
496
535
|
const rule = this.rules.get(token.type);
|
|
497
536
|
if (rule) {
|
|
498
537
|
try {
|
|
499
538
|
let tokenToRender = token;
|
|
500
539
|
if (token.children && token.children.length > 0) {
|
|
501
|
-
const renderedChildren = this.render(token.children);
|
|
540
|
+
const renderedChildren = token.type === "ul" || token.type === "ol" ? token.children.map((child) => this.renderToken(child)).join("") : this.render(token.children);
|
|
502
541
|
tokenToRender = {
|
|
503
542
|
...token,
|
|
504
543
|
attributes: {
|
|
@@ -999,7 +1038,8 @@ var ImageExtension = {
|
|
|
999
1038
|
attributes: {
|
|
1000
1039
|
alt: match[1] || "",
|
|
1001
1040
|
src: match[2] || "",
|
|
1002
|
-
|
|
1041
|
+
caption: match[3] || ""
|
|
1042
|
+
// Renamed from 'title' to 'caption' for clarity
|
|
1003
1043
|
}
|
|
1004
1044
|
})
|
|
1005
1045
|
}
|
|
@@ -1010,13 +1050,24 @@ var ImageExtension = {
|
|
|
1010
1050
|
render: (token) => {
|
|
1011
1051
|
const src = token.attributes?.src || "";
|
|
1012
1052
|
const alt = token.attributes?.alt || "";
|
|
1013
|
-
const
|
|
1014
|
-
const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
|
|
1053
|
+
const caption = token.attributes?.caption || "";
|
|
1015
1054
|
const format = token.attributes?.format || "html";
|
|
1055
|
+
if (caption) {
|
|
1056
|
+
if (format === "html") {
|
|
1057
|
+
return `<figure style="margin: 16px 0; text-align: center;">
|
|
1058
|
+
<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px;" loading="lazy" />
|
|
1059
|
+
<figcaption style="margin-top: 8px; font-size: 14px; color: #6b7280; font-style: italic;">${escapeHtml(caption)}</figcaption>
|
|
1060
|
+
</figure>`;
|
|
1061
|
+
}
|
|
1062
|
+
return `<figure class="my-4 text-center">
|
|
1063
|
+
<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg" loading="lazy" />
|
|
1064
|
+
<figcaption class="mt-2 text-sm text-gray-500 italic">${escapeHtml(caption)}</figcaption>
|
|
1065
|
+
</figure>`;
|
|
1066
|
+
}
|
|
1016
1067
|
if (format === "html") {
|
|
1017
|
-
return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"
|
|
1068
|
+
return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
|
|
1018
1069
|
}
|
|
1019
|
-
return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"
|
|
1070
|
+
return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
|
|
1020
1071
|
}
|
|
1021
1072
|
}
|
|
1022
1073
|
]
|
|
@@ -1068,16 +1119,57 @@ var ListExtension = {
|
|
|
1068
1119
|
name: "list",
|
|
1069
1120
|
parseRules: [
|
|
1070
1121
|
{
|
|
1071
|
-
name: "list-item",
|
|
1122
|
+
name: "unordered-list-item",
|
|
1072
1123
|
pattern: /^(\s*)[-*+]\s+(.+)$/m,
|
|
1073
1124
|
render: (match) => ({
|
|
1074
1125
|
type: "list-item",
|
|
1075
1126
|
content: match[2] || "",
|
|
1076
|
-
raw: match[0] || ""
|
|
1127
|
+
raw: match[0] || "",
|
|
1128
|
+
attributes: {
|
|
1129
|
+
indent: match[1]?.length || 0,
|
|
1130
|
+
ordered: false,
|
|
1131
|
+
marker: match[1] ? match[0].match(/[-*+]/)?.[0] : "-"
|
|
1132
|
+
}
|
|
1133
|
+
})
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
name: "ordered-list-item",
|
|
1137
|
+
pattern: /^(\s*)(\d+)\.\s+(.+)$/m,
|
|
1138
|
+
render: (match) => ({
|
|
1139
|
+
type: "ordered-list-item",
|
|
1140
|
+
content: match[3] || "",
|
|
1141
|
+
raw: match[0] || "",
|
|
1142
|
+
attributes: {
|
|
1143
|
+
indent: match[1]?.length || 0,
|
|
1144
|
+
ordered: true,
|
|
1145
|
+
number: parseInt(match[2] || "1")
|
|
1146
|
+
}
|
|
1077
1147
|
})
|
|
1078
1148
|
}
|
|
1079
1149
|
],
|
|
1080
1150
|
renderRules: [
|
|
1151
|
+
{
|
|
1152
|
+
type: "ul",
|
|
1153
|
+
render: (token) => {
|
|
1154
|
+
const format = token.attributes?.format || "tailwind";
|
|
1155
|
+
const content = token.attributes?.renderedChildren || "";
|
|
1156
|
+
if (format === "html") {
|
|
1157
|
+
return `<ul style="margin: 8px 0; padding-left: 24px; list-style: disc;">${content}</ul>`;
|
|
1158
|
+
}
|
|
1159
|
+
return `<ul class="my-2 pl-6 list-disc">${content}</ul>`;
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
type: "ol",
|
|
1164
|
+
render: (token) => {
|
|
1165
|
+
const format = token.attributes?.format || "tailwind";
|
|
1166
|
+
const content = token.attributes?.renderedChildren || "";
|
|
1167
|
+
if (format === "html") {
|
|
1168
|
+
return `<ol style="margin: 8px 0; padding-left: 24px; list-style: decimal;">${content}</ol>`;
|
|
1169
|
+
}
|
|
1170
|
+
return `<ol class="my-2 pl-6 list-decimal">${content}</ol>`;
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1081
1173
|
{
|
|
1082
1174
|
type: "list-item",
|
|
1083
1175
|
render: (token) => {
|
|
@@ -1088,6 +1180,17 @@ var ListExtension = {
|
|
|
1088
1180
|
}
|
|
1089
1181
|
return `<li>${content}</li>`;
|
|
1090
1182
|
}
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
type: "ordered-list-item",
|
|
1186
|
+
render: (token) => {
|
|
1187
|
+
const format = token.attributes?.format || "tailwind";
|
|
1188
|
+
const content = token.attributes?.renderedChildren || escapeHtml(token.content);
|
|
1189
|
+
if (format === "html") {
|
|
1190
|
+
return `<li>${content}</li>`;
|
|
1191
|
+
}
|
|
1192
|
+
return `<li>${content}</li>`;
|
|
1193
|
+
}
|
|
1091
1194
|
}
|
|
1092
1195
|
]
|
|
1093
1196
|
};
|
|
@@ -1102,6 +1205,7 @@ var TaskListExtension = {
|
|
|
1102
1205
|
content: match[3] || "",
|
|
1103
1206
|
raw: match[0] || "",
|
|
1104
1207
|
attributes: {
|
|
1208
|
+
indent: match[1]?.length || 0,
|
|
1105
1209
|
checked: String((match[2] || "").toLowerCase() === "x")
|
|
1106
1210
|
}
|
|
1107
1211
|
})
|
|
@@ -1114,15 +1218,20 @@ var TaskListExtension = {
|
|
|
1114
1218
|
const isChecked = token.attributes?.checked === "true";
|
|
1115
1219
|
const content = token.attributes?.renderedChildren || escapeHtml(token.content);
|
|
1116
1220
|
const format = token.attributes?.format || "html";
|
|
1221
|
+
const checkmark = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink: 0; margin-top: 2px;"><polyline points="20 6 9 17 4 12"></polyline></svg>`;
|
|
1222
|
+
const checkbox = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink: 0; margin-top: 2px;"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect></svg>`;
|
|
1117
1223
|
if (format === "html") {
|
|
1118
|
-
return `<div style="display: flex; align-items:
|
|
1119
|
-
<
|
|
1224
|
+
return `<div style="display: flex; align-items: flex-start; gap: 8px; margin: 8px 0;">
|
|
1225
|
+
<div style="color: ${isChecked ? "#10b981" : "#9ca3af"}; margin-top: 2px;">
|
|
1226
|
+
${isChecked ? checkmark : checkbox}
|
|
1227
|
+
</div>
|
|
1120
1228
|
<span${isChecked ? ' style="text-decoration: line-through; color: #6b7280;"' : ""}>${content}</span>
|
|
1121
1229
|
</div>`;
|
|
1122
1230
|
}
|
|
1123
|
-
return `<div class="flex items-
|
|
1124
|
-
<
|
|
1125
|
-
|
|
1231
|
+
return `<div class="flex items-start gap-2 my-2 task-list-item">
|
|
1232
|
+
<div class="${isChecked ? "text-green-600" : "text-gray-400"} flex-shrink-0 mt-0.5">
|
|
1233
|
+
${isChecked ? checkmark : checkbox}
|
|
1234
|
+
</div>
|
|
1126
1235
|
<span${isChecked ? ' class="line-through text-muted-foreground"' : ""}>${content}</span>
|
|
1127
1236
|
</div>`;
|
|
1128
1237
|
}
|
|
@@ -1167,6 +1276,35 @@ var TextExtension = {
|
|
|
1167
1276
|
]
|
|
1168
1277
|
};
|
|
1169
1278
|
|
|
1279
|
+
// src/extensions/core/strikethrough.ts
|
|
1280
|
+
var StrikethroughExtension = {
|
|
1281
|
+
name: "strikethrough",
|
|
1282
|
+
parseRules: [
|
|
1283
|
+
{
|
|
1284
|
+
name: "strikethrough",
|
|
1285
|
+
pattern: /~~((?:(?!~~).)+)~~/,
|
|
1286
|
+
render: (match) => ({
|
|
1287
|
+
type: "strikethrough",
|
|
1288
|
+
content: match[1] || "",
|
|
1289
|
+
raw: match[0] || ""
|
|
1290
|
+
})
|
|
1291
|
+
}
|
|
1292
|
+
],
|
|
1293
|
+
renderRules: [
|
|
1294
|
+
{
|
|
1295
|
+
type: "strikethrough",
|
|
1296
|
+
render: (token) => {
|
|
1297
|
+
const content = escapeHtml(token.content);
|
|
1298
|
+
const format = token.attributes?.format;
|
|
1299
|
+
if (format === "html") {
|
|
1300
|
+
return `<del style="text-decoration: line-through; color: #6b7280;">${content}</del>`;
|
|
1301
|
+
}
|
|
1302
|
+
return `<del class="line-through text-gray-500">${content}</del>`;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
]
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1170
1308
|
// src/extensions/core/index.ts
|
|
1171
1309
|
var CoreExtensions = [
|
|
1172
1310
|
TextExtension,
|
|
@@ -1181,6 +1319,7 @@ var CoreExtensions = [
|
|
|
1181
1319
|
TaskListExtension,
|
|
1182
1320
|
BlockquoteExtension,
|
|
1183
1321
|
HorizontalRuleExtension,
|
|
1322
|
+
StrikethroughExtension,
|
|
1184
1323
|
ParagraphExtension,
|
|
1185
1324
|
LineBreakExtension
|
|
1186
1325
|
];
|