#include <iostream>
std::string fmt(size_t margin, size_t width, std::string text)
{
std::string result;
while (!text.empty())
{
result += std::string(margin, ' ');
if (width >= text.size())
return (result += text) += '\n';
size_t n = width - 1;
while (n > width / 2 && isalnum(text[n]) && isalnum(text[n - 1]))
--n; // between characters - reduce width until word break or 1/2 width left
(result += text.substr(0, n)) += '\n';
text.erase(0, n);
}
return result;
}
int main()
{
std::cout << fmt(5, 70,
"This is essentially what I do with large blocks of "
"descriptive text. It lets me see how long each of "
"the lines will be, but it's really a hassle, see?");
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RkOjpzdHJpbmcgZm10KHNpemVfdCBtYXJnaW4sIHNpemVfdCB3aWR0aCwgc3RkOjpzdHJpbmcgdGV4dCkKewoJc3RkOjpzdHJpbmcgcmVzdWx0OwoJd2hpbGUgKCF0ZXh0LmVtcHR5KCkpCgl7CgkJcmVzdWx0ICs9IHN0ZDo6c3RyaW5nKG1hcmdpbiwgJyAnKTsKCQlpZiAod2lkdGggPj0gdGV4dC5zaXplKCkpCgkJICAgIHJldHVybiAocmVzdWx0ICs9IHRleHQpICs9ICdcbic7CgkJc2l6ZV90IG4gPSB3aWR0aCAtIDE7CgkJd2hpbGUgKG4gPiB3aWR0aCAvIDIgJiYgaXNhbG51bSh0ZXh0W25dKSAmJiBpc2FsbnVtKHRleHRbbiAtIDFdKSkKCQkgICAgLS1uOyAvLyBiZXR3ZWVuIGNoYXJhY3RlcnMgLSByZWR1Y2Ugd2lkdGggdW50aWwgd29yZCBicmVhayBvciAxLzIgd2lkdGggbGVmdAoJCShyZXN1bHQgKz0gdGV4dC5zdWJzdHIoMCwgbikpICs9ICdcbic7CgkJdGV4dC5lcmFzZSgwLCBuKTsKCX0KCXJldHVybiByZXN1bHQ7Cn0KCmludCBtYWluKCkKewoJc3RkOjpjb3V0IDw8IGZtdCg1LCA3MCwKCSAgICAiVGhpcyBpcyBlc3NlbnRpYWxseSB3aGF0IEkgZG8gd2l0aCBsYXJnZSBibG9ja3Mgb2YgIgogICAgICAgICJkZXNjcmlwdGl2ZSB0ZXh0LiBJdCBsZXRzIG1lIHNlZSBob3cgbG9uZyBlYWNoIG9mICIKICAgICAgICAidGhlIGxpbmVzIHdpbGwgYmUsIGJ1dCBpdCdzIHJlYWxseSBhIGhhc3NsZSwgc2VlPyIpOyAKCn0=