@dr-ishaan/remake-blocks 1.3.0 → 1.4.1
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/remark-remake-blocks.d.ts.map +1 -1
- package/dist/remark-remake-blocks.js +251 -28
- package/dist/remark-remake-blocks.js.map +1 -1
- package/dist/styles.css +84 -26
- package/dist/theme/docusaurus.css +26 -8
- package/dist/theme/github.css +84 -26
- package/dist/theme/obsidian.css +32 -12
- package/dist/theme/vitepress.css +30 -11
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remark-remake-blocks.d.ts","sourceRoot":"","sources":["../src/remark-remake-blocks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAqC,MAAM,OAAO,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EAId,MAAM,YAAY,CAAC;AAMpB,QAAA,MAAM,gBAAgB,EAAE,aAAa,EAsKpC,CAAC;
|
|
1
|
+
{"version":3,"file":"remark-remake-blocks.d.ts","sourceRoot":"","sources":["../src/remark-remake-blocks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAqC,MAAM,OAAO,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EAId,MAAM,YAAY,CAAC;AAMpB,QAAA,MAAM,gBAAgB,EAAE,aAAa,EAsKpC,CAAC;AA+LF,iBAAS,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5C;AAUD,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAW9D;AAmPD,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOvC;AAmzBD,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAoGnE,CAAC;AAiFF,eAAO,MAAM,mBAAmB,oDAAqB,CAAC;AAItD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -218,6 +218,34 @@ const LUCIDE_ICONS = {
|
|
|
218
218
|
missing: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/><path d="M8 11h6"/></svg>`,
|
|
219
219
|
error: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"/><path d="M12 8v4"/><path d="M12 16h.01"/></svg>`,
|
|
220
220
|
cite: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/></svg>`,
|
|
221
|
+
// ── v1.4.0: Extra Lucide icons for per-callout named icon ({icon="rocket"}) ──
|
|
222
|
+
rocket: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/></svg>`,
|
|
223
|
+
heart: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/></svg>`,
|
|
224
|
+
star: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>`,
|
|
225
|
+
bell: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>`,
|
|
226
|
+
flag: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" x2="4" y1="22" y2="15"/></svg>`,
|
|
227
|
+
bookmark: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z"/></svg>`,
|
|
228
|
+
lightbulb: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>`,
|
|
229
|
+
fire: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/></svg>`,
|
|
230
|
+
zap: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>`,
|
|
231
|
+
shield: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/></svg>`,
|
|
232
|
+
code: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>`,
|
|
233
|
+
book: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/></svg>`,
|
|
234
|
+
pencil: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/><path d="m15 5 4 4"/></svg>`,
|
|
235
|
+
eye: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>`,
|
|
236
|
+
globe: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>`,
|
|
237
|
+
lock: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>`,
|
|
238
|
+
key: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4"/><path d="m21 2-9.6 9.6"/><circle cx="7.5" cy="15.5" r="5.5"/></svg>`,
|
|
239
|
+
clock: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>`,
|
|
240
|
+
calendar: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="4" rx="2" ry="2"/><line x1="16" x2="16" y1="2" y2="6"/><line x1="8" x2="8" y1="2" y2="6"/><line x1="3" x2="21" y1="10" y2="10"/></svg>`,
|
|
241
|
+
package: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m7.5 4.27 9 5.15"/><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></svg>`,
|
|
242
|
+
download: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>`,
|
|
243
|
+
upload: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></svg>`,
|
|
244
|
+
link: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71a5 5 0 0 0-.54 7.54"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71a5 5 0 0 0 .54-7.54"/></svg>`,
|
|
245
|
+
settings: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>`,
|
|
246
|
+
terminal: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/></svg>`,
|
|
247
|
+
database: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></svg>`,
|
|
248
|
+
cloud: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"/></svg>`,
|
|
221
249
|
};
|
|
222
250
|
const EMOJI_ICONS = {
|
|
223
251
|
note: "ℹ️",
|
|
@@ -301,6 +329,9 @@ const DEFAULT_OPTIONS = {
|
|
|
301
329
|
tags: {},
|
|
302
330
|
// v1.3.0 defaults
|
|
303
331
|
enableDirectiveSyntax: false,
|
|
332
|
+
// v1.4.0 defaults
|
|
333
|
+
labels: {},
|
|
334
|
+
enableMkDocsSyntax: false,
|
|
304
335
|
};
|
|
305
336
|
// ---------------------------------------------------------------------------
|
|
306
337
|
// Helper: Validate + normalize a single custom callout config.
|
|
@@ -446,6 +477,11 @@ function parseOverrides(overridesBlock) {
|
|
|
446
477
|
result.icon = false;
|
|
447
478
|
else if (value === "true" || value === "1" || value === "yes")
|
|
448
479
|
result.icon = true;
|
|
480
|
+
else if (value.length > 0) {
|
|
481
|
+
// v1.4.0: per-callout named icon (e.g. {icon="rocket"} uses Lucide rocket icon)
|
|
482
|
+
result.iconName = value;
|
|
483
|
+
result.icon = true; // ensure icon is shown
|
|
484
|
+
}
|
|
449
485
|
}
|
|
450
486
|
else if (key === "appearance") {
|
|
451
487
|
if (value === "default" || value === "minimal" || value === "simple" || value === "hidden") {
|
|
@@ -467,11 +503,52 @@ function parseOverrides(overridesBlock) {
|
|
|
467
503
|
}
|
|
468
504
|
// Unknown keys silently ignored
|
|
469
505
|
}
|
|
470
|
-
if (result.icon === undefined && result.appearance === undefined && result.inline === undefined)
|
|
506
|
+
if (result.icon === undefined && result.appearance === undefined && result.inline === undefined && result.iconName === undefined)
|
|
471
507
|
return undefined;
|
|
472
508
|
return result;
|
|
473
509
|
}
|
|
474
510
|
// ---------------------------------------------------------------------------
|
|
511
|
+
// v1.4.0: Parse directive attribute block `{#id .class key="value"}`
|
|
512
|
+
// Supports the remark-directive attribute syntax:
|
|
513
|
+
// #id — sets element id
|
|
514
|
+
// .class-name — adds CSS class
|
|
515
|
+
// key="value" — adds arbitrary HTML attribute
|
|
516
|
+
// key=value — adds arbitrary HTML attribute (bareword)
|
|
517
|
+
// ---------------------------------------------------------------------------
|
|
518
|
+
function parseDirectiveAttrs(attrsBlock) {
|
|
519
|
+
if (!attrsBlock)
|
|
520
|
+
return undefined;
|
|
521
|
+
const inner = attrsBlock.trim().replace(/^\{|\}$/g, "").trim();
|
|
522
|
+
if (!inner)
|
|
523
|
+
return undefined;
|
|
524
|
+
const result = { classes: [], attrs: {} };
|
|
525
|
+
// Match #id, .class, key="value", key='value', key=value
|
|
526
|
+
const tokenRe = /(#)([\w-]+)|(\.)([\w-]+)|(\w[\w-]*)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s}]+))/g;
|
|
527
|
+
let m;
|
|
528
|
+
while ((m = tokenRe.exec(inner)) !== null) {
|
|
529
|
+
if (m[1] === "#" && m[2]) {
|
|
530
|
+
result.id = m[2];
|
|
531
|
+
}
|
|
532
|
+
else if (m[3] === "." && m[4]) {
|
|
533
|
+
result.classes.push(m[4]);
|
|
534
|
+
}
|
|
535
|
+
else if (m[5]) {
|
|
536
|
+
const key = m[5];
|
|
537
|
+
const value = (m[6] ?? m[7] ?? m[8] ?? "").trim();
|
|
538
|
+
// Block event handlers and style for security
|
|
539
|
+
if (key.toLowerCase().startsWith("on"))
|
|
540
|
+
continue;
|
|
541
|
+
if (key.toLowerCase() === "style")
|
|
542
|
+
continue;
|
|
543
|
+
result.attrs[key] = value;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
if (!result.id && (!result.classes || result.classes.length === 0) && Object.keys(result.attrs || {}).length === 0) {
|
|
547
|
+
return undefined;
|
|
548
|
+
}
|
|
549
|
+
return result;
|
|
550
|
+
}
|
|
551
|
+
// ---------------------------------------------------------------------------
|
|
475
552
|
// Helper: Parse the first paragraph of a blockquote to detect a callout
|
|
476
553
|
// ---------------------------------------------------------------------------
|
|
477
554
|
function parseCalloutDirective(blockquote, calloutPattern, configMap, enableDisclosures) {
|
|
@@ -646,8 +723,13 @@ function buildCalloutHtml(parsed, blockquote, calloutPattern, configMap, options
|
|
|
646
723
|
}
|
|
647
724
|
// ── Regular / Collapsible Callout ──────────────────────────────────
|
|
648
725
|
const config = configMap.get(parsed.type);
|
|
649
|
-
|
|
726
|
+
// v1.4.0: i18n label customization — labels option overrides defaultTitle
|
|
727
|
+
// Use || instead of ?? so empty strings also fall back to default
|
|
728
|
+
const defaultTitle = options.labels?.[parsed.type] || config.defaultTitle;
|
|
729
|
+
const title = parsed.customTitle || defaultTitle;
|
|
650
730
|
const dataAttr = options.dataCalloutType ? ` data-callout-type="${escapeAttribute(parsed.type)}"` : "";
|
|
731
|
+
// v1.4.0: data-collapsible attribute (for CSS targeting of collapsible vs non-collapsible)
|
|
732
|
+
const collapsibleDataAttr = ` data-collapsible="${parsed.collapsible ? "true" : "false"}"`;
|
|
651
733
|
const bodyHtml = buildBodyHtml(blockquote, calloutPattern, options);
|
|
652
734
|
// v1.2.0: resolve per-callout visuals (icon visibility + appearance)
|
|
653
735
|
const { showIcon, appearance } = resolveVisuals(parsed, options);
|
|
@@ -666,9 +748,6 @@ function buildCalloutHtml(parsed, blockquote, calloutPattern, configMap, options
|
|
|
666
748
|
// Sanitize colors before interpolating into style attribute
|
|
667
749
|
const safeIconColor = sanitizeColor(config.iconColor || config.color, "#57606a");
|
|
668
750
|
// v1.2.0: WCAG fix — use role="note" for ALL callouts (was: role="alert" for warnings).
|
|
669
|
-
// role="alert" is for dynamically-inserted content and causes aggressive immediate
|
|
670
|
-
// announcement that disrupts screen reader users on static content.
|
|
671
|
-
// Use role="note" + aria-labelledby for proper title→container association.
|
|
672
751
|
const ariaRole = "note";
|
|
673
752
|
// Escape className + calloutClass to prevent attribute breakout
|
|
674
753
|
const safeCalloutClass = escapeAttribute(options.calloutClass);
|
|
@@ -680,14 +759,39 @@ function buildCalloutHtml(parsed, blockquote, calloutPattern, configMap, options
|
|
|
680
759
|
// v1.2.0: resolve per-type props (dir, style, data-*, etc.)
|
|
681
760
|
const extraProps = resolveProps(options.props, parsed.type, parsed);
|
|
682
761
|
const extraAttrs = formatPropsAsAttrs(extraProps);
|
|
762
|
+
// v1.4.0: directive attributes (#id, .class, key="value")
|
|
763
|
+
let directiveId = "";
|
|
764
|
+
let directiveClasses = "";
|
|
765
|
+
let directiveAttrs = "";
|
|
766
|
+
if (parsed.directiveAttrs) {
|
|
767
|
+
if (parsed.directiveAttrs.id) {
|
|
768
|
+
directiveId = ` id="${escapeAttribute(parsed.directiveAttrs.id)}"`;
|
|
769
|
+
}
|
|
770
|
+
if (parsed.directiveAttrs.classes && parsed.directiveAttrs.classes.length > 0) {
|
|
771
|
+
directiveClasses = " " + parsed.directiveAttrs.classes.map(c => escapeAttribute(c)).join(" ");
|
|
772
|
+
}
|
|
773
|
+
if (parsed.directiveAttrs.attrs) {
|
|
774
|
+
directiveAttrs = formatPropsAsAttrs(parsed.directiveAttrs.attrs);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
683
777
|
// v1.2.0: appearance class
|
|
684
778
|
const appearanceClass = appearance !== "default" ? ` callout-${appearance}` : "";
|
|
685
779
|
// v1.3.0: inline floating class (responsive float left/right)
|
|
686
780
|
const inlineClass = parsed.overrides?.inline ? ` callout-${parsed.overrides.inline}` : "";
|
|
687
781
|
// v1.2.0: icon HTML — only render if showIcon AND appearance allows it
|
|
688
782
|
// v1.3.0: resolve icon based on iconSet option (octicon|lucide|emoji|none)
|
|
783
|
+
// v1.4.0: per-callout named icon override ({icon="rocket"})
|
|
689
784
|
const renderIcon = showIcon && appearance !== "simple" && appearance !== "hidden";
|
|
690
|
-
|
|
785
|
+
let resolvedIcon = "";
|
|
786
|
+
if (renderIcon) {
|
|
787
|
+
if (parsed.overrides?.iconName) {
|
|
788
|
+
// v1.4.0: per-callout named icon (Lucide icon by name)
|
|
789
|
+
resolvedIcon = LUCIDE_ICONS[parsed.overrides.iconName] ?? resolveIcon(parsed.type, config, options.iconSet);
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
resolvedIcon = resolveIcon(parsed.type, config, options.iconSet);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
691
795
|
const effectiveRenderIcon = renderIcon && resolvedIcon.length > 0;
|
|
692
796
|
const iconHtml = effectiveRenderIcon
|
|
693
797
|
? `<span class="callout-icon" style="color:${safeIconColor}" aria-hidden="true">${resolvedIcon}</span>`
|
|
@@ -735,7 +839,7 @@ function buildCalloutHtml(parsed, blockquote, calloutPattern, configMap, options
|
|
|
735
839
|
if (parsed.collapsible) {
|
|
736
840
|
const openAttr = parsed.collapsibleOpen ? " open" : "";
|
|
737
841
|
return html([
|
|
738
|
-
`<${containerTag} class="${safeCalloutClass} ${safeConfigClassName} collapsible${appearanceClass}${inlineClass}"${dataAttr} role="${ariaRole}"${labelledby}${dirAuto}${openAttr}${extraAttrs}>`,
|
|
842
|
+
`<${containerTag} class="${safeCalloutClass} ${safeConfigClassName} collapsible${appearanceClass}${inlineClass}${directiveClasses}"${dataAttr}${collapsibleDataAttr} role="${ariaRole}"${labelledby}${dirAuto}${openAttr}${directiveId}${extraAttrs}${directiveAttrs}>`,
|
|
739
843
|
titleBlockWithDir,
|
|
740
844
|
` <${bodyTag} class="${safeCalloutBodyClass}">`,
|
|
741
845
|
bodyHtml,
|
|
@@ -744,7 +848,7 @@ function buildCalloutHtml(parsed, blockquote, calloutPattern, configMap, options
|
|
|
744
848
|
].filter(Boolean).join("\n"));
|
|
745
849
|
}
|
|
746
850
|
return html([
|
|
747
|
-
`<${containerTag} class="${safeCalloutClass} ${safeConfigClassName}${appearanceClass}${inlineClass}"${dataAttr} role="${ariaRole}"${labelledby}${dirAuto}${extraAttrs}>`,
|
|
851
|
+
`<${containerTag} class="${safeCalloutClass} ${safeConfigClassName}${appearanceClass}${inlineClass}${directiveClasses}"${dataAttr}${collapsibleDataAttr} role="${ariaRole}"${labelledby}${dirAuto}${directiveId}${extraAttrs}${directiveAttrs}>`,
|
|
748
852
|
titleBlockWithDir,
|
|
749
853
|
` <${bodyTag} class="${safeCalloutBodyClass}">`,
|
|
750
854
|
bodyHtml,
|
|
@@ -995,6 +1099,8 @@ function transformDirectiveSyntax(tree, configMap, options) {
|
|
|
995
1099
|
const config = configMap.get(type);
|
|
996
1100
|
const customTitle = title?.trim() || undefined;
|
|
997
1101
|
const overrides = parseOverrides(overridesBlock);
|
|
1102
|
+
// v1.4.0: parse directive attributes (#id, .class, key="value")
|
|
1103
|
+
const directiveAttrs = parseDirectiveAttrs(overridesBlock);
|
|
998
1104
|
// Check for fold override
|
|
999
1105
|
let foldMarker = "";
|
|
1000
1106
|
if (overridesBlock) {
|
|
@@ -1011,6 +1117,7 @@ function transformDirectiveSyntax(tree, configMap, options) {
|
|
|
1011
1117
|
collapsibleOpen,
|
|
1012
1118
|
isDisclosure: false,
|
|
1013
1119
|
overrides,
|
|
1120
|
+
directiveAttrs,
|
|
1014
1121
|
};
|
|
1015
1122
|
// Build body HTML from the bodyText
|
|
1016
1123
|
const bodyLines = bodyText.split("\n");
|
|
@@ -1039,25 +1146,114 @@ function transformDirectiveSyntax(tree, configMap, options) {
|
|
|
1039
1146
|
tree.children = newChildren;
|
|
1040
1147
|
}
|
|
1041
1148
|
// ---------------------------------------------------------------------------
|
|
1149
|
+
// v1.4.0: MkDocs admonition syntax transformer (!!! / ??? / ???+)
|
|
1150
|
+
// ---------------------------------------------------------------------------
|
|
1151
|
+
// Detects !!! type, ??? type, ???+ type paragraphs and converts them to
|
|
1152
|
+
// callouts. This enables content portability with MkDocs Material.
|
|
1153
|
+
//
|
|
1154
|
+
// Supported syntax:
|
|
1155
|
+
// !!! note — non-collapsible callout
|
|
1156
|
+
// ??? note — collapsed callout (same as > [!NOTE]-)
|
|
1157
|
+
// ???+ note — expanded collapsible callout (same as > [!NOTE]+)
|
|
1158
|
+
// !!! note "Title" — with custom title (quoted)
|
|
1159
|
+
// !!! note "" — no title (strips default)
|
|
1160
|
+
//
|
|
1161
|
+
// The body is indented 4 spaces under the directive.
|
|
1162
|
+
function transformMkDocsSyntax(tree, configMap, options) {
|
|
1163
|
+
if (!tree.children)
|
|
1164
|
+
return;
|
|
1165
|
+
const newChildren = [];
|
|
1166
|
+
let i = 0;
|
|
1167
|
+
while (i < tree.children.length) {
|
|
1168
|
+
const child = tree.children[i];
|
|
1169
|
+
if (child.type === "paragraph") {
|
|
1170
|
+
const text = extractTextContent(child);
|
|
1171
|
+
// Check for !!! type, ??? type, or ???+ type
|
|
1172
|
+
// Pattern: (!!!|???\+?) type ["Title"]\n body (4-space indented)
|
|
1173
|
+
if (text.startsWith("!!!") || text.startsWith("???")) {
|
|
1174
|
+
// Determine the marker: !!!, ???, or ???+
|
|
1175
|
+
let marker = "";
|
|
1176
|
+
let markerEnd = 3;
|
|
1177
|
+
if (text.startsWith("???+")) {
|
|
1178
|
+
marker = "???+";
|
|
1179
|
+
markerEnd = 4;
|
|
1180
|
+
}
|
|
1181
|
+
else if (text.startsWith("???")) {
|
|
1182
|
+
marker = "???";
|
|
1183
|
+
markerEnd = 3;
|
|
1184
|
+
}
|
|
1185
|
+
else if (text.startsWith("!!!")) {
|
|
1186
|
+
marker = "!!!";
|
|
1187
|
+
markerEnd = 3;
|
|
1188
|
+
}
|
|
1189
|
+
const afterMarker = text.slice(markerEnd);
|
|
1190
|
+
// Parse type name
|
|
1191
|
+
const typeMatch = afterMarker.match(/^\s+([a-zA-Z][\w-]*)/);
|
|
1192
|
+
if (typeMatch) {
|
|
1193
|
+
const type = typeMatch[1].toLowerCase();
|
|
1194
|
+
let remaining = afterMarker.slice(typeMatch[0].length);
|
|
1195
|
+
// Parse optional "Title" (quoted)
|
|
1196
|
+
let title;
|
|
1197
|
+
const titleMatch = remaining.match(/^\s+"([^"]*)"/);
|
|
1198
|
+
if (titleMatch) {
|
|
1199
|
+
title = titleMatch[1];
|
|
1200
|
+
remaining = remaining.slice(titleMatch[0].length);
|
|
1201
|
+
}
|
|
1202
|
+
// Must be followed by \n
|
|
1203
|
+
if (remaining.startsWith("\n")) {
|
|
1204
|
+
remaining = remaining.slice(1);
|
|
1205
|
+
// Only convert if the type is a known callout type
|
|
1206
|
+
if (configMap.has(type)) {
|
|
1207
|
+
const config = configMap.get(type);
|
|
1208
|
+
const customTitle = title !== undefined ? (title.trim() || undefined) : undefined;
|
|
1209
|
+
// Determine collapsible state from marker
|
|
1210
|
+
const collapsible = marker === "???" || marker === "???+";
|
|
1211
|
+
const collapsibleOpen = marker === "???+";
|
|
1212
|
+
const parsed = {
|
|
1213
|
+
type: type,
|
|
1214
|
+
customTitle,
|
|
1215
|
+
collapsible,
|
|
1216
|
+
collapsibleOpen,
|
|
1217
|
+
isDisclosure: false,
|
|
1218
|
+
};
|
|
1219
|
+
// Build body HTML from the remaining text
|
|
1220
|
+
// Strip 4-space indentation from each line
|
|
1221
|
+
const bodyLines = remaining.split("\n").map((line) => {
|
|
1222
|
+
if (line.startsWith(" "))
|
|
1223
|
+
return line.slice(4);
|
|
1224
|
+
return line;
|
|
1225
|
+
});
|
|
1226
|
+
const bodyHtml = bodyLines
|
|
1227
|
+
.map((line) => {
|
|
1228
|
+
if (line.trim() === "")
|
|
1229
|
+
return "";
|
|
1230
|
+
const escaped = options.allowDangerousHtml ? line : escapeHtml(line);
|
|
1231
|
+
return `<p>${escaped}</p>\n`;
|
|
1232
|
+
})
|
|
1233
|
+
.join("");
|
|
1234
|
+
const calloutHtml = buildCalloutFromParts(parsed, config, bodyHtml, options);
|
|
1235
|
+
newChildren.push(html(calloutHtml));
|
|
1236
|
+
i++;
|
|
1237
|
+
continue;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
newChildren.push(child);
|
|
1244
|
+
i++;
|
|
1245
|
+
}
|
|
1246
|
+
tree.children = newChildren;
|
|
1247
|
+
}
|
|
1248
|
+
// ---------------------------------------------------------------------------
|
|
1042
1249
|
// Helper: Build callout HTML from parsed parts (used by directive syntax)
|
|
1043
1250
|
// ---------------------------------------------------------------------------
|
|
1044
1251
|
function buildCalloutFromParts(parsed, config, bodyHtml, options) {
|
|
1045
|
-
//
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
const fakeBlockquote = {
|
|
1049
|
-
type: "blockquote",
|
|
1050
|
-
children: [
|
|
1051
|
-
{
|
|
1052
|
-
type: "paragraph",
|
|
1053
|
-
children: [{ type: "text", value: "" }],
|
|
1054
|
-
},
|
|
1055
|
-
],
|
|
1056
|
-
};
|
|
1057
|
-
// We need to call buildCalloutHtml which expects a real blockquote.
|
|
1058
|
-
// Instead, inline the essential rendering logic here.
|
|
1059
|
-
const title = parsed.customTitle || config.defaultTitle;
|
|
1252
|
+
// v1.4.0: i18n label customization
|
|
1253
|
+
const defaultTitle = options.labels?.[parsed.type] || config.defaultTitle;
|
|
1254
|
+
const title = parsed.customTitle || defaultTitle;
|
|
1060
1255
|
const dataAttr = options.dataCalloutType ? ` data-callout-type="${escapeAttribute(parsed.type)}"` : "";
|
|
1256
|
+
const collapsibleDataAttr = ` data-collapsible="${parsed.collapsible ? "true" : "false"}"`;
|
|
1061
1257
|
const safeIconColor = sanitizeColor(config.iconColor || config.color, "#57606a");
|
|
1062
1258
|
const ariaRole = "note";
|
|
1063
1259
|
const safeCalloutClass = escapeAttribute(options.calloutClass);
|
|
@@ -1065,10 +1261,32 @@ function buildCalloutFromParts(parsed, config, bodyHtml, options) {
|
|
|
1065
1261
|
const safeCalloutTitleClass = escapeAttribute(options.calloutTitleClass);
|
|
1066
1262
|
const safeCalloutBodyClass = escapeAttribute(options.calloutBodyClass);
|
|
1067
1263
|
const titleId = generateCalloutId(parsed.type);
|
|
1264
|
+
// v1.4.0: directive attributes
|
|
1265
|
+
let directiveId = "";
|
|
1266
|
+
let directiveClasses = "";
|
|
1267
|
+
let directiveAttrs = "";
|
|
1268
|
+
if (parsed.directiveAttrs) {
|
|
1269
|
+
if (parsed.directiveAttrs.id) {
|
|
1270
|
+
directiveId = ` id="${escapeAttribute(parsed.directiveAttrs.id)}"`;
|
|
1271
|
+
}
|
|
1272
|
+
if (parsed.directiveAttrs.classes && parsed.directiveAttrs.classes.length > 0) {
|
|
1273
|
+
directiveClasses = " " + parsed.directiveAttrs.classes.map(c => escapeAttribute(c)).join(" ");
|
|
1274
|
+
}
|
|
1275
|
+
if (parsed.directiveAttrs.attrs) {
|
|
1276
|
+
directiveAttrs = formatPropsAsAttrs(parsed.directiveAttrs.attrs);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1068
1279
|
const { showIcon, appearance } = resolveVisuals(parsed, options);
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1280
|
+
// v1.4.0: per-callout named icon
|
|
1281
|
+
let resolvedIcon = "";
|
|
1282
|
+
if (showIcon && appearance !== "simple" && appearance !== "hidden") {
|
|
1283
|
+
if (parsed.overrides?.iconName) {
|
|
1284
|
+
resolvedIcon = LUCIDE_ICONS[parsed.overrides.iconName] ?? resolveIcon(parsed.type, config, options.iconSet);
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
resolvedIcon = resolveIcon(parsed.type, config, options.iconSet);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1072
1290
|
const effectiveRenderIcon = showIcon && appearance !== "simple" && appearance !== "hidden" && resolvedIcon.length > 0;
|
|
1073
1291
|
const iconSpan = effectiveRenderIcon
|
|
1074
1292
|
? `<span class="callout-icon" style="color:${safeIconColor}" aria-hidden="true">${resolvedIcon}</span>`
|
|
@@ -1088,7 +1306,7 @@ function buildCalloutFromParts(parsed, config, bodyHtml, options) {
|
|
|
1088
1306
|
if (parsed.collapsible) {
|
|
1089
1307
|
const openAttr = parsed.collapsibleOpen ? " open" : "";
|
|
1090
1308
|
return [
|
|
1091
|
-
`<details class="${safeCalloutClass} ${safeConfigClassName} collapsible${appearanceClass}${inlineClass}"${dataAttr} role="${ariaRole}"${labelledby} dir="auto"${openAttr}>`,
|
|
1309
|
+
`<details class="${safeCalloutClass} ${safeConfigClassName} collapsible${appearanceClass}${inlineClass}${directiveClasses}"${dataAttr}${collapsibleDataAttr} role="${ariaRole}"${labelledby} dir="auto"${openAttr}${directiveId}${directiveAttrs}>`,
|
|
1092
1310
|
titleBlock.replace(/<div /, "<summary ").replace(/<\/div>$/, "</summary>"),
|
|
1093
1311
|
` <div class="${safeCalloutBodyClass}">`,
|
|
1094
1312
|
bodyHtml,
|
|
@@ -1097,7 +1315,7 @@ function buildCalloutFromParts(parsed, config, bodyHtml, options) {
|
|
|
1097
1315
|
].filter(Boolean).join("\n");
|
|
1098
1316
|
}
|
|
1099
1317
|
return [
|
|
1100
|
-
`<aside class="${safeCalloutClass} ${safeConfigClassName}${appearanceClass}${inlineClass}"${dataAttr} role="${ariaRole}"${labelledby} dir="auto">`,
|
|
1318
|
+
`<aside class="${safeCalloutClass} ${safeConfigClassName}${appearanceClass}${inlineClass}${directiveClasses}"${dataAttr}${collapsibleDataAttr} role="${ariaRole}"${labelledby} dir="auto"${directiveId}${directiveAttrs}>`,
|
|
1101
1319
|
titleBlock,
|
|
1102
1320
|
` <div class="${safeCalloutBodyClass}">`,
|
|
1103
1321
|
bodyHtml,
|
|
@@ -1125,6 +1343,11 @@ export const remarkRemakeBlocks = (userOptions) => {
|
|
|
1125
1343
|
if (options.enableDirectiveSyntax) {
|
|
1126
1344
|
transformDirectiveSyntax(tree, configMap, options);
|
|
1127
1345
|
}
|
|
1346
|
+
// v1.4.0: Pass 0b — Transform !!! note / ??? note / ???+ note MkDocs admonition syntax
|
|
1347
|
+
// into callouts (MkDocs Material content portability).
|
|
1348
|
+
if (options.enableMkDocsSyntax) {
|
|
1349
|
+
transformMkDocsSyntax(tree, configMap, options);
|
|
1350
|
+
}
|
|
1128
1351
|
// ── Pass 1: Transform blockquotes → callouts / disclosures ──────
|
|
1129
1352
|
// We must process DEEPEST blockquotes first (inside-out) so that
|
|
1130
1353
|
// nested [!] directives are converted before their parents read them.
|