tomEmitLiteralBlock function

String? tomEmitLiteralBlock(
  1. String value,
  2. int keyIndent
)

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 — | when value ends 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 (so source: |2- puts content at column 4 under content:).
  • 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();
}