Skip to content

Commit 280edb6

Browse files
committed
Extract 'getBlockStringIndentation' function
1 parent 3e84962 commit 280edb6

File tree

2 files changed

+60
-16
lines changed

2 files changed

+60
-16
lines changed

src/language/__tests__/blockString-test.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99

1010
import { expect } from 'chai';
1111
import { describe, it } from 'mocha';
12-
import { dedentBlockStringValue, printBlockString } from '../blockString';
12+
import {
13+
dedentBlockStringValue,
14+
getBlockStringIndentation,
15+
printBlockString,
16+
} from '../blockString';
1317

1418
function joinLines(...args) {
1519
return args.join('\n');
@@ -99,6 +103,37 @@ describe('dedentBlockStringValue', () => {
99103
});
100104
});
101105

106+
describe('getBlockStringIndentation', () => {
107+
it('returns zero for an empty array', () => {
108+
expect(getBlockStringIndentation([])).to.equal(0);
109+
});
110+
111+
it('do not take first line into account', () => {
112+
expect(getBlockStringIndentation([' a'])).to.equal(0);
113+
expect(getBlockStringIndentation([' a', ' b'])).to.equal(2);
114+
});
115+
116+
it('returns minimal indentation length', () => {
117+
expect(getBlockStringIndentation(['', ' a', ' b'])).to.equal(1);
118+
expect(getBlockStringIndentation(['', ' a', ' b'])).to.equal(1);
119+
expect(getBlockStringIndentation(['', ' a', ' b', 'c'])).to.equal(0);
120+
});
121+
122+
it('count both tab and space as single character', () => {
123+
expect(getBlockStringIndentation(['', '\ta', ' b'])).to.equal(1);
124+
expect(getBlockStringIndentation(['', '\t a', ' b'])).to.equal(2);
125+
expect(getBlockStringIndentation(['', ' \t a', ' b'])).to.equal(3);
126+
});
127+
128+
it('do not take empty lines into account', () => {
129+
expect(getBlockStringIndentation(['a', '\t'])).to.equal(0);
130+
expect(getBlockStringIndentation(['a', ' '])).to.equal(0);
131+
expect(getBlockStringIndentation(['a', ' ', ' b'])).to.equal(2);
132+
expect(getBlockStringIndentation(['a', ' ', ' b'])).to.equal(2);
133+
expect(getBlockStringIndentation(['a', '', ' b'])).to.equal(1);
134+
});
135+
});
136+
102137
describe('printBlockString', () => {
103138
it('by default print block strings as single line', () => {
104139
const str = 'one liner';

src/language/blockString.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,9 @@ export function dedentBlockStringValue(rawString: string): string {
1818
const lines = rawString.split(/\r\n|[\n\r]/g);
1919

2020
// Remove common indentation from all lines but first.
21-
let commonIndent = null;
22-
for (let i = 1; i < lines.length; i++) {
23-
const line = lines[i];
24-
const indent = leadingWhitespace(line);
25-
if (
26-
indent < line.length &&
27-
(commonIndent === null || indent < commonIndent)
28-
) {
29-
commonIndent = indent;
30-
if (commonIndent === 0) {
31-
break;
32-
}
33-
}
34-
}
21+
const commonIndent = getBlockStringIndentation(lines);
3522

36-
if (commonIndent) {
23+
if (commonIndent !== 0) {
3724
for (let i = 1; i < lines.length; i++) {
3825
lines[i] = lines[i].slice(commonIndent);
3926
}
@@ -51,6 +38,28 @@ export function dedentBlockStringValue(rawString: string): string {
5138
return lines.join('\n');
5239
}
5340

41+
// @internal
42+
export function getBlockStringIndentation(lines: Array<string>): number {
43+
let commonIndent = null;
44+
45+
for (let i = 1; i < lines.length; i++) {
46+
const line = lines[i];
47+
const indent = leadingWhitespace(line);
48+
if (indent === line.length) {
49+
continue; // skip empty lines
50+
}
51+
52+
if (commonIndent === null || indent < commonIndent) {
53+
commonIndent = indent;
54+
if (commonIndent === 0) {
55+
break;
56+
}
57+
}
58+
}
59+
60+
return commonIndent === null ? 0 : commonIndent;
61+
}
62+
5463
function leadingWhitespace(str) {
5564
let i = 0;
5665
while (i < str.length && (str[i] === ' ' || str[i] === '\t')) {

0 commit comments

Comments
 (0)