ignore special chars that occurs in tag values
ncmpcpp shouldn't treat '$' characters that are part of a tag as special format chars.
This commit is contained in:
@@ -221,12 +221,17 @@ void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
|
|||||||
if (is_now_playing)
|
if (is_now_playing)
|
||||||
*menu << Config.now_playing_prefix;
|
*menu << Config.now_playing_prefix;
|
||||||
|
|
||||||
std::string line = s.toString(*static_cast<std::string *>(data));
|
std::string line = s.toString(*static_cast<std::string *>(data), "$");
|
||||||
for (std::string::const_iterator it = line.begin(); it != line.end(); ++it)
|
for (std::string::const_iterator it = line.begin(); it != line.end(); ++it)
|
||||||
{
|
{
|
||||||
if (*it == '$')
|
if (*it == '$')
|
||||||
{
|
{
|
||||||
if (isdigit(*++it))
|
if (++it == line.end()) // end of format
|
||||||
|
{
|
||||||
|
*menu << '$';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (isdigit(*it)) // color
|
||||||
{
|
{
|
||||||
*menu << Color(*it-'0');
|
*menu << Color(*it-'0');
|
||||||
}
|
}
|
||||||
@@ -240,8 +245,15 @@ void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
|
|||||||
*menu << XY(menu->GetWidth()-buf.Str().length(), menu->Y()) << buf;
|
*menu << XY(menu->GetWidth()-buf.Str().length(), menu->Y()) << buf;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else // not a color nor right align, just a random character
|
||||||
*menu << *it;
|
*menu << *--it;
|
||||||
|
}
|
||||||
|
else if (*it == MPD::Song::FormatEscapeCharacter)
|
||||||
|
{
|
||||||
|
// treat '$' as a normal character if song format escape char is prepended to it
|
||||||
|
if (++it == line.end() || *it != '$')
|
||||||
|
--it;
|
||||||
|
*menu << *it;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*menu << *it;
|
*menu << *it;
|
||||||
|
|||||||
@@ -92,48 +92,73 @@ template <typename C> void String2Buffer(const std::basic_string<C> &s, basic_bu
|
|||||||
{
|
{
|
||||||
for (typename std::basic_string<C>::const_iterator it = s.begin(); it != s.end(); ++it)
|
for (typename std::basic_string<C>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||||
{
|
{
|
||||||
if (*it != '$')
|
if (*it == '$')
|
||||||
buf << *it;
|
|
||||||
else if (isdigit(*++it))
|
|
||||||
buf << Color(*it-'0');
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
switch (*it)
|
if (++it == s.end())
|
||||||
{
|
{
|
||||||
case 'b':
|
buf << '$';
|
||||||
buf << fmtBold;
|
break;
|
||||||
break;
|
}
|
||||||
case 'u':
|
else if (isdigit(*it))
|
||||||
buf << fmtUnderline;
|
{
|
||||||
break;
|
buf << Color(*it-'0');
|
||||||
case 'a':
|
}
|
||||||
buf << fmtAltCharset;
|
else
|
||||||
break;
|
{
|
||||||
case 'r':
|
switch (*it)
|
||||||
buf << fmtReverse;
|
{
|
||||||
break;
|
case 'b':
|
||||||
case '/':
|
buf << fmtBold;
|
||||||
switch (*++it)
|
break;
|
||||||
{
|
case 'u':
|
||||||
case 'b':
|
buf << fmtUnderline;
|
||||||
buf << fmtBoldEnd;
|
break;
|
||||||
|
case 'a':
|
||||||
|
buf << fmtAltCharset;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
buf << fmtReverse;
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
if (++it == s.end())
|
||||||
|
{
|
||||||
|
buf << "$/";
|
||||||
break;
|
break;
|
||||||
case 'u':
|
}
|
||||||
buf << fmtUnderlineEnd;
|
switch (*it)
|
||||||
break;
|
{
|
||||||
case 'a':
|
case 'b':
|
||||||
buf << fmtAltCharsetEnd;
|
buf << fmtBoldEnd;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'u':
|
||||||
buf << fmtReverseEnd;
|
buf << fmtUnderlineEnd;
|
||||||
break;
|
break;
|
||||||
}
|
case 'a':
|
||||||
break;
|
buf << fmtAltCharsetEnd;
|
||||||
default:
|
break;
|
||||||
buf << *it;
|
case 'r':
|
||||||
break;
|
buf << fmtReverseEnd;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buf << '$' << *--it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buf << *--it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (*it == MPD::Song::FormatEscapeCharacter)
|
||||||
|
{
|
||||||
|
// treat '$' as a normal character if song format escape char is prepended to it
|
||||||
|
if (++it == s.end() || *it != '$')
|
||||||
|
--it;
|
||||||
|
buf << *it;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
buf << *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/song.cpp
14
src/song.cpp
@@ -305,7 +305,7 @@ void MPD::Song::SetPosition(int pos)
|
|||||||
itsSong->pos = pos;
|
itsSong->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
|
std::string MPD::Song::ParseFormat(std::string::const_iterator &it, const char *escape_chars) const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
bool has_some_tags = 0;
|
bool has_some_tags = 0;
|
||||||
@@ -314,7 +314,7 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
|
|||||||
{
|
{
|
||||||
while (*it == '{')
|
while (*it == '{')
|
||||||
{
|
{
|
||||||
std::string tags = ParseFormat(it);
|
std::string tags = ParseFormat(it, escape_chars);
|
||||||
if (!tags.empty())
|
if (!tags.empty())
|
||||||
{
|
{
|
||||||
has_some_tags = 1;
|
has_some_tags = 1;
|
||||||
@@ -379,6 +379,10 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
|
|||||||
if (get)
|
if (get)
|
||||||
{
|
{
|
||||||
std::string tag = (this->*get)();
|
std::string tag = (this->*get)();
|
||||||
|
if (escape_chars) // prepend format escape character to all given chars to escape
|
||||||
|
for (const char *ch = escape_chars; *ch; ++ch)
|
||||||
|
for (size_t i = tag.find(*ch); i != std::string::npos; i = tag.find(*ch, i += 2))
|
||||||
|
tag.replace(i, 1, std::string(1, FormatEscapeCharacter) + ch);
|
||||||
if (!tag.empty() && (get != &MPD::Song::GetLength || GetTotalLength()))
|
if (!tag.empty() && (get != &MPD::Song::GetLength || GetTotalLength()))
|
||||||
{
|
{
|
||||||
has_some_tags = 1;
|
has_some_tags = 1;
|
||||||
@@ -402,7 +406,7 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
|
|||||||
--brace_counter;
|
--brace_counter;
|
||||||
}
|
}
|
||||||
if (*++it == '|')
|
if (*++it == '|')
|
||||||
return ParseFormat(++it);
|
return ParseFormat(++it, escape_chars);
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -423,10 +427,10 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MPD::Song::toString(const std::string &format) const
|
std::string MPD::Song::toString(const std::string &format, const char *escape_chars) const
|
||||||
{
|
{
|
||||||
std::string::const_iterator it = format.begin();
|
std::string::const_iterator it = format.begin();
|
||||||
return ParseFormat(it);
|
return ParseFormat(it, escape_chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
MPD::Song &MPD::Song::operator=(const MPD::Song &s)
|
MPD::Song &MPD::Song::operator=(const MPD::Song &s)
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ namespace MPD
|
|||||||
void SetNewName(const std::string &name) { itsNewName = name == GetName() ? "" : name; }
|
void SetNewName(const std::string &name) { itsNewName = name == GetName() ? "" : name; }
|
||||||
std::string GetNewName() const { return itsNewName; }
|
std::string GetNewName() const { return itsNewName; }
|
||||||
|
|
||||||
std::string toString(const std::string &) const;
|
std::string toString(const std::string &, const char *escape_chars = 0) const;
|
||||||
|
static const char FormatEscapeCharacter = 1;
|
||||||
|
|
||||||
void NullMe() { itsSong = 0; }
|
void NullMe() { itsSong = 0; }
|
||||||
void CopyPtr(bool copy) { copyPtr = copy; }
|
void CopyPtr(bool copy) { copyPtr = copy; }
|
||||||
@@ -97,7 +98,7 @@ namespace MPD
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void SetHashAndSlash();
|
void SetHashAndSlash();
|
||||||
std::string ParseFormat(std::string::const_iterator &it) const;
|
std::string ParseFormat(std::string::const_iterator &it, const char *escape_chars) const;
|
||||||
|
|
||||||
mpd_Song *itsSong;
|
mpd_Song *itsSong;
|
||||||
std::string itsNewName;
|
std::string itsNewName;
|
||||||
|
|||||||
Reference in New Issue
Block a user