pantoniou / libfyaml

Fully feature complete YAML parser and emitter, supporting the latest YAML spec and passing the full YAML testsuite.
MIT License
239 stars 73 forks source link

Fix emission of document start markers #112

Closed kdubb closed 1 month ago

kdubb commented 1 month ago

This fixes two issues with emitting document start/end markers and root scalar values. The first is that document start markers and root scalars are output on the same line, and the second is pretty mode forces document start markers but doesn't emit the matching end marker.

Isolated Document Start Markers

Currently, when emitting a single scalar value as the root object of a document with document markers enabled, some scalars (e.g., plain string) are output on the same line as the document start marker.

For example, the following code:

fy_emit_eventf(emit, FYET_STREAM_START);
fy_emit_eventf(emit, FYET_DOCUMENT_START, false, NULL, NULL);
fy_emit_event(emit, FYET_SCALAR, FYSS_PLAIN, "simple", FY_NT, NULL, NULL);
fy_emit_eventf(emitter, FYET_DOCUMENT_END, false);

Generates this YAML:

--- simple
...

This looked incorrect, so I looked into whether it was valid YAML. The YAML spec, section 9.1.2, refers to them as "lines":

The solution is the use of two special marker lines to control the processing of directives, one at the start of a document and one at the end.

However, it gives an example of a document marker with a comment afterward. Also, libyaml accepts YAML with the scalar on the same line as the document marker.

In any case, it still seems wrong to emit them on the same line when you consider the spec language and how visually unpleasing it is.

With this change, the document start markers are always emitted on their own line, like:

---
simple
...

Emit Root Scalar with Pretty Mode

When emitting a single root scalar value in pretty mode, a document start marker is emitted, even when implicit markers are requested.

This leads to imbalanced output (in pretty mode), like:

--- simple

The PR tracks when an implicit document start marker is requested but emitted anyway, like in pretty mode, and forces the emission of a matching document end marker.

[!NOTE] This currently only affects emitted YAML when pretty mode is enabled because, currently, that is the only time a document start marker may be forced. Although, the new flag could be used in other situations.

kdubb commented 1 month ago

This passes all tests, including the new tests added in #110.