@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.
@@ -530,20 +530,59 @@ var MarkdownRenderer = class {
530
530
  format: this.config.format
531
531
  }
532
532
  }));
533
- const htmlParts = tokensWithFormat.map((token) => this.renderToken(token));
533
+ const groupedTokens = this.groupListItems(tokensWithFormat);
534
+ const htmlParts = groupedTokens.map((token) => this.renderToken(token));
534
535
  const combinedHtml = htmlParts.join("");
535
536
  if (this.config.sanitize && !this.config.allowUnsafeHtml) {
536
537
  return sanitizeHtml(combinedHtml);
537
538
  }
538
539
  return combinedHtml;
539
540
  }
541
+ groupListItems(tokens) {
542
+ const result = [];
543
+ let i = 0;
544
+ while (i < tokens.length) {
545
+ const token = tokens[i];
546
+ const isListItem = token?.type === "list-item" || token?.type === "ordered-list-item" || token?.type === "task-item";
547
+ if (isListItem) {
548
+ const listItems = [];
549
+ const firstItemType = token.type;
550
+ const isOrdered = firstItemType === "ordered-list-item";
551
+ while (i < tokens.length) {
552
+ const item = tokens[i];
553
+ if (!item) break;
554
+ const itemType = item.type;
555
+ const isSameListType = isOrdered && itemType === "ordered-list-item" || !isOrdered && (itemType === "list-item" || itemType === "task-item");
556
+ if (isSameListType) {
557
+ listItems.push(item);
558
+ i++;
559
+ } else {
560
+ break;
561
+ }
562
+ }
563
+ const wrappedList = {
564
+ type: isOrdered ? "ol" : "ul",
565
+ content: "",
566
+ raw: "",
567
+ children: listItems,
568
+ attributes: { format: this.config.format }
569
+ };
570
+ wrappedList._isWrapped = true;
571
+ result.push(wrappedList);
572
+ } else {
573
+ result.push(token);
574
+ i++;
575
+ }
576
+ }
577
+ return result;
578
+ }
540
579
  renderToken(token) {
541
580
  const rule = this.rules.get(token.type);
542
581
  if (rule) {
543
582
  try {
544
583
  let tokenToRender = token;
545
584
  if (token.children && token.children.length > 0) {
546
- const renderedChildren = this.render(token.children);
585
+ const renderedChildren = token.type === "ul" || token.type === "ol" ? token.children.map((child) => this.renderToken(child)).join("") : this.render(token.children);
547
586
  tokenToRender = {
548
587
  ...token,
549
588
  attributes: {
@@ -1044,7 +1083,8 @@ var ImageExtension = {
1044
1083
  attributes: {
1045
1084
  alt: match[1] || "",
1046
1085
  src: match[2] || "",
1047
- title: match[3] || ""
1086
+ caption: match[3] || ""
1087
+ // Renamed from 'title' to 'caption' for clarity
1048
1088
  }
1049
1089
  })
1050
1090
  }
@@ -1055,13 +1095,24 @@ var ImageExtension = {
1055
1095
  render: (token) => {
1056
1096
  const src = token.attributes?.src || "";
1057
1097
  const alt = token.attributes?.alt || "";
1058
- const title = token.attributes?.title || "";
1059
- const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
1098
+ const caption = token.attributes?.caption || "";
1060
1099
  const format = token.attributes?.format || "html";
1100
+ if (caption) {
1101
+ if (format === "html") {
1102
+ return `<figure style="margin: 16px 0; text-align: center;">
1103
+ <img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px;" loading="lazy" />
1104
+ <figcaption style="margin-top: 8px; font-size: 14px; color: #6b7280; font-style: italic;">${escapeHtml(caption)}</figcaption>
1105
+ </figure>`;
1106
+ }
1107
+ return `<figure class="my-4 text-center">
1108
+ <img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg" loading="lazy" />
1109
+ <figcaption class="mt-2 text-sm text-gray-500 italic">${escapeHtml(caption)}</figcaption>
1110
+ </figure>`;
1111
+ }
1061
1112
  if (format === "html") {
1062
- return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
1113
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
1063
1114
  }
1064
- return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
1115
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
1065
1116
  }
1066
1117
  }
1067
1118
  ]
@@ -1113,16 +1164,57 @@ var ListExtension = {
1113
1164
  name: "list",
1114
1165
  parseRules: [
1115
1166
  {
1116
- name: "list-item",
1167
+ name: "unordered-list-item",
1117
1168
  pattern: /^(\s*)[-*+]\s+(.+)$/m,
1118
1169
  render: (match) => ({
1119
1170
  type: "list-item",
1120
1171
  content: match[2] || "",
1121
- raw: match[0] || ""
1172
+ raw: match[0] || "",
1173
+ attributes: {
1174
+ indent: match[1]?.length || 0,
1175
+ ordered: false,
1176
+ marker: match[1] ? match[0].match(/[-*+]/)?.[0] : "-"
1177
+ }
1178
+ })
1179
+ },
1180
+ {
1181
+ name: "ordered-list-item",
1182
+ pattern: /^(\s*)(\d+)\.\s+(.+)$/m,
1183
+ render: (match) => ({
1184
+ type: "ordered-list-item",
1185
+ content: match[3] || "",
1186
+ raw: match[0] || "",
1187
+ attributes: {
1188
+ indent: match[1]?.length || 0,
1189
+ ordered: true,
1190
+ number: parseInt(match[2] || "1")
1191
+ }
1122
1192
  })
1123
1193
  }
1124
1194
  ],
1125
1195
  renderRules: [
1196
+ {
1197
+ type: "ul",
1198
+ render: (token) => {
1199
+ const format = token.attributes?.format || "tailwind";
1200
+ const content = token.attributes?.renderedChildren || "";
1201
+ if (format === "html") {
1202
+ return `<ul style="margin: 8px 0; padding-left: 24px; list-style: disc;">${content}</ul>`;
1203
+ }
1204
+ return `<ul class="my-2 pl-6 list-disc">${content}</ul>`;
1205
+ }
1206
+ },
1207
+ {
1208
+ type: "ol",
1209
+ render: (token) => {
1210
+ const format = token.attributes?.format || "tailwind";
1211
+ const content = token.attributes?.renderedChildren || "";
1212
+ if (format === "html") {
1213
+ return `<ol style="margin: 8px 0; padding-left: 24px; list-style: decimal;">${content}</ol>`;
1214
+ }
1215
+ return `<ol class="my-2 pl-6 list-decimal">${content}</ol>`;
1216
+ }
1217
+ },
1126
1218
  {
1127
1219
  type: "list-item",
1128
1220
  render: (token) => {
@@ -1133,6 +1225,17 @@ var ListExtension = {
1133
1225
  }
1134
1226
  return `<li>${content}</li>`;
1135
1227
  }
1228
+ },
1229
+ {
1230
+ type: "ordered-list-item",
1231
+ render: (token) => {
1232
+ const format = token.attributes?.format || "tailwind";
1233
+ const content = token.attributes?.renderedChildren || escapeHtml(token.content);
1234
+ if (format === "html") {
1235
+ return `<li>${content}</li>`;
1236
+ }
1237
+ return `<li>${content}</li>`;
1238
+ }
1136
1239
  }
1137
1240
  ]
1138
1241
  };
@@ -1147,6 +1250,7 @@ var TaskListExtension = {
1147
1250
  content: match[3] || "",
1148
1251
  raw: match[0] || "",
1149
1252
  attributes: {
1253
+ indent: match[1]?.length || 0,
1150
1254
  checked: String((match[2] || "").toLowerCase() === "x")
1151
1255
  }
1152
1256
  })
@@ -1159,15 +1263,20 @@ var TaskListExtension = {
1159
1263
  const isChecked = token.attributes?.checked === "true";
1160
1264
  const content = token.attributes?.renderedChildren || escapeHtml(token.content);
1161
1265
  const format = token.attributes?.format || "html";
1266
+ 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>`;
1267
+ 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>`;
1162
1268
  if (format === "html") {
1163
- return `<div style="display: flex; align-items: center; gap: 8px; margin: 8px 0;">
1164
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled style="margin: 0;" />
1269
+ return `<div style="display: flex; align-items: flex-start; gap: 8px; margin: 8px 0;">
1270
+ <div style="color: ${isChecked ? "#10b981" : "#9ca3af"}; margin-top: 2px;">
1271
+ ${isChecked ? checkmark : checkbox}
1272
+ </div>
1165
1273
  <span${isChecked ? ' style="text-decoration: line-through; color: #6b7280;"' : ""}>${content}</span>
1166
1274
  </div>`;
1167
1275
  }
1168
- return `<div class="flex items-center gap-2 my-2 task-list-item">
1169
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled
1170
- class="form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" />
1276
+ return `<div class="flex items-start gap-2 my-2 task-list-item">
1277
+ <div class="${isChecked ? "text-green-600" : "text-gray-400"} flex-shrink-0 mt-0.5">
1278
+ ${isChecked ? checkmark : checkbox}
1279
+ </div>
1171
1280
  <span${isChecked ? ' class="line-through text-muted-foreground"' : ""}>${content}</span>
1172
1281
  </div>`;
1173
1282
  }
@@ -1212,6 +1321,35 @@ var TextExtension = {
1212
1321
  ]
1213
1322
  };
1214
1323
 
1324
+ // src/extensions/core/strikethrough.ts
1325
+ var StrikethroughExtension = {
1326
+ name: "strikethrough",
1327
+ parseRules: [
1328
+ {
1329
+ name: "strikethrough",
1330
+ pattern: /~~((?:(?!~~).)+)~~/,
1331
+ render: (match) => ({
1332
+ type: "strikethrough",
1333
+ content: match[1] || "",
1334
+ raw: match[0] || ""
1335
+ })
1336
+ }
1337
+ ],
1338
+ renderRules: [
1339
+ {
1340
+ type: "strikethrough",
1341
+ render: (token) => {
1342
+ const content = escapeHtml(token.content);
1343
+ const format = token.attributes?.format;
1344
+ if (format === "html") {
1345
+ return `<del style="text-decoration: line-through; color: #6b7280;">${content}</del>`;
1346
+ }
1347
+ return `<del class="line-through text-gray-500">${content}</del>`;
1348
+ }
1349
+ }
1350
+ ]
1351
+ };
1352
+
1215
1353
  // src/extensions/core/index.ts
1216
1354
  var CoreExtensions = [
1217
1355
  TextExtension,
@@ -1226,6 +1364,7 @@ var CoreExtensions = [
1226
1364
  TaskListExtension,
1227
1365
  BlockquoteExtension,
1228
1366
  HorizontalRuleExtension,
1367
+ StrikethroughExtension,
1229
1368
  ParagraphExtension,
1230
1369
  LineBreakExtension
1231
1370
  ];