summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--locales/help_docs/en.yml101
-rw-r--r--locales/help_docs/zh-CN.yml91
-rw-r--r--src/utils/display.rs191
3 files changed, 300 insertions, 83 deletions
diff --git a/locales/help_docs/en.yml b/locales/help_docs/en.yml
index 4bf312e..048cf09 100644
--- a/locales/help_docs/en.yml
+++ b/locales/help_docs/en.yml
@@ -1,3 +1,29 @@
+# l10n file - en
+
+# The following syntax can be used in text
+# 1. **Bold**
+# 2. *Italic*
+# 3. [[red]]Color[[/]]
+# 4. `text` (auto colored green)
+# 5. <文本> (auto colored cyan)
+#
+# For color usage, please refer to:
+# RED = Emergency, Error
+# YELLOW = Warning
+#
+# CYAN = Emphasis
+# GREEN = Text Content
+#
+# GRAY = De-emphasis, Ignore
+# GREY = Same as above
+#
+# For Analyzer results:
+# YELLOW = Move operation = ">" symbol
+# GREEN = Create operation = "+" symbol
+# RED = Lost operation = "-" symbol
+# MAGENTA = Erase operation = "&" symbol
+# CYAN = Modify operation = "*" symbol
+
common:
confirm: |
Confirm to perform the above operation? (Y/n):
@@ -166,13 +192,13 @@ jvv:
jv:
version:
header: |
- JustEnoughVCS - %{version}
+ JustEnoughVCS - [[cyan]]%{version}[[/]]
compile_info: |
Compile Info
- Compile Date - %{build_time}
- Target - %{build_target}
- Platform - %{build_platform} - %{build_toolchain}
+ Compile Date - [[cyan]]%{build_time}[[/]]
+ Target - [[cyan]]%{build_target}[[/]]
+ Platform - [[cyan]]%{build_platform} - %{build_toolchain}[[/]]
tip:
not_workspace: |
@@ -200,16 +226,16 @@ jv:
This program connects to upstream vaults to synchronize and commit changes to local workspace files for collaborative work.
**ALIASES**:
- jv u - Download latest information [REMOTE]
- jv t - Track files [REMOTE]
+ jv u - Download latest information [[cyan]][REMOTE][[/]]
+ jv t - Track files [[cyan]][REMOTE][[/]]
jv a - Align files to sheet
- jv [in|out] - Import or export files [REMOTE]
+ jv [in|out] - Import or export files [[cyan]][REMOTE][[/]]
**UPSTREAM VAULT**:
- login <ACCOUNT> <UPSTREAM> - Login to upstream vault [REMOTE]
- direct <UPSTREAM> - Direct workspace to upstream vault [REMOTE]
+ login <ACCOUNT> <UPSTREAM> - Login to upstream vault [[cyan]][REMOTE][[/]]
+ direct <UPSTREAM> - Direct workspace to upstream vault [[cyan]][REMOTE][[/]]
unstain - Unstain workspace, clear association
- update - Download latest information [REMOTE]
+ update - Download latest information [[cyan]][REMOTE][[/]]
**ACCOUNTS**:
account [list|as|add|remove|movekey|genpub]
@@ -225,9 +251,9 @@ jv:
list - List all sheets
use - Use sheet, start work
exit - Exit sheet, clear current modifications
- make - Create a new sheet for yourself [REMOTE]
- drop - Drop the sheet for others to use [REMOTE]
- align - Align files to sheet [REMOTE]
+ make - Create a new sheet for yourself [[cyan]][REMOTE][[/]]
+ drop - Drop the sheet for others to use [[cyan]][REMOTE][[/]]
+ align - Align files to sheet [[cyan]][REMOTE][[/]]
**CONTEXT**:
here - Display path information
@@ -235,16 +261,16 @@ jv:
info - Display individual file status
**FILE TRANSFER**:
- import <PACKAGE_NAME> - Import files from import area [REMOTE]
- import <REFERENCE_SHEET_PATH> - Import files from reference sheet [REMOTE]
- export <FILE> <SHEET_NAME> - Export files to other sheets [REMOTE]
+ import <PACKAGE_NAME> - Import files from import area [[cyan]][REMOTE][[/]]
+ import <REFERENCE_SHEET_PATH> - Import files from reference sheet [[cyan]][REMOTE][[/]]
+ export <FILE> <SHEET_NAME> - Export files to other sheets [[cyan]][REMOTE][[/]]
**FILE OPERATIONS**:
- move <FILE> <TO> - Safely rename files [REMOTE]
- track <FILE> - Track files to latest version [REMOTE]
- hold <FILE> - Hold, sync and lock file [REMOTE]
- throw <FILE> - Throw, sync and unlock file [REMOTE]
- jump <FILE> <VERSION> - Jump file to other version [REMOTE]
+ move <FILE> <TO> - Safely rename files [[cyan]][REMOTE][[/]]
+ track <FILE> - Track files to latest version [[cyan]][REMOTE][[/]]
+ hold <FILE> - Hold, sync and lock file [[cyan]][REMOTE][[/]]
+ throw <FILE> - Throw, sync and unlock file [[cyan]][REMOTE][[/]]
+ jump <FILE> <VERSION> - Jump file to other version [[cyan]][REMOTE][[/]]
**DOCUMENTATION**:
docs list - List all available documentation
@@ -656,7 +682,7 @@ jv:
status:
no_sheet_in_use: |
- You are not using any sheet! Cannot analyze workspace status in this state
+ You are not using any sheet! Cannot analyze workspace status in this situation
**Tip**: You can use `jv use <sheet_name>` to select and use a sheet
analyze: |
@@ -722,25 +748,26 @@ jv:
Great, no structural deviations in the local workspace, no alignment needed!
suggestion_1: |
- Suggestion **Confirm Erased Items**:
- The file no longer exists remotely, but it still exists locally!
- **Example**: Use `jv align %{example_erased} confirm` to confirm this erased item!
- **Tip**: After confirmation, the local mapping will be erased, and the file at that location will be moved away.
+ **Suggestion**: Confirm [[magenta]]Erased Items[[/]]
+ **Example**: Use `jv align %{example_erased} confirm` to confirm this [[magenta]]Erased Item[[/]]!
+
+ [[yellow]]**Note**: After confirmation, the local mapping will be erased, and the file at that location will be moved away.[[/]]
suggestion_2: |
- Suggestion **Confirm Lost Items**:
- Cannot determine if the intent for the lost file is `deletion` or `move`!
- Therefore, you need to use a command to confirm the action:
- **Example**: Use `jv align %{example_lost} <action>` to confirm this loss.
- **Confirm Deletion**: Enter `confirm` to confirm your action is a `deletion`.
- **Declare Move**: Enter the created item to form a move relationship with it.
+ **Suggestion**: Confirm [[red]]Lost Items[[/]]
+ Cannot determine if the intent of the file loss is [[red]]Deletion[[/]] or [[yellow]]Move[[/]]!
+ **Example**: Use `jv align %{example_lost} <action>` to handle this [[red]]Lost Item[[/]]
+
+ **Confirm Deletion**: Enter `confirm` to confirm your operation is a [[red]]Deletion[[/]]
+ **Declare Move**: Enter a [[green]]Created Item[[/]] to form a [[yellow]]Move[[/]] relationship with it
suggestion_3: |
- Only **Moved Items**, please confirm them based on local or remote.
- **Example**: Use `jv align moved [local|remote]` to batch align,
- or Use `jv align %{example_moved} [local|remote]` to precisely align a move.
- **Align to Local**: Requires network, will modify the upstream mapping to your actual local location.
- **Align to Remote**: Can be offline, will move the local file to the location of the upstream address.
+ **Suggestion**: Align [[yellow]]Moved Items[[/]], confirm they are based on Local or Remote
+ **Example**: Use `jv align moved [local|remote]` to batch align
+ or use `jv align %{example_moved} [local|remote]` to precisely align a move
+
+ **Align to Local**: Online , modify the upstream mapping to the local location
+ **Align to Remote**: Offline, move the local file to the upstream location
docs:
list:
diff --git a/locales/help_docs/zh-CN.yml b/locales/help_docs/zh-CN.yml
index 156761e..fd83ca7 100644
--- a/locales/help_docs/zh-CN.yml
+++ b/locales/help_docs/zh-CN.yml
@@ -1,3 +1,29 @@
+# l10n file - zh-CN - 简体中文
+
+# 文本中可使用以下语法
+# 1. **粗体**
+# 2. *斜体*
+# 3. [[red]]颜色[[/]]
+# 4. `文本`(自动着色绿色)
+# 5. <文本>(自动着色青色)
+#
+# 对于颜色的使用,请参考:
+# RED = 紧急情况,错误
+# YELLOW = 警告
+#
+# CYAN = 强调
+# GREEN = 文本内容
+#
+# GRAY = 不强调,忽略
+# GREY = 同上
+#
+# 对于 分析器 结果:
+# YELLOW = 移动操作 = ">" 符号
+# GREEN = 创建操作 = "+" 符号
+# RED = 丢失操作 = "-" 符号
+# MAGENTA = 擦除操作 = "&" 符号
+# CYAN = 修改操作 = "*" 符号
+
common:
confirm: |
是否执行上述操作?(Y/n):
@@ -161,13 +187,13 @@ jvv:
jv:
version:
header: |
- JustEnoughVCS - %{version}
+ JustEnoughVCS - [[cyan]]%{version}[[/]]
compile_info: |
编译信息:
- 时间:%{build_time}
- 目标:%{build_target}
- 平台:%{build_platform} - %{build_toolchain}
+ 时间:[[cyan]]%{build_time}[[/]]
+ 目标:[[cyan]]%{build_target}[[/]]
+ 平台:[[cyan]]%{build_platform} - %{build_toolchain}[[/]]
tip:
not_workspace: |
@@ -196,10 +222,10 @@ jv:
jv u 下载最新信息,jv t 追踪文件,jv a 对齐文件结构到表,jv in/out 导入或导出文件
**上游库**:
- login <账户> <地址> - 设置账户、定向并获得上游信息 [远程]
- direct <地址> - 定向到工作区到上游库 [远程]
+ login <账户> <地址> - 设置账户、定向并获得上游信息 [[cyan]][远程][[/]]
+ direct <地址> - 定向到工作区到上游库 [[cyan]][远程][[/]]
unstain - 祛色工作区,清除关联
- update - 同步最新的信息 [远程]
+ update - 同步最新的信息 [[cyan]][远程][[/]]
**账户**:
account [list|as|add|remove|movekey|genpub]
@@ -217,9 +243,9 @@ jv:
list - 列出所有表
use - 使用表,并开始工作
exit - 退出表,清除当前修改
- make - 创建新表以供自己使用 [远程]
- drop - 抛弃表以供他人使用 [远程]
- align - 对齐文件结构到表 [远程]
+ make - 创建新表以供自己使用 [[cyan]][远程][[/]]
+ drop - 抛弃表以供他人使用 [[cyan]][远程][[/]]
+ align - 对齐文件结构到表 [[cyan]][远程][[/]]
**上下文查询**:
here - 显示当前路径的相关信息
@@ -227,16 +253,16 @@ jv:
info - 显示单个文件的状态
**文件传递**:
- import <文件包名称> - 从导入区导入文件 [远程]
- import <参照表中目录> - 从参照表导入文件 [远程]
- export <文件> <表名称> - 导出文件到其他表 [远程]
+ import <文件包名称> - 从导入区导入文件 [[cyan]][远程][[/]]
+ import <参照表中目录> - 从参照表导入文件 [[cyan]][远程][[/]]
+ export <文件> <表名称> - 导出文件到其他表 [[cyan]][远程][[/]]
**文件操作**:
- move <文件> <到> - 安全地重命名文件 [远程]
- track <文件> - 追踪文件内容到最新版本 [远程]
- hold <文件> - 拿取文件,同步版本并获得编辑权 [远程]
- throw <文件> - 丢弃文件,同步版本并放弃编辑权 [远程]
- jump <文件> <版本> - 将文件的版本跳转至其他版本 [远程]
+ move <文件> <到> - 安全地重命名文件 [[cyan]][远程][[/]]
+ track <文件> - 追踪文件内容到最新版本 [[cyan]][远程][[/]]
+ hold <文件> - 拿取文件,同步版本并获得编辑权 [[cyan]][远程][[/]]
+ throw <文件> - 丢弃文件,同步版本并放弃编辑权 [[cyan]][远程][[/]]
+ jump <文件> <版本> - 将文件的版本跳转至其他版本 [[cyan]][远程][[/]]
**内建文档**:
docs list - 列出所有可用的文档
@@ -647,7 +673,7 @@ jv:
status:
no_sheet_in_use: |
- 您并没有使用任何一张表!无法在此状态分析工作区状态
+ 您并没有使用任何一张表!无法在此情况下分析工作区状态
**提示**:您可以使用 `jv use <表名>` 选择并使用一张表
analyze: |
@@ -714,25 +740,26 @@ jv:
很好,本地工作区未产生结构偏差,无需对齐!
suggestion_1: |
- 建议 **确认擦除项**:
- 文件在远程已不存在,但是本地仍存在!
- **例如**:使用 `jv align %{example_erased} confirm` 来确认该擦除项!
- **注意**:确认后,本地映射将被擦除,同时,该位置的文件将被移走
+ **建议**:确认 [[magenta]]擦除项[[/]]
+ **例如**:使用 `jv align %{example_erased} confirm` 来确认该 [[magenta]]擦除项[[/]]!
+
+ [[yellow]]**注意**:确认后,本地映射将被擦除,同时,该位置的文件将被移走[[/]]
suggestion_2: |
- 建议 **确认丢失项**:
- 无法确认文件丢失意图为 `删除` 或 `移动`!
- 因此,您需要通过命令以确认行为:
- **例如**:使用 `jv align %{example_lost} <行为>` 来确认该丢失
- **确认删除**:填写 `confirm` 来确认您的操作是一次 `删除`
- **声明移动**:填写 创建项 与其形成移动关系
+ **建议**:确认 [[red]]丢失项[[/]]
+ 无法确认文件丢失意图为 [[red]]删除[[/]] 或 [[yellow]]移动[[/]]!
+ **例如**:使用 `jv align %{example_lost} <行为>` 来处理该 [[red]]丢失项[[/]]
+
+ **确认删除**:填写 `confirm` 来确认您的操作是一次 [[red]]删除[[/]]
+ **声明移动**:填写 [[green]]创建项[[/]] 与其形成 [[yellow]]移动[[/]] 关系
suggestion_3: |
- 只有 **移动项**,请确认他们基于本地或远程
+ **建议**:对齐 [[yellow]]移动项[[/]],确认他们基于 本地 或 远程
**例如**:使用 `jv align moved [local|remote]` 批量对齐
或使用 `jv align %{example_moved} [local|remote]` 精确对齐移动
- **对齐至本地**:需联网,会修改上游映射至您本地实际的位置
- **对齐至远程**:可脱机,会将本地文件移动至上游地址的位置
+
+ **对齐至本地**:联网,修改上游映射至本地位置
+ **对齐至远程**:脱机,将本地文件移至上游位置
docs:
list:
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(),
+ }
+}