| 4056 | class Text { |
| 4057 | public: |
| 4058 | Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) |
| 4059 | : attr( _attr ) |
| 4060 | { |
| 4061 | std::string wrappableChars = " [({.,/|\\-"; |
| 4062 | std::size_t indent = _attr.initialIndent != std::string::npos |
| 4063 | ? _attr.initialIndent |
| 4064 | : _attr.indent; |
| 4065 | std::string remainder = _str; |
| 4066 | |
| 4067 | while( !remainder.empty() ) { |
| 4068 | if( lines.size() >= 1000 ) { |
| 4069 | lines.push_back( "... message truncated due to excessive size" ); |
| 4070 | return; |
| 4071 | } |
| 4072 | std::size_t tabPos = std::string::npos; |
| 4073 | std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); |
| 4074 | std::size_t pos = remainder.find_first_of( '\n' ); |
| 4075 | if( pos <= width ) { |
| 4076 | width = pos; |
| 4077 | } |
| 4078 | pos = remainder.find_last_of( _attr.tabChar, width ); |
| 4079 | if( pos != std::string::npos ) { |
| 4080 | tabPos = pos; |
| 4081 | if( remainder[width] == '\n' ) |
| 4082 | width--; |
| 4083 | remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); |
| 4084 | } |
| 4085 | |
| 4086 | if( width == remainder.size() ) { |
| 4087 | spliceLine( indent, remainder, width ); |
| 4088 | } |
| 4089 | else if( remainder[width] == '\n' ) { |
| 4090 | spliceLine( indent, remainder, width ); |
| 4091 | if( width <= 1 || remainder.size() != 1 ) |
| 4092 | remainder = remainder.substr( 1 ); |
| 4093 | indent = _attr.indent; |
| 4094 | } |
| 4095 | else { |
| 4096 | pos = remainder.find_last_of( wrappableChars, width ); |
| 4097 | if( pos != std::string::npos && pos > 0 ) { |
| 4098 | spliceLine( indent, remainder, pos ); |
| 4099 | if( remainder[0] == ' ' ) |
| 4100 | remainder = remainder.substr( 1 ); |
| 4101 | } |
| 4102 | else { |
| 4103 | spliceLine( indent, remainder, width-1 ); |
| 4104 | lines.back() += "-"; |
| 4105 | } |
| 4106 | if( lines.size() == 1 ) |
| 4107 | indent = _attr.indent; |
| 4108 | if( tabPos != std::string::npos ) |
| 4109 | indent += tabPos; |
| 4110 | } |
| 4111 | } |
| 4112 | } |
| 4113 | |
| 4114 | void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { |
| 4115 | lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); |