Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/emitterutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,28 @@ bool WriteDoubleQuotedString(ostream_wrapper& out, const char* str, std::size_t

bool WriteLiteralString(ostream_wrapper& out, const char* str, std::size_t size,
std::size_t indent) {
out << "|\n";
// depending on the numbers of new lines at the end of the string
// we need to use 'clip (-)', 'strip (default)' or 'keep' (+) annotation.
// if there is no newline at the end, we need 'clip'
// if there is single new line at the end, we need 'strip'
// otherwise 'keep'
//
// see YAML spec 1.2 chapter '8.1.1.2 Block Chomping Indicator' for more information
// https://yaml.org/spec/1.2.2/#8112-block-chomping-indicator


// The chomping depends on the number of new lines.
// The output following this 'WriteLiteralString' call will add an additional '\n',
// because of this we need to remove one in the case of 'strip' and 'keep'.
if (size == 0 || str[size-1] != '\n') { // clip
out << "|-\n";
} else if (size == 1 || str[size-2] != '\n') { // strip
out << "|\n";
size -= 1;
} else { // 'keep'
out << "|+\n";
size -= 1;
}
int codePoint;
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
Expand Down
26 changes: 21 additions & 5 deletions test/integration/emitter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ TEST_F(EmitterTest, StringFormat) {
out << "string";
out << EndSeq;

ExpectEmit("- 'string'\n- \"string\"\n- |\n string");
ExpectEmit("- 'string'\n- \"string\"\n- |-\n string");
}

TEST_F(EmitterTest, IntBase) {
Expand Down Expand Up @@ -409,7 +409,7 @@ TEST_F(EmitterTest, ScalarFormat) {
"- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit "
"double-quoted scalar\"\n- \"auto-detected\\ndouble-quoted "
"scalar\"\n- a "
"non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n "
"non-\"auto-detected\" double-quoted scalar\n- |-\n literal scalar\n "
" "
"that may span\n many, many\n lines and have \"whatever\" "
"crazy\tsymbols that we like");
Expand All @@ -424,18 +424,34 @@ TEST_F(EmitterTest, LiteralWithoutTrailingSpaces) {
out << YAML::EndMap;

ExpectEmit(
"key: |\n"
"key: |-\n"
" expect that with two newlines\n\n"
" no spaces are emitted in the empty line");
}

TEST_F(EmitterTest, LiteralWithAndWithoutTrailingEmptyLines) {
out << BeginSeq;
out << Literal << "A\nB";
out << Literal << "A\nB\n";
out << Literal << "A\nB\n\n\n";
out << "something";
out << EndSeq;

ExpectEmit(
"- |-\n A\n B\n"
"- |\n A\n B\n"
"- |+\n A\n B\n\n\n"
"- something");
}


TEST_F(EmitterTest, AutoLongKeyScalar) {
out << BeginMap;
out << Key << Literal << "multi-line\nscalar";
out << Value << "and its value";
out << EndMap;

ExpectEmit("? |\n multi-line\n scalar\n: and its value");
ExpectEmit("? |-\n multi-line\n scalar\n: and its value");
}

TEST_F(EmitterTest, LongKeyFlowMap) {
Expand Down Expand Up @@ -717,7 +733,7 @@ TEST_F(EmitterTest, ComplexDoc) {
"given: Dorothy\n family: Gale\nitems:\n - part_no: A4786\n "
"descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n - "
"part_no: E1628\n descrip: High Heeled \"Ruby\" Slippers\n price: "
"100.27\n quantity: 1\nbill-to: &id001\n street: |\n 123 Tornado "
"100.27\n quantity: 1\nbill-to: &id001\n street: |-\n 123 Tornado "
"Alley\n Suite 16\n city: East Westville\n state: KS\nship-to: "
"*id001");
}
Expand Down
Loading