return (unsigned) c;
}
-// ---------------------------------------------------------------------------
std::string mbs_substr_by_width(
const std::string & str,
return string();
return string(sptr, eptr - sptr);
}
-
-// ---------------------------------------------------------------------------
-
-void mbs_write_wrapped(ostream & out, const string & text,
- unsigned indent, unsigned wrap_width, int initial)
-{
- const char * s = text.c_str();
- size_t s_bytes = text.length();
- const char * prevwp = s;
- const char * linep = s;
- wchar_t wc;
- size_t bytes_read;
- bool in_word = false;
- bool in_ctrlseq = false;
-
- mbstate_t shift_state;
- memset (&shift_state, 0, sizeof (shift_state));
-
- unsigned col = 0;
- unsigned toindent = initial < 0 ? indent : initial;
- do
- {
- // indentation
- if (!col)
- {
- out << string(toindent, ' ');
- col = toindent;
- }
-
- bytes_read = mbrtowc (&wc, s, s_bytes, &shift_state);
- if (bytes_read > 0)
- {
- // ignore the length of terminal control sequences in order
- // to wrap colored text correctly
- if (!in_ctrlseq && ::wcsncmp(&wc, L"\033", 1) == 0)
- in_ctrlseq = true;
- else if (in_ctrlseq && ::wcsncmp(&wc, L"m", 1) == 0)
- in_ctrlseq = false;
- else if (!in_ctrlseq)
- col += ::wcwidth(wc);
-
- if (::iswspace(wc))
- in_word = false;
- //else if (::wcscmp(wc, L"\n"))
- //{
- // if (!in_word)
- // prevwp = s;
- // in_word = true;
- //}
- else
- {
- if (!in_word)
- prevwp = s;
- in_word = true;
- }
-
- // current wc exceeded the wrap width
- if (col > wrap_width)
- {
- bool wanthyphen = false;
- // A single word is longer than the wrap width. Split the word and
- // append a hyphen at the end of the line. This won't normally happen,
- // but it can eventually happen e.g. with paths or too low screen widths.
- //! \todo make word-splitting more intelligent, e.g. if the word already
- //! contains a hyphen, split there; do not split because
- //! of a non-alphabet character; do not leave orphans, etc...
- if (linep == prevwp)
- {
- prevwp = s - 2;
- wanthyphen = true;
- }
-
- // update the size of the string to read
- s_bytes -= (prevwp - linep);
- // print the line, leave linep point to the start of the last word.
- for (; linep < prevwp; ++linep)
- out << *linep;
- if (wanthyphen)
- out << "-";
- out << endl;
- // reset column counter
- col = 0;
- toindent = indent;
- // reset original text pointer (points to current wc, not the start of the word)
- s = linep;
- // reset shift state
- ::memset (&shift_state, 0, sizeof (shift_state));
- }
- else
- s += bytes_read;
- }
- // we're at the end of the string
- else
- {
- // print the rest of the text
- for(; *linep; ++linep)
- out << *linep;
- }
- }
- while(bytes_read > 0);
-}
/** Returns the column width of a multi-byte character string \a str */
unsigned mbs_width (const std::string & str);
-/**
- * Wrap and indent given \a text and write it to the output stream \a out.
- *
- * TODO
- * - delete whitespace at the end of lines
- * - keep one-letter words with the next
- *
- * \param out output stream to write to
- * \param test text to wrap
- * \param indent number of columns by which to indent the whole text
- * \param wrap_width number of columns the text should be wrapped into
- * \param initial number of columns by which the first line should be indented
- * by default, the first line is indented by \a indent
- *
- */
-void mbs_write_wrapped (
- std::ostream & out,
- const std::string & text,
- unsigned indent, unsigned wrap_width, int initial = -1);
-
/**
* Returns a substring of a multi-byte character string \a str starting
* at screen column \a pos and being \a n columns wide, as far as possible