Skip to content

Commit 46a816e

Browse files
committed
fix: Do not skip folding lines after the first in indented block scalars (fixes #529)
1 parent 750adbe commit 46a816e

File tree

2 files changed

+75
-33
lines changed

2 files changed

+75
-33
lines changed

src/stringify/foldFlowLines.ts

+19-10
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function foldFlowLines(
6767
let escStart = -1
6868
let escEnd = -1
6969
if (mode === FOLD_BLOCK) {
70-
i = consumeMoreIndentedLines(text, i)
70+
i = consumeMoreIndentedLines(text, i, indent.length)
7171
if (i !== -1) end = i + endStep
7272
}
7373
for (let ch; (ch = text[(i += 1)]); ) {
@@ -89,8 +89,9 @@ export function foldFlowLines(
8989
escEnd = i
9090
}
9191
if (ch === '\n') {
92-
if (mode === FOLD_BLOCK) i = consumeMoreIndentedLines(text, i)
93-
end = i + endStep
92+
if (mode === FOLD_BLOCK)
93+
i = consumeMoreIndentedLines(text, i, indent.length)
94+
end = i + indent.length + endStep
9495
split = undefined
9596
} else {
9697
if (
@@ -151,13 +152,21 @@ export function foldFlowLines(
151152
* Presumes `i + 1` is at the start of a line
152153
* @returns index of last newline in more-indented block
153154
*/
154-
function consumeMoreIndentedLines(text: string, i: number) {
155-
let ch = text[i + 1]
155+
function consumeMoreIndentedLines(text: string, i: number, indent: number) {
156+
let end = i
157+
let start = i + 1
158+
let ch = text[start]
156159
while (ch === ' ' || ch === '\t') {
157-
do {
158-
ch = text[(i += 1)]
159-
} while (ch && ch !== '\n')
160-
ch = text[i + 1]
160+
if (i < start + indent) {
161+
ch = text[++i]
162+
} else {
163+
do {
164+
ch = text[++i]
165+
} while (ch && ch !== '\n')
166+
end = i
167+
start = i + 1
168+
ch = text[start]
169+
}
161170
}
162-
return i
171+
return end
163172
}

tests/doc/foldFlowLines.ts

+56-23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as YAML from 'yaml'
22
import { foldFlowLines as fold, FoldOptions } from 'yaml/util'
33
import { source } from '../_utils'
44

5+
const FOLD_BLOCK = 'block'
56
const FOLD_FLOW = 'flow'
67
const FOLD_QUOTED = 'quoted'
78

@@ -278,31 +279,33 @@ describe('end-to-end', () => {
278279
const foldOptions = { lineWidth: 20, minContentWidth: 0 }
279280

280281
test('more-indented folded block', () => {
281-
const src = `> # comment with an excessive length that won't get folded
282-
Text on a line that
283-
should get folded
284-
with a line width of
285-
20 characters.
282+
const src = source`
283+
> # comment with an excessive length that won't get folded
284+
Text on a line that
285+
should get folded
286+
with a line width of
287+
20 characters.
286288
287-
Indented text
288-
that appears to be
289-
folded but is not.
289+
Indented text
290+
that appears to be
291+
folded but is not.
290292
291-
Text that is prevented from folding due to being more-indented.
293+
Text that is prevented from folding due to being more-indented.
292294
293-
Unfolded paragraph.\n`
295+
Unfolded paragraph.
296+
`
294297
const doc = YAML.parseDocument<YAML.Scalar, false>(src)
295-
expect(doc.contents.value).toBe(
296-
`Text on a line that should get folded with a line width of 20 characters.
298+
expect(doc.contents.value).toBe(source`
299+
Text on a line that should get folded with a line width of 20 characters.
297300
298-
Indented text
299-
that appears to be
300-
folded but is not.
301+
Indented text
302+
that appears to be
303+
folded but is not.
301304
302-
Text that is prevented from folding due to being more-indented.
305+
Text that is prevented from folding due to being more-indented.
303306
304-
Unfolded paragraph.\n`
305-
)
307+
Unfolded paragraph.
308+
`)
306309
expect(doc.toString(foldOptions)).toBe(src)
307310
})
308311

@@ -313,10 +316,12 @@ Unfolded paragraph.\n`
313316
})
314317

315318
test('plain string', () => {
316-
const src = `- plain value with
317-
enough length to
318-
fold twice
319-
- plain with comment # that won't get folded\n`
319+
const src = source`
320+
- plain value with
321+
enough length to
322+
fold twice
323+
- plain with comment # that won't get folded
324+
`
320325
const doc = YAML.parseDocument<YAML.YAMLSeq<YAML.Scalar>, false>(src)
321326
expect(doc.contents.items[0].value).toBe(
322327
'plain value with enough length to fold twice'
@@ -326,7 +331,8 @@ Unfolded paragraph.\n`
326331
})
327332

328333
test('long line width', () => {
329-
const src = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. In laoreet massa eros, dignissim aliquam nunc elementum sit amet. Mauris pulvinar nunc eget ante sodales viverra. Vivamus quis convallis sapien, ut auctor magna. Cras volutpat erat eu lacus luctus facilisis. Aenean sapien leo, auctor sed tincidunt at, scelerisque a urna. Nunc ullamcorper, libero non mollis aliquet, nulla diam lobortis neque, ac rutrum dui nibh iaculis lectus. Aenean lobortis interdum arcu eget sollicitudin.
334+
const src = `\
335+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In laoreet massa eros, dignissim aliquam nunc elementum sit amet. Mauris pulvinar nunc eget ante sodales viverra. Vivamus quis convallis sapien, ut auctor magna. Cras volutpat erat eu lacus luctus facilisis. Aenean sapien leo, auctor sed tincidunt at, scelerisque a urna. Nunc ullamcorper, libero non mollis aliquet, nulla diam lobortis neque, ac rutrum dui nibh iaculis lectus. Aenean lobortis interdum arcu eget sollicitudin.
330336
331337
Duis quam enim, ultricies a enim non, tincidunt lobortis ipsum. Mauris condimentum ultrices eros rutrum euismod. Fusce et mi eget quam dapibus blandit. Maecenas sodales tempor euismod. Phasellus vulputate purus felis, eleifend ullamcorper tortor semper sit amet. Sed nunc quam, iaculis et neque sit amet, consequat egestas lectus. Aenean dapibus lorem sed accumsan porttitor. Curabitur eu magna congue, mattis urna ac, lacinia eros. In in iaculis justo, nec faucibus enim. Fusce id viverra purus, nec ultricies mi. Aliquam eu risus risus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse potenti. \n`
332338

@@ -338,4 +344,31 @@ Duis quam enim, ultricies a enim non, tincidunt lobortis ipsum. Mauris condiment
338344
for (const lineWidth of [1000, 0, -1])
339345
expect(YAML.stringify(src, { lineWidth })).toBe(exp)
340346
})
347+
348+
test('multiple lines', () => {
349+
const src = source`
350+
first line which is long enough to be wrapped to another line
351+
second line which is long enough to be wrapped to another line
352+
third line which is not wrapped because it's indented
353+
fourth line which is long enough to be wrapped to another line
354+
`
355+
expect(YAML.stringify({ src }, { lineWidth: 20, minContentWidth: 0 }))
356+
.toBe(source`
357+
src: >
358+
first line which
359+
is long enough to
360+
be wrapped to
361+
another line
362+
363+
second line which
364+
is long enough to
365+
be wrapped to
366+
another line
367+
third line which is not wrapped because it's indented
368+
fourth line which
369+
is long enough to
370+
be wrapped to
371+
another line
372+
`)
373+
})
341374
})

0 commit comments

Comments
 (0)