diff --git a/doc/en/text-styles.md b/doc/en/text-styles.md
index e85437e1..4afce42a 100644
--- a/doc/en/text-styles.md
+++ b/doc/en/text-styles.md
@@ -19,3 +19,34 @@ Styles can be combined. Example:
Output:
***Message*** using *~~combed~~ combined* styles~~.~~
+
+# Colors
+
+Text color can be set using a color code: [#RRGGBB]
+
+
+| Component | Purpose |
+| --------- | --------------------------------- |
+| R | Represents the intensity of red |
+| G | Represents the intensity of green |
+| B | Represents the intensity of blue |
+
+### Example:
+
+
+
+ [#ff0000]
+ Red Text
+
+
+
+
+ [#00ff00]
+ Green Text
+
+
+
+
+ [#0000ff]
+ Blue Text
+
diff --git a/doc/ru/text-styles.md b/doc/ru/text-styles.md
index 0a09abe3..4fbe3ed5 100644
--- a/doc/ru/text-styles.md
+++ b/doc/ru/text-styles.md
@@ -19,3 +19,33 @@
Вывод:
***Сообщение***, демонстрирующее *~~обедненные~~ объединенные* стили~~.~~
+
+## Цвета
+
+Цвет текста задается при помощи цветового кода: [#RRGGBB]
+
+| Компонент | Назначение |
+| ------------ | ------------------------- |
+| R | Используется для интенсивности красного |
+| G | Используется для интенсивности зеленого |
+| B | Используется для интенсивности синего |
+
+### Например:
+
+
+
+ [#ff0000]
+ Красный Текст
+
+
+
+
+ [#00ff00]
+ Зеленый Текст
+
+
+
+
+ [#0000ff]
+ Синий Текст
+
\ No newline at end of file
diff --git a/src/graphics/ui/markdown.cpp b/src/graphics/ui/markdown.cpp
index ab328e66..44991804 100644
--- a/src/graphics/ui/markdown.cpp
+++ b/src/graphics/ui/markdown.cpp
@@ -1,5 +1,6 @@
#include "markdown.hpp"
+#include "coders/commons.hpp"
#include "graphics/core/Font.hpp"
using namespace markdown;
@@ -9,7 +10,7 @@ static inline void emit(
CharT c, FontStylesScheme& styles, std::basic_stringstream& ss
) {
ss << c;
- styles.map.emplace_back(styles.palette.size()-1);
+ styles.map.emplace_back(styles.palette.size() - 1);
}
template
@@ -20,6 +21,38 @@ static inline void emit_md(
styles.map.emplace_back(0);
}
+template
+static glm::vec4 parse_color(const std::basic_string_view& color_code) {
+ if (color_code.size() != 8 || color_code[0] != '#') {
+ return glm::vec4(1, 1, 1, 1); // default to white
+ }
+
+ auto hex_to_float = [](char high, char low) {
+ int high_val = hexchar2int(high);
+ int low_val = hexchar2int(low);
+ if (high_val == -1 || low_val == -1) {
+ return 1.0f; // default to max value on error
+ }
+ return (high_val * 16 + low_val) / 255.0f;
+ };
+
+ return glm::vec4(
+ hex_to_float(color_code[1], color_code[2]),
+ hex_to_float(color_code[3], color_code[4]),
+ hex_to_float(color_code[5], color_code[6]),
+ 1
+ );
+}
+
+template
+static inline void apply_color(
+ const std::basic_string_view& color_code, FontStylesScheme& styles
+) {
+ FontStyle style = styles.palette.back();
+ style.color = parse_color(color_code);
+ styles.palette.push_back(style);
+}
+
template
static inline void restyle(
CharT c,
@@ -43,13 +76,14 @@ Result process_markdown(
std::basic_stringstream ss;
FontStylesScheme styles {
// markdown default
- {{false, false, false, false, glm::vec4(1,1,1,0.5f)}, {}},
+ {{false, false, false, false, glm::vec4(1, 1, 1, 0.5f)}, {}},
{}
};
FontStyle style;
int pos = 0;
while (pos < source.size()) {
CharT first = source[pos];
+
if (first == '\\') {
if (pos + 1 < source.size()) {
CharT second = source[++pos];
@@ -63,14 +97,37 @@ Result process_markdown(
emit(second, styles, ss);
pos++;
continue;
+ case '[':
+ if (pos + 9 < source.size() && source[pos + 1] == '#' &&
+ source[pos + 8] == ']') {
+ if (!eraseMarkdown) {
+ emit_md(source[pos - 1], styles, ss);
+ }
+ for (int i = 0; i < 10; ++i) {
+
+ emit(source[pos + i], styles, ss);
+ }
+
+ pos += 10;
+ continue;
+ }
}
pos--;
}
+ } else if (first == '[' && pos + 9 <= source.size() && source[pos + 1] == '#' && source[pos + 8] == ']') {
+ std::basic_string_view color_code = source.substr(pos + 1, 8);
+ apply_color(color_code, styles);
+ if (!eraseMarkdown) {
+ for (int i = 0; i < 9; ++i) {
+ emit_md(source[pos + i], styles, ss);
+ }
+ }
+ pos += 9; // Skip past the color code
+ continue;
} else if (first == '*') {
- if (pos + 1 < source.size() && source[pos+1] == '*') {
+ if (pos + 1 < source.size() && source[pos + 1] == '*') {
pos++;
- if (!eraseMarkdown)
- emit_md(first, styles, ss);
+ if (!eraseMarkdown) emit_md(first, styles, ss);
style.bold = !style.bold;
restyle(first, style, styles, ss, pos, eraseMarkdown);
continue;
@@ -78,17 +135,17 @@ Result process_markdown(
style.italic = !style.italic;
restyle(first, style, styles, ss, pos, eraseMarkdown);
continue;
- } else if (first == '_' && pos + 1 < source.size() && source[pos+1] == '_') {
+ } else if (first == '_' && pos + 1 < source.size() &&
+ source[pos + 1] == '_') {
pos++;
- if (!eraseMarkdown)
- emit_md(first, styles, ss);
+ if (!eraseMarkdown) emit_md(first, styles, ss);
style.underline = !style.underline;
restyle(first, style, styles, ss, pos, eraseMarkdown);
continue;
- } else if (first == '~' && pos + 1 < source.size() && source[pos+1] == '~') {
+ } else if (first == '~' && pos + 1 < source.size() &&
+ source[pos + 1] == '~') {
pos++;
- if (!eraseMarkdown)
- emit_md(first, styles, ss);
+ if (!eraseMarkdown) emit_md(first, styles, ss);
style.strikethrough = !style.strikethrough;
restyle(first, style, styles, ss, pos, eraseMarkdown);
continue;
@@ -106,6 +163,8 @@ Result markdown::process(std::string_view source, bool eraseMarkdown) {
return process_markdown(source, eraseMarkdown);
}
-Result markdown::process(std::wstring_view source, bool eraseMarkdown) {
+Result markdown::process(
+ std::wstring_view source, bool eraseMarkdown
+) {
return process_markdown(source, eraseMarkdown);
}