27 if (s.empty())
return "";
28 std::vector<std::string> lines = absl::StrSplit(s,
'\n');
29 DCHECK_GE(lines.size(), 1);
32 const bool has_terminating_newline = lines.back().empty();
33 if (has_terminating_newline) lines.pop_back();
35 constexpr char kMultiLineCropTemplate[] =
"###% 4d LINES SKIPPED ###";
36 constexpr char kSingleLineCropTemplate[] =
" ..[% 4d CHARS CROPPED ].. ";
37 const int single_line_crop_template_length =
38 absl::StrFormat(kSingleLineCropTemplate, 0).size();
39 int num_lines_before = -1;
40 int num_lines_after = -1;
41 int num_lines_cropped = -1;
42 if (lines.size() > max_num_lines) {
43 num_lines_after = (max_num_lines - 1) / 2;
46 max_num_lines == 0 ? 0 : max_num_lines - 1 - num_lines_after;
47 num_lines_cropped = lines.size() - num_lines_before - num_lines_after;
48 lines.erase(lines.begin() + num_lines_before + 1,
49 lines.end() - num_lines_after);
52 lines[num_lines_before].clear();
54 for (std::string&
line : lines) {
55 if (
line.size() <= max_line_length)
continue;
56 const int num_chars_after = std::max(
58 (max_line_length - single_line_crop_template_length) / 2));
59 const int num_chars_before = std::max(
60 0,
static_cast<int>(max_line_length - single_line_crop_template_length -
63 line.substr(0, num_chars_before),
65 kSingleLineCropTemplate,
66 static_cast<int>(
line.size() - num_chars_after - num_chars_before)),
67 line.substr(
line.size() - num_chars_after));
69 if (num_lines_cropped >= 0) {
70 lines[num_lines_before] =
71 absl::StrFormat(kMultiLineCropTemplate, num_lines_cropped);
73 if (has_terminating_newline) lines.push_back(
"");
74 return absl::StrJoin(lines,
"\n");