src/language-yaml/utils.js/removeUnnecessaryTrailingNewlines
function getBlockValueLineContents(
  node,
  { parentIndent, isLastDescendant, options }
) {
  const content =
    node.position.start.line === node.position.end.line
      ? ""
      : options.originalText
          .slice(node.position.start.offset, node.position.end.offset)
          // exclude open line `>` or `|`
          .match(/^[^\n]*?\n([\S\s]*)$/)[1];

  const leadingSpaceCount =
    node.indent === null
      ? ((match) => (match ? match[1].length : Infinity))(
          content.match(/^( *)\S/m)
        )
      : node.indent - 1 + parentIndent;

  const rawLineContents = content
    .split("\n")
    .map((lineContent) => lineContent.slice(leadingSpaceCount));

  if (options.proseWrap === "preserve" || node.type === "blockLiteral") {
    return removeUnnecessaryTrailingNewlines(
      rawLineContents.map((lineContent) =>
        lineContent.length === 0 ? [] : [lineContent]
      )
    );
  }

  return removeUnnecessaryTrailingNewlines(
    rawLineContents
      .map((lineContent) =>
        lineContent.length === 0 ? [] : splitWithSingleSpace(lineContent)
      )
      .reduce(
        (reduced, lineContentWords, index) =>
          index !== 0 &&
          rawLineContents[index - 1].length !== 0 &&
          lineContentWords.length !== 0 &&
          !/^\s/.test(lineContentWords[0]) &&
          !/^\s|\s$/.test(getLast(reduced))
            ? reduced.concat([reduced.pop().concat(lineContentWords)])
            : reduced.concat([lineContentWords]),
        []
      )
      .map((lineContentWords) =>
        lineContentWords.reduce(
          (reduced, word) =>
            // disallow trailing spaces
            reduced.length !== 0 && /\s$/.test(getLast(reduced))
              ? reduced.concat(reduced.pop() + " " + word)
              : reduced.concat(word),
          []
        )
      )
      .map((lineContentWords) =>
        options.proseWrap === "never"
          ? [lineContentWords.join(" ")]
          : lineContentWords
      )
  );

  function removeUnnecessaryTrailingNewlines(lineContents) {
    if (node.chomping === "keep") {
      return getLast(lineContents).length === 0
        ? lineContents.slice(0, -1)
        : lineContents;
    }

    let trailingNewlineCount = 0;
    for (let i = lineContents.length - 1; i >= 0; i--) {
      if (lineContents[i].length === 0) {
        trailingNewlineCount++;
      } else {
        break;
      }
    }

    return trailingNewlineCount === 0
      ? lineContents
      : trailingNewlineCount >= 2 && !isLastDescendant
      ? // next empty line
        lineContents.slice(0, -(trailingNewlineCount - 1))
      : lineContents.slice(0, -trailingNewlineCount);
  }
}