feat(token): Add optional suffix to label tokens

This commit is contained in:
Michael Carlberg 2016-12-04 04:03:17 +01:00
parent 70bd235e9e
commit 0cfddf7d72
5 changed files with 43 additions and 42 deletions

View File

@ -65,7 +65,7 @@ tray-padding = 2
[module/xwindow] [module/xwindow]
type = internal/xwindow type = internal/xwindow
label = %title:0:30% label = %title:0:30:...%
[module/xkeyboard] [module/xkeyboard]
type = internal/xkeyboard type = internal/xkeyboard

View File

@ -11,10 +11,11 @@ POLYBAR_NS
*/ */
namespace drawtypes { namespace drawtypes {
struct bounds { struct token {
string token; string token;
size_t min; size_t min;
size_t max; size_t max;
string suffix{""};
}; };
class label; class label;
@ -41,7 +42,7 @@ namespace drawtypes {
explicit label(string text, int font) : m_font(font), m_text(text), m_tokenized(m_text) {} explicit label(string text, int font) : m_font(font), m_text(text), m_tokenized(m_text) {}
explicit label(string text, string foreground = "", string background = "", string underline = "", explicit label(string text, string foreground = "", string background = "", string underline = "",
string overline = "", int font = 0, int padding = 0, int margin = 0, size_t maxlen = 0, bool ellipsis = true, string overline = "", int font = 0, int padding = 0, int margin = 0, size_t maxlen = 0, bool ellipsis = true,
const vector<struct bounds>& bound = {}) vector<token>&& tokens = {})
: m_foreground(foreground) : m_foreground(foreground)
, m_background(background) , m_background(background)
, m_underline(underline) , m_underline(underline)
@ -53,7 +54,7 @@ namespace drawtypes {
, m_ellipsis(ellipsis) , m_ellipsis(ellipsis)
, m_text(text) , m_text(text)
, m_tokenized(m_text) , m_tokenized(m_text)
, m_token_bounds(bound) {} , m_tokens(forward<vector<token>>(tokens)) {}
string get() const; string get() const;
operator bool(); operator bool();
@ -66,7 +67,7 @@ namespace drawtypes {
private: private:
string m_text, m_tokenized; string m_text, m_tokenized;
const vector<struct bounds> m_token_bounds; const vector<token> m_tokens;
}; };
label_t load_label(const config& conf, const string& section, string name, bool required = true, string def = ""); label_t load_label(const config& conf, const string& section, string name, bool required = true, string def = "");

View File

@ -16,12 +16,10 @@ namespace string_util {
string upper(const string& s); string upper(const string& s);
string lower(const string& s); string lower(const string& s);
bool compare(const string& s1, const string& s2); bool compare(const string& s1, const string& s2);
string replace( string replace(const string& haystack, const string& needle, const string& replacement, size_t start = 0,
const string& haystack, const string& needle, const string& reply, size_t start = 0, size_t end = string::npos); size_t end = string::npos);
string replace_all( string replace_all(const string& haystack, const string& needle, const string& replacement, size_t start = 0,
const string& haystack, const string& needle, const string& reply, size_t start = 0, size_t end = string::npos); size_t end = string::npos);
string replace_all_bounded(const string& haystack, string needle, string replacement, size_t min, size_t max,
size_t start = 0, size_t end = string::npos);
string squeeze(const string& haystack, char needle); string squeeze(const string& haystack, char needle);
string strip(const string& haystack, char needle); string strip(const string& haystack, char needle);
string strip_trailing_newline(const string& haystack); string strip_trailing_newline(const string& haystack);

View File

@ -14,8 +14,13 @@ namespace drawtypes {
} }
label_t label::clone() { label_t label::clone() {
vector<token> tokens;
if (!m_tokens.empty()) {
std::back_insert_iterator<decltype(tokens)> back_it(tokens);
std::copy(m_tokens.begin(), m_tokens.end(), back_it);
}
return make_shared<label>(m_text, m_foreground, m_background, m_underline, m_overline, m_font, m_padding, m_margin, return make_shared<label>(m_text, m_foreground, m_background, m_underline, m_overline, m_font, m_padding, m_margin,
m_maxlen, m_ellipsis, m_token_bounds); m_maxlen, m_ellipsis, move(tokens));
} }
void label::reset_tokens() { void label::reset_tokens() {
@ -31,11 +36,15 @@ namespace drawtypes {
return; return;
} }
for (auto&& bound : m_token_bounds) { for (auto&& tok : m_tokens) {
if (token != bound.token) { if (token == tok.token) {
continue; if (tok.max != 0 && replacement.length() > tok.max) {
replacement = replacement.erase(tok.max) + tok.suffix;
} else if (tok.min != 0 && replacement.length() < tok.min) {
replacement.insert(0, tok.min - replacement.length(), ' ');
}
m_tokenized = string_util::replace_all(m_tokenized, token, move(replacement));
} }
m_tokenized = string_util::replace_all_bounded(m_tokenized, token, move(replacement), bound.min, bound.max);
} }
} }
@ -99,7 +108,7 @@ namespace drawtypes {
* Create a label by loading values from the configuration * Create a label by loading values from the configuration
*/ */
label_t load_label(const config& conf, const string& section, string name, bool required, string def) { label_t load_label(const config& conf, const string& section, string name, bool required, string def) {
vector<struct bounds> bound; vector<token> tokens;
size_t start, end, pos; size_t start, end, pos;
name = string_util::ltrim(string_util::rtrim(name, '>'), '<'); name = string_util::ltrim(string_util::rtrim(name, '>'), '<');
@ -115,46 +124,52 @@ namespace drawtypes {
string line{text}; string line{text};
while ((start = line.find('%')) != string::npos && (end = line.find('%', start + 1)) != string::npos) { while ((start = line.find('%')) != string::npos && (end = line.find('%', start + 1)) != string::npos) {
auto token = line.substr(start, end - start + 1); auto token_str = line.substr(start, end - start + 1);
// ignore false positives (lemonbar-style declarations) // ignore false positives (lemonbar-style declarations)
if (token[1] == '{') { if (token_str[1] == '{') {
line.erase(0, start + 1); line.erase(0, start + 1);
continue; continue;
} }
line.erase(start, end - start + 1); line.erase(start, end - start + 1);
bound.emplace_back(bounds{token, 0, 0}); tokens.emplace_back(token{token_str, 0, 0});
auto& token = tokens.back();
// find min delimiter // find min delimiter
if ((pos = token.find(':')) == string::npos) { if ((pos = token_str.find(':')) == string::npos) {
continue; continue;
} }
// strip min/max specifiers from the label string token // strip min/max specifiers from the label string token
bound.back().token = token.substr(0, pos) + '%'; token.token = token_str.substr(0, pos) + '%';
text = string_util::replace(text, token, bound.back().token); text = string_util::replace(text, token_str, token.token);
try { try {
bound.back().min = std::stoul(&token[pos + 1], nullptr, 10); token.min = std::stoul(&token_str[pos + 1], nullptr, 10);
} catch (const std::invalid_argument& err) { } catch (const std::invalid_argument& err) {
continue; continue;
} }
// find max delimiter // find max delimiter
if ((pos = token.find(':', pos + 1)) == string::npos) { if ((pos = token_str.find(':', pos + 1)) == string::npos) {
continue; continue;
} }
try { try {
bound.back().max = std::stoul(&token[pos + 1], nullptr, 10); token.max = std::stoul(&token_str[pos + 1], nullptr, 10);
} catch (const std::invalid_argument& err) { } catch (const std::invalid_argument& err) {
continue; continue;
} }
// ignore max lengths less than min // ignore max lengths less than min
if (bound.back().max < bound.back().min) { if (token.max < token.min) {
bound.back().max = 0; token.max = 0;
}
// find suffix delimiter
if ((pos = token_str.find(':', pos + 1)) != string::npos) {
token.suffix = token_str.substr(pos + 1, end - pos - 1);
} }
} }
@ -169,7 +184,7 @@ namespace drawtypes {
conf.get<int>(section, name + "-margin", 0), conf.get<int>(section, name + "-margin", 0),
conf.get<size_t>(section, name + "-maxlen", 0), conf.get<size_t>(section, name + "-maxlen", 0),
conf.get<bool>(section, name + "-ellipsis", true), conf.get<bool>(section, name + "-ellipsis", true),
bound); move(tokens));
// clang-format on // clang-format on
} }

View File

@ -85,19 +85,6 @@ namespace string_util {
return replaced; return replaced;
} }
/**
* Replace all occurrences with bounded replacement
*/
string replace_all_bounded(
const string& haystack, string needle, string replacement, size_t min, size_t max, size_t start, size_t end) {
if (max != 0 && replacement.length() > max) {
replacement = replacement.erase(max);
} else if (min != 0 && replacement.length() < min) {
replacement.insert(0, min - replacement.length(), ' ');
}
return replace_all(haystack, move(needle), replacement, start, end);
}
/** /**
* Replace all consecutive occurrences of needle in haystack * Replace all consecutive occurrences of needle in haystack
*/ */