You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bugs fixed:
- Normalize CRLF line endings at file-read boundary
- Error on diff-step + side-by-side (was silently discarding diff)
- Error on diff-reference + diff-step on same block (was silently
ignoring diff-step)
Code smells addressed:
- Extract parseFlags() helper (eliminates duplicated flag parsing)
- Consolidate resolveRef() last 2 params into opts bag
- Deduplicate LINE_RANGE_RE (export from extract-lines, import in index)
- Add (?:^|\s) anchoring to REF_REGEX, DIFF_REF_REGEX, DIFF_STEP_REGEX
- Remove unnecessary .* prefix from PRESET_STRIP.markers patterns
Project config:
- Add unified as peerDependency
- Add build + CJS smoke test to CI
- Add TypeScript declarations (index.d.mts)
- Document tab groups in README with tabGroupClass in Options table
Test coverage:
- CRLF fixture + region/line-range tests
- Backslash-escaped spaces in file= paths
- CJS entry point regression test (subprocess-based)
- Focused cleanDiffMeta tests (8 tests for order-sensitive stripping)
- Duplicate region name behavior documented in test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .github/workflows/ci.yml
+6Lines changed: 6 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -26,5 +26,11 @@ jobs:
26
26
- name: Lint
27
27
run: npm run lint
28
28
29
+
- name: Build
30
+
run: npm run build
31
+
32
+
- name: Verify CJS bundle
33
+
run: node -e "const p = require('./index.cjs'); if (typeof p !== 'function') { console.error('CJS export is not a function:', typeof p); process.exit(1); }"
Copy file name to clipboardExpand all lines: README.md
+55Lines changed: 55 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -378,6 +378,60 @@ The reader sees complete, copyable code at every step -- with green/red highligh
378
378
| Output | Diff only | Full current code with change annotations |
379
379
| Default format |`unified` (+/- prefixes) |`inline-annotations` (Shiki highlights) |
380
380
381
+
## Tab groups
382
+
383
+
Group consecutive code fences into tabs using the `tab` attribute. Each fence is processed independently (reference extraction, strip, transmute, diff — everything works), then consecutive `tab` fences are wrapped in a `tabGroup` AST node.
Bare `tab` (no value) derives the label from the language tag: `` ```python tab `` → label "Python".
418
+
419
+
### Sync key
420
+
421
+
Use `tab-group="id"` to synchronize tab selection across multiple tab groups on a page (like Docusaurus `groupId` or Starlight `syncKey`). Clicking "Python" in one group switches all groups with the same sync key.
To split adjacent tab groups without visible content between them, use an HTML comment (`<!-- -->`), which creates an invisible node that breaks the consecutive grouping.
428
+
429
+
### AST output
430
+
431
+
The plugin emits `tabGroup` wrapper nodes with `data.hName = 'div'` and `data.hProperties.class = 'code-tabs'` (customizable via `tabGroupClass` option). Each child code node gets `data.tabLabel` and `data.hProperties['data-tab']`.
432
+
433
+
Without a companion plugin, this renders as a `<div class="code-tabs">` wrapping stacked `<pre><code>` blocks. Framework-specific companion plugins (coming soon) will transform these into native Docusaurus `<Tabs>`, Starlight tabs, etc.
434
+
381
435
## Auto-dedent
382
436
383
437
Extracted regions are automatically dedented. Common leading whitespace is removed so that code nested inside test functions or classes renders flush-left in your docs.
0 commit comments