feat(token): Add optional suffix to label tokens
This commit is contained in:
parent
70bd235e9e
commit
0cfddf7d72
@ -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
|
||||||
|
@ -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 = "");
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user