Skip to content

Commit

Permalink
feat(strings): add tab conversion fns
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jan 8, 2021
1 parent 2a283c0 commit aefdd97
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/strings/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export * from "./repeat";
export * from "./slugify";
export * from "./splice";
export * from "./split";
export * from "./tabs";
export * from "./trim";
export * from "./truncate";
export * from "./truncate-left";
Expand Down
94 changes: 94 additions & 0 deletions packages/strings/src/tabs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { repeat } from "./repeat";

const nextTab = (x: number, tabSize: number) =>
Math.floor((x + tabSize) / tabSize) * tabSize;

/**
* Multi-line version of {@link tabsToSpacesLine}.
*
* @example
* ```ts
* console.log(
* tabsToSpaces("0\t1\t2", 10)
* + "\n" +
* tabsToSpaces("0\t45\t890\t\t6\t0")
* + "\n" +
* tabsToSpaces("^\t^\t^\t^\t^\t^")
* );
* // 0 1 2
* // 0 45 890 6 0
* // ^ ^ ^ ^ ^ ^
* ```
*
* @param src
* @param tabSize
*/
export const tabsToSpaces = (src: string, tabSize = 4) =>
src
.split(/\r?\n/g)
.map((line) => tabsToSpacesLine(line, tabSize))
.join("\n");

/**
* Takes a single line string and converts all tab characters to spaces, using
* given `tabSize`.
*
* @param line
* @param tabSize
*/
export const tabsToSpacesLine = (line: string, tabSize = 4) => {
let res = "";
let words = line.split(/\t/g);
let n = words.length - 1;
for (let i = 0; i < n; i++) {
const w = words[i];
res += w;
res += repeat(" ", nextTab(res.length, tabSize) - res.length);
}
res += words[n];
return res;
};

/**
* Multi-line version of {@link spacesToTabsLine}.
*
* @param src
* @param tabSize
*/
export const spacesToTabs = (src: string, tabSize = 4) =>
src
.split(/\r?\n/g)
.map((line) => spacesToTabsLine(line, tabSize))
.join("\n");

/**
* Takes a single line string and converts all tab characters to spaces, using
* given `tabSize`. Inverse op of {@link tabsToSpacesLine}.
*
* @param line
* @param tabSize
*/
export const spacesToTabsLine = (line: string, tabSize = 4) => {
const re = /\s{2,}/g;
let i = 0;
let res = "";
let m: RegExpExecArray | null;
while ((m = re.exec(line))) {
const numSpaces = m[0].length;
res += line.substring(i, m.index);
i = m.index;
const end = m.index + numSpaces;
while (i < end) {
const j = nextTab(i, tabSize);
if (j <= end) {
res += "\t";
i = j;
} else {
res += repeat(" ", end - i);
i = end;
}
}
i = end;
}
return res + line.substr(i);
};

0 comments on commit aefdd97

Please sign in to comment.