diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-04-23 16:57:33 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-04-23 16:57:33 +0800 |
| commit | 7525fe0834e47bef425135e8cda1d576c44060a5 (patch) | |
| tree | 0d9367b7f0aa0b3542f165095c10ab698b3b2c05 /src/ast/parser/headings.rs | |
| parent | 277bc93f84b298c7cb24e136f67eb237fb3a68a2 (diff) | |
Initialize Rust project with Markdown AST structure
Diffstat (limited to 'src/ast/parser/headings.rs')
| -rw-r--r-- | src/ast/parser/headings.rs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/ast/parser/headings.rs b/src/ast/parser/headings.rs new file mode 100644 index 0000000..260efa4 --- /dev/null +++ b/src/ast/parser/headings.rs @@ -0,0 +1,104 @@ +use std::mem::replace; + +use crate::ast::{ + Line, + parser::{ParserInternalStatus, ParserMatchResult}, +}; + +#[derive(Default)] +struct HeadingTmp { + /// 当前输入的层级 + lvl: u8, + + /// 是否正在输入标题前缀 + typing_heading_prefix: bool, + + /// 是否正在输入标题内容 + typing_heading_content: bool, + + // 第一个 Sharp 符号的位置 + first_sharp_col: Option<u16>, +} + +pub(crate) fn proc(c: &char, inr: &mut ParserInternalStatus) -> ParserMatchResult { + // 如果本行在剔除开头所有字符后仍不为 # 开头,则说明本行无法用于标题解析 + let lookback = inr.lookback.clone(); + if !lookback.trim_start().starts_with('#') { + // 本行不是标题行,放弃整行的解析 + return ParserMatchResult::Abort; + } + + // 当前行 + let row = inr.row; + let col = inr.col; + + // 获得临时数据 + let tmp = inr.get_tmp_or_init::<HeadingTmp>("headings_tmp"); + + // 如果是行首,则初始化 tmp 数据 + if col == 0 { + tmp.lvl = 0; + tmp.typing_heading_prefix = false; + tmp.typing_heading_content = false; + tmp.first_sharp_col = None; + } + + match c { + // 键入了 # 符号 + '#' => { + // 如果正在输入标题前缀,则层级增加 + if tmp.typing_heading_prefix { + tmp.lvl += 1; + + // 如果层级大于 6 (6级标题) + if tmp.lvl > 6 { + // 语法异常,抛出 + return ParserMatchResult::SyntaxError { + begin_col: tmp.first_sharp_col.unwrap_or(col), + begin_row: row, + end_col: col, + end_row: row, + msg: "Heading level cannot exceed 6".to_string(), + }; + } + } + // 如果不在输入标题 + else { + // 记录为正在输入前缀 + tmp.typing_heading_prefix = true; + + // 设置层级为 1 + tmp.lvl = 1; + + // 标记第一个 # 符号的位置 + tmp.first_sharp_col = Some(col); + } + } + // 输入了空格 + ' ' => { + // 如果正在输入标题前缀 + if tmp.typing_heading_prefix { + // 标记为没输入前缀,并切换为正在输入内容 + tmp.typing_heading_prefix = false; + tmp.typing_heading_content = true; + } + } + // 输入了换行 + '\n' => { + // 如果正在输入标题内容 + if tmp.typing_heading_content { + // 拿出所有 records_tokens + let tokens = replace(&mut inr.records_tokens, Vec::new()); + + // 建立标题行 + let line = Line { row, tokens }; + + // 追加行 + inr.records_lines.push(line); + } + } + _ => return ParserMatchResult::Sad, + } + + ParserMatchResult::Done +} |
