Skip to content

Commit

Permalink
color: Add the ability to selectively preserve colors
Browse files Browse the repository at this point in the history
This adds back the "DECOLOR" functionality that was removed as part of Unvanquished/Unvanquished@d61c9d2.
No motivation was given for the removal, and the DECOLOR functionality
is important for external tools that parse game logs to display player
colors leading to a richer experience.
  • Loading branch information
DolceTriade committed Oct 20, 2024
1 parent f989ce9 commit 92c33c1
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
50 changes: 48 additions & 2 deletions src/common/Color.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,30 @@ int StrlenNocolor( const char *string )

void StripColors( const char *in, char *out, size_t len )
{
bool preserveColor = false;

for ( const auto& token : Parser( in ) )
{
Str::StringView text = token.PlainText();
if ( token.Type() == Token::TokenType::CONTROL )
{
if ( token.RawToken().size() != 1 )
{
Log::Warn( "Invalid control token of length %d", token.RawToken().size() );
continue;
}
switch ( token.RawToken()[0] )
{
case Constants::DECOLOR_ON:
preserveColor = false;
break;
case Constants::DECOLOR_OFF:
preserveColor = true;
break;
}
continue;
}
Str::StringView text = ( preserveColor && token.Type() == Token::TokenType::COLOR ) ?
token.RawToken() : token.PlainText();
if ( text.size() >= len )
{
break;
Expand All @@ -106,9 +127,30 @@ std::string StripColors( Str::StringRef input )
std::string output;
output.reserve( input.size() );

bool preserveColor = false;

for ( const auto& token : Parser( input.c_str() ) )
{
Str::StringView text = token.PlainText();
if ( token.Type() == Token::TokenType::CONTROL )
{
if ( token.RawToken().size() != 1 )
{
Log::Warn( "Invalid control token of length %d", token.RawToken().size() );
continue;
}
switch ( token.RawToken()[0] )
{
case Constants::DECOLOR_ON:
preserveColor = false;
break;
case Constants::DECOLOR_OFF:
preserveColor = true;
break;
}
continue;
}
Str::StringView text = ( preserveColor && token.Type() == Token::TokenType::COLOR ) ?
token.RawToken() : token.PlainText();
output.append( text.begin(), text.end() );
}

Expand Down Expand Up @@ -210,6 +252,10 @@ TokenIterator::value_type TokenIterator::NextToken(const char* input)
}
}
}
else if ( input[0] == Constants::DECOLOR_ON || input[0] == Constants::DECOLOR_OFF )
{
return value_type( input, input + 1, value_type::TokenType::CONTROL );
}

return value_type( input, input + Q_UTF8_Width( input ), value_type::TokenType::CHARACTER );
}
Expand Down
4 changes: 4 additions & 0 deletions src/common/Color.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ namespace Constants {
enum {
ESCAPE = '^',
NULL_COLOR = '*',
// Magic chars to preserve colors between DECOLOR_OFF and DECOLOR_ON when calling StripColors.
DECOLOR_OFF = '\16',
DECOLOR_ON = '\17',
}; // enum
} // namespace Constants

Expand Down Expand Up @@ -371,6 +374,7 @@ class Token
CHARACTER, // A character
ESCAPE, // Color escape
COLOR, // Color code
CONTROL, // Control character (basically controlling decolor behavior.)
};

/*
Expand Down
12 changes: 11 additions & 1 deletion src/common/ColorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ TEST(StripColorTest, ReturningString)

std::string onlyColors = "^xF1A^1^0^O^9^a^;^*^xeE2^#123Aa5^#3903ff";
EXPECT_EQ("", StripColors(onlyColors));

// Decolor
std::string decolor = Str::Format("%c^1wtf^#aabbccbad%c^1a^2c^^^3c", Constants::DECOLOR_ON, Constants::DECOLOR_OFF);
EXPECT_EQ("wtfbad^1a^2c^^3c", StripColors(decolor));

}

TEST(StripColorTest, ToBuffer)
Expand All @@ -57,8 +62,13 @@ TEST(StripColorTest, ToBuffer)
char justright[7];
StripColors("dretc^#123456h", justright, sizeof(justright));
EXPECT_EQ("dretch", std::string(justright));

// Decolor
char decolorjustright[9];
StripColors(Str::Format("%c^1dretc%c^#123456h", Constants::DECOLOR_OFF, Constants::DECOLOR_ON).c_str(), decolorjustright, sizeof(decolorjustright));
EXPECT_EQ("^1dretch", std::string(decolorjustright));

}

} // namespace
} // namespace Color

0 comments on commit 92c33c1

Please sign in to comment.