Draft
Conversation
Add resolve_format_config() to extract format-specific settings from metadata.
This enables proper merging of _quarto.yml settings with document frontmatter,
where format.html.* settings override top-level settings when rendering to HTML.
Changes:
- New quarto-config/src/format.rs with resolve_format_config() function
- ProjectConfig stores full metadata as ConfigValue (replaces raw + format_config)
- AstTransformsStage flattens both project and document metadata for target format
- TocGenerateTransform reads from ast.meta instead of format metadata
- WASM updated to use ProjectConfig::with_metadata()
Merge precedence (lowest to highest):
1. Project top-level settings
2. Project format-specific settings (format.{target}.*)
3. Document top-level settings
4. Document format-specific settings (format.{target}.*)
Includes unit tests for format resolution and integration tests for
metadata merging in AstTransformsStage.
Add support for _metadata.yml files in directory hierarchies, matching TS Quarto behavior. Directory metadata is discovered by walking from project root to document's parent directory. Core implementation: - Add directory_metadata_for_document() in project.rs - Walk directory hierarchy, parse _metadata.yml files - Support both .yml and .yaml extensions - Return layers in root-to-leaf order for merging - Resolve relative paths in _metadata.yml against their source directory Merge integration: - Update ast_transforms.rs to include directory metadata - Merge order: project -> dir[0] -> dir[1] -> ... -> document - Each layer flattened for target format before merging Smoke-all tests for basic inheritance, multi-level hierarchy merging, document overrides, and path resolution. Also adds default noErrorsOrWarnings assertion to smoke-all tests (matching TS Quarto conventions) and supportPath file existence checks.
Replace the hardcoded single-file ProjectContext in render_qmd() with ProjectContext::discover(), enabling _quarto.yml and _metadata.yml support in hub-client WASM rendering. Key changes: - Unify the two WasmRuntime instances: the global VFS singleton is now stored as Arc<WasmRuntime> and shared with the rendering pipeline (previously each render created a fresh empty WasmRuntime) - Port directory_metadata_for_document() from std::fs to SystemRuntime trait, enabling it to work with both native filesystem and WASM VFS - render_qmd() now calls ProjectContext::discover() to find _quarto.yml in VFS parent directories (render_qmd_content* variants remain single-file since they receive inline content) Includes 6 end-to-end WASM tests verifying project title inheritance, document override precedence, parent directory discovery, and directory metadata merging.
Vitest-based test runner that exercises all 15 smoke-all fixtures through the WASM rendering pipeline, verifying feature parity with the native Rust test runner. Implements all assertion types: ensureFileRegexMatches, ensureHtmlElements (via jsdom), noErrors, noErrorsOrWarnings, shouldError, and printsMessage. Filesystem assertions (fileExists, folderExists, pathDoesNotExist) are parsed but treated as no-ops in WASM context. One skip: expected-error.qmd's printsMessage check is bypassed because WASM formats the error message differently than native render_to_file. The shouldError assertion still runs for that fixture. Adds `yaml` devDependency for frontmatter parsing.
Introduce a general-purpose mechanism for runtimes to inject metadata into the configuration merge pipeline at the highest precedence, matching how quarto-cli handles --metadata flags. Any runtime (WASM, native, sandboxed) can now provide arbitrary metadata without per-feature API additions. Changes: - Add runtime_metadata() to SystemRuntime trait (returns Option<serde_json::Value>) - Implement runtime metadata storage in WasmRuntime with set/get methods - Add vfs_set_runtime_metadata/vfs_get_runtime_metadata WASM entry points - Update AstTransformsStage to merge runtime metadata as highest-precedence layer - Relax merge gate to also trigger when runtime metadata present (no project needed) - Fix pre-existing bug: pampa HTML writer now reads top-level source-location key (consistent with Pandoc, which receives flattened metadata after format resolution) Merge precedence (lowest to highest): Project → Directory → Document → Runtime Tests: 6 Rust unit tests + 12 WASM integration tests, all passing. Full suite: 6550 Rust tests + 47 WASM tests green.
Replace render_qmd_content (content string, no project context) with
render_qmd (VFS path, full project context) for the Preview component.
This gives live preview access to _quarto.yml, _metadata.yml, themes,
and all metadata layers.
Key changes:
- renderToHtml() now takes {documentPath} instead of (content, opts)
- Add renderContentToHtml() for standalone rendering (AboutTab)
- Add setScrollSyncEnabled() via runtime metadata (not per-render)
- Add setRuntimeMetadata/getRuntimeMetadata wrappers
- Remove renderQmdContentWithOptions and WasmRenderOptions
Known issue: compileAndInjectThemeCss causes "too much recursion" crash
in dart-sass when called after renderQmd. Needs investigation — theme
CSS compilation works but triggers infinite recursion in a Vite chunk.
The hub server's file discovery only recognized _quarto.yml/yaml, .qmd files, and binary resources. Directory metadata files (_metadata.yml/_metadata.yaml) were silently ignored, so they were never added to the Automerge index, never synced to clients, and never appeared in the VFS or file browser. Add _metadata.yml and _metadata.yaml to the config file discovery filter alongside _quarto.yml/yaml.
directory_metadata_for_document uses strip_prefix to compute the relative path from project root to document directory. This requires both paths to be in the same canonical form. ProjectContext::discover always canonicalizes project.dir, but callers could pass relative or non-canonical document paths (e.g., WASM render_qmd with VFS paths like "chapters/chapter1.qmd"), causing strip_prefix to fail silently and return no directory metadata layers. Canonicalize the document_path inside the function using the runtime, matching the established pattern (ProjectContext::discover, ThemeContext, compile_document_css all canonicalize internally). Also fix the test helper to canonicalize project.dir, matching the invariant that discover enforces in production. On macOS, TempDir paths go through /tmp -> /private/tmp symlinks, so without canonicalization the test helper created ProjectContexts that didn't match real-world behavior.
This function is superseded by the runtime metadata layer (ddcc1236). Source location and other render options are now configured via vfs_set_runtime_metadata() instead of a separate render function. Removes WasmRenderOptions struct, the function itself, and all references from TS interfaces and type definitions. Updates ad-hoc WASM test scripts to use runtime metadata pattern instead.
The trim_prefix_suffix feature was stabilized in newer nightly Rust, causing CI failures. The codebase only uses the stable strip_prefix/ strip_suffix methods, so the feature gate was unused.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
_quarto.ymland_metadata.ymlcontribute to metadata across runtimes.Includes
smoke-alltests for the wasm runtime. quarto-hub uses common render functionrender_qmdThe browser runtime is a little different - maybe it would be worth also running the smoke tests there or instead of the current wasm smoke-all tests. It took a few more steps to get this running in the browser, tested manually.
Filing as draft for CI until we discuss, but I think this is ready to merge.
Metadata Merge Layers
During the
AstTransformsStage, metadata from multiple sources is mergedinto a single flat config for the target format. Each layer is first
flattened via
resolve_format_config: top-level keys are kept, theformatkey is removed, andformat.{target}.*keys are merged on top(overriding same-named top-level keys). The flattened layers are then
merged in order — later layers override earlier ones.
Merge order (lowest → highest precedence)
_quarto.ymlmetadata_metadata.ymlfiles between project root and documentdirectory, walked root-to-leaf (deeper directories override shallower).
The project root directory itself is excluded (the walk starts from the
first subdirectory toward the document).
.qmdfileformat.html.source-location: fullfor scroll sync)Layers 1–2 require a project config (
_quarto.yml) to exist.Layer 4 is optional and comes from
SystemRuntime::runtime_metadata().Compatibility with TS Quarto
This matches the TS Quarto merge order in
directoryMetadataForInputFile(
src/project/project-shared.ts), which walks from project root towardthe input directory, plus project and CLI metadata layers. TS Quarto's
CLI
--metadata/--metadata-fileflags correspond to our runtimemetadata layer.
Note: TS Quarto's directory walk uses
relative(projectDir, inputDir)split by path separator, which means root
_metadata.ymlis only checkedwhen the relative path is non-empty (i.e., the document is in a
subdirectory). Our implementation matches this behavior.
Implementation
crates/quarto-core/src/stage/stages/ast_transforms.rs(merge logic)crates/quarto-core/src/project.rs—directory_metadata_for_documentcrates/quarto-config/src/format.rs—resolve_format_config