Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add collectionStyle option #343

Merged
merged 1 commit into from
Dec 28, 2021
Merged
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
1 change: 1 addition & 0 deletions docs/03_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ Used by: `stringify()` and `doc.toString()`
| Name | Type | Default | Description |
| ------------------------------ | -------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| blockQuote | `boolean ⎮ 'folded' ⎮ 'literal'` | `true` | Use block quote styles for scalar values where applicable. Set to `false` to disable block quotes completely. |
| collectionStyle | `'any' ⎮ 'block' ⎮ 'flow'` | `'any'` | Enforce `'block'` or `'flow'` style on maps and sequences. By default, allows each collection to set its own `flow: boolean` property. |
| commentString | `(comment: string) => string` | | Output should be valid for the current schema. By default, empty comment lines are left empty, lines consisting of a single space are replaced by `#`, and all other lines are prefixed with a `#`. |
| defaultKeyType | `Type ⎮ null` | `null` | If not `null`, overrides `defaultStringType` for implicit key values. |
| defaultStringType | `Type` | `'PLAIN'` | The default type of string literal used to stringify values. |
Expand Down
9 changes: 9 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ export type ToStringOptions = {
*/
blockQuote?: boolean | 'folded' | 'literal'

/**
* Enforce `'block'` or `'flow'` style on maps and sequences.
* Empty collections will always be stringified as `{}` or `[]`.
*
* Default: `'any'`, allowing each node to set its style separately
* with its `flow: boolean` (default `false`) property.
*/
collectionStyle?: 'any' | 'block' | 'flow'

/**
* Comment stringifier.
* Output should be valid for the current schema.
Expand Down
19 changes: 17 additions & 2 deletions src/stringify/stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ export type StringifyContext = {
indent: string
indentStep: string
indentAtStart?: number
inFlow?: boolean
inFlow: boolean | null
inStringifyKey?: boolean
options: Readonly<Required<Omit<ToStringOptions, 'indent'>>>
options: Readonly<
Required<Omit<ToStringOptions, 'collectionStyle' | 'indent'>>
>
}

export function createStringifyContext(
Expand Down Expand Up @@ -56,11 +58,24 @@ export function createStringifyContext(
options
)

let inFlow: boolean | null
switch (opt.collectionStyle) {
case 'block':
inFlow = false
break
case 'flow':
inFlow = true
break
default:
inFlow = null
}

return {
anchors: new Set(),
doc,
indent: '',
indentStep: typeof opt.indent === 'number' ? ' '.repeat(opt.indent) : ' ',
inFlow,
options: opt
}
}
Expand Down
6 changes: 2 additions & 4 deletions src/stringify/stringifyCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ export function stringifyCollection(
ctx: StringifyContext,
options: StringifyCollectionOptions
) {
const stringify =
collection.flow || ctx.inFlow
? stringifyFlowCollection
: stringifyBlockCollection
const flow = ctx.inFlow ?? collection.flow
const stringify = flow ? stringifyFlowCollection : stringifyBlockCollection
return stringify(collection, ctx, options)
}

Expand Down
53 changes: 53 additions & 0 deletions tests/doc/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,59 @@ describe('indentSeq: false', () => {
})
})

describe('collectionStyle', () => {
test('collectionStyle: undefined', () => {
const doc = new YAML.Document({ foo: ['bar'] })
expect(doc.toString()).toBe('foo:\n - bar\n')

doc.contents.flow = false
doc.get('foo').flow = true
expect(doc.toString()).toBe('foo: [ bar ]\n')

doc.contents.flow = true
doc.get('foo').flow = false
expect(doc.toString()).toBe('{ foo: [ bar ] }\n')
})

test("collectionStyle: 'any'", () => {
const doc = new YAML.Document({ foo: ['bar'] })
expect(doc.toString({ collectionStyle: 'any' })).toBe('foo:\n - bar\n')

doc.contents.flow = false
doc.get('foo').flow = true
expect(doc.toString({ collectionStyle: 'any' })).toBe('foo: [ bar ]\n')

doc.contents.flow = true
doc.get('foo').flow = false
expect(doc.toString({ collectionStyle: 'any' })).toBe('{ foo: [ bar ] }\n')
})

test("collectionStyle: 'block'", () => {
const doc = new YAML.Document({ foo: ['bar'] })
expect(doc.toString({ collectionStyle: 'block' })).toBe('foo:\n - bar\n')

doc.contents.flow = false
doc.get('foo').flow = true
expect(doc.toString({ collectionStyle: 'block' })).toBe('foo:\n - bar\n')

doc.contents.flow = true
doc.get('foo').flow = false
expect(doc.toString({ collectionStyle: 'block' })).toBe('foo:\n - bar\n')
})

test("collectionStyle: 'flow'", () => {
const doc = new YAML.Document({ foo: ['bar'] })
expect(doc.toString({ collectionStyle: 'flow' })).toBe('{ foo: [ bar ] }\n')

doc.get('foo').flow = true
expect(doc.toString({ collectionStyle: 'flow' })).toBe('{ foo: [ bar ] }\n')

doc.contents.flow = true
doc.get('foo').flow = false
expect(doc.toString({ collectionStyle: 'flow' })).toBe('{ foo: [ bar ] }\n')
})
})

describe('Scalar options', () => {
describe('defaultStringType & defaultKeyType', () => {
test('PLAIN, PLAIN', () => {
Expand Down