package yamlx
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=f691a9e174828cc130b14a87b70a322c129351d3e399871ca9a53774b9205738
sha512=ba0e837f1773ba0b09cd0d9720c033f9b0d6b9816dbad8cb9f3b167cac6ae855d6b8fd39db2956e91f575e886689db38324a5e879593127b3e726771151a2a4b
doc/CHANGES.html
0.3.0 (2026-04-24)
New features
Nodesubmodule — single-node interface for the lossless AST (#37, #38). Mirrors theValuemodule for thenodetype:Node.t— forwarding type alias fornode, exposing all four constructors (Node.Scalar_node,Node.Sequence_node,Node.Mapping_node,Node.Alias_node) alongside the top-level names.Node.has_comments : Node.t -> bool— returnstrueif the node or any descendant carries a comment (head, line, or foot).Node.pp/Node.show— aliases forpp_node/show_node.Nodes.has_comments : Nodes.t -> bool— returnstrueif any document in the parsed stream contains a comment. BothNodeandNodesexposehas_commentson their ownt.
Value.tforwarding type (#36).Value.tis an alias forvaluethat re-exports all constructors (Value.Null,Value.Bool, etc.) under theValuenamespace.Valuesubmodule — single-document interface for typed YAML values (#32). Most config files contain exactly one YAML document; the newValuemodule provides a cleaner API for this common case:Value.of_yaml/of_yaml_exn: parse a string expecting one document.Value.of_yaml_file: read and parse a file expecting one document.Value.to_yaml/to_yaml_file: serialize a single value back to YAML.Value.equal: structural equality ignoring source locations.Value.compare: total order on values ignoring source locations.Value.pp/Value.show: pretty-printer and string renderer (aliases for the PPX-derivedpp_value/show_value, which remain undeprecated for use by[@@deriving show]on types that embedvalue).Value.loc: extract the source location from any value constructor. TheValues.one_of_yaml/one_of_yaml_exn/one_of_yaml_filefunctions andYAMLx.equal_valueandYAMLx.value_locare now deprecated in favor of theirValue.*equivalents.
Block scalar heuristics for
Values.to_nodes/Values.to_yaml(#30). String values longer than 70 characters are now serialized using block scalar styles where appropriate:- Strings with internal newlines and only safe characters → literal block (
|or|-), preserving newlines exactly. - Single-line strings with spaces and only printable characters → folded block (
>or>-), with lines wrapped at approximately 70 characters. - Short strings and strings containing control characters continue to use
PlainorDouble_quotedas before.
- Strings with internal newlines and only safe characters → literal block (
reformatoutput format for theyamlxCLI (#30).yamlx -f reformatreads the input through the typed-value layer (dropping comments, anchors, and tags) and re-serializes using the block scalar heuristics above. This produces a normalized, human-readable YAML output from any conforming input.
0.2.0 (2026-04-20)
Bug fixes
Node
locfields now exclude trailing whitespace and line terminators (#27):- Plain scalars (block and flow context):
end_posis now right after the last content character, not past trailing spaces or consumed newlines. - Block scalars (
|,>):end_posis now at the line terminator of the last content line, not at the start of the next token's line.
- Plain scalars (block and flow context):
- The
---document separator is now always emitted on its own line. Previously it was followed by a space and the document content on the same line for scalar and flow-collection documents, e.g.--- fooinstead of---\nfoo. (#25)
Comment attachment improvements (#20)
- Comments between a mapping key and its value (when the value starts on the next line) are now correctly attached as
head_commentsof the value node. Previously they were silently discarded. - Trailing comments after the last item of a block collection are now attached as
foot_commentsof the collection and printed at the correct indentation level. Previously they were attached to the last item'sfoot_commentsand printed at column 0. - Block scalar header comments (
| # note,> # note) are now captured and round-trip correctly. Previously the comment was silently dropped. - Standalone comments that appear between two documents (before
---) are now attached asfoot_commentsof the preceding document rather than leaking into thehead_commentsof the following document's root node. - Added
foot_comments : string listfield toScalar_nodeandAlias_node(previously only collection nodes had this field).
0.1.0 (2026-04-08)
Initial release.
Parser
- Full YAML 1.2 parser written in pure OCaml with no C bindings or external runtime dependencies.
- Passes all 371 tests from the yaml-test-suite.
- UTF-8 input with BOM stripping and line-ending normalization (CR+LF, bare CR, NEL, LS, PS → LF).
- Multi-document streams.
- Anchors and aliases, including cycle detection: cyclic structures raise
Cycle_errorrather than looping forever. - Anchors are scoped to the document in which they are defined.
- Tags (both shorthand and verbatim forms).
- All scalar styles: plain, single-quoted, double-quoted, literal block, folded block.
- Flow and block sequences and mappings.
- Directives (
%YAML,%TAG).
YAML 1.1 support
- Optional YAML 1.1 schema (selectable per-parse or per-document via the
%YAML 1.1directive). - Extended booleans:
yes/no,on/off,y/nand their case variants. - Legacy octal:
0755in addition to0o755. - Sexagesimal integers and floats:
3:25:45= 12345,20:30.15= 1230.15. - Merge keys: plain
<<mapping key merges the associated mapping(s) into the current mapping; explicit keys win over merged keys.
Lossless AST (Nodes module)
- The
nodetype preserves scalar style (plain / single-quoted / double-quoted / literal / folded), flow vs. block collection style, tags, anchors, and source positions (line, column, byte offset). - Best-effort comment preservation: head comments (standalone lines before a node), line comments (end-of-line comments on the same line as a node), and foot comments (trailing lines after the last item of a block collection) are attached to the nearest node and faithfully re-emitted by the printer.
Nodes.of_yaml/of_yaml_exn/of_yaml_file: parse YAML to anode list(one entry per document).Nodes.to_yaml: serialize back to YAML, round-tripping styles and comments.Nodes.to_plain_yaml/to_plain_yaml_exn: serialize to simplified YAML (aliases expanded, tags stripped, block collections only).
Typed values (Values module)
valuetype:Null | Bool of bool | Int of int | Float of float | String of string | Seq of value list | Map of (value * value) list.- Applies the YAML 1.2 JSON schema (or YAML 1.1 schema when requested) to resolve plain scalars to typed values.
Values.of_yaml/of_yaml_exn/of_yaml_file: parse and resolve in one step.Values.one_of_yaml/one_of_yaml_exn/one_of_yaml_file: parse a single-document stream and return the value directly (error on zero or multiple documents).Optional parameters on all resolution functions:
?schema: chooseYaml_1_2(default) orYaml_1_1.?strict_keys: raiseDuplicate_key_erroron duplicate mapping keys (default: keep the last occurrence silently).?plain: raiseSimplicity_errorif the input uses anchors, aliases, or explicit tags — useful when only simple, unambiguous YAML is acceptable.?strict_schema: error when a document's%YAMLdirective conflicts with the?schemasetting.?reject_ambiguous: with YAML 1.2, error on plain scalars that would resolve differently under YAML 1.1.
Safety limits
- Expansion limit (default 1 000 000 nodes): alias expansion is counted and raises
Expansion_limit_exceededbefore the node tree can grow unboundedly. Protects against YAML bombs. - Depth limit (default 512 levels): deeply nested inputs raise
Depth_limit_exceededrather than overflowing the stack. - Both limits are configurable via optional parameters on the parse functions.
Error handling
- All exceptions share a single
Error of errorwrapper, making it straightforward to catch every YAMLx error in one place. errorvariants:Scan_error,Parse_error,Compose_error,Resolve_error,Schema_error,Duplicate_key_error,Simplicity_error,Cycle_error,Expansion_limit_exceeded,Depth_limit_exceeded,Printer_error.- Every error carries a
locvalue with the start and end position (line, column, byte offset) of the offending input range. show_yaml_error: formats an error as a human-readable string. Accepts an optional?format_locparameter for custom location formatting (e.g. for LSP servers or structured logging).catch_errors: wraps a thunk, returningOk valueorError message. Accepts an optional?fileargument to prefix messages with the file path.register_exception_printers: registersPrintexcprinters so YAMLx exceptions print legibly in uncaught-exception output.
Command-line tool (yamlx)
Seven output formats selectable with -f FORMAT:
Format | Description |
|---|---|
| Re-emit YAML preserving styles and comments (default) |
| Simplified YAML: aliases expanded, tags stripped, block-only |
| Typed-value tree without source locations |
| Typed-value tree with source locations |
| AST without source locations or heights |
| Full AST with source locations, anchors, tags, and comments |
| yaml-test-suite event-tree notation (for debugging) |
Options:
--schema 1.1 / 1.2: choose the default YAML schema for the stream.--strict-schema: error when a document's%YAMLdirective contradicts--schema.--reject-ambiguous: with--schema 1.2, error on scalars that are ambiguous between YAML 1.1 and 1.2.--strict-keys: error on duplicate mapping keys (with-f value/value-loc).--plain: reject anchors, aliases, and tags in the input (with-f value/value-loc).--strict: with-f plain, error on tags rather than stripping them.--depth-limit N/--expansion-limit N: override the default safety limits.