tomEmitLiteralBlock function
The canonical literal-block emission of value under a key written at
keyIndent spaces: the text that follows key: — header and content lines
— or null when value has no canonical block form and is emitted by
rule 4 instead.
- Chomping —
|whenvalueends with one\n,|-when it ends with none; never|+. - Indentation — every content line, an empty one included, is indented exactly two spaces deeper than the key.
- Indentation indicator — written iff the first line is empty or begins
with a space, since YAML would otherwise infer the block indentation from
the first non-empty line and silently re-indent the source. The digit is
2: a YAML indentation indicator counts from the indentation of the mapping that holds the key, and the content sits two columns deeper than that key (sosource: |2-puts content at column 4 undercontent:). - Empty or whitespace-only — null, so rule 4 writes
"".
Null too for a value no literal block can carry byte-for-byte — a \r
(YAML folds it into a line break), two or more trailing newlines (would
need |+), trailing whitespace or a tab in a line's leading whitespace, or
a character YAML does not admit in a block scalar. The double-quoted
fallback keeps any such value round-tripping.
Implementation
String? tomEmitLiteralBlock(String value, int keyIndent) {
if (value.trim().isEmpty) return null;
if (value.contains('\r') || value.endsWith('\n\n')) return null;
for (final rune in value.runes) {
if (!_blockPrintable(rune)) return null;
}
final clip = value.endsWith('\n');
final body = clip ? value.substring(0, value.length - 1) : value;
final lines = body.split('\n');
for (final line in lines) {
if (line.endsWith(' ') || line.endsWith('\t')) return null;
final lead = line.length - line.trimLeft().length;
if (line.substring(0, lead).contains('\t')) return null;
}
final first = lines.first;
final indicator = first.isEmpty || first.startsWith(' ') ? '2' : '';
final pad = ' ' * (keyIndent + 2);
final out = StringBuffer('|$indicator${clip ? '' : '-'}\n');
for (final line in lines) {
out.writeln('$pad$line');
}
return out.toString();
}