1 /*******************************************************************************
2  * tlx/string/word_wrap.cpp
3  *
4  * Part of tlx - http://panthema.net/tlx
5  *
6  * Copyright (C) 2016-2017 Timo Bingmann <tb@panthema.net>
7  *
8  * All rights reserved. Published under the Boost Software License, Version 1.0
9  ******************************************************************************/
10 
11 #include <tlx/string/word_wrap.hpp>
12 
13 #include <cctype>
14 
15 namespace tlx {
16 
is_space(char ch)17 bool is_space(char ch) {
18     return ch == ' ' || ch == '\f' || ch == '\t' ||
19            ch == '\r' || ch == '\n' || ch == '\v';
20 }
21 
word_wrap(const std::string & str,unsigned int wrap)22 std::string word_wrap(const std::string& str, unsigned int wrap) {
23     std::string out;
24     out.resize(str.size());
25 
26     std::string::size_type i = 0, last_space;
27 
28     while (i < str.size())
29     {
30         last_space = std::string::npos;
31 
32         // copy string until the end of the line is reached
33         for (std::string::size_type count = 0; count < wrap; ++count)
34         {
35             if (i == str.size()) {
36                 // end of string reached
37                 return out;
38             }
39 
40             out[i] = str[i];
41 
42             // check for newlines in input and reset counter
43             if (out[i] == '\n')
44                 count = 0;
45             // save last space position
46             if (is_space(out[i]))
47                 last_space = i;
48 
49             ++i;
50         }
51 
52         if (last_space != std::string::npos)
53         {
54             // turn last space into newline and step counter back
55             out[last_space] = '\n';
56 
57             if (i == str.size()) {
58                 // end of string reached
59                 return out;
60             }
61 
62             i = last_space + 1;
63         }
64         else
65         {
66             // no space in last line, copy until we find one
67             while (i != str.size() && !is_space(str[i]))
68                 out[i] = str[i], ++i;
69 
70             if (i == str.size()) {
71                 // end of string reached
72                 return out;
73             }
74 
75             out[i] = '\n';
76             ++i;
77         }
78     }
79 
80     return out;
81 }
82 
83 } // namespace tlx
84 
85 /******************************************************************************/
86