37 KiB
Slidev Export Workflow Verification
Language: English | 简体中文
This document is for maintainers. It defines the verification workflow for the NoteMD Slidev export UI path.
Why This Workflow Exists
Directly running slidev build proves the local Slidev CLI can build a deck, but it does not prove the NoteMD export buttons work.
The NoteMD workflow must verify all of these steps together:
- The active Markdown note is converted into a real Slidev deck before export.
- The full Slidev skill directory is discovered, including
references/*.md, not onlySKILL.md. - The local Slidev fork is preferred when present.
- Existing Slidev decks are copied into an isolated prepared working workspace before verification so patch/retry never mutates the source note directly and sibling Slidev support entries plus explicitly referenced local assets can be mirrored into the working copy.
- The output directory is recreated before each HTML build so stale chunks cannot survive.
- Generated deck guardrails normalize theme and slide frontmatter, strip generated Mermaid slide
zoomso rendered audit owns measured fit, and reject LLM-generated decks that change source Mermaid fences before the prepared deck is written. - HTML export attempts native standalone first, records the actual HTML mode, and falls back to server-script-compatible HTML only when the generated standalone bundle really misses slide loader bindings.
- The final HTML output is opened by a real browser check, auditing the full deck by default.
- Generated inspection artifacts remain visible to Git and are not accidentally hidden by
.gitignore.
Maintainer Command
Run the real workflow against the docs vault and the architecture note:
npm run verify:slidev-export
The default source is:
docs/architecture.zh-CN.md
The command writes the same kind of artifacts the UI writes:
docs/export/_slidev-sources/architecture.zh-CN.slidev.md
docs/export/architecture.zh-CN-slides/index-standalone.html
or docs/export/architecture.zh-CN-slides/index.html when standalone falls back
docs/export/architecture.zh-CN-slides/slide-*-workflow.png
For a quieter machine-readable run:
npm run verify:slidev-export -- --no-screenshots --json
To make a native standalone claim, do not rely on the compatibility default alone. Run the strict gate:
npm run verify:slidev-export -- --format html --html-mode standalone --require-native-standalone --source architecture.zh-CN.md --json
This must report htmlExport.actualMode: "standalone" and standaloneGate.passed: true.
To test another vault-relative source:
npm run verify:slidev-export -- --source path/to/source.md
To run the heavier synthetic full-deck layout fixtures without committing generated files:
npm run verify:slidev-layout-fixtures -- --archive /home/jacob/slidev-export-review/2026-06-20-full-deck-layout-fixtures
This command creates temporary vaults outside the repository, runs the production verifier, and archives the source fixture, final deck, report, and standalone export. Use it when layout audit, Mermaid fit, table/code splitting, text measurement, or slot Transform behavior changes.
The current expanded fixture archive is:
/home/jacob/slidev-export-review/2026-06-20-expanded-layout-fixtures/
The current Stage 12 fixture archive is:
/home/jacob/slidev-export-review/2026-06-20-stage12-mixed-component-prose-fixtures/
It adds mixed-component-prose-stress, proving that a custom dashboard-shell slide with one complete Vue component surface and one Markdown prose/list content block can first be separated into independent presentation surfaces. The component page can then converge through measured local <Transform>, while the prose page does not inherit whole-slide zoom. The suite still requires Mermaid fences to remain byte-stable, must not split one source Mermaid diagram into several diagrams, and must not rewrite fence metadata or diagram bodies.
Stage 13/14 add expected-failure fixtures for unsafe component/table, component/fence, and component/image boundaries:
npm run verify:slidev-layout-fixtures -- --fixture unsupported-component-table-boundary-stress --archive /home/jacob/slidev-export-review/2026-06-20-stage13-unsupported-component-boundary-fixture --timeout-ms 300000
npm run verify:slidev-layout-fixtures -- --fixture unsupported-component-fence-boundary-stress --archive /home/jacob/slidev-export-review/2026-06-20-stage14-unsupported-component-fence-boundary-fixture --timeout-ms 300000
npm run verify:slidev-layout-fixtures -- --fixture unsupported-component-image-boundary-stress --archive /home/jacob/slidev-export-review/2026-06-20-stage14-unsupported-component-image-boundary-fixture --timeout-ms 300000
These fixtures pass only when the production verifier reports ok = false, the blocked reason includes mixed component and primary Markdown content cannot be fixed with whole-slide zoom, and native standalone export, browser loading, Git-visible artifacts, the failure fingerprint, and Mermaid source preservation all remain valid. The image fixture also requires the local SVG asset to exist in both the prepared deck and final standalone export. The default fixture suite excludes expected failures; pass --include-expected-failures only when explicitly auditing fail-transparent boundaries.
For a live desktop-session smoke against the real Obsidian command path:
obsidian open path=architecture.zh-CN.md vault=/home/jacob/obsidian-NotEMD/docs
obsidian command id=notemd:export-slides vault=/home/jacob/obsidian-NotEMD/docs
On 2026-06-18 this command executed successfully in Jacob's docs vault. It is a real host-command smoke, not a DOM click automation pass.
The strict standalone acceptance index for the real architecture.zh-CN.md run is tracked in:
docs/maintainer/slidev-standalone-acceptance-2026-06-18.md
Passing Criteria
Treat the command as passing only when the final JSON report has:
ok: trueenvironment.capabilities.html: trueenvironment.slidev.versionshowing the local fork path when the fork is installedslideSource.skillRootPathset to the resolved Slidev skill directoryslideSource.skillReferenceCountgreater than zerodeck.themeequal to the configured theme, normallydefaultdeck.containsKnownStaleText: falsedeck.containsMissingTheme: false- every
playwright[].failedvalue equal tofalse ignoredOutputs: []layoutAuditSummary.overflowCount: 0layoutAuditSummary.unreadableCount: 0- for strict native standalone closure,
htmlExport.actualMode: "standalone" - for strict native standalone closure,
htmlExport.requiresLocalServer: false - for strict native standalone closure,
htmlExport.standaloneAttempt.loaderGaps: [] - for strict native standalone closure,
standaloneGate.passed: true - when the source contains Mermaid fences, the exported deck preserves the same Mermaid fence count, order, fence metadata, and exact fence body unless a human explicitly edits the source.
- mixed Mermaid/prose slides must not retain low whole-slide zoom; if non-Mermaid content can be moved, the Mermaid fence opener, metadata, body, and closer stay byte-stable on a Mermaid-focused slide and only non-Mermaid prose moves to a readable slide.
- existing local
<Transform>wrappers, including non-slot single-surface wrappers, must not be compounded with later whole-slidezoom. - mixed component/prose slides must not retain whole-slide zoom when a safe component/prose boundary exists; if the boundary is unsafe, the patcher should block whole-slide zoom and surface blocked/manual-review instead of shrinking prose.
- expected-failure fixtures should not be treated as normal regressions just because verifier
ok = false; they must prove the intended failure reason, native standalone environment, artifact visibility, and source preservation. The default success suite must still contain onlyok = trueconverging fixtures.
If any check fails, fix the NoteMD workflow before relying on the exported files.
Rendered Layout Quality Gate
The current workflow proves that the UI-equivalent export path creates a deck and that the full prepared deck can open in a browser. That is necessary because dense architecture notes can still build successfully while Mermaid diagrams, tables, code blocks, or long text are clipped by Slidev's fixed 16:9 canvas.
The current implementation now includes a shared render-feedback gate after deck generation, used by maintainer verification and by the real product export command whenever Playwright is available:
- wait for
document.fonts.ready, image decode, and Mermaid rendering before measuring; - inspect every audited slide for DOM bounding boxes outside the actual visible slide root, scroll overflow, Mermaid container overflow, table natural width overflow, and code block overflow;
- classify each finding as
overflow,unreadable-scale,stale-output, orrender-error; - patch and retry the prepared working deck with bounded rendered-evidence rewrites, currently up to 6 passes;
- fail closed with an audit report when the visible slide root still clips content after those retries.
Use ref/infinite-canvas only as a clean-room design reference. The useful idea is not to embed an infinite canvas in Slidev export; it is to model generated slide elements as measurable world rectangles, compute union bounds, and derive a fit camera for the fixed Slidev safe rectangle. When fitting would make content unreadable, only non-Mermaid table/code/prose/component presentation surfaces may be structurally split or locally transformed. Mermaid must remain one source fence to one exported fence, with source-preserved-fit-review or manual-review surfacing quality risk. Do not copy AGPL-3.0 implementation code into this MIT project.
The report shape now separates the hard gate from the quality gate. It records:
layoutAudit[].slide
layoutAudit[].findings[]
layoutAudit[].safeRect
layoutAudit[].contentBounds
layoutAudit[].effectiveMinFontPx
layoutAudit[].svgTextMinFontPx
layoutAudit[].tableBodyMinFontPx
layoutAudit[].codeMinFontPx
layoutAudit[].qualityMargins
layoutAudit[].contentAreaRatio
layoutAudit[].mermaidFit.status
layoutAudit[].mermaidFit.reason
layoutAudit[].mermaidFit.pageScale
layoutAudit[].mermaidFit.fitScale
layoutAudit[].mermaidFit.nextZoom
layoutAudit[].mermaidFit.diagramBounds
layoutAudit[].mermaidFit.effectiveMinFontPx
layoutAudit[].mermaidFit.svgTextMinFontPx
layoutAudit[].mermaidFit.qualityMargins
layoutAudit[].mermaidFit.contentAreaRatio
layoutAudit[].mermaidFit.lowZoom
layoutAudit[].mermaidFit.lowFont
layoutAudit[].mermaidFit.tightMargin
layoutAudit[].recommendedPatch
layoutAuditSummary.hardOverflowCount
layoutAuditSummary.unreadableScaleCount
layoutAuditSummary.lowEffectiveFontCount
layoutAuditSummary.qualityMarginWarningCount
layoutAuditSummary.lowContentUtilizationCount
layoutAuditSummary.preSplitCount
layoutAuditSummary.postPatchCount
layoutAuditSummary.mermaidSlideCount
layoutAuditSummary.mermaidFitReviewCount
layoutAuditSummary.mermaidLowZoomCount
layoutAuditSummary.mermaidManualReviewCount
layoutAuditSummary.retryCount
mermaidSourcePreservation.required
mermaidSourcePreservation.passed
mermaidSourcePreservation.sourceFenceCount
mermaidSourcePreservation.deckFenceCount
mermaidSourcePreservation.changedFenceIndexes
For Mermaid, mermaidFit.status is source-preserving evidence, not permission to rewrite or split a user diagram. fits means the preserved diagram satisfies the current rendered thresholds. source-preserved-fit-review means the deck remains structurally valid but should be visually reviewed, usually because zoom is low or margins are tight. manual-review means the preserved source diagram and presentation readability are in tension; the workflow must surface that fact instead of silently splitting the diagram.
mermaidSourcePreservation is a stricter structural gate: when the source note has Mermaid fences, the verifier compares each exported Mermaid fence against the corresponding source fence. A count-only match is not enough; changed content, reordered fences, changed fence metadata, or one source diagram rewritten as several diagrams must fail the report.
The same invariant is enforced earlier in source preparation: one-shot LLM generation and outline-continuation LLM generation compare source and candidate Mermaid fences before writing _slidev-sources. If the candidate changes count, order, fence metadata, or body text, the workflow falls back to deterministic source-preserving deck preparation.
The detailed implementation direction is tracked in docs/brainstorms/2026-06-20-slidev-layout-quality-and-canvas-roadmap.zh-CN.md. That route keeps the current render-feedback loop as the final fact gate, adds a clean-room layout planning IR before generation, and translates the world-rect / viewport-fit ideas from ref/infinite-canvas into NoteMD-owned geometry logic instead of copying AGPL-3.0 implementation code or embedding an infinite-canvas UI in Slidev export.
Current landed truth as of 2026-06-20:
- default HTML verification audits the full prepared deck when
--sample-slidesis not provided; - the patcher derives
zoomfrom measured overflow instead of fixed export constants; - the patcher preserves source Mermaid fences by default; structural splitting applies to Markdown tables, pathological width-heavy or long-cell tables through record-list fallback, non-Mermaid fenced code blocks, simple heading + paragraph/list slides, generic slot-marked layouts (including explicit
::default::), and first-slide deck headmatter content when structural splitting is possible; - generated Mermaid slide guardrails no longer seed or trust LLM-chosen
zoom; generated Mermaid zoom is stripped before_slidev-sourcesis written, while existing user-authored Slidev decks keep their explicit source settings in the isolated working copy; - existing Slidev decks now use isolated prepared working-copy directories under
_slidev-sources/<deck-basename>/, and common sibling Slidev support entries such aslayouts/,public/,setup/,components/,snippets/,styles/,global-top.vue, andglobal-bottom.vueare mirrored into that workspace when present; - rendered layout audit now also measures direct-text
div/section/article/aside/spanblocks, so component-heavy slides do not silently under-audit as empty layouts; - component-heavy slot zones now carry lightweight owner wrappers inside prepared working copies, and rendered measurement now records zone-level owner rects, content bounds, scroll overflow, and recommended local transform scales for those zones;
- slot-owned descendants are now measured even when
overflow-hiddenclips them out of the current viewport, so the audit no longer silently undercounts component-heavy slot content just because the slot container hides the overflow; - component-heavy custom slot layouts can now fall back to local
<Transform :scale=\"...\">wrapping for overflowing slot zones when structural splitting is unavailable; that scale is derived from the detected out-of-bounds geometry and scroll overflow of the current slot-owner surface instead of fixed constants or manual LLM choice; when several component-heavy zones overflow independently, the patcher can now wrap each transformable zone in the same pass, and when a unique owner still must be chosen it prefers zone-level geometry first and falls back to slot signals / rendered text hints only when geometry ties; - hard overflow findings still use the rendered slide root as the pass/fail boundary, while
safeRectremains the fit target for measured scale recommendations; this keeps edge-aligned layouts from being over-rejected while still letting the patcher derive conservative shrink factors; - the shared
convergeSlidevDeckLayout()workflow now runs insideexportSlidesCommand()and the maintainer verifier, so HTML/PDF/PNG/MP4 export all reuse the same converged prepared deck; - the HTML exporter now returns a structured outcome with
requestedMode,actualMode, fallback state, and standalone sanity details; known-bad native attempts are preserved asindex-standalone.failed.htmlbefore compatibility fallback; - the real
docs/architecture.zh-CN.mdstrict native standalone workflow now closes withok: true,actualMode: "standalone",requiresLocalServer: false,standaloneGate.passed: true,27audited slides, and zero hard overflow / unreadable scale / low effective font / quality margin warning / low utilization findings withretryCount = 4; the preserve-Mermaid run kept the source and exported deck at3Mermaid fences, and current verifier reports must also showmermaidSourcePreservation.passed = true; the current Stage 14 evidence package is stored at/home/jacob/slidev-export-review/2026-06-20-stage14-real/; PDFandPNGverification on the same source also returnok: true, and now export from the same converged deck instead of the raw prepared source;- rendered layout audit now reports effective minimum font, SVG text font, table/code minimum font, quality margins, and content-area ratio alongside hard overflow;
- low effective font, tight margin, and low content utilization findings now carry structural
recommendedPatchvalues for table/code/prose; Mermaid low-font metrics are recorded while preserving the source fence instead of automatically splitting one diagram into several diagrams; - source preparation now builds a clean-room
SlideLayoutPlanand injects its deterministic layout budget into generated outlines, one-shot Slidev deck prompts, and outline-continuation prompts. - rendered layout audit now also reports
mermaidFitand the matching summary counters so low Mermaid zoom, low Mermaid font, and manual-review cases remain visible without mutating the original Mermaid fence; the realarchitecture.zh-CN.mdrerun reportsmermaidSlideCount = 3,mermaidFitReviewCount = 3,mermaidLowZoomCount = 2, andmermaidManualReviewCount = 1. - table/code quality splitting now has a second structural slice: long table cells convert to key-value record-list slides, and code fences split by semantic blocks before falling back to blank-line or line-budget chunking.
- effective font measurement now multiplies each text sample by local CSS
transform, independentscale, and CSSzoomfrom the text node up to the slide root, so content wrapped in local<Transform>is judged by its rendered size instead of its unscaled computed font size. - TypeScript and JavaScript code fences now use a lightweight top-level tokenizer before generic semantic splitting, so contiguous import groups and top-level type/function/class/const declarations stay intact when a dense code slide is distributed across several slides.
- Mermaid source preservation now has explicit regression tests: even if a Mermaid slide is mistakenly routed toward a code structural patch, the patcher must not treat one
mermaidfence as a splittable code block; if one-shot or outline-continuation LLM generation changes source Mermaid fences, source preparation must reject the candidate before writing the prepared deck. - Python and Rust code fences now also use lightweight top-level tokenizers before generic semantic splitting, preserving Python import groups, decorators, top-level class/function blocks, Rust use groups, attributes, and top-level struct/enum/trait/impl/fn/mod items.
- Stage 5 fixture coverage now separates
source-preserved-fit-reviewfrommanual-reviewfor preserved Mermaid diagrams and uses a Playwright measurement fixture to prove record-list table fallback renders as readable text instead of an overflowing table. - synthetic full-deck layout fixtures now run through the production verifier:
source-layout-stresscovers full skill references, native standalone, preserved Mermaid fences, record-list fallback, and code splitting;slot-component-stresscovers component-heavy slot Transform convergence without whole-slide zoom stacking. The 2026-06-20 archive is/home/jacob/slidev-export-review/2026-06-20-full-deck-layout-fixtures/. - text overflow measurement now uses text-node Range glyph rectangles for text elements instead of block-level element boxes, so layouts are not failed because an
h1block is wider than its actual visible text. - Mermaid-only slides may apply a measured low zoom to keep one preserved source diagram fully visible; the readability risk is surfaced through
mermaidFit.manual-reviewinstead of splitting or rewriting the source diagram. - mixed Mermaid/prose slides now move non-Mermaid primary content before permitting source-preserved Mermaid fit; every source Mermaid fence remains one byte-stable fence with unchanged opener, metadata, body, and closer, and unsupported mixed layouts block low whole-slide zoom instead of shrinking prose.
- prepared deck workspaces now copy explicit local relative assets referenced by Markdown images, HTML media/link/srcset attributes, and Slidev frontmatter keys such as
background,image,src,favicon,poster, anddownload; local CSS files referenced by the deck are then parsed as a local dependency graph, includingurl(...)image/font dependencies and local@importstylesheet chains relative to each CSS file location. URLs, absolute paths, null bytes, and out-of-scope traversal are rejected, copied CSS removes or neutralizes those rejected local references, and the source directory is not copied wholesale. - the local Slidev fork's standalone bundler now uses brace-balanced function replacement when stubbing Vite preload helpers, preventing the first slide loader binding from being deleted. The NoteMD strict standalone gate remains fail-closed and still reports loader gaps instead of accepting fallback output as native standalone.
- after native standalone or server-script HTML build, the exporter syncs the prepared deck's explicit local file references, CSS
url(...)dependencies, and local CSS@importchains into the final<source>-slides/directory so frontmatter backgrounds, image layouts, favicons, posters, linked CSS files, imported CSS files, local fonts, and local CSS background images do not resolve back to the temporary prepared workspace; rejected CSS imports/URLs are removed or neutralized in the copied CSS so standalone output does not request missing local files. - prepared decks inject
fonts.provider: nonewhen no explicit top-levelfonts:config exists, avoiding strict standalone verification failures caused by remote Google Fonts fetches; explicit user font configuration is preserved. - the 2026-06-20 CSS asset dependency closeout archive is
/home/jacob/slidev-export-review/2026-06-20-css-asset-dependencies-final/; the realarchitecture.zh-CN.mdstrict standalone report isok = true,actualMode = "standalone",requiresLocalServer = false,standaloneGate.passed = true,skillReferenceCount = 52, andmermaidSourcePreservation.passed = true. - the 2026-06-20 CSS import/media fixture archive is
/home/jacob/slidev-export-review/2026-06-20-css-import-media-fixtures/; the production fixture suite now covers recursive local CSS@import, imported CSS font/background dependencies, local video/audio/track/poster assets, CSS sanitizer behavior, and rejection of out-of-scope imported stylesheets in both prepared workspace and final standalone export. - generated test export artifacts are no longer tracked under
docs/export/test-slidev-*,docs/export/test-slidev.pdf,docs/export/test-slidev-video.mp4, or the olddocs/export/slides/; keep future generated Slidev outputs as external evidence packages unless a task explicitly asks to commit a reviewed artifact. - the 2026-06-20 font-safe slot/code convergence archive is
/home/jacob/slidev-export-review/2026-06-20-competing-slot-zones-final-fixtures-v2/; slot-zone audit now records each zone's minimum effective font and minimum readable local Transform scale, and both local<Transform>and whole-slidezoomreject scale values that would push non-Mermaid text below the font floor. - multiple component-heavy named slots that cannot be locally transformed at a readable scale are split into independent default canvases while preserving
data-notemd-slot-zoneevidence; table/code structural splitting also triggers when the font floor rejects zoom, with chunk count derived from the measured fit factor. - the matching real
architecture.zh-CN.mdstrict standalone archive is/home/jacob/slidev-export-review/2026-06-20-font-safe-real/; the report isok = true, uses Jacob's local Slidev fork, loads 52 skill references, outputs native standalone HTML, passes Mermaid source preservation, and archives the reviewablearchitecture.zh-CN.slidev.md. - bounded raw HTML/component single-surface custom layouts can now use measured local
<Transform>convergence withoutdata-notemd-slot-zonewrappers. Thecustom-single-surface-component-stressfixture keepslayout: surface-shell, preserves the component surface content, and rejects the previous regression where a local Transform was compounded with whole-slidezoom. - the Stage 9 real
architecture.zh-CN.mdstrict standalone archive is/home/jacob/slidev-export-review/2026-06-20-stage9-architecture-real/; the report isok = true, uses Jacob's local Slidev fork, loads 52 skill references, outputs native standalone HTML, preserves all 3 Mermaid fences withchangedFenceIndexes = [], and archives the reviewablearchitecture.zh-CN.stage9.slidev.md. - bounded component-only Vue tree surfaces can now use the same measured local
<Transform>convergence path. Thecustom-vue-component-tree-stressfixture covers multiline component openers, multiline prop arrays, nested components, and named template slots while keepinglayout: dashboard-shell, avoidingdata-notemd-slot-zone, and avoiding whole-slidezoom. - the Stage 10 real
architecture.zh-CN.mdstrict standalone archive is/home/jacob/slidev-export-review/2026-06-20-stage10-architecture-real/; the report isok = true, uses Jacob's local Slidev fork, loads 52 skill references, outputs native standalone HTML, preserves all 3 Mermaid fences withchangedFenceIndexes = [], closes withhardOverflowCount = 0andlowEffectiveFontCount = 0, and archives the reviewablearchitecture.zh-CN.stage10.slidev.md. - the Stage 11 Mermaid source-boundary archive is
/home/jacob/slidev-export-review/2026-06-20-stage11-mermaid-source-boundary/; new regression tests cover inline Mermaid fence metadata after mixed Mermaid/prose content movement and reject LLM candidates that only change Mermaid fence metadata. The realarchitecture.zh-CN.mdstrict native standalone report isok = true,actualMode = "standalone",requiresLocalServer = false,mermaidSourcePreservation.passed = true,changedFenceIndexes = [],hardOverflowCount = 0, andlowEffectiveFontCount = 0, with the reviewablearchitecture.zh-CN.stage11.slidev.mdarchived. - the Stage 12 mixed component/prose closeout archive is
/home/jacob/slidev-export-review/2026-06-20-stage12-mixed-component-prose-fixtures/; it addsmixed-component-prose-stress, and the full production fixture suite now covers 9 fixtures.mixed-component-prose-stressconverges to 3 slides in 2 patch passes, preserveslayout: dashboard-shell, preserves prose/component fingerprints, avoids whole-slidezoom, and converges the component page with measured local<Transform>. - the Stage 12 real
architecture.zh-CN.mdstrict native standalone archive is/home/jacob/slidev-export-review/2026-06-20-stage12-mixed-component-prose-real/; the report isok = true, uses/home/jacob/slidev/packages/slidev/bin/slidev.mjsand/home/jacob/slidev/skills/slidevwith 52 references, reportsactualMode = "standalone",requiresLocalServer = false,standaloneGate.passed = true, preserves all 3 Mermaid fences withchangedFenceIndexes = [], closes withhardOverflowCount = 0andlowEffectiveFontCount = 0, and archives the reviewablearchitecture.zh-CN.stage12.slidev.mdplusarchitecture.zh-CN-slides/index-standalone.html. - the Stage 13 expected-failure fixture archive is
/home/jacob/slidev-export-review/2026-06-20-stage13-unsupported-component-boundary-fixture/;unsupported-component-table-boundary-stressproves an unsupported component/table boundary is not silently repaired with whole-slidezoom, while one source Mermaid fence remains one exported Mermaid fence. - the Stage 13 default success fixture suite is archived at
/home/jacob/slidev-export-review/2026-06-20-stage13-success-fixtures/; all 9 converging production fixtures pass, and expected-failure fixtures are excluded by default. - the Stage 13 real
architecture.zh-CN.mdstrict native standalone archive is/home/jacob/slidev-export-review/2026-06-20-stage13-real/; the report isok = true, uses the local Slidev fork and 52 skill references, reportsactualMode = "standalone",requiresLocalServer = false,standaloneGate.passed = true, preserves all 3 Mermaid fences withchangedFenceIndexes = [], closes withhardOverflowCount = 0andlowEffectiveFontCount = 0, and archives the reviewablearchitecture.zh-CN.stage13.slidev.mdplusarchitecture.zh-CN-slides/index-standalone.html. - the Stage 14 component/fence expected-failure fixture archive is
/home/jacob/slidev-export-review/2026-06-20-stage14-unsupported-component-fence-boundary-fixture/;unsupported-component-fence-boundary-stressproves an unsupported component/fence boundary is not silently repaired with whole-slidezoom, while one source Mermaid fence remains one exported Mermaid fence. - the Stage 14 component/image expected-failure fixture archive is
/home/jacob/slidev-export-review/2026-06-20-stage14-unsupported-component-image-boundary-fixture/;unsupported-component-image-boundary-stressproves the image boundary also fails transparently and verifiesassets/boundary-image.svgin both the prepared deck and final standalone export. - the Stage 14 default success fixture suite is archived at
/home/jacob/slidev-export-review/2026-06-20-stage14-success-fixtures/; all 9 converging production fixtures pass, and the three expected-failure fixtures are excluded by default. - the Stage 14 real
architecture.zh-CN.mdstrict native standalone archive is/home/jacob/slidev-export-review/2026-06-20-stage14-real/; the report isok = true, uses the local Slidev fork and 52 skill references, reportsactualMode = "standalone",requiresLocalServer = false,standaloneGate.passed = true, preserves all 3 Mermaid fences withchangedFenceIndexes = [], closes withhardOverflowCount = 0andlowEffectiveFontCount = 0, and archives the reviewablearchitecture.zh-CN.stage14.slidev.mdplusarchitecture.zh-CN-slides/index-standalone.html.
Current limitation:
- effective font measurement now accounts for common local CSS transform/scale/zoom chains, but the browser rendered audit remains the authority for complex Vue layouts; do not replace it with static Markdown estimates;
- richer custom/component-heavy Slidev layouts beyond the current supported structural set still remain conservative/manual-review paths, especially when no stable owner surface exists, when component/prose/component ordering is unstable, or when content cannot be safely paginated. Stage 14 covers component/table/fence/image fail-transparent behavior and component/directive zoom blocking is covered by unit tests; it is not proof that arbitrary Vue component trees can be transformed safely;
- native standalone export now has a strict gate and the real architecture fixture passes it, but correctness still depends on post-build sanity detection; server-script fallback remains a compatibility lane and must not be counted as native standalone success;
- full-deck Playwright verification is deliberately slower than representative sampling, so future work should improve convergence rather than weaken the audit;
obsidian command id=notemd:export-slidesis still only a dispatch-level smoke because the Obsidian CLI does not expose an export-complete handshake.- Mermaid
manual-reviewevidence is not a hard gate failure. It is the correct fail-transparent outcome when preserving the original Mermaid source and guaranteeing projector-level readability cannot both be proven automatically. - code splitting is still parser-light. TypeScript/JavaScript/Python/Rust now have top-level tokenizers, but full AST splitting and more language-specific splitters remain future work.
- The Mermaid no-split constraint does not mean Mermaid presentation quality automatically passes. If a very large source diagram can only remain complete at low zoom, the workflow should surface
source-preserved-fit-reviewormanual-reviewinstead of silently rewriting or splitting the diagram. - the current full-deck fixtures cover long-table, wide-table, mixed-code, Mermaid source-preserved fit, component-heavy slot Transform boundaries, mixed Mermaid/prose non-diagram content movement, local image assets, nested slot components, ultra-wide tables, frontmatter background/image/favicon assets, cross-directory assets, CSS
url(...)image/font dependencies, local CSS@importchains, local video/audio/track assets, offline font-provider boundaries, bounded raw HTML/component single-surface slides, bounded component-only Vue tree surfaces, clear-boundary mixed component/prose, and unsupported component/table/fence/image expected failures, but they are not exhaustive; add more fixture sources for complex Vue components and unsupported layouts as they fail in real documents.
Output Policy
The generated files under docs/export/ are maintainer inspection artifacts. They are intentionally useful for local visual review, but they should not be committed unless a release or documentation task explicitly asks for that artifact.
Before committing Slidev-export work, inspect:
git status --short docs/export
git check-ignore -v docs/export/_slidev-sources/architecture.zh-CN.slidev.md docs/export/architecture.zh-CN-slides/index-standalone.html
Expected maintainer-local state:
- generated files may appear as untracked;
git check-ignoreshould print nothing for the current verification artifacts;- the final commit should include source/workflow/docs changes, not ad hoc generated test output.
UI Contract
The command palette export action and the sidebar export action both enter exportSlidesCommand().
That method must keep the order:
- probe environment;
- prepare a Slidev export source;
- export the prepared source in the selected format;
- report the concrete output path.
Settings must expose the default export format (HTML, PDF, PNG, MP4) and the HTML mode when HTML is selected. A UI change that hides format selection regresses the export workflow.
When To Run
Run npm run verify:slidev-export whenever a change touches:
src/main.tsexport command wiring;src/ui/NotemdSidebarView.tsor Slidev export controls;src/ui/NotemdSettingTab.tsSlidev settings;src/slideExport/*;- local Slidev fork resolution;
- Slidev skill loading or prompt preparation;
- output cleanup, bundling, or browser-launch behavior.
Run npm run verify:slidev-layout-fixtures as well when a change touches:
- rendered layout measurement;
- Mermaid fit/manual-review handling;
- table/code structural splitting;
- slot-zone measurement or local Transform patching;
- any rule intended to avoid whole-slide low zoom for non-Mermaid content.
For code changes, also run:
npm test -- --runInBand src/tests/slidevLayoutAudit.test.ts src/tests/slidevSourcePreparer.test.ts src/tests/slideExportComprehensive.test.ts src/tests/sidebarDomButtonClicks.test.ts
PLAYWRIGHT_BROWSERS_PATH=/home/jacob/.cache/ms-playwright npm test -- --runInBand src/tests/slidevRenderedMeasurement.test.ts
PLAYWRIGHT_BROWSERS_PATH=/home/jacob/.cache/ms-playwright npm run verify:slidev-layout-fixtures -- --timeout-ms 300000
npm run build
git diff --check
Slidev Skill PR Assessment
A PR to the shared Slidev skill is worthwhile only for generic guidance that applies beyond NoteMD.
Good upstream skill candidates:
- when converting long-form technical documents into Slidev decks, use the full skill reference set instead of relying only on the top-level
SKILL.md; - prefer built-in or configured themes unless the project explicitly declares an installed custom theme;
- close per-slide frontmatter before slide body content;
- keep user Mermaid diagrams intact and let rendered browser audit derive any required Mermaid zoom or review state, while tables and dense code blocks use structural splits,
zoom, orTransformaccording to measured overflow; - verify exported decks by building and opening rendered slides in a browser, not only by checking that Markdown was generated;
- clear or recreate output directories before rebuilds when stale assets can affect browser output.
Keep these project-local instead of upstreaming:
/home/jacob/slidev/packages/slidev/bin/slidev.mjsfork discovery;- NoteMD's vault-relative output paths;
- the exact
architecture.zh-CN.mdsmoke fixture; - NoteMD-specific stale text checks such as
快速定位.
Recommendation: prepare a small upstream Slidev skill PR for the generic deck-conversion/export guardrails after this NoteMD workflow stabilizes. Do not upstream NoteMD-specific path or vault behavior.