fix: 优化markdown解析器

This commit is contained in:
imeepos
2025-07-22 15:04:37 +08:00
parent 31d97834dc
commit f92d9a7c39
24 changed files with 5702 additions and 703 deletions

View File

@@ -0,0 +1,423 @@
use crate::infrastructure::markdown_parser::{
MarkdownParser, MarkdownParserConfig, MarkdownParseResult,
OutlineItem, LinkInfo, ValidationResult, MarkdownNode, Range, Position
};
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::sync::Mutex;
use tauri::{command, State};
use tracing::{error, info};
/// Markdown解析器状态
pub struct MarkdownParserState {
parser: Mutex<Option<MarkdownParser>>,
}
impl MarkdownParserState {
pub fn new() -> Self {
Self {
parser: Mutex::new(None),
}
}
/// 获取或创建解析器实例
pub fn get_or_create_parser(&self, config: Option<MarkdownParserConfig>) -> Result<()> {
let mut parser_guard = self.parser.lock().unwrap();
if parser_guard.is_none() {
let parser = MarkdownParser::new(config)?;
*parser_guard = Some(parser);
}
Ok(())
}
/// 执行解析操作
pub fn with_parser<F, R>(&self, f: F) -> Result<R>
where
F: FnOnce(&mut MarkdownParser) -> Result<R>,
{
let mut parser_guard = self.parser.lock().unwrap();
if let Some(ref mut parser) = *parser_guard {
f(parser)
} else {
Err(anyhow::anyhow!("Parser not initialized"))
}
}
}
/// 解析Markdown请求
#[derive(Debug, Deserialize)]
pub struct ParseMarkdownRequest {
/// 要解析的Markdown文本
pub text: String,
/// 解析器配置
pub config: Option<MarkdownParserConfigDto>,
}
/// 解析器配置DTO
#[derive(Debug, Deserialize)]
pub struct MarkdownParserConfigDto {
/// 是否保留空白节点
pub preserve_whitespace: Option<bool>,
/// 是否解析内联HTML
pub parse_inline_html: Option<bool>,
/// 最大解析深度
pub max_depth: Option<usize>,
/// 超时时间(毫秒)
pub timeout_ms: Option<u64>,
}
impl From<MarkdownParserConfigDto> for MarkdownParserConfig {
fn from(dto: MarkdownParserConfigDto) -> Self {
let default = MarkdownParserConfig::default();
Self {
preserve_whitespace: dto.preserve_whitespace.unwrap_or(default.preserve_whitespace),
parse_inline_html: dto.parse_inline_html.unwrap_or(default.parse_inline_html),
max_depth: dto.max_depth.unwrap_or(default.max_depth),
timeout_ms: dto.timeout_ms.unwrap_or(default.timeout_ms),
}
}
}
/// 解析Markdown响应
#[derive(Debug, Serialize)]
pub struct ParseMarkdownResponse {
/// 是否成功
pub success: bool,
/// 解析结果
pub result: Option<MarkdownParseResult>,
/// 错误信息
pub error: Option<String>,
}
/// 查询节点请求
#[derive(Debug, Deserialize)]
pub struct QueryNodesRequest {
/// Markdown文本
pub text: String,
/// 查询名称
pub query_name: String,
}
/// 查询节点响应
#[derive(Debug, Serialize)]
pub struct QueryNodesResponse {
/// 是否成功
pub success: bool,
/// 查询结果
pub nodes: Option<Vec<MarkdownNode>>,
/// 错误信息
pub error: Option<String>,
}
/// 位置查询请求
#[derive(Debug, Deserialize)]
pub struct FindNodeAtPositionRequest {
/// Markdown文本
pub text: String,
/// 行号从0开始
pub line: usize,
/// 列号从0开始
pub column: usize,
}
/// 位置查询响应
#[derive(Debug, Serialize)]
pub struct FindNodeAtPositionResponse {
/// 是否成功
pub success: bool,
/// 找到的节点
pub node: Option<MarkdownNode>,
/// 错误信息
pub error: Option<String>,
}
/// 大纲提取请求
#[derive(Debug, Deserialize)]
pub struct ExtractOutlineRequest {
/// Markdown文本
pub text: String,
}
/// 大纲提取响应
#[derive(Debug, Serialize)]
pub struct ExtractOutlineResponse {
/// 是否成功
pub success: bool,
/// 大纲项目
pub outline: Option<Vec<OutlineItem>>,
/// 错误信息
pub error: Option<String>,
}
/// 链接提取请求
#[derive(Debug, Deserialize)]
pub struct ExtractLinksRequest {
/// Markdown文本
pub text: String,
}
/// 链接提取响应
#[derive(Debug, Serialize)]
pub struct ExtractLinksResponse {
/// 是否成功
pub success: bool,
/// 链接信息
pub links: Option<Vec<LinkInfo>>,
/// 错误信息
pub error: Option<String>,
}
/// 验证请求
#[derive(Debug, Deserialize)]
pub struct ValidateMarkdownRequest {
/// Markdown文本
pub text: String,
}
/// 验证响应
#[derive(Debug, Serialize)]
pub struct ValidateMarkdownResponse {
/// 是否成功
pub success: bool,
/// 验证结果
pub validation: Option<ValidationResult>,
/// 错误信息
pub error: Option<String>,
}
/// 解析Markdown文档
#[command]
pub async fn parse_markdown(
request: ParseMarkdownRequest,
state: State<'_, MarkdownParserState>,
) -> Result<ParseMarkdownResponse, String> {
info!("Received Markdown parse request, text length: {}", request.text.len());
// 转换配置
let parser_config = request.config.map(|c| c.into());
// 确保解析器已初始化
if let Err(e) = state.get_or_create_parser(parser_config) {
error!("Failed to initialize Markdown parser: {}", e);
return Ok(ParseMarkdownResponse {
success: false,
result: None,
error: Some(format!("Parser initialization failed: {}", e)),
});
}
// 执行解析
match state.with_parser(|parser| parser.parse(&request.text)) {
Ok(result) => {
info!("Markdown parsing completed successfully");
Ok(ParseMarkdownResponse {
success: true,
result: Some(result),
error: None,
})
}
Err(e) => {
error!("Markdown parsing failed: {}", e);
Ok(ParseMarkdownResponse {
success: false,
result: None,
error: Some(e.to_string()),
})
}
}
}
/// 查询特定类型的节点
#[command]
pub async fn query_markdown_nodes(
request: QueryNodesRequest,
state: State<'_, MarkdownParserState>,
) -> Result<QueryNodesResponse, String> {
info!("Received query nodes request: {}", request.query_name);
// 确保解析器已初始化
if let Err(e) = state.get_or_create_parser(None) {
error!("Failed to initialize Markdown parser: {}", e);
return Ok(QueryNodesResponse {
success: false,
nodes: None,
error: Some(format!("Parser initialization failed: {}", e)),
});
}
// 执行查询
match state.with_parser(|parser| parser.query_nodes(&request.text, &request.query_name)) {
Ok(nodes) => {
info!("Query completed successfully, found {} nodes", nodes.len());
Ok(QueryNodesResponse {
success: true,
nodes: Some(nodes),
error: None,
})
}
Err(e) => {
error!("Query failed: {}", e);
Ok(QueryNodesResponse {
success: false,
nodes: None,
error: Some(e.to_string()),
})
}
}
}
/// 根据位置查找节点
#[command]
pub async fn find_markdown_node_at_position(
request: FindNodeAtPositionRequest,
state: State<'_, MarkdownParserState>,
) -> Result<FindNodeAtPositionResponse, String> {
info!("Received find node at position request: {}:{}", request.line, request.column);
// 确保解析器已初始化
if let Err(e) = state.get_or_create_parser(None) {
error!("Failed to initialize Markdown parser: {}", e);
return Ok(FindNodeAtPositionResponse {
success: false,
node: None,
error: Some(format!("Parser initialization failed: {}", e)),
});
}
// 执行查找
match state.with_parser(|parser| parser.find_node_at_position(&request.text, request.line, request.column)) {
Ok(node) => {
info!("Find node at position completed successfully");
Ok(FindNodeAtPositionResponse {
success: true,
node,
error: None,
})
}
Err(e) => {
error!("Find node at position failed: {}", e);
Ok(FindNodeAtPositionResponse {
success: false,
node: None,
error: Some(e.to_string()),
})
}
}
}
/// 提取文档大纲
#[command]
pub async fn extract_markdown_outline(
request: ExtractOutlineRequest,
state: State<'_, MarkdownParserState>,
) -> Result<ExtractOutlineResponse, String> {
info!("Received extract outline request");
// 确保解析器已初始化
if let Err(e) = state.get_or_create_parser(None) {
error!("Failed to initialize Markdown parser: {}", e);
return Ok(ExtractOutlineResponse {
success: false,
outline: None,
error: Some(format!("Parser initialization failed: {}", e)),
});
}
// 执行大纲提取
match state.with_parser(|parser| parser.extract_outline(&request.text)) {
Ok(outline) => {
info!("Extract outline completed successfully, found {} items", outline.len());
Ok(ExtractOutlineResponse {
success: true,
outline: Some(outline),
error: None,
})
}
Err(e) => {
error!("Extract outline failed: {}", e);
Ok(ExtractOutlineResponse {
success: false,
outline: None,
error: Some(e.to_string()),
})
}
}
}
/// 提取所有链接
#[command]
pub async fn extract_markdown_links(
request: ExtractLinksRequest,
state: State<'_, MarkdownParserState>,
) -> Result<ExtractLinksResponse, String> {
info!("Received extract links request");
// 确保解析器已初始化
if let Err(e) = state.get_or_create_parser(None) {
error!("Failed to initialize Markdown parser: {}", e);
return Ok(ExtractLinksResponse {
success: false,
links: None,
error: Some(format!("Parser initialization failed: {}", e)),
});
}
// 执行链接提取
match state.with_parser(|parser| parser.extract_links(&request.text)) {
Ok(links) => {
info!("Extract links completed successfully, found {} links", links.len());
Ok(ExtractLinksResponse {
success: true,
links: Some(links),
error: None,
})
}
Err(e) => {
error!("Extract links failed: {}", e);
Ok(ExtractLinksResponse {
success: false,
links: None,
error: Some(e.to_string()),
})
}
}
}
/// 验证Markdown文档结构
#[command]
pub async fn validate_markdown(
request: ValidateMarkdownRequest,
state: State<'_, MarkdownParserState>,
) -> Result<ValidateMarkdownResponse, String> {
info!("Received validate markdown request");
// 确保解析器已初始化
if let Err(e) = state.get_or_create_parser(None) {
error!("Failed to initialize Markdown parser: {}", e);
return Ok(ValidateMarkdownResponse {
success: false,
validation: None,
error: Some(format!("Parser initialization failed: {}", e)),
});
}
// 执行验证
match state.with_parser(|parser| parser.validate_structure(&request.text)) {
Ok(validation) => {
info!("Validate markdown completed successfully, found {} issues", validation.issues.len());
Ok(ValidateMarkdownResponse {
success: true,
validation: Some(validation),
error: None,
})
}
Err(e) => {
error!("Validate markdown failed: {}", e);
Ok(ValidateMarkdownResponse {
success: false,
validation: None,
error: Some(e.to_string()),
})
}
}
}