Skip to content

Commit

Permalink
fix: Do not skip folding lines after the first in indented block scal…
Browse files Browse the repository at this point in the history
…ars (fixes #529)
  • Loading branch information
eemeli committed Mar 6, 2024
1 parent 750adbe commit 46a816e
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 33 deletions.
29 changes: 19 additions & 10 deletions src/stringify/foldFlowLines.ts
Expand Up @@ -67,7 +67,7 @@ export function foldFlowLines(
let escStart = -1
let escEnd = -1
if (mode === FOLD_BLOCK) {
i = consumeMoreIndentedLines(text, i)
i = consumeMoreIndentedLines(text, i, indent.length)
if (i !== -1) end = i + endStep
}
for (let ch; (ch = text[(i += 1)]); ) {
Expand All @@ -89,8 +89,9 @@ export function foldFlowLines(
escEnd = i
}
if (ch === '\n') {
if (mode === FOLD_BLOCK) i = consumeMoreIndentedLines(text, i)
end = i + endStep
if (mode === FOLD_BLOCK)
i = consumeMoreIndentedLines(text, i, indent.length)
end = i + indent.length + endStep
split = undefined
} else {
if (
Expand Down Expand Up @@ -151,13 +152,21 @@ export function foldFlowLines(
* Presumes `i + 1` is at the start of a line
* @returns index of last newline in more-indented block
*/
function consumeMoreIndentedLines(text: string, i: number) {
let ch = text[i + 1]
function consumeMoreIndentedLines(text: string, i: number, indent: number) {
let end = i
let start = i + 1
let ch = text[start]
while (ch === ' ' || ch === '\t') {
do {
ch = text[(i += 1)]
} while (ch && ch !== '\n')
ch = text[i + 1]
if (i < start + indent) {
ch = text[++i]
} else {
do {
ch = text[++i]
} while (ch && ch !== '\n')
end = i
start = i + 1
ch = text[start]
}
}
return i
return end
}
79 changes: 56 additions & 23 deletions tests/doc/foldFlowLines.ts
Expand Up @@ -2,6 +2,7 @@ import * as YAML from 'yaml'
import { foldFlowLines as fold, FoldOptions } from 'yaml/util'
import { source } from '../_utils'

const FOLD_BLOCK = 'block'

Check failure on line 5 in tests/doc/foldFlowLines.ts

View workflow job for this annotation

GitHub Actions / typescript

'FOLD_BLOCK' is declared but its value is never read.
const FOLD_FLOW = 'flow'
const FOLD_QUOTED = 'quoted'

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

test('more-indented folded block', () => {
const src = `> # comment with an excessive length that won't get folded
Text on a line that
should get folded
with a line width of
20 characters.
const src = source`
> # comment with an excessive length that won't get folded
Text on a line that
should get folded
with a line width of
20 characters.
Indented text
that appears to be
folded but is not.
Indented text
that appears to be
folded but is not.
Text that is prevented from folding due to being more-indented.
Text that is prevented from folding due to being more-indented.
Unfolded paragraph.\n`
Unfolded paragraph.
`
const doc = YAML.parseDocument<YAML.Scalar, false>(src)
expect(doc.contents.value).toBe(
`Text on a line that should get folded with a line width of 20 characters.
expect(doc.contents.value).toBe(source`
Text on a line that should get folded with a line width of 20 characters.
Indented text
that appears to be
folded but is not.
Indented text
that appears to be
folded but is not.
Text that is prevented from folding due to being more-indented.
Text that is prevented from folding due to being more-indented.
Unfolded paragraph.\n`
)
Unfolded paragraph.
`)
expect(doc.toString(foldOptions)).toBe(src)
})

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

test('plain string', () => {
const src = `- plain value with
enough length to
fold twice
- plain with comment # that won't get folded\n`
const src = source`
- plain value with
enough length to
fold twice
- plain with comment # that won't get folded
`
const doc = YAML.parseDocument<YAML.YAMLSeq<YAML.Scalar>, false>(src)
expect(doc.contents.items[0].value).toBe(
'plain value with enough length to fold twice'
Expand All @@ -326,7 +331,8 @@ Unfolded paragraph.\n`
})

test('long line width', () => {
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.
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.
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`

Expand All @@ -338,4 +344,31 @@ Duis quam enim, ultricies a enim non, tincidunt lobortis ipsum. Mauris condiment
for (const lineWidth of [1000, 0, -1])
expect(YAML.stringify(src, { lineWidth })).toBe(exp)
})

test('multiple lines', () => {
const src = source`
first line which is long enough to be wrapped to another line
second line which is long enough to be wrapped to another line
third line which is not wrapped because it's indented
fourth line which is long enough to be wrapped to another line
`
expect(YAML.stringify({ src }, { lineWidth: 20, minContentWidth: 0 }))
.toBe(source`
src: >
first line which
is long enough to
be wrapped to
another line
second line which
is long enough to
be wrapped to
another line
third line which is not wrapped because it's indented
fourth line which
is long enough to
be wrapped to
another line
`)
})
})

0 comments on commit 46a816e

Please sign in to comment.