- Bump `oxc-yaml-parser` to 0.0.7 - handles NUL as content, BOM only outside a document, markers only at column 0 - Keep `---`/`...` content on the `---` line, keep `?` on a root key starting with a marker, and indent a flow scalar continuation line starting with a marker - Add `---` before a document whose first text is U+FEFF
3.4 KiB
Coding agent guides for crates/oxc_formatter_yaml
Follow @../oxc_formatter_core/FORMATTER_POLICY.md , this file holds only the YAML-specific rules and translations. Known divergences live in DIVERGENCES.md.
Overview
Prettier compatible YAML formatter (oxfmt's Tier 1 backend), using the oxc_formatter_core APIs.
- Built on
oxc_formatter_corefor the language-agnostic IR + Printer + builders + macros- See
crates/oxc_formatter_core/AGENTS.mdfor the IR/pipeline details
- See
- Entry points (see their docs in
src/format.rs):format()for standalone files,format_to_ir()for embedded use via the dispatcher (e.g. CSS front matter, JSDoc fenced blocks)parse_for_format(): the parseformat()runs, exposed for callers that inspect the AST (e.g. the fixture harness's fingerprint)
Parser
Parses with oxc-yaml-parser.
Its AST follows yaml-unist-parser's node naming (the nodes Prettier's printer operates on), with spans designed for layout work (see the parser's ast module docs)
One caveat the printer still owns: a block scalar's span consumes its trailing line breaks.
The split between the scalar's own output and the inter-item gap is printer policy, kept together in src/print/block.rs (see consumed_trailing_newlines / item_gap_anchor).
Error semantics
The shared policy applies; YAML specifics:
oxc-yaml-parseris fail-fast (no partial AST), so any syntax error is anErr- Under-indented multi-line flow scalars (prettier#8602) are one such error
- Prettier 3.9.6 also rejects them since its
yaml@2upgrade, so the string corruption reported there cannot happen in either implementation
- Prettier 3.9.6 also rejects them since its
Line endings
The source is normalized to \n-only BEFORE parsing (see parse_root for why).
The printer re-emits the configured end_of_line at the final stage.
A leading BOM is stripped before parsing and re-emitted by format().
Line starts
A line the printer starts at column 0 must not read back as stream-level syntax (see the parser README "Input acceptance"):
---/...followed by a blank or the end is a document marker- U+FEFF outside a document is a BOM
Column 0 is reached at these sites, each guarded without changing the value:
- The document's first text (
print/document.rs): content after---stays on its line; a document without---whose first text is U+FEFF gets one - A root mapping key (
print/mapping_item.rs): a key starting with a marker keeps its? - A flow scalar's continuation line outside block collections (
print/scalar.rs): a line starting with a marker is indented- This also covers entries of a root flow collection, already indented, where the extra indent is harmless
Elsewhere lines start at column 2 or more and Prettier's layout is matched. See DIVERGENCES.md#document-marker-content and DIVERGENCES.md#bom-content.
Comments
Positional cursor (Comments in src/comments.rs), same approach as graphql/json, yaml-unist-parser's attach algorithm is NOT ported.
Placement is decided at print sites; the rules live as doc comments on the placement helpers, all in src/comments.rs.
Stream-tail end comments (write_end_comments) are the one document-layer exception, in src/print/document.rs.
Verification
Manual checks:
cargo run -p oxc_formatter_yaml --example yaml_formatter [filename]
# Dump the formatter IR
DUMP_IR=1 cargo run -p oxc_formatter_yaml --example yaml_formatter [filename]