blob: 9fbd38842adf5bb2a74982b4d0fb9b3819e35967 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include "wrap.h"
#include <library/cpp/colorizer/colors.h>
#include <util/generic/string.h>
#include <util/stream/str.h>
#include <util/charset/utf8.h>
#include <cctype>
namespace NLastGetopt {
TString Wrap(ui32 width, TStringBuf text, TStringBuf indent, size_t* lastLineLen, bool* hasParagraphs) {
if (width == 0) {
return TString(text);
}
if (width >= indent.size()) {
width -= indent.size();
}
if (hasParagraphs) {
*hasParagraphs = false;
}
TString res;
auto os = TStringOutput(res);
const char* spaceBegin = text.begin();
const char* wordBegin = text.begin();
const char* wordEnd = text.begin();
const char* end = text.end();
size_t lenSoFar = 0;
bool isPreParagraph = false;
do {
spaceBegin = wordBegin = wordEnd;
while (wordBegin < end && *wordBegin == ' ') {
wordBegin++;
}
if (wordBegin == end) {
break;
}
wordEnd = wordBegin;
while (wordEnd < end && *wordEnd != ' ' && *wordEnd != '\n') {
wordEnd++;
}
auto spaces = TStringBuf(spaceBegin, wordBegin);
auto word = TStringBuf(wordBegin, wordEnd);
size_t spaceLen = spaces.size();
size_t wordLen = 0;
if (!GetNumberOfUTF8Chars(word.data(), word.size(), wordLen)) {
wordLen = word.size(); // not a utf8 string -- just use its binary size
}
wordLen -= NColorizer::TotalAnsiEscapeCodeLen(word);
// Empty word means we've found a bunch of whitespaces followed by newline.
// We don't want to print trailing whitespaces.
if (word) {
// We can't fit this word into the line -- insert additional line break.
// We shouldn't insert line breaks if we're at the beginning of a line, hence `lenSoFar` check.
if (lenSoFar && lenSoFar + spaceLen + wordLen > width) {
os << Endl << indent << word;
lenSoFar = wordLen;
} else {
os << spaces << word;
lenSoFar += spaceLen + wordLen;
}
isPreParagraph = false;
}
if (wordEnd != end && *wordEnd == '\n') {
os << Endl << indent;
lenSoFar = 0;
wordEnd++;
if (hasParagraphs && isPreParagraph) {
*hasParagraphs = true;
} else {
isPreParagraph = true;
}
continue;
}
} while (wordEnd < end);
if (lastLineLen) {
*lastLineLen = lenSoFar;
}
return res;
}
}
|