@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.
@@ -485,20 +485,59 @@ var MarkdownRenderer = class {
485
485
  format: this.config.format
486
486
  }
487
487
  }));
488
- const htmlParts = tokensWithFormat.map((token) => this.renderToken(token));
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
- title: match[3] || ""
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 title = token.attributes?.title || "";
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)}"${titleAttr} style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
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)}"${titleAttr} class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
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: center; gap: 8px; margin: 8px 0;">
1119
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled style="margin: 0;" />
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-center gap-2 my-2 task-list-item">
1124
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled
1125
- class="form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" />
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
  ];