Skip to content

Commit

Permalink
119000% improvement on the HTML log file size. Yes - this is not a typo
Browse files Browse the repository at this point in the history
  • Loading branch information
Epixu committed Jan 17, 2025
1 parent 40400e1 commit 7cdb0a7
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 163 deletions.
282 changes: 126 additions & 156 deletions source/HTML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,180 +28,50 @@ ToHTML::~ToHTML() {
/// Write text
/// @param text - the text to append to the file
void ToHTML::Write(const TextView& text) const noexcept {
TextView stripped = text;
int trailing_spaces = 0;
while (not stripped.empty() and stripped.ends_with(' ')) {
stripped = stripped.substr(0, stripped.size() - 1);
++trailing_spaces;
}

mFile << stripped;
while (trailing_spaces) {
mFile << "&nbsp;";
--trailing_spaces;
}

mFile << text;
mFile.flush();
}

/// Apply some style
/// @param style - the style to set
void ToHTML::Write(Style style) const noexcept {
// Always reset before a style change
mFile << "\n</code></strong></em></u></blink></del></span><code>";

if (style.has_emphasis()) {
const auto em = static_cast<uint8_t>(style.get_emphasis());
if (em & static_cast<uint8_t>(fmt::emphasis::bold))
mFile << "<strong>";
//if (em & static_cast<uint8_t>(fmt::emphasis::faint))
// ;
if (em & static_cast<uint8_t>(fmt::emphasis::italic))
mFile << "<em>";
if (em & static_cast<uint8_t>(fmt::emphasis::underline))
mFile << "<u>";
if (em & static_cast<uint8_t>(fmt::emphasis::blink))
mFile << "<blink>";
//if (em & static_cast<uint8_t>(fmt::emphasis::reverse))
// ;
//if (em & static_cast<uint8_t>(fmt::emphasis::conceal))
// ;
if (em & static_cast<uint8_t>(fmt::emphasis::strikethrough))
mFile << "<del>";
if ((not style.has_foreground() or style.get_foreground().value.term_color == Instance.DefaultStyle.get_foreground().value.term_color)
and (not style.has_background() or style.get_background().value.term_color == Instance.DefaultStyle.get_background().value.term_color)
and (not style.has_emphasis() or style.get_emphasis() == Instance.DefaultStyle.get_emphasis())) {
mFile << "</span><span>";
return;
}

if (not style.has_foreground() and not style.has_background())
return;
// Always reset before a style change
mFile << "</span><span class=\"";

std::string style_string = "<span style = \"display: inline-block; white-space: pre; "; // add to debug -> border: 1px solid blue;
if (style.has_foreground()) {
const auto fg = static_cast<fmt::terminal_color>(
style.get_foreground().value.term_color);

switch (fg) {
case fmt::terminal_color::black:
style_string += "color: black; ";
break;
case fmt::terminal_color::red:
style_string += "color: DarkRed; ";
break;
case fmt::terminal_color::green:
style_string += "color: ForestGreen; ";
break;
case fmt::terminal_color::yellow:
style_string += "color: DarkOrange; ";
break;
case fmt::terminal_color::blue:
style_string += "color: blue; ";
break;
case fmt::terminal_color::magenta:
style_string += "color: DarkMagenta; ";
break;
case fmt::terminal_color::cyan:
style_string += "color: DarkCyan; ";
break;
case fmt::terminal_color::white:
style_string += "color: LightGray; ";
break;
case fmt::terminal_color::bright_black:
style_string += "color: gray; ";
break;
case fmt::terminal_color::bright_red:
style_string += "color: Red; ";
break;
case fmt::terminal_color::bright_green:
style_string += "color: GreenYellow; ";
break;
case fmt::terminal_color::bright_yellow:
style_string += "color: Gold; ";
break;
case fmt::terminal_color::bright_blue:
style_string += "color: royalblue; ";
break;
case fmt::terminal_color::bright_magenta:
style_string += "color: magenta; ";
break;
case fmt::terminal_color::bright_cyan:
style_string += "color: cyan; ";
break;
case fmt::terminal_color::bright_white:
style_string += "color: white; ";
break;
}
const auto hex = Hex(style.get_foreground().value.term_color);
mFile << " f" << hex[0] << hex[1];
}

if (style.has_background()) {
const auto bg = static_cast<fmt::terminal_color>(
style.get_background().value.term_color);

switch (bg) {
case fmt::terminal_color::black:
style_string += "background-color: black; ";
break;
case fmt::terminal_color::red:
style_string += "background-color: DarkRed; ";
break;
case fmt::terminal_color::green:
style_string += "background-color: ForestGreen; ";
break;
case fmt::terminal_color::yellow:
style_string += "background-color: DarkOrange; ";
break;
case fmt::terminal_color::blue:
style_string += "background-color: blue; ";
break;
case fmt::terminal_color::magenta:
style_string += "background-color: DarkMagenta; ";
break;
case fmt::terminal_color::cyan:
style_string += "background-color: DarkCyan; ";
break;
case fmt::terminal_color::white:
style_string += "background-color: LightGray; ";
break;
case fmt::terminal_color::bright_black:
style_string += "background-color: gray; ";
break;
case fmt::terminal_color::bright_red:
style_string += "background-color: Red; ";
break;
case fmt::terminal_color::bright_green:
style_string += "background-color: GreenYellow; ";
break;
case fmt::terminal_color::bright_yellow:
style_string += "background-color: Gold; ";
break;
case fmt::terminal_color::bright_blue:
style_string += "background-color: royalblue; ";
break;
case fmt::terminal_color::bright_magenta:
style_string += "background-color: magenta; ";
break;
case fmt::terminal_color::bright_cyan:
style_string += "background-color: cyan; ";
break;
case fmt::terminal_color::bright_white:
style_string += "background-color: white; ";
break;
}
const auto hex = Hex(style.get_background().value.term_color);
mFile << " b" << hex[0] << hex[1];
}

style_string += "\">";
mFile << style_string;
if (style.has_emphasis()) {
const auto hex = Hex(style.get_emphasis());
mFile << " e" << hex[0] << hex[1];
}

mFile << "\">";
}

/// Remove formatting, add a new line, add a timestamp and tabulate
/// @attention top of the style stack is not applied
void ToHTML::NewLine() const noexcept {
mFile << "</code></strong></em></u></blink></del></span><br>";
Write(Instance.TimeStampStyle);
mFile << "</span></p><p>\n";
mFile << GetSimpleTime();
Write(Instance.IntentStyle[int(Instance.CurrentIntent)].prefix);
mFile.flush();

auto tabs = Instance.GetTabs();
if (tabs) {
Write(Instance.TabStyle);
while (tabs) {
Write(Instance.TabString);
--tabs;
Expand All @@ -221,17 +91,117 @@ void ToHTML::Clear() const noexcept {
/// Write file header - general HTML styling options, etc.
void ToHTML::WriteHeader() const {
mFile << "<!DOCTYPE html><html>\n";
mFile << "<body style = \"color: LightGray; background-color: black; font-family: monospace; font-size: 14px;\">\n";
mFile << "<body style = \"color: LightGray; background-color: black; font-family: monospace; font-size: 14px; white-space: pre; \">\n";
mFile << "<head><style>\n";
mFile << " @keyframes blink {\n"
" 0 % {opacity : 1;}\n"
" 50 % {opacity : 0;}\n"
" 100 % {opacity : 1;}\n"
" }\n";

// Predeclare all combinations of styles for shorter tags
std::unordered_map<fmt::terminal_color, std::string> foregroundColors;
foregroundColors[fmt::terminal_color::black ] = "color: black; ";
foregroundColors[fmt::terminal_color::red ] = "color: DarkRed; ";
foregroundColors[fmt::terminal_color::green ] = "color: ForestGreen; ";
foregroundColors[fmt::terminal_color::yellow ] = "color: DarkOrange; ";
foregroundColors[fmt::terminal_color::blue ] = "color: blue; ";
foregroundColors[fmt::terminal_color::magenta ] = "color: DarkMagenta; ";
foregroundColors[fmt::terminal_color::cyan ] = "color: DarkCyan; ";
foregroundColors[fmt::terminal_color::white ] = "color: LightGray; ";
foregroundColors[fmt::terminal_color::bright_black ] = "color: gray; ";
foregroundColors[fmt::terminal_color::bright_red ] = "color: Red; ";
foregroundColors[fmt::terminal_color::bright_green ] = "color: GreenYellow; ";
foregroundColors[fmt::terminal_color::bright_yellow ] = "color: Gold; ";
foregroundColors[fmt::terminal_color::bright_blue ] = "color: royalblue; ";
foregroundColors[fmt::terminal_color::bright_magenta] = "color: magenta; ";
foregroundColors[fmt::terminal_color::bright_cyan ] = "color: cyan; ";
foregroundColors[fmt::terminal_color::bright_white ] = "color: white; ";
for (auto fg : foregroundColors) {
const auto hex = Hex(fg.first);
mFile << " .f" << hex[0] << hex[1] << "{" << fg.second << "}\n";
}

std::unordered_map<fmt::terminal_color, std::string> backgroundColors;
backgroundColors[fmt::terminal_color::black ] = "background-" + foregroundColors[fmt::terminal_color::black];
backgroundColors[fmt::terminal_color::red ] = "background-" + foregroundColors[fmt::terminal_color::red];
backgroundColors[fmt::terminal_color::green ] = "background-" + foregroundColors[fmt::terminal_color::green];
backgroundColors[fmt::terminal_color::yellow ] = "background-" + foregroundColors[fmt::terminal_color::yellow];
backgroundColors[fmt::terminal_color::blue ] = "background-" + foregroundColors[fmt::terminal_color::blue];
backgroundColors[fmt::terminal_color::magenta ] = "background-" + foregroundColors[fmt::terminal_color::magenta];
backgroundColors[fmt::terminal_color::cyan ] = "background-" + foregroundColors[fmt::terminal_color::cyan];
backgroundColors[fmt::terminal_color::white ] = "background-" + foregroundColors[fmt::terminal_color::white];
backgroundColors[fmt::terminal_color::bright_black ] = "background-" + foregroundColors[fmt::terminal_color::bright_black];
backgroundColors[fmt::terminal_color::bright_red ] = "background-" + foregroundColors[fmt::terminal_color::bright_red];
backgroundColors[fmt::terminal_color::bright_green ] = "background-" + foregroundColors[fmt::terminal_color::bright_green];
backgroundColors[fmt::terminal_color::bright_yellow ] = "background-" + foregroundColors[fmt::terminal_color::bright_yellow];
backgroundColors[fmt::terminal_color::bright_blue ] = "background-" + foregroundColors[fmt::terminal_color::bright_blue];
backgroundColors[fmt::terminal_color::bright_magenta] = "background-" + foregroundColors[fmt::terminal_color::bright_magenta];
backgroundColors[fmt::terminal_color::bright_cyan ] = "background-" + foregroundColors[fmt::terminal_color::bright_cyan];
backgroundColors[fmt::terminal_color::bright_white ] = "background-" + foregroundColors[fmt::terminal_color::bright_white];
for (auto bg : backgroundColors) {
const auto hex = Hex(bg.first);
mFile << " .b" << hex[0] << hex[1] << "{" << bg.second << "}\n";
}

std::unordered_map<fmt::emphasis, std::string> emphasee;
emphasee[fmt::emphasis::blink] = "animation: blink 1s infinite; ";
emphasee[fmt::emphasis::bold] = "font-weight: bold; ";
emphasee[fmt::emphasis::conceal] = "visibility: hidden; ";
emphasee[fmt::emphasis::faint] = "text-opacity: 50%; ";
emphasee[fmt::emphasis::italic] = "font-style: italic; ";
emphasee[fmt::emphasis::reverse] = "mix-blend-mode: difference; ";
emphasee[fmt::emphasis::strikethrough] = "text-decoration: line-through; ";
emphasee[fmt::emphasis::underline] = "text-decoration: underline; ";
for (unsigned combination = 0; combination <= 255; ++combination) {
const auto hex = Hex(static_cast<uint8_t>(combination));
mFile << " .e" << hex[0] << hex[1] << "{";
for (auto em : emphasee) {
if (combination & static_cast<uint8_t>(em.first))
mFile << em.second;
}
mFile << "}\n";
}


// Write the most commonly used new-line style as <p>
{
mFile << " p {\n";
mFile << " margin: 0em;\n";
mFile << " padding: 0em;\n";
mFile << " line-height: 9px;\n";

if (Instance.DefaultStyle.has_foreground()) {
auto c = Instance.DefaultStyle.get_foreground().value.term_color;
mFile << " " << foregroundColors[static_cast<fmt::terminal_color>(c)] << "\n";
}

if (Instance.DefaultStyle.has_background()) {
auto c = Instance.DefaultStyle.get_background().value.term_color;
mFile << " " << backgroundColors[static_cast<fmt::terminal_color>(c)] << "\n";
}

if (Instance.DefaultStyle.has_emphasis()) {
auto e = Instance.DefaultStyle.get_emphasis();
for (auto em : emphasee) {
if (static_cast<uint8_t>(e) & static_cast<uint8_t>(em.first))
mFile << " " << em.second;
}
}

mFile << " }\n";
}

// Prepare for messages
mFile << "</style></head>\n";
mFile << "<h2>Log started - ";
mFile << GetAdvancedTime();
mFile << "</h2><code>\n";
mFile.flush();
mFile << "</h2><p><span>\n";
}

/// Write file footer - just the official shutdown timestamp
void ToHTML::WriteFooter() const {
mFile << "</strong></em></u></blink></del></span><h2>Log ended - ";
mFile << "</span></p><h2>Log ended - ";
mFile << GetAdvancedTime();
mFile << "</h2></code></body></html>";
mFile.flush();
mFile << "</h2></body></html>";
}
15 changes: 10 additions & 5 deletions source/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,11 @@ void Interface::NewLine() const noexcept {

// Clear formatting, add new line, simple time stamp, and tabs
fmt::print("\n");
FmtPrintStyle(TimeStampStyle);
FmtPrintStyle(DefaultStyle);
fmt::print("{}{}", GetSimpleTime(), IntentStyle[int(CurrentIntent)].prefix);

if (mTabulator) {
auto tabs = mTabulator;
FmtPrintStyle(TabStyle);
while (tabs) {
fmt::print("{}", TabString);
--tabs;
Expand All @@ -188,10 +187,8 @@ void Interface::NewLine() const noexcept {
FmtPrintStyle(mStyleStack.top());

// Dispatch to duplicators
for (auto attachment : mDuplicators) {
for (auto attachment : mDuplicators)
attachment->NewLine();
attachment->Write(mStyleStack.top());
}
}

/// Clear the entire log (clear the console window or file)
Expand All @@ -208,6 +205,14 @@ void Interface::Clear() const noexcept {
// Clear the window
fmt::print("{}", "\x1b[2J");

// Resume the last style
if (mStyleStack.empty()) {
const_cast<decltype(mStyleStack)&>(mStyleStack)
.push(GetCurrentStyle());
}

FmtPrintStyle(mStyleStack.top());

// Dispatch to duplicators
for (auto attachment : mDuplicators)
attachment->Clear();
Expand Down
Loading

0 comments on commit 7cdb0a7

Please sign in to comment.