Skip to content

Commit

Permalink
feat(yaml): add support for YAML block folded scalars
Browse files Browse the repository at this point in the history
Closes #249
  • Loading branch information
char0n committed Jan 29, 2021
1 parent e5e4c7a commit 038d3af
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 16 deletions.
23 changes: 9 additions & 14 deletions apidom/packages/apidom-ast/src/nodes/yaml/YamlScalar/formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ import {
tail,
compose,
pathOr,
__,
map,
concat,
transduce,
ifElse,
always,
prop,
pipe,
trim,
Expand Down Expand Up @@ -86,7 +83,9 @@ const preventNlCollapseToSpace = (val: string) => val.replace(/\\\n\s*/g, '');

// collapse newlines into spaces
const collapseNlToSpace = (val: string) =>
val.replace(/\n([^\n]+)/g, (match: string, p1: string) => ` ${p1.trimLeft()}`);
val
.replace(/(?<![\n]+)\n([^\n]+)/g, (match: string, p1: string) => ` ${p1.trimLeft()}`)
.replace(/[\n]{2}/g, '\n');

const removeQuotes = curry((quoteType, val) =>
val.replace(new RegExp(`^${quoteType}`), '').replace(new RegExp(`${quoteType}$`), ''),
Expand Down Expand Up @@ -149,9 +148,9 @@ export const formatBlockLiteral = (scalarNode: any): string => {
const lines = tail(scalarNode.text.split('\n')); // first line only contains indicators
const transducer = compose(map(trimCharsStart(indentation)), map(concatRight('\n')));
// @ts-ignore
const formatted: string = transduce(transducer, concat, '', lines);
const deindented: string = transduce(transducer, concat, '', lines);

return chomp(chompingIndicator, formatted);
return chomp(chompingIndicator, deindented);
};

/**
Expand All @@ -162,14 +161,10 @@ export const formatBlockFolded = (scalarNode: any): string => {
const indentation = getIndentation(scalarNode);
const chompingIndicator = getChompingIndicator(scalarNode);
const lines = tail(scalarNode.text.split('\n')); // first line only contains indicators
const transducer = compose(map(trimCharsStart(indentation)), map(concatRight('\n')));
// @ts-ignore
const transducer = compose(
map(trimCharsStart(indentation)),
// @ts-ignore
map(ifElse(isEmptyString, always('\n'), concat(__, ' '))),
);
// @ts-ignore
const formatted: string = transduce(transducer, concat, '', lines);
const deindented: string = transduce(transducer, concat, '', lines);
const collapsed = collapseNlToSpace(deindented);

return chomp(chompingIndicator, formatted);
return chomp(chompingIndicator, collapsed);
};
5 changes: 5 additions & 0 deletions apidom/packages/apidom-ast/src/nodes/yaml/YamlScalar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
formatFlowSingleQuoted,
formatFlowDoubleQuoted,
formatBlockLiteral,
formatBlockFolded,
} from './formats';

interface YamlScalar extends YamlNode {
Expand Down Expand Up @@ -45,6 +46,10 @@ const YamlScalar: stampit.Stamp<YamlScalar> = stampit(YamlNode, {
// @ts-ignore
return formatBlockLiteral(this);
}
if (this.style === YamlStyle.Folded) {
// @ts-ignore
return formatBlockFolded(this);
}

// @ts-ignore
return this.text;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Several lines of text, with some "quotes" of various 'types', and also a blank line:
plus another line at the end.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
>
Several lines of text,
with some "quotes" of various 'types',
and also a blank line:

plus another line at the end.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Several lines of text, with some "quotes" of various 'types', and also a blank line:
plus another line at the end.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
>2
Several lines of text,
with some "quotes" of various 'types',
and also a blank line:

plus another line at the end.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Several lines of text, with some "quotes" of various 'types', and also a blank line:
plus another line at the end.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
>+
Several lines of text,
with some "quotes" of various 'types',
and also a blank line:

plus another line at the end.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Several lines of text, with some "quotes" of various 'types', and also a blank line:
plus another line at the end.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
>-
Several lines of text,
with some "quotes" of various 'types',
and also a blank line:

plus another line at the end.

Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,35 @@ const literalStripExpectedPath = path.join(__dirname, 'fixtures', 'literal-strip
const literalClipPath = path.join(__dirname, 'fixtures', 'literal-clip.yaml');
const literalClipExpectedPath = path.join(__dirname, 'fixtures', 'literal-clip-expected.yaml');

const literalIndentationIndicatorPath = path.join(__dirname, 'fixtures', 'literal-clip.yaml');
const literalIndentationIndicatorPath = path.join(
__dirname,
'fixtures',
'literal-indentation-indicator.yaml',
);
const literalIndentationIndicatorExpectedPath = path.join(
__dirname,
'fixtures',
'literal-clip-expected.yaml',
'literal-indentation-indicator-expected.yaml',
);

const foldedKeepPath = path.join(__dirname, 'fixtures', 'folded-keep.yaml');
const foldedKeepExpectedPath = path.join(__dirname, 'fixtures', 'folded-keep-expected.yaml');

const foldedStripPath = path.join(__dirname, 'fixtures', 'folded-strip.yaml');
const foldedStripExpectedPath = path.join(__dirname, 'fixtures', 'folded-strip-expected.yaml');

const foldedClipPath = path.join(__dirname, 'fixtures', 'folded-clip.yaml');
const foldedClipExpectedPath = path.join(__dirname, 'fixtures', 'folded-clip-expected.yaml');

const foldedIndentationIndicatorPath = path.join(
__dirname,
'fixtures',
'folded-indentation-indicator.yaml',
);
const foldedIndentationIndicatorExpectedPath = path.join(
__dirname,
'fixtures',
'folded-indentation-indicator-expected.yaml',
);

describe('nodes', function () {
Expand Down Expand Up @@ -120,6 +144,52 @@ describe('nodes', function () {
assert.strictEqual(scalar.content, expected);
});
});

context('formatBlockFolded', function () {
specify('should format folded + keep', function () {
const text = fs.readFileSync(foldedKeepPath).toString();
const scalar = YamlScalar({
style: YamlStyle.Folded,
styleGroup: YamlStyleGroup.Block,
text,
});
const expected = fs.readFileSync(foldedKeepExpectedPath).toString();
assert.strictEqual(scalar.content, expected);
});

specify('should format folded + strip', function () {
const text = fs.readFileSync(foldedStripPath).toString();
const scalar = YamlScalar({
style: YamlStyle.Folded,
styleGroup: YamlStyleGroup.Block,
text,
});
const expected = fs.readFileSync(foldedStripExpectedPath).toString().trimRight();
assert.strictEqual(scalar.content, expected);
});

specify('should format folded + clip', function () {
const text = fs.readFileSync(foldedClipPath).toString();
const scalar = YamlScalar({
style: YamlStyle.Folded,
styleGroup: YamlStyleGroup.Block,
text,
});
const expected = fs.readFileSync(foldedClipExpectedPath).toString();
assert.strictEqual(scalar.content, expected);
});

specify('should format folded + clip + indentation indicator', function () {
const text = fs.readFileSync(foldedIndentationIndicatorPath).toString();
const scalar = YamlScalar({
style: YamlStyle.Folded,
styleGroup: YamlStyleGroup.Block,
text,
});
const expected = fs.readFileSync(foldedIndentationIndicatorExpectedPath).toString();
assert.strictEqual(scalar.content, expected);
});
});
});
});
});
Expand Down

0 comments on commit 038d3af

Please sign in to comment.