diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-04-23 18:58:41 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-04-23 18:58:41 +0800 |
| commit | 7d9f9be43469748148da5cdf516cd8b32238e1f5 (patch) | |
| tree | e3904be9901294e0193419cb30e8f6fa1d33fae3 /src/ast/parser/emphasis.rs | |
| parent | 7525fe0834e47bef425135e8cda1d576c44060a5 (diff) | |
重构AST抽象rewrite
Diffstat (limited to 'src/ast/parser/emphasis.rs')
| -rw-r--r-- | src/ast/parser/emphasis.rs | 137 |
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; +} |
