summaryrefslogtreecommitdiff
path: root/src/ast/parser/emphasis.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-04-23 18:58:41 +0800
committer魏曹先生 <1992414357@qq.com>2026-04-23 18:58:41 +0800
commit7d9f9be43469748148da5cdf516cd8b32238e1f5 (patch)
treee3904be9901294e0193419cb30e8f6fa1d33fae3 /src/ast/parser/emphasis.rs
parent7525fe0834e47bef425135e8cda1d576c44060a5 (diff)
重构AST抽象rewrite
Diffstat (limited to 'src/ast/parser/emphasis.rs')
-rw-r--r--src/ast/parser/emphasis.rs137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/ast/parser/emphasis.rs b/src/ast/parser/emphasis.rs
new file mode 100644
index 0000000..c8e6b9b
--- /dev/null
+++ b/src/ast/parser/emphasis.rs
@@ -0,0 +1,137 @@
+use crate::ast::parser::{ParserInternalStatus, ParserMatchResult};
+
+#[derive(Default)]
+struct EmphasisTmp {
+ /// 强调开始的列
+ emphasis_begin_col: u16,
+
+ /// 前缀,用于后缀匹配
+ prefix_count: String,
+
+ /// 是否正在输入强调前缀
+ typing_emphasis_prefix: bool,
+
+ /// 是否正在输入强调内容
+ typing_emphasis_content: bool,
+}
+
+#[derive(Default, PartialEq, Eq)]
+#[repr(u8)]
+enum Style {
+ /// 无样式
+ #[default]
+ None,
+
+ /// 星号
+ Star,
+
+ /// 下划线
+ Underline,
+}
+
+impl Style {
+ /// 反转样式
+ pub fn invert(&self) -> Style {
+ match self {
+ Style::Underline => Style::Star,
+ Style::Star => Style::Underline,
+ Style::None => Style::None,
+ }
+ }
+}
+
+impl std::fmt::Display for Style {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Style::None => write!(f, ""),
+ Style::Star => write!(f, "*"),
+ Style::Underline => write!(f, "_"),
+ }
+ }
+}
+
+impl From<Style> for char {
+ fn from(style: Style) -> char {
+ match style {
+ Style::None => ' ',
+ Style::Star => '*',
+ Style::Underline => '_',
+ }
+ }
+}
+
+fn get_tmp<'a>(inr: &'a mut ParserInternalStatus) -> &'a mut EmphasisTmp {
+ inr.get_tmp_or_init::<EmphasisTmp>("emphasis_tmp")
+}
+
+pub(crate) fn proc(c: &char, inr: &mut ParserInternalStatus) -> ParserMatchResult {
+ match c {
+ // 输入能被识别的符号时
+
+ // 星星
+ '*' => typed_emphasis_char(Style::Star, inr),
+
+ // 下划线
+ '_' => typed_emphasis_char(Style::Underline, inr),
+
+ // 输入其他字符时
+ _ => typed_other_char(c, inr),
+ }
+}
+
+fn typed_emphasis_char(s: Style, inr: &mut ParserInternalStatus) -> ParserMatchResult {
+ let col = inr.col;
+ let tmp = get_tmp(inr);
+
+ // 如果没设置样式(没初始化)
+ if tmp.prefix_style == Style::None {
+ // 设置样式
+ tmp.prefix_style = s;
+ // 设置前缀长度
+ tmp.prefix_count = 1;
+ // 设置开始位置
+ tmp.emphasis_begin_col = col;
+
+ tmp.typing_emphasis_prefix = true;
+ tmp.typing_emphasis_content = false;
+ } else
+ // 如果设置了样式,则判断其是否匹配
+ if tmp.prefix_style == s {
+ // 如果匹配,增加前缀长度
+ tmp.prefix_count += 1;
+
+ // 增加长度后,如果前缀长度大于 3(最长),将报语法错误
+ if tmp.prefix_count > 3 {
+ return ParserMatchResult::SyntaxError {
+ begin_col: tmp.emphasis_begin_col,
+ begin_row: inr.row,
+ end_col: inr.col,
+ end_row: inr.row,
+ msg: "Emphasis characters can be at most 3".to_string(),
+ };
+ }
+ } else {
+ // 如果不匹配,将报语法错误
+ return ParserMatchResult::SyntaxError {
+ begin_col: inr.col,
+ begin_row: inr.row,
+ end_col: inr.col,
+ end_row: inr.row,
+ msg: format!(
+ "Emphasis statement (style: \"{}\") cannot use another emphasis statement (style: \"{}\") before closing",
+ s.invert(),
+ s
+ ),
+ };
+ }
+
+ ParserMatchResult::Done
+}
+
+fn typed_other_char(c: &char, inr: &mut ParserInternalStatus) -> ParserMatchResult {
+ let tmp = get_tmp(inr);
+
+ // 修改当前状态
+ tmp.typing_emphasis_prefix = false;
+ tmp.typing_emphasis_content = true;
+}