summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2025-12-17 15:13:39 +0800
committer魏曹先生 <1992414357@qq.com>2025-12-17 15:13:39 +0800
commite372cfff7296e907d257aa4ecbd8400d1ce3bcad (patch)
tree328ba914689af9f4a76a4edffae7de38274d2d84 /src/utils
parentc3dc8f411d6ff0b83a66589b29d76155afe2c803 (diff)
Add color formatting support to help documentation
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/display.rs191
1 files changed, 177 insertions, 14 deletions
diff --git a/src/utils/display.rs b/src/utils/display.rs
index a7ccb9c..ca1f3b5 100644
--- a/src/utils/display.rs
+++ b/src/utils/display.rs
@@ -1,5 +1,5 @@
use colored::*;
-use regex::Regex;
+use std::collections::VecDeque;
pub struct SimpleTable {
items: Vec<String>,
@@ -168,19 +168,182 @@ pub fn size_str(total_size: usize) -> String {
// Convert the Markdown formatted text into a format supported by the command line
pub fn md(text: impl AsRef<str>) -> String {
- let bold_re = Regex::new(r"\*\*(.*?)\*\*").unwrap();
- let mut result = bold_re
- .replace_all(text.as_ref().trim(), |caps: &regex::Captures| {
- format!("{}", caps[1].bold())
- })
- .to_string();
-
- let italic_re = Regex::new(r"\*(.*?)\*").unwrap();
- result = italic_re
- .replace_all(&result, |caps: &regex::Captures| {
- format!("{}", caps[1].italic())
- })
- .to_string();
+ let text = text.as_ref().trim();
+ let mut result = String::new();
+ let mut color_stack: VecDeque<String> = VecDeque::new();
+
+ let mut i = 0;
+ let chars: Vec<char> = text.chars().collect();
+
+ while i < chars.len() {
+ // Check for color tag start [[color]]
+ if i + 1 < chars.len() && chars[i] == '[' && chars[i + 1] == '[' {
+ let mut j = i + 2;
+ while j < chars.len()
+ && !(chars[j] == ']' && j + 1 < chars.len() && chars[j + 1] == ']')
+ {
+ j += 1;
+ }
+
+ if j + 1 < chars.len() {
+ let tag_content: String = chars[i + 2..j].iter().collect();
+
+ // Check if it's a closing tag [[/]]
+ if tag_content == "/" {
+ color_stack.pop_back();
+ i = j + 2;
+ continue;
+ }
+
+ // It's a color tag
+ color_stack.push_back(tag_content.clone());
+ i = j + 2;
+ continue;
+ }
+ }
+
+ // Check for bold **text**
+ if i + 1 < chars.len() && chars[i] == '*' && chars[i + 1] == '*' {
+ let mut j = i + 2;
+ while j + 1 < chars.len() && !(chars[j] == '*' && chars[j + 1] == '*') {
+ j += 1;
+ }
+
+ if j + 1 < chars.len() {
+ let bold_text: String = chars[i + 2..j].iter().collect();
+ let mut formatted_text = bold_text.bold().to_string();
+
+ // Apply current color stack
+ for color in color_stack.iter().rev() {
+ formatted_text = apply_color(&formatted_text, color);
+ }
+
+ result.push_str(&formatted_text);
+ i = j + 2;
+ continue;
+ }
+ }
+
+ // Check for italic *text*
+ if chars[i] == '*' {
+ let mut j = i + 1;
+ while j < chars.len() && chars[j] != '*' {
+ j += 1;
+ }
+
+ if j < chars.len() {
+ let italic_text: String = chars[i + 1..j].iter().collect();
+ let mut formatted_text = italic_text.italic().to_string();
+
+ // Apply current color stack
+ for color in color_stack.iter().rev() {
+ formatted_text = apply_color(&formatted_text, color);
+ }
+
+ result.push_str(&formatted_text);
+ i = j + 1;
+ continue;
+ }
+ }
+
+ // Check for inline code `text`
+ if chars[i] == '`' {
+ let mut j = i + 1;
+ while j < chars.len() && chars[j] != '`' {
+ j += 1;
+ }
+
+ if j < chars.len() {
+ // Include the backticks in the output
+ let code_text: String = chars[i..=j].iter().collect();
+ let mut formatted_text = code_text.green().to_string();
+
+ // Apply current color stack
+ for color in color_stack.iter().rev() {
+ formatted_text = apply_color(&formatted_text, color);
+ }
+
+ result.push_str(&formatted_text);
+ i = j + 1;
+ continue;
+ }
+ }
+
+ // Check for angle-bracketed content <text>
+ if chars[i] == '<' {
+ let mut j = i + 1;
+ while j < chars.len() && chars[j] != '>' {
+ j += 1;
+ }
+
+ if j < chars.len() {
+ // Include the angle brackets in the output
+ let angle_text: String = chars[i..=j].iter().collect();
+ let mut formatted_text = angle_text.cyan().to_string();
+
+ // Apply current color stack
+ for color in color_stack.iter().rev() {
+ formatted_text = apply_color(&formatted_text, color);
+ }
+
+ result.push_str(&formatted_text);
+ i = j + 1;
+ continue;
+ }
+ }
+
+ // Regular character
+ let mut current_char = chars[i].to_string();
+
+ // Apply current color stack
+ for color in color_stack.iter().rev() {
+ current_char = apply_color(&current_char, color);
+ }
+
+ result.push_str(&current_char);
+ i += 1;
+ }
result
}
+
+// Helper function to apply color to text
+fn apply_color(text: &str, color_name: &str) -> String {
+ match color_name {
+ // Normal colors
+ "black" => text.black().to_string(),
+ "red" => text.red().to_string(),
+ "green" => text.green().to_string(),
+ "yellow" => text.yellow().to_string(),
+ "blue" => text.blue().to_string(),
+ "magenta" => text.magenta().to_string(),
+ "cyan" => text.cyan().to_string(),
+ "white" => text.white().to_string(),
+ "bright_black" => text.bright_black().to_string(),
+ "bright_red" => text.bright_red().to_string(),
+ "bright_green" => text.bright_green().to_string(),
+ "bright_yellow" => text.bright_yellow().to_string(),
+ "bright_blue" => text.bright_blue().to_string(),
+ "bright_magenta" => text.bright_magenta().to_string(),
+ "bright_cyan" => text.bright_cyan().to_string(),
+ "bright_white" => text.bright_white().to_string(),
+
+ // Short aliases for bright colors
+ "b_black" => text.bright_black().to_string(),
+ "b_red" => text.bright_red().to_string(),
+ "b_green" => text.bright_green().to_string(),
+ "b_yellow" => text.bright_yellow().to_string(),
+ "b_blue" => text.bright_blue().to_string(),
+ "b_magenta" => text.bright_magenta().to_string(),
+ "b_cyan" => text.bright_cyan().to_string(),
+ "b_white" => text.bright_white().to_string(),
+
+ // Gray colors using truecolor
+ "gray" | "grey" => text.truecolor(128, 128, 128).to_string(),
+ "bright_gray" | "bright_grey" => text.truecolor(192, 192, 192).to_string(),
+ "b_gray" | "b_grey" => text.truecolor(192, 192, 192).to_string(),
+
+ // Default to white if color not recognized
+ _ => text.to_string(),
+ }
+}