Improved support for unicode including indeterminate progress bar. Updated unicode sample

This commit is contained in:
Pranav Srinivas Kumar
2020-05-23 17:15:18 -05:00
parent cf1f888a0f
commit 16eb028686
5 changed files with 469 additions and 38 deletions

View File

@@ -179,13 +179,30 @@ public:
: os(os), bar_width(bar_width), fill(fill), lead(lead) {}
std::ostream &write(size_t progress) {
for (size_t i = 0; i < bar_width; ++i) {
if (i < progress)
os << fill;
else if (i == progress)
os << lead;
else
os << fill;
for (size_t i = 0, current_display_width = 0; i < bar_width;) {
std::string next;
if (i < progress) {
next = fill;
current_display_width = unicode::display_width(fill);
} else if (i == progress) {
next = lead;
current_display_width = unicode::display_width(lead);
} else {
next = fill;
current_display_width = unicode::display_width(fill);
}
i += current_display_width;
if (i > bar_width) {
// `next` is larger than the allowed bar width
// fill with empty space instead
os << std::string((bar_width - (i - current_display_width)), ' ');
break;
}
os << next;
}
return os;
}

View File

@@ -77,7 +77,7 @@ struct interval {
};
/* auxiliary function for binary search in interval table */
static int bisearch(wchar_t ucs, const struct interval* table, int max) {
static inline int bisearch(wchar_t ucs, const struct interval* table, int max) {
int min = 0;
int mid;
@@ -129,7 +129,7 @@ static int bisearch(wchar_t ucs, const struct interval* table, int max) {
* in ISO 10646.
*/
int mk_wcwidth(wchar_t ucs)
static inline int mk_wcwidth(wchar_t ucs)
{
/* sorted list of non-overlapping intervals of non-spacing characters */
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
@@ -213,8 +213,7 @@ int mk_wcwidth(wchar_t ucs)
(ucs >= 0x30000 && ucs <= 0x3fffd)));
}
int mk_wcswidth(const wchar_t* pwcs, size_t n)
static inline int mk_wcswidth(const wchar_t* pwcs, size_t n)
{
int w, width = 0;
@@ -237,7 +236,7 @@ int mk_wcswidth(const wchar_t* pwcs, size_t n)
* the traditional terminal character-width behaviour. It is not
* otherwise recommended for general use.
*/
int mk_wcwidth_cjk(wchar_t ucs)
static inline int mk_wcwidth_cjk(wchar_t ucs)
{
/* sorted list of non-overlapping intervals of East Asian Ambiguous
* characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
@@ -304,8 +303,7 @@ int mk_wcwidth_cjk(wchar_t ucs)
return mk_wcwidth(ucs);
}
int mk_wcswidth_cjk(const wchar_t* pwcs, size_t n)
static inline int mk_wcswidth_cjk(const wchar_t* pwcs, size_t n)
{
int w, width = 0;
@@ -319,25 +317,25 @@ int mk_wcswidth_cjk(const wchar_t* pwcs, size_t n)
}
// convert UTF-8 string to wstring
std::wstring utf8_decode(const std::string& str) {
static inline std::wstring utf8_decode(const std::string& str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.from_bytes(str);
}
// convert wstring to UTF-8 string
std::string utf8_encode(const std::wstring& str) {
static inline std::string utf8_encode(const std::wstring& str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.to_bytes(str);
}
}
int display_width(const std::string& input) {
static inline int display_width(const std::string& input) {
using namespace unicode::details;
return mk_wcswidth(utf8_decode(input).c_str(), input.size());
}
int display_width(const std::wstring& input) {
static inline int display_width(const std::wstring& input) {
return details::mk_wcswidth(input.c_str(), input.size());
}