refactor(builder): Don't track raw tags

When adding a string to the builder directly, it would parse the string
for formatting tags, delete them and readd them with the methods in the
builder that keep track of open tags so that we can properly close them
when flushing.

This parser has a bug, it parses multiple formatting tags in a single
block as a single tag, e.g.

  %{F#000000 u#FFFFFF +u}

would be parsed as an `F` tag with value `#000000 u#FFFFFF +u` which is
of course wrong.

Removing the parsing step fixes this problem in the simplest way
possible. This has two benefits:
* Building of modules is sped up because we don't have to do the parsing
step in the builder and many modules use this function to add strings
from a progressbar (which already has properly closed tags).
* We don't have parser logic in two places. Until now both `parser.cpp`
and `builder.cpp` actually parsed formatting tags. This leads to a lot
of code duplication and, as we've seen, bugs.

All of the modules that use this function to add text already make sure
that they properly close formatting tags (mostly by using the builder to
generate the strings)

NOTE: This change slightly changes polybar's behavior. Raw tags (tags
added by the user through the config) can now have their effects reach
neighboring modules because the builder doesn't track and thus doesn't
close them on each flush. This can (and will) be resolved by resetting
all tags at module borders.

Fixes #1555
This commit is contained in:
patrick96 2019-01-02 18:59:34 +01:00 committed by Patrick Ziegler
parent ddb40db490
commit 928cd92a4f

View File

@ -91,97 +91,8 @@ void builder::node(string str, bool add_space) {
return;
}
string::size_type n, m;
string s(move(str));
append(move(str));
while (true) {
if (s.empty()) {
break;
} else if ((n = s.find("%{F-}")) == 0) {
color_close();
s.erase(0, 5);
} else if ((n = s.find("%{F#")) == 0 && (m = s.find('}')) != string::npos) {
if (m - n - 4 == 2) {
color_alpha(s.substr(n + 3, m - 3));
} else {
color(s.substr(n + 3, m - 3));
}
s.erase(n, m + 1);
} else if ((n = s.find("%{B-}")) == 0) {
background_close();
s.erase(0, 5);
} else if ((n = s.find("%{B#")) == 0 && (m = s.find('}')) != string::npos) {
background(s.substr(n + 3, m - 3));
s.erase(n, m + 1);
} else if ((n = s.find("%{T-}")) == 0) {
font_close();
s.erase(0, 5);
} else if ((n = s.find("%{T")) == 0 && (m = s.find('}')) != string::npos) {
font(strtol(s.substr(n + 3, m - 3).c_str(), nullptr, 10));
s.erase(n, m + 1);
} else if ((n = s.find("%{U-}")) == 0) {
line_color_close();
s.erase(0, 5);
} else if ((n = s.find("%{u-}")) == 0) {
underline_color_close();
s.erase(0, 5);
} else if ((n = s.find("%{o-}")) == 0) {
overline_color_close();
s.erase(0, 5);
} else if ((n = s.find("%{u#")) == 0 && (m = s.find('}')) != string::npos) {
underline_color(s.substr(n + 3, m - 3));
s.erase(n, m + 1);
} else if ((n = s.find("%{o#")) == 0 && (m = s.find('}')) != string::npos) {
overline_color(s.substr(n + 3, m - 3));
s.erase(n, m + 1);
} else if ((n = s.find("%{U#")) == 0 && (m = s.find('}')) != string::npos) {
line_color(s.substr(n + 3, m - 3));
s.erase(n, m + 1);
} else if ((n = s.find("%{+u}")) == 0) {
underline();
s.erase(0, 5);
} else if ((n = s.find("%{+o}")) == 0) {
overline();
s.erase(0, 5);
} else if ((n = s.find("%{-u}")) == 0) {
underline_close();
s.erase(0, 5);
} else if ((n = s.find("%{-o}")) == 0) {
overline_close();
s.erase(0, 5);
} else if ((n = s.find("%{")) == 0 && (m = s.find('}')) != string::npos) {
append(s.substr(n, m + 1));
s.erase(n, m + 1);
} else if ((n = s.find("%{")) > 0) {
append(s.substr(0, n));
s.erase(0, n);
} else {
break;
}
}
if (!s.empty()) {
append(s);
}
if (add_space) {
space();
}