@thi.ng/strings 3.7.2 → 3.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/word-wrap.js CHANGED
@@ -1,154 +1,91 @@
1
1
  import { lengthAnsi } from "./ansi.js";
2
2
  import { split } from "./split.js";
3
- /**
4
- * Internal representation of a single line (for word wrapping purposes). A thin
5
- * wrapper of individual word and the _logical_ line length (rather than the
6
- * actualy string width).
7
- *
8
- * @internal
9
- */
10
3
  class Line {
11
- n = 0;
12
- w = [];
13
- constructor(word, n) {
14
- word != null && this.add(word, n);
15
- }
16
- add(word, n = word.length) {
17
- this.w.push(word);
18
- this.n += n + ~~(this.n > 0);
19
- return this;
20
- }
21
- toString() {
22
- return this.w.join(" ");
23
- }
4
+ n = 0;
5
+ w = [];
6
+ constructor(word, n) {
7
+ word != null && this.add(word, n);
8
+ }
9
+ add(word, n = word.length) {
10
+ this.w.push(word);
11
+ this.n += n + ~~(this.n > 0);
12
+ return this;
13
+ }
14
+ toString() {
15
+ return this.w.join(" ");
16
+ }
24
17
  }
25
- /**
26
- * (Default) wordwrap word splitting strategy for plain text.
27
- */
28
- export const SPLIT_PLAIN = {
29
- length: (x) => x.length,
30
- split: (_, max) => max,
18
+ const SPLIT_PLAIN = {
19
+ length: (x) => x.length,
20
+ split: (_, max) => max
31
21
  };
32
- /**
33
- * Wordwrap word splitting strategy for text containing ANSI control sequences.
34
- */
35
- export const SPLIT_ANSI = {
36
- length: lengthAnsi,
37
- split: (x, max) => {
38
- const re = /\x1b\[[0-9;]+m/g;
39
- let i = max;
40
- let match;
41
- while ((match = re.exec(x))) {
42
- if (match.index >= max)
43
- break;
44
- const n = match[0].length;
45
- i += n;
46
- max += n;
47
- }
48
- return i;
49
- },
22
+ const SPLIT_ANSI = {
23
+ length: lengthAnsi,
24
+ split: (x, max) => {
25
+ const re = /\x1b\[[0-9;]+m/g;
26
+ let i = max;
27
+ let match;
28
+ while (match = re.exec(x)) {
29
+ if (match.index >= max)
30
+ break;
31
+ const n = match[0].length;
32
+ i += n;
33
+ max += n;
34
+ }
35
+ return i;
36
+ }
50
37
  };
51
- /**
52
- * Attempts to append given word to current line or else creates a new line.
53
- *
54
- * @internal
55
- */
56
38
  const append = (acc, word, wordLen, width) => {
57
- const curr = acc[acc.length - 1];
58
- curr && width - curr.n > wordLen
59
- ? curr.add(word, wordLen)
60
- : acc.push(new Line(word, wordLen));
39
+ const curr = acc[acc.length - 1];
40
+ curr && width - curr.n > wordLen ? curr.add(word, wordLen) : acc.push(new Line(word, wordLen));
61
41
  };
62
- /**
63
- * Depending on wrap mode (hard/soft), splits too long words into multiple lines
64
- * and appends them to `acc`.
65
- *
66
- * @remarks
67
- * Splitting uses the provided {@link IWordSplit} impl (or, if missing,
68
- * {@link SPLIT_PLAIN}). If the current start line only has less than
69
- * {@link WordWrapOpts.min} chars available and the word is longer than that, it
70
- * will be placed into a new line (thus minimizing legibility issues).
71
- *
72
- * @param word -
73
- * @param opts -
74
- * @param offset -
75
- * @param acc -
76
- *
77
- * @internal
78
- */
79
42
  const wrapWord = (word, { width, min, hard, splitter }, offset = 0, acc = []) => {
80
- let len = splitter.length(word);
81
- let free = width - offset;
82
- // don't start word in current line if only
83
- // a few chars left...
84
- if (free < min && free < len) {
85
- free = width;
86
- }
87
- // (maybe) hardwrap long word
88
- while (hard && len > free) {
89
- const split = splitter.split(word, free);
90
- const chunk = word.substring(0, split);
91
- append(acc, chunk, free, width);
92
- word = word.substring(split);
93
- free = width;
94
- len = splitter.length(word);
95
- }
96
- append(acc, word, len, width);
97
- return acc;
43
+ let len = splitter.length(word);
44
+ let free = width - offset;
45
+ if (free < min && free < len) {
46
+ free = width;
47
+ }
48
+ while (hard && len > free) {
49
+ const split2 = splitter.split(word, free);
50
+ const chunk = word.substring(0, split2);
51
+ append(acc, chunk, free, width);
52
+ word = word.substring(split2);
53
+ free = width;
54
+ len = splitter.length(word);
55
+ }
56
+ append(acc, word, len, width);
57
+ return acc;
98
58
  };
99
- /**
100
- * Wordwraps a single-`line` string using provided options. Returns array of
101
- * {@link Line} objects, which can simply be `.join("\n")`ed to convert back
102
- * into text.
103
- *
104
- * @see {@link wordWrap} for main user facing alternative.
105
- *
106
- * @param line -
107
- * @param opts -
108
- * @param acc -
109
- *
110
- * @internal
111
- */
112
- export const wordWrapLine = (line, opts, acc = []) => {
113
- if (!line.length) {
114
- acc.push(new Line());
115
- return acc;
116
- }
117
- const $opts = {
118
- width: 80,
119
- min: 4,
120
- hard: false,
121
- splitter: SPLIT_PLAIN,
122
- ...opts,
123
- };
124
- for (let word of split(line, opts.delimWord || /\s/g)) {
125
- const curr = acc[acc.length - 1];
126
- wrapWord(word, $opts, curr && curr.n > 0 ? curr.n + 1 : 0, acc);
127
- }
59
+ const wordWrapLine = (line, opts, acc = []) => {
60
+ if (!line.length) {
61
+ acc.push(new Line());
128
62
  return acc;
63
+ }
64
+ const $opts = {
65
+ width: 80,
66
+ min: 4,
67
+ hard: false,
68
+ splitter: SPLIT_PLAIN,
69
+ ...opts
70
+ };
71
+ for (let word of split(line, opts.delimWord || /\s/g)) {
72
+ const curr = acc[acc.length - 1];
73
+ wrapWord(word, $opts, curr && curr.n > 0 ? curr.n + 1 : 0, acc);
74
+ }
75
+ return acc;
129
76
  };
130
- /**
131
- * Wordwraps a multi-`line` string using provided options. Returns array of
132
- * {@link Line} objects, which can simply be `.join("\n")`ed to convert back
133
- * into text.
134
- *
135
- * @see {@link wordWrap} for main user facing alternative.
136
- *
137
- * @param lines -
138
- * @param opts -
139
- */
140
- export const wordWrapLines = (lines, opts) => {
141
- let acc = [];
142
- for (let line of split(lines, opts.delimLine)) {
143
- acc = acc.concat(wordWrapLine(line, opts));
144
- }
145
- return acc;
77
+ const wordWrapLines = (lines, opts) => {
78
+ let acc = [];
79
+ for (let line of split(lines, opts.delimLine)) {
80
+ acc = acc.concat(wordWrapLine(line, opts));
81
+ }
82
+ return acc;
83
+ };
84
+ const wordWrap = (str, opts) => wordWrapLines(str, opts).join("\n");
85
+ export {
86
+ SPLIT_ANSI,
87
+ SPLIT_PLAIN,
88
+ wordWrap,
89
+ wordWrapLine,
90
+ wordWrapLines
146
91
  };
147
- /**
148
- * Same as {@link wordWrapLines}, but returns wordwrapped result as string. See
149
- * {@link WordWrapOpts} for options.
150
- *
151
- * @param str -
152
- * @param opts -
153
- */
154
- export const wordWrap = (str, opts) => wordWrapLines(str, opts).join("\n");
package/wrap.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { memoizeJ } from "@thi.ng/memoize/memoizej";
2
- /**
3
- * Returns a {@link Stringer} which wrap inputs with given `pad` string on
4
- * both sides.
5
- */
6
- export const wrap = memoizeJ((pad) => (x) => pad + x + pad);
2
+ const wrap = memoizeJ(
3
+ (pad) => (x) => pad + x + pad
4
+ );
5
+ export {
6
+ wrap
7
+ };