summaryrefslogtreecommitdiff
path: root/src/ast/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast/parser.rs')
-rw-r--r--src/ast/parser.rs52
1 files changed, 37 insertions, 15 deletions
diff --git a/src/ast/parser.rs b/src/ast/parser.rs
index 9add926..bfcf271 100644
--- a/src/ast/parser.rs
+++ b/src/ast/parser.rs
@@ -1,25 +1,26 @@
use std::{any::Any, collections::HashMap, str::Chars};
-use crate::ast::{Layer, Line, MarkdownAST, Token};
+use crate::ast::{Fragment, Line, MarkdownAST, Token};
+pub mod emphasis;
pub mod headings;
type ProcessFn = fn(&char, &mut ParserInternalStatus) -> ParserMatchResult;
fn match_fn_list() -> Vec<ProcessFn> {
- // 要求以 预处理、词、行、层、后处理 的顺序编写列表
- // 因为 词处理器 将会写入 records_tokens 由 行处理器 消费
- // 接着 行处理器 将会写入 records_lines 由 层处理器 消费
- // 最后 层处理器 将所有行写入当前层中
+ // 要求以 预处理、词、行、块、后处理 的顺序编写列表
+ // 然后 词处理器 将会写入 records_tokens 由 行处理器 消费
+ // 接着 行处理器 将会写入 records_lines 由 块处理器 消费
+ // 块处理器则将自身加入块列表中
vec![
// 预处理器
// ...
// 词处理器
- // ...
+ emphasis::proc,
// 行处理器
- headings::proc,
- // 层处理器
// ...
+ // 块处理器
+ headings::proc,
// 后处理器
post,
]
@@ -76,6 +77,9 @@ pub(crate) struct ParserInternalStatus<'a> {
/// 记录的 Token,用于暂存无归属的 Token
records_tokens: Vec<Token>,
+ /// 记录的 Fragment,用于暂存无归属的 Fragment
+ records_fragment: Fragment,
+
/// 临时类型表
tmp: HashMap<&'a str, Box<dyn Any>>,
}
@@ -120,17 +124,19 @@ pub(crate) enum ParserMatchResult {
}
pub fn markdown_parser(
- content: &str,
+ content: String,
cfg: MarkdownParserConfig,
) -> Result<MarkdownAST, MarkdownASTParseError> {
// 创建空 AST,无任何内容
- let ast = MarkdownAST {
- root: Layer {
- range_row_begin: 0,
- range_row_end: 0,
- lines: Vec::new(),
- },
+ let ast = MarkdownAST { blocks: vec![] };
+
+ // 在末尾添加换行符,以确保末尾行一定能被执行
+ let mut content = content;
+ let ending = match cfg.ending_rule {
+ LineEndingRule::CRLF => "\r\n",
+ LineEndingRule::LF => "\n",
};
+ content.push_str(ending);
// 初始化内部状态
let mut inr = ParserInternalStatus {
@@ -142,6 +148,7 @@ pub fn markdown_parser(
col: 0,
records_lines: Vec::new(),
records_tokens: Vec::new(),
+ records_fragment: Fragment::default(),
tmp: HashMap::new(),
};
@@ -165,6 +172,9 @@ pub fn markdown_parser(
// 当前处理函数的索引值
let mut idx: u8 = 0;
+ // 该字符是否已完成处理
+ let mut done = false;
+
for v in &match_vec {
// 当前处理函数在放弃列表中
if aborted.contains(&idx) {
@@ -180,8 +190,13 @@ pub fn markdown_parser(
//
// 在 `post` 中,必须处理该字符的换行逻辑,否则会产生字符位置指针异常
if !matches!(c, '\r' | '\n') {
+ // 为字符标记为已完成处理
+ done = true;
+
// 跳过当前步骤前,提前将列指针右移
inr.col += 1;
+
+ // 所有处理器跳过当前步骤
break;
}
}
@@ -213,9 +228,16 @@ pub fn markdown_parser(
));
}
}
+
+ // 下一个处理器继续处理
idx += 1;
}
+ if !done {
+ // 如果字符未完成处理,说明是普通字符,需要加入 records_fragment
+ inr.records_fragment.str.push(c);
+ }
+
// 将列指针右移
inr.col += 1;
}