From 2a283c018592d8cc76f4ef83b69c6ce3c378aca6 Mon Sep 17 00:00:00 2001 From: Karsten Schmidt Date: Fri, 8 Jan 2021 00:48:24 +0000 Subject: [PATCH] feat(strings): add wordWrap*() fns --- packages/strings/src/index.ts | 1 + packages/strings/src/word-wrap.ts | 43 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 packages/strings/src/word-wrap.ts diff --git a/packages/strings/src/index.ts b/packages/strings/src/index.ts index 8d08ae5868..a1e4b53c16 100644 --- a/packages/strings/src/index.ts +++ b/packages/strings/src/index.ts @@ -27,3 +27,4 @@ export * from "./truncate-left"; export * from "./units"; export * from "./uuid"; export * from "./wrap"; +export * from "./word-wrap"; diff --git a/packages/strings/src/word-wrap.ts b/packages/strings/src/word-wrap.ts new file mode 100644 index 0000000000..a8deece03d --- /dev/null +++ b/packages/strings/src/word-wrap.ts @@ -0,0 +1,43 @@ +import { lengthAnsi } from "./ansi"; + +export const wordWrap = (str: string, lineWidth?: number) => + wordWrapLines(str, lineWidth).join("\n"); + +export const wordWrapLines = (str: string, lineWidth = 80) => { + const res: string[] = []; + for (let line of str.split("\n")) { + if (!line.length) { + res.push(""); + continue; + } + wordWrapLine(line, lineWidth, res); + } + return res; +}; + +export const wordWrapLine = ( + line: string, + lineWidth = 80, + acc: string[] = [] +) => { + let ln = 0; + let curr: string[] = []; + for (let w of line.split(" ")) { + const l = lengthAnsi(w) + (ln > 0 ? 1 : 0); + if (ln + l <= lineWidth) { + curr.push(w, " "); + ln += l; + } else { + acc.push(trimLine(curr)); + curr = [w, " "]; + ln = l; + } + } + ln && acc.push(trimLine(curr)); + return acc; +}; + +const trimLine = (x: string[]) => { + /^\s+$/.test(x[x.length - 1]) && x.pop(); + return x.join(""); +};