| 373 | } |
| 374 | |
| 375 | bool word_wrap(std::vector<std::string> *out, const std::string &str, size_t line_length, |
| 376 | word_wrap_whitespace_mode mode) |
| 377 | { |
| 378 | if (line_length == 0) |
| 379 | line_length = SIZE_MAX; |
| 380 | |
| 381 | std::string line; |
| 382 | size_t break_pos = 0; |
| 383 | bool ignore_whitespace = false; |
| 384 | |
| 385 | for (auto &c : str) |
| 386 | { |
| 387 | if (c == '\n') |
| 388 | { |
| 389 | out->push_back(line); |
| 390 | line.clear(); |
| 391 | break_pos = 0; |
| 392 | ignore_whitespace = (mode == WSMODE_TRIM_LEADING); |
| 393 | continue; |
| 394 | } |
| 395 | |
| 396 | if (isspace(c)) |
| 397 | { |
| 398 | if (ignore_whitespace || (mode == WSMODE_COLLAPSE_ALL && break_pos == line.length())) |
| 399 | continue; |
| 400 | |
| 401 | line.push_back((mode == WSMODE_COLLAPSE_ALL) ? ' ' : c); |
| 402 | break_pos = line.length(); |
| 403 | } |
| 404 | else |
| 405 | { |
| 406 | line.push_back(c); |
| 407 | ignore_whitespace = false; |
| 408 | } |
| 409 | |
| 410 | if (line.length() > line_length) |
| 411 | { |
| 412 | if (break_pos > 0) |
| 413 | { |
| 414 | // Break before last space, and skip that space |
| 415 | out->push_back(line.substr(0, break_pos - 1)); |
| 416 | } |
| 417 | else |
| 418 | { |
| 419 | // Single word is too long, just break it |
| 420 | out->push_back(line.substr(0, line_length)); |
| 421 | break_pos = line_length; |
| 422 | } |
| 423 | line = line.substr(break_pos); |
| 424 | break_pos = 0; |
| 425 | ignore_whitespace = (mode == WSMODE_TRIM_LEADING); |
| 426 | } |
| 427 | } |
| 428 | if (line.length()) |
| 429 | out->push_back(line); |
| 430 | |
| 431 | return true; |
| 432 | } |