@dr-ishaan/remake-blocks 1.4.2 → 1.4.3
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/README.md +96 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -586,6 +586,102 @@ GFM-only features like tables, autolinks, and task list items require the `remar
|
|
|
586
586
|
|
|
587
587
|
---
|
|
588
588
|
|
|
589
|
+
## How It Works: Parsing Pipeline
|
|
590
|
+
|
|
591
|
+
The plugin processes markdown through 4 passes. Each syntax is detected at a different stage:
|
|
592
|
+
|
|
593
|
+
### Pass overview
|
|
594
|
+
|
|
595
|
+
| Pass | Name | When it runs | What it detects | Output |
|
|
596
|
+
|------|------|-------------|-----------------|--------|
|
|
597
|
+
| 0a | Directive syntax transformer | `enableDirectiveSyntax: true` | `:::type[Title]{attrs}` ... `:::` paragraphs | Callout HTML node |
|
|
598
|
+
| 0b | MkDocs syntax transformer | `enableMkDocsSyntax: true` | `!!! type`, `??? type`, `???+ type` paragraphs | Callout HTML node |
|
|
599
|
+
| 1 | Blockquote callout transformer | Always runs | `> [!TYPE]` in blockquote nodes | Callout HTML node or enhanced blockquote |
|
|
600
|
+
| 2 | Accordion grouping | `enableAccordion: true` | Consecutive disclosure `<details>` nodes | `<div class="disclosure-accordion">` wrapper |
|
|
601
|
+
|
|
602
|
+
### Syntax detection methods
|
|
603
|
+
|
|
604
|
+
| Syntax | How remark-parse sees it | How the plugin detects it | Key parsing logic |
|
|
605
|
+
|--------|------------------------|--------------------------|-------------------|
|
|
606
|
+
| **Blockquote** (`> [!NOTE]`) | `blockquote` → `paragraph` → `text` starting with `[!TYPE]` | Regex on first text child: `^\[!(NOTE\|TIP\|...)\]([+-]?)(title)?({overrides})?` | Dynamically built regex from registered types + aliases + empty string for `[!]` disclosures |
|
|
607
|
+
| **Directive** (`:::note`) | `paragraph` → `text` containing entire `:::type...\n:::` block | `text.startsWith(":::")` → count colons → extract type → parse `[Title]` → parse `{attrs}` → find closing `:::` | String methods (not regex `^` — avoids Node.js anchor issue); body is everything between opening and closing lines |
|
|
608
|
+
| **MkDocs** (`!!! note`) | `paragraph` → `text` containing entire `!!! type\n body` block | `text.startsWith("!!!")` or `text.startsWith("???")` → extract marker → extract type → parse `"Title"` → body is 4-space indented | String methods; strips 4-space indent from each body line |
|
|
609
|
+
|
|
610
|
+
### Blockquote callout regex capture groups
|
|
611
|
+
|
|
612
|
+
| Group | Content | Example | Used for |
|
|
613
|
+
|-------|---------|---------|----------|
|
|
614
|
+
| `[1]` | Type name (or empty for `[!]`) | `note`, `warning`, `""` | Look up callout config or identify as disclosure |
|
|
615
|
+
| `[2]` | Fold marker | `+`, `-`, or `""` | `+` = expanded collapsible, `-` = collapsed, `""` = not collapsible |
|
|
616
|
+
| `[3]` | Custom title text | `Breaking Change` | Override default title |
|
|
617
|
+
| `[4]` | Overrides block | `{icon=false appearance=minimal}` | Parsed by `parseOverrides()` + `parseDirectiveAttrs()` |
|
|
618
|
+
|
|
619
|
+
### Disclosure widget detection
|
|
620
|
+
|
|
621
|
+
The `[!]` syntax is detected in the **same blockquote pass** as regular callouts. The key difference is an **empty string** added to the regex alternatives:
|
|
622
|
+
|
|
623
|
+
| Aspect | Regular callout (`> [!NOTE]`) | Disclosure (`> [!]`) |
|
|
624
|
+
|--------|------------------------------|---------------------|
|
|
625
|
+
| **Type name** | `note`, `warning`, etc. | `disclosure` (synthetic) |
|
|
626
|
+
| **Config lookup** | `configMap.get(type)` → icon, color, className | No config — plain |
|
|
627
|
+
| **Icon** | SVG icon from iconSet | None |
|
|
628
|
+
| **Color** | Per-type border/bg colors | None (gray left line only) |
|
|
629
|
+
| **CSS class** | `callout callout-note` | `disclosure` |
|
|
630
|
+
| **Container** | `<aside>` or `<details>` | Always `<details>` |
|
|
631
|
+
| **Collapsible** | Only if `+`/`-` marker present | Always collapsible |
|
|
632
|
+
| **Default title** | From config (e.g., "Note") | "Details" |
|
|
633
|
+
| **data-callout-type** | `note`, `warning`, etc. | Not set |
|
|
634
|
+
| **role** | `role="note"` | Not set (uses native `<details>`) |
|
|
635
|
+
| **Left accent line** | Colored (matches callout type) | Gray (`#d0d7de`) |
|
|
636
|
+
| **Fold markers** | `+`/`-` = collapsible, none = not collapsible | `+`/none = expanded, `-` = collapsed |
|
|
637
|
+
|
|
638
|
+
### `{overrides}` block parsing
|
|
639
|
+
|
|
640
|
+
Two parsers run on the `{...}` block (used by all 3 syntaxes):
|
|
641
|
+
|
|
642
|
+
| Parser | Input pattern | Output keys | Purpose |
|
|
643
|
+
|--------|--------------|-------------|---------|
|
|
644
|
+
| `parseOverrides()` | `icon=false`, `appearance=minimal`, `inline`, `icon="rocket"` | `overrides.icon`, `overrides.appearance`, `overrides.inline`, `overrides.iconName` | Plugin-specific per-callout visual overrides |
|
|
645
|
+
| `parseDirectiveAttrs()` | `#my-id`, `.custom-class`, `data-x="y"` | `directiveAttrs.id`, `directiveAttrs.classes`, `directiveAttrs.attrs` | remark-directive compatible HTML attributes |
|
|
646
|
+
|
|
647
|
+
### Override keys reference
|
|
648
|
+
|
|
649
|
+
| Key | Values | Effect | Example |
|
|
650
|
+
|-----|--------|--------|---------|
|
|
651
|
+
| `icon` | `false`, `true`, `"name"` | Hide icon / show icon / use named Lucide icon | `{icon=false}`, `{icon="rocket"}` |
|
|
652
|
+
| `appearance` | `default`, `minimal`, `simple`, `hidden` | Visual density variant | `{appearance=minimal}` |
|
|
653
|
+
| `inline` | `inline`, `inline-end` (or bare keywords) | Float left / float right (responsive) | `{inline}`, `{inline-end}` |
|
|
654
|
+
| `fold` | `+`, `-` | Collapsible expanded / collapsed (directive syntax only) | `{fold=-}` |
|
|
655
|
+
| `#id` | Any valid HTML id | Sets element id | `{#my-section}` |
|
|
656
|
+
| `.class` | Any valid CSS class name | Adds CSS class | `{.highlight}` |
|
|
657
|
+
| `key="value"` | Any key/value pair | Adds HTML attribute (event handlers and `style` blocked) | `{data-type="example"}` |
|
|
658
|
+
|
|
659
|
+
### Processing order
|
|
660
|
+
|
|
661
|
+
| Step | What happens | Why this order |
|
|
662
|
+
|------|-------------|----------------|
|
|
663
|
+
| 1. remark-parse | Raw markdown → mdast tree | Must happen before plugin (external) |
|
|
664
|
+
| 2. Pass 0a: Directive | `:::type` paragraphs → callout HTML | Must run before blockquote pass (directive paragraphs are not blockquotes) |
|
|
665
|
+
| 3. Pass 0b: MkDocs | `!!! type` paragraphs → callout HTML | Same reason — paragraph-level, not blockquote-level |
|
|
666
|
+
| 4. Pass 1: Blockquote | `> [!TYPE]` blockquotes → callout HTML | Processes deepest blockquotes first (inside-out) so nested callouts are resolved before parents |
|
|
667
|
+
| 5. Pass 2: Accordion | Groups consecutive disclosure `<details>` | Must run after all disclosures are rendered |
|
|
668
|
+
|
|
669
|
+
### `ParsedCallout` object (internal)
|
|
670
|
+
|
|
671
|
+
All 3 syntaxes produce the same `ParsedCallout` object, which is passed to `buildCalloutHtml()`:
|
|
672
|
+
|
|
673
|
+
| Field | Type | Source | Description |
|
|
674
|
+
|-------|------|--------|-------------|
|
|
675
|
+
| `type` | `string` | Regex group [1] | Callout type (lowercased) or `"disclosure"` |
|
|
676
|
+
| `customTitle` | `string \| undefined` | Regex group [3] or `[Title]` or `"Title"` | User-provided title (overrides default) |
|
|
677
|
+
| `collapsible` | `boolean` | Fold marker or `???`/`???+` | Whether callout is collapsible |
|
|
678
|
+
| `collapsibleOpen` | `boolean` | `+` marker or `???+` or no marker (disclosures) | Whether collapsible starts expanded |
|
|
679
|
+
| `isDisclosure` | `boolean` | Empty type match | True for `[!]` syntax |
|
|
680
|
+
| `overrides` | `object \| undefined` | `{overrides}` block via `parseOverrides()` | Per-callout icon/appearance/inline overrides |
|
|
681
|
+
| `directiveAttrs` | `object \| undefined` | `{attrs}` block via `parseDirectiveAttrs()` | Per-callout id/class/HTML attributes |
|
|
682
|
+
|
|
683
|
+
---
|
|
684
|
+
|
|
589
685
|
## Advanced: Using the Remark Plugin Directly
|
|
590
686
|
|
|
591
687
|
The remark plugin can be used independently of the Astro integration:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dr-ishaan/remake-blocks",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "Astro 6 + remark plugin — 27 callout types, 4 themes, disclosure widgets, inline callouts, directive syntax, MkDocs syntax, i18n labels, safe-by-default XSS escaping, WCAG accessibility, Lucide/emoji icons",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|