@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.
@@ -1543,20 +1543,59 @@ var ChangerawrMarkdown = (() => {
1543
1543
  format: this.config.format
1544
1544
  })
1545
1545
  }));
1546
- const htmlParts = tokensWithFormat.map((token) => this.renderToken(token));
1546
+ const groupedTokens = this.groupListItems(tokensWithFormat);
1547
+ const htmlParts = groupedTokens.map((token) => this.renderToken(token));
1547
1548
  const combinedHtml = htmlParts.join("");
1548
1549
  if (this.config.sanitize && !this.config.allowUnsafeHtml) {
1549
1550
  return sanitizeHtml(combinedHtml);
1550
1551
  }
1551
1552
  return combinedHtml;
1552
1553
  }
1554
+ groupListItems(tokens) {
1555
+ const result = [];
1556
+ let i = 0;
1557
+ while (i < tokens.length) {
1558
+ const token = tokens[i];
1559
+ const isListItem = (token == null ? void 0 : token.type) === "list-item" || (token == null ? void 0 : token.type) === "ordered-list-item" || (token == null ? void 0 : token.type) === "task-item";
1560
+ if (isListItem) {
1561
+ const listItems = [];
1562
+ const firstItemType = token.type;
1563
+ const isOrdered = firstItemType === "ordered-list-item";
1564
+ while (i < tokens.length) {
1565
+ const item = tokens[i];
1566
+ if (!item) break;
1567
+ const itemType = item.type;
1568
+ const isSameListType = isOrdered && itemType === "ordered-list-item" || !isOrdered && (itemType === "list-item" || itemType === "task-item");
1569
+ if (isSameListType) {
1570
+ listItems.push(item);
1571
+ i++;
1572
+ } else {
1573
+ break;
1574
+ }
1575
+ }
1576
+ const wrappedList = {
1577
+ type: isOrdered ? "ol" : "ul",
1578
+ content: "",
1579
+ raw: "",
1580
+ children: listItems,
1581
+ attributes: { format: this.config.format }
1582
+ };
1583
+ wrappedList._isWrapped = true;
1584
+ result.push(wrappedList);
1585
+ } else {
1586
+ result.push(token);
1587
+ i++;
1588
+ }
1589
+ }
1590
+ return result;
1591
+ }
1553
1592
  renderToken(token) {
1554
1593
  const rule = this.rules.get(token.type);
1555
1594
  if (rule) {
1556
1595
  try {
1557
1596
  let tokenToRender = token;
1558
1597
  if (token.children && token.children.length > 0) {
1559
- const renderedChildren = this.render(token.children);
1598
+ const renderedChildren = token.type === "ul" || token.type === "ol" ? token.children.map((child) => this.renderToken(child)).join("") : this.render(token.children);
1560
1599
  tokenToRender = __spreadProps(__spreadValues({}, token), {
1561
1600
  attributes: __spreadProps(__spreadValues({}, token.attributes), {
1562
1601
  renderedChildren
@@ -2065,7 +2104,8 @@ var ChangerawrMarkdown = (() => {
2065
2104
  attributes: {
2066
2105
  alt: match[1] || "",
2067
2106
  src: match[2] || "",
2068
- title: match[3] || ""
2107
+ caption: match[3] || ""
2108
+ // Renamed from 'title' to 'caption' for clarity
2069
2109
  }
2070
2110
  })
2071
2111
  }
@@ -2077,13 +2117,24 @@ var ChangerawrMarkdown = (() => {
2077
2117
  var _a, _b, _c, _d;
2078
2118
  const src = ((_a = token.attributes) == null ? void 0 : _a.src) || "";
2079
2119
  const alt = ((_b = token.attributes) == null ? void 0 : _b.alt) || "";
2080
- const title = ((_c = token.attributes) == null ? void 0 : _c.title) || "";
2081
- const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
2120
+ const caption = ((_c = token.attributes) == null ? void 0 : _c.caption) || "";
2082
2121
  const format = ((_d = token.attributes) == null ? void 0 : _d.format) || "html";
2122
+ if (caption) {
2123
+ if (format === "html") {
2124
+ return `<figure style="margin: 16px 0; text-align: center;">
2125
+ <img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px;" loading="lazy" />
2126
+ <figcaption style="margin-top: 8px; font-size: 14px; color: #6b7280; font-style: italic;">${escapeHtml(caption)}</figcaption>
2127
+ </figure>`;
2128
+ }
2129
+ return `<figure class="my-4 text-center">
2130
+ <img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg" loading="lazy" />
2131
+ <figcaption class="mt-2 text-sm text-gray-500 italic">${escapeHtml(caption)}</figcaption>
2132
+ </figure>`;
2133
+ }
2083
2134
  if (format === "html") {
2084
- return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
2135
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
2085
2136
  }
2086
- return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
2137
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
2087
2138
  }
2088
2139
  }
2089
2140
  ]
@@ -2136,16 +2187,65 @@ var ChangerawrMarkdown = (() => {
2136
2187
  name: "list",
2137
2188
  parseRules: [
2138
2189
  {
2139
- name: "list-item",
2190
+ name: "unordered-list-item",
2140
2191
  pattern: /^(\s*)[-*+]\s+(.+)$/m,
2141
- render: (match) => ({
2142
- type: "list-item",
2143
- content: match[2] || "",
2144
- raw: match[0] || ""
2145
- })
2192
+ render: (match) => {
2193
+ var _a, _b;
2194
+ return {
2195
+ type: "list-item",
2196
+ content: match[2] || "",
2197
+ raw: match[0] || "",
2198
+ attributes: {
2199
+ indent: ((_a = match[1]) == null ? void 0 : _a.length) || 0,
2200
+ ordered: false,
2201
+ marker: match[1] ? (_b = match[0].match(/[-*+]/)) == null ? void 0 : _b[0] : "-"
2202
+ }
2203
+ };
2204
+ }
2205
+ },
2206
+ {
2207
+ name: "ordered-list-item",
2208
+ pattern: /^(\s*)(\d+)\.\s+(.+)$/m,
2209
+ render: (match) => {
2210
+ var _a;
2211
+ return {
2212
+ type: "ordered-list-item",
2213
+ content: match[3] || "",
2214
+ raw: match[0] || "",
2215
+ attributes: {
2216
+ indent: ((_a = match[1]) == null ? void 0 : _a.length) || 0,
2217
+ ordered: true,
2218
+ number: parseInt(match[2] || "1")
2219
+ }
2220
+ };
2221
+ }
2146
2222
  }
2147
2223
  ],
2148
2224
  renderRules: [
2225
+ {
2226
+ type: "ul",
2227
+ render: (token) => {
2228
+ var _a, _b;
2229
+ const format = ((_a = token.attributes) == null ? void 0 : _a.format) || "tailwind";
2230
+ const content = ((_b = token.attributes) == null ? void 0 : _b.renderedChildren) || "";
2231
+ if (format === "html") {
2232
+ return `<ul style="margin: 8px 0; padding-left: 24px; list-style: disc;">${content}</ul>`;
2233
+ }
2234
+ return `<ul class="my-2 pl-6 list-disc">${content}</ul>`;
2235
+ }
2236
+ },
2237
+ {
2238
+ type: "ol",
2239
+ render: (token) => {
2240
+ var _a, _b;
2241
+ const format = ((_a = token.attributes) == null ? void 0 : _a.format) || "tailwind";
2242
+ const content = ((_b = token.attributes) == null ? void 0 : _b.renderedChildren) || "";
2243
+ if (format === "html") {
2244
+ return `<ol style="margin: 8px 0; padding-left: 24px; list-style: decimal;">${content}</ol>`;
2245
+ }
2246
+ return `<ol class="my-2 pl-6 list-decimal">${content}</ol>`;
2247
+ }
2248
+ },
2149
2249
  {
2150
2250
  type: "list-item",
2151
2251
  render: (token) => {
@@ -2157,6 +2257,18 @@ var ChangerawrMarkdown = (() => {
2157
2257
  }
2158
2258
  return `<li>${content}</li>`;
2159
2259
  }
2260
+ },
2261
+ {
2262
+ type: "ordered-list-item",
2263
+ render: (token) => {
2264
+ var _a, _b;
2265
+ const format = ((_a = token.attributes) == null ? void 0 : _a.format) || "tailwind";
2266
+ const content = ((_b = token.attributes) == null ? void 0 : _b.renderedChildren) || escapeHtml(token.content);
2267
+ if (format === "html") {
2268
+ return `<li>${content}</li>`;
2269
+ }
2270
+ return `<li>${content}</li>`;
2271
+ }
2160
2272
  }
2161
2273
  ]
2162
2274
  };
@@ -2166,14 +2278,18 @@ var ChangerawrMarkdown = (() => {
2166
2278
  {
2167
2279
  name: "task-item",
2168
2280
  pattern: /^(\s*)-\s*\[([ xX])\]\s*(.+)$/m,
2169
- render: (match) => ({
2170
- type: "task-item",
2171
- content: match[3] || "",
2172
- raw: match[0] || "",
2173
- attributes: {
2174
- checked: String((match[2] || "").toLowerCase() === "x")
2175
- }
2176
- })
2281
+ render: (match) => {
2282
+ var _a;
2283
+ return {
2284
+ type: "task-item",
2285
+ content: match[3] || "",
2286
+ raw: match[0] || "",
2287
+ attributes: {
2288
+ indent: ((_a = match[1]) == null ? void 0 : _a.length) || 0,
2289
+ checked: String((match[2] || "").toLowerCase() === "x")
2290
+ }
2291
+ };
2292
+ }
2177
2293
  }
2178
2294
  ],
2179
2295
  renderRules: [
@@ -2184,15 +2300,20 @@ var ChangerawrMarkdown = (() => {
2184
2300
  const isChecked = ((_a = token.attributes) == null ? void 0 : _a.checked) === "true";
2185
2301
  const content = ((_b = token.attributes) == null ? void 0 : _b.renderedChildren) || escapeHtml(token.content);
2186
2302
  const format = ((_c = token.attributes) == null ? void 0 : _c.format) || "html";
2303
+ 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>`;
2304
+ 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>`;
2187
2305
  if (format === "html") {
2188
- return `<div style="display: flex; align-items: center; gap: 8px; margin: 8px 0;">
2189
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled style="margin: 0;" />
2306
+ return `<div style="display: flex; align-items: flex-start; gap: 8px; margin: 8px 0;">
2307
+ <div style="color: ${isChecked ? "#10b981" : "#9ca3af"}; margin-top: 2px;">
2308
+ ${isChecked ? checkmark : checkbox}
2309
+ </div>
2190
2310
  <span${isChecked ? ' style="text-decoration: line-through; color: #6b7280;"' : ""}>${content}</span>
2191
2311
  </div>`;
2192
2312
  }
2193
- return `<div class="flex items-center gap-2 my-2 task-list-item">
2194
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled
2195
- class="form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" />
2313
+ return `<div class="flex items-start gap-2 my-2 task-list-item">
2314
+ <div class="${isChecked ? "text-green-600" : "text-gray-400"} flex-shrink-0 mt-0.5">
2315
+ ${isChecked ? checkmark : checkbox}
2316
+ </div>
2196
2317
  <span${isChecked ? ' class="line-through text-muted-foreground"' : ""}>${content}</span>
2197
2318
  </div>`;
2198
2319
  }
@@ -2238,6 +2359,36 @@ var ChangerawrMarkdown = (() => {
2238
2359
  ]
2239
2360
  };
2240
2361
 
2362
+ // src/extensions/core/strikethrough.ts
2363
+ var StrikethroughExtension = {
2364
+ name: "strikethrough",
2365
+ parseRules: [
2366
+ {
2367
+ name: "strikethrough",
2368
+ pattern: /~~((?:(?!~~).)+)~~/,
2369
+ render: (match) => ({
2370
+ type: "strikethrough",
2371
+ content: match[1] || "",
2372
+ raw: match[0] || ""
2373
+ })
2374
+ }
2375
+ ],
2376
+ renderRules: [
2377
+ {
2378
+ type: "strikethrough",
2379
+ render: (token) => {
2380
+ var _a;
2381
+ const content = escapeHtml(token.content);
2382
+ const format = (_a = token.attributes) == null ? void 0 : _a.format;
2383
+ if (format === "html") {
2384
+ return `<del style="text-decoration: line-through; color: #6b7280;">${content}</del>`;
2385
+ }
2386
+ return `<del class="line-through text-gray-500">${content}</del>`;
2387
+ }
2388
+ }
2389
+ ]
2390
+ };
2391
+
2241
2392
  // src/extensions/core/index.ts
2242
2393
  var CoreExtensions = [
2243
2394
  TextExtension,
@@ -2252,6 +2403,7 @@ var ChangerawrMarkdown = (() => {
2252
2403
  TaskListExtension,
2253
2404
  BlockquoteExtension,
2254
2405
  HorizontalRuleExtension,
2406
+ StrikethroughExtension,
2255
2407
  ParagraphExtension,
2256
2408
  LineBreakExtension
2257
2409
  ];
@@ -528,20 +528,59 @@ var MarkdownRenderer = class {
528
528
  format: this.config.format
529
529
  }
530
530
  }));
531
- const htmlParts = tokensWithFormat.map((token) => this.renderToken(token));
531
+ const groupedTokens = this.groupListItems(tokensWithFormat);
532
+ const htmlParts = groupedTokens.map((token) => this.renderToken(token));
532
533
  const combinedHtml = htmlParts.join("");
533
534
  if (this.config.sanitize && !this.config.allowUnsafeHtml) {
534
535
  return sanitizeHtml(combinedHtml);
535
536
  }
536
537
  return combinedHtml;
537
538
  }
539
+ groupListItems(tokens) {
540
+ const result = [];
541
+ let i = 0;
542
+ while (i < tokens.length) {
543
+ const token = tokens[i];
544
+ const isListItem = token?.type === "list-item" || token?.type === "ordered-list-item" || token?.type === "task-item";
545
+ if (isListItem) {
546
+ const listItems = [];
547
+ const firstItemType = token.type;
548
+ const isOrdered = firstItemType === "ordered-list-item";
549
+ while (i < tokens.length) {
550
+ const item = tokens[i];
551
+ if (!item) break;
552
+ const itemType = item.type;
553
+ const isSameListType = isOrdered && itemType === "ordered-list-item" || !isOrdered && (itemType === "list-item" || itemType === "task-item");
554
+ if (isSameListType) {
555
+ listItems.push(item);
556
+ i++;
557
+ } else {
558
+ break;
559
+ }
560
+ }
561
+ const wrappedList = {
562
+ type: isOrdered ? "ol" : "ul",
563
+ content: "",
564
+ raw: "",
565
+ children: listItems,
566
+ attributes: { format: this.config.format }
567
+ };
568
+ wrappedList._isWrapped = true;
569
+ result.push(wrappedList);
570
+ } else {
571
+ result.push(token);
572
+ i++;
573
+ }
574
+ }
575
+ return result;
576
+ }
538
577
  renderToken(token) {
539
578
  const rule = this.rules.get(token.type);
540
579
  if (rule) {
541
580
  try {
542
581
  let tokenToRender = token;
543
582
  if (token.children && token.children.length > 0) {
544
- const renderedChildren = this.render(token.children);
583
+ const renderedChildren = token.type === "ul" || token.type === "ol" ? token.children.map((child) => this.renderToken(child)).join("") : this.render(token.children);
545
584
  tokenToRender = {
546
585
  ...token,
547
586
  attributes: {
@@ -1042,7 +1081,8 @@ var ImageExtension = {
1042
1081
  attributes: {
1043
1082
  alt: match[1] || "",
1044
1083
  src: match[2] || "",
1045
- title: match[3] || ""
1084
+ caption: match[3] || ""
1085
+ // Renamed from 'title' to 'caption' for clarity
1046
1086
  }
1047
1087
  })
1048
1088
  }
@@ -1053,13 +1093,24 @@ var ImageExtension = {
1053
1093
  render: (token) => {
1054
1094
  const src = token.attributes?.src || "";
1055
1095
  const alt = token.attributes?.alt || "";
1056
- const title = token.attributes?.title || "";
1057
- const titleAttr = title ? ` title="${escapeHtml(title)}"` : "";
1096
+ const caption = token.attributes?.caption || "";
1058
1097
  const format = token.attributes?.format || "html";
1098
+ if (caption) {
1099
+ if (format === "html") {
1100
+ return `<figure style="margin: 16px 0; text-align: center;">
1101
+ <img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px;" loading="lazy" />
1102
+ <figcaption style="margin-top: 8px; font-size: 14px; color: #6b7280; font-style: italic;">${escapeHtml(caption)}</figcaption>
1103
+ </figure>`;
1104
+ }
1105
+ return `<figure class="my-4 text-center">
1106
+ <img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg" loading="lazy" />
1107
+ <figcaption class="mt-2 text-sm text-gray-500 italic">${escapeHtml(caption)}</figcaption>
1108
+ </figure>`;
1109
+ }
1059
1110
  if (format === "html") {
1060
- return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
1111
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" style="max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;" loading="lazy" />`;
1061
1112
  }
1062
- return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}"${titleAttr} class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
1113
+ return `<img src="${escapeHtml(src)}" alt="${escapeHtml(alt)}" class="max-w-full h-auto rounded-lg my-4" loading="lazy" />`;
1063
1114
  }
1064
1115
  }
1065
1116
  ]
@@ -1111,16 +1162,57 @@ var ListExtension = {
1111
1162
  name: "list",
1112
1163
  parseRules: [
1113
1164
  {
1114
- name: "list-item",
1165
+ name: "unordered-list-item",
1115
1166
  pattern: /^(\s*)[-*+]\s+(.+)$/m,
1116
1167
  render: (match) => ({
1117
1168
  type: "list-item",
1118
1169
  content: match[2] || "",
1119
- raw: match[0] || ""
1170
+ raw: match[0] || "",
1171
+ attributes: {
1172
+ indent: match[1]?.length || 0,
1173
+ ordered: false,
1174
+ marker: match[1] ? match[0].match(/[-*+]/)?.[0] : "-"
1175
+ }
1176
+ })
1177
+ },
1178
+ {
1179
+ name: "ordered-list-item",
1180
+ pattern: /^(\s*)(\d+)\.\s+(.+)$/m,
1181
+ render: (match) => ({
1182
+ type: "ordered-list-item",
1183
+ content: match[3] || "",
1184
+ raw: match[0] || "",
1185
+ attributes: {
1186
+ indent: match[1]?.length || 0,
1187
+ ordered: true,
1188
+ number: parseInt(match[2] || "1")
1189
+ }
1120
1190
  })
1121
1191
  }
1122
1192
  ],
1123
1193
  renderRules: [
1194
+ {
1195
+ type: "ul",
1196
+ render: (token) => {
1197
+ const format = token.attributes?.format || "tailwind";
1198
+ const content = token.attributes?.renderedChildren || "";
1199
+ if (format === "html") {
1200
+ return `<ul style="margin: 8px 0; padding-left: 24px; list-style: disc;">${content}</ul>`;
1201
+ }
1202
+ return `<ul class="my-2 pl-6 list-disc">${content}</ul>`;
1203
+ }
1204
+ },
1205
+ {
1206
+ type: "ol",
1207
+ render: (token) => {
1208
+ const format = token.attributes?.format || "tailwind";
1209
+ const content = token.attributes?.renderedChildren || "";
1210
+ if (format === "html") {
1211
+ return `<ol style="margin: 8px 0; padding-left: 24px; list-style: decimal;">${content}</ol>`;
1212
+ }
1213
+ return `<ol class="my-2 pl-6 list-decimal">${content}</ol>`;
1214
+ }
1215
+ },
1124
1216
  {
1125
1217
  type: "list-item",
1126
1218
  render: (token) => {
@@ -1131,6 +1223,17 @@ var ListExtension = {
1131
1223
  }
1132
1224
  return `<li>${content}</li>`;
1133
1225
  }
1226
+ },
1227
+ {
1228
+ type: "ordered-list-item",
1229
+ render: (token) => {
1230
+ const format = token.attributes?.format || "tailwind";
1231
+ const content = token.attributes?.renderedChildren || escapeHtml(token.content);
1232
+ if (format === "html") {
1233
+ return `<li>${content}</li>`;
1234
+ }
1235
+ return `<li>${content}</li>`;
1236
+ }
1134
1237
  }
1135
1238
  ]
1136
1239
  };
@@ -1145,6 +1248,7 @@ var TaskListExtension = {
1145
1248
  content: match[3] || "",
1146
1249
  raw: match[0] || "",
1147
1250
  attributes: {
1251
+ indent: match[1]?.length || 0,
1148
1252
  checked: String((match[2] || "").toLowerCase() === "x")
1149
1253
  }
1150
1254
  })
@@ -1157,15 +1261,20 @@ var TaskListExtension = {
1157
1261
  const isChecked = token.attributes?.checked === "true";
1158
1262
  const content = token.attributes?.renderedChildren || escapeHtml(token.content);
1159
1263
  const format = token.attributes?.format || "html";
1264
+ 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>`;
1265
+ 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>`;
1160
1266
  if (format === "html") {
1161
- return `<div style="display: flex; align-items: center; gap: 8px; margin: 8px 0;">
1162
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled style="margin: 0;" />
1267
+ return `<div style="display: flex; align-items: flex-start; gap: 8px; margin: 8px 0;">
1268
+ <div style="color: ${isChecked ? "#10b981" : "#9ca3af"}; margin-top: 2px;">
1269
+ ${isChecked ? checkmark : checkbox}
1270
+ </div>
1163
1271
  <span${isChecked ? ' style="text-decoration: line-through; color: #6b7280;"' : ""}>${content}</span>
1164
1272
  </div>`;
1165
1273
  }
1166
- return `<div class="flex items-center gap-2 my-2 task-list-item">
1167
- <input type="checkbox" ${isChecked ? "checked" : ""} disabled
1168
- class="form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" />
1274
+ return `<div class="flex items-start gap-2 my-2 task-list-item">
1275
+ <div class="${isChecked ? "text-green-600" : "text-gray-400"} flex-shrink-0 mt-0.5">
1276
+ ${isChecked ? checkmark : checkbox}
1277
+ </div>
1169
1278
  <span${isChecked ? ' class="line-through text-muted-foreground"' : ""}>${content}</span>
1170
1279
  </div>`;
1171
1280
  }
@@ -1210,6 +1319,35 @@ var TextExtension = {
1210
1319
  ]
1211
1320
  };
1212
1321
 
1322
+ // src/extensions/core/strikethrough.ts
1323
+ var StrikethroughExtension = {
1324
+ name: "strikethrough",
1325
+ parseRules: [
1326
+ {
1327
+ name: "strikethrough",
1328
+ pattern: /~~((?:(?!~~).)+)~~/,
1329
+ render: (match) => ({
1330
+ type: "strikethrough",
1331
+ content: match[1] || "",
1332
+ raw: match[0] || ""
1333
+ })
1334
+ }
1335
+ ],
1336
+ renderRules: [
1337
+ {
1338
+ type: "strikethrough",
1339
+ render: (token) => {
1340
+ const content = escapeHtml(token.content);
1341
+ const format = token.attributes?.format;
1342
+ if (format === "html") {
1343
+ return `<del style="text-decoration: line-through; color: #6b7280;">${content}</del>`;
1344
+ }
1345
+ return `<del class="line-through text-gray-500">${content}</del>`;
1346
+ }
1347
+ }
1348
+ ]
1349
+ };
1350
+
1213
1351
  // src/extensions/core/index.ts
1214
1352
  var CoreExtensions = [
1215
1353
  TextExtension,
@@ -1224,6 +1362,7 @@ var CoreExtensions = [
1224
1362
  TaskListExtension,
1225
1363
  BlockquoteExtension,
1226
1364
  HorizontalRuleExtension,
1365
+ StrikethroughExtension,
1227
1366
  ParagraphExtension,
1228
1367
  LineBreakExtension
1229
1368
  ];