mf_model/
content.rs

1use std::fmt;
2use std::{cell::RefCell, collections::HashMap, rc::Rc};
3
4use std::cmp::Ordering;
5
6use crate::error::PoolResult;
7
8use super::node::Node;
9use super::node_type::NodeType;
10use super::schema::Schema;
11#[derive(Clone, PartialEq, Eq, Debug)]
12pub struct MatchEdge {
13    pub node_type: NodeType,
14    pub next: ContentMatch,
15}
16
17#[derive(Clone, PartialEq, Eq, Debug, Default)]
18pub struct ContentMatch {
19    pub next: Vec<MatchEdge>,
20    pub wrap_cache: Vec<Option<NodeType>>,
21    pub valid_end: bool,
22}
23impl Ord for ContentMatch {
24    fn cmp(
25        &self,
26        other: &Self,
27    ) -> Ordering {
28        let _ = other;
29        Ordering::Equal
30    }
31}
32impl PartialOrd for ContentMatch {
33    fn partial_cmp(
34        &self,
35        other: &Self,
36    ) -> Option<Ordering> {
37        Some(self.cmp(other))
38    }
39}
40
41impl ContentMatch {
42    pub fn parse(
43        str: String,
44        nodes: &HashMap<String, NodeType>,
45    ) -> ContentMatch {
46        let mut stream = TokenStream::new(str, nodes.clone());
47        if stream.next().is_none() {
48            return ContentMatch::empty();
49        }
50        let expr = parse_expr(&mut stream);
51
52        let arr = nfa(expr);
53
54        dfa(arr)
55    }
56    pub fn empty() -> Self {
57        ContentMatch {
58            next: Vec::new(),
59            wrap_cache: Vec::new(),
60            valid_end: true,
61        }
62    }
63
64    pub fn match_type(
65        &self,
66        node_type: &NodeType,
67    ) -> Option<&ContentMatch> {
68        self.next
69            .iter()
70            .find(|edge| &edge.node_type == node_type)
71            .map(|edge| &edge.next)
72    }
73
74    pub fn match_fragment(
75        &self,
76        frag: &[Node],
77        schema: &Schema,
78    ) -> Option<&ContentMatch> {
79        let mut current: &ContentMatch = self;
80
81        for content in frag.iter() {
82            if let Some(next) =
83                current.match_type(schema.nodes.get(&content.r#type).unwrap())
84            {
85                current = next;
86            } else {
87                // 如果无法匹配某个节点类型,返回 None 表示匹配失败
88                return None;
89            }
90        }
91        Some(current)
92    }
93
94    /// 根据内容匹配规则推导需要的节点类型
95    ///
96    /// # 参数
97    /// - `after`: 待匹配的节点列表
98    /// - `to_end`: 是否需要匹配到结束状态
99    /// - `schema`: 当前使用的文档模式
100    ///
101    /// # 返回值
102    /// 返回需要的节点类型名称列表,如果无法匹配则返回None
103    pub fn fill(
104        &self,
105        after: &Vec<Node>,
106        to_end: bool,
107        schema: &Schema,
108    ) -> Option<Vec<String>> {
109        let mut seen: Vec<ContentMatch> = Vec::new();
110        seen.push(self.clone());
111        fn search(
112            seen: &mut Vec<ContentMatch>,
113            to_end: bool,
114            after: &Vec<Node>,
115            match_: &ContentMatch,
116            types: &mut Vec<String>,
117            schema: &Schema,
118        ) -> Option<Vec<String>> {
119            // 首先检查是否可以匹配当前片段
120            if let Some(finished) = match_.match_fragment(after, schema) {
121                if finished.valid_end || !to_end {
122                    return Some(types.clone());
123                }
124            } else if !after.is_empty() {
125                // 如果 after 不为空但无法匹配,直接返回 None
126                return None;
127            }
128
129            // 然后尝试按顺序匹配每个边
130            for edge in &match_.next {
131                if !seen.contains(&edge.next) {
132                    seen.push(edge.next.clone());
133                    types.push(edge.node_type.name.clone());
134                    if let Some(found) =
135                        search(seen, to_end, after, &edge.next, types, schema)
136                    {
137                        return Some(found);
138                    }
139                    types.pop();
140                }
141            }
142            None
143        }
144
145        search(&mut seen, to_end, after, self, &mut Vec::new(), schema)
146    }
147
148    pub fn default_type(&self) -> Option<&NodeType> {
149        self.next
150            .iter()
151            .find(|edge| !edge.node_type.has_required_attrs())
152            .map(|edge| &edge.node_type)
153    }
154
155    pub fn compatible(
156        &self,
157        other: &ContentMatch,
158    ) -> bool {
159        for edge1 in &self.next {
160            for edge2 in &other.next {
161                if edge1.node_type == edge2.node_type {
162                    return true;
163                }
164            }
165        }
166        false
167    }
168
169    pub fn edge_count(&self) -> usize {
170        self.next.len()
171    }
172
173    pub fn edge(
174        &self,
175        n: usize,
176        // 根据错误提示,PoolResult 类型别名可能只接受一个泛型参数,这里修改为只传递一个泛型参数
177    ) -> PoolResult<&MatchEdge> {
178        if n >= self.next.len() {
179            Err(anyhow::anyhow!(format!("{} 超出了 {}", n, self.next.len())))
180        } else {
181            Ok(&self.next[n])
182        }
183    }
184}
185impl fmt::Display for ContentMatch {
186    fn fmt(
187        &self,
188        f: &mut fmt::Formatter<'_>,
189    ) -> fmt::Result {
190        let mut seen = Vec::new();
191        fn scan(
192            m: &ContentMatch,
193            seen: &mut Vec<ContentMatch>,
194        ) {
195            seen.push(m.clone());
196            for edge in &m.next {
197                if !seen.iter().any(|s| s == &edge.next) {
198                    scan(&edge.next, seen);
199                }
200            }
201        }
202        scan(self, &mut seen);
203
204        let str = seen
205            .iter()
206            .enumerate()
207            .map(|(i, m)| {
208                let mut out =
209                    format!("{} ", if m.valid_end { i + 1 } else { i });
210                for (j, edge) in m.next.iter().enumerate() {
211                    if j > 0 {
212                        out.push_str(", ");
213                    }
214                    out.push_str(&format!(
215                        "{}->{}",
216                        edge.node_type.name,
217                        seen.iter().position(|s| s == &edge.next).unwrap() + 1
218                    ));
219                }
220                out
221            })
222            .collect::<Vec<_>>()
223            .join("\n");
224
225        write!(f, "{str}")
226    }
227}
228
229#[derive(Clone, PartialEq, Eq, Debug)]
230pub struct TokenStream {
231    pos: usize,
232    tokens: Vec<String>,
233    node_types: HashMap<String, NodeType>,
234    string: String,
235}
236
237impl TokenStream {
238    pub fn new(
239        string: String,
240        node_types: HashMap<String, NodeType>,
241    ) -> Self {
242        let mut tokens = Vec::new();
243        let mut current_token = String::new();
244        for c in string.chars() {
245            if c.is_whitespace() {
246                // 如果当前字符是空白字符,且当前令牌不为空,则将当前令牌添加到令牌列表中
247                if !current_token.is_empty() {
248                    tokens.push(current_token.clone());
249                    current_token.clear(); // 清空当前令牌
250                }
251            } else if !c.is_alphanumeric() && c != '_' {
252                // 如果当前字符是非字母数字字符(不包括下划线),且当前令牌不为空,则将当前令牌添加到令牌列表中
253                if !current_token.is_empty() {
254                    tokens.push(current_token.clone());
255                    current_token.clear(); // 清空当前令牌
256                }
257                // 将非字母数字字符作为单独的令牌添加到列表中
258                tokens.push(c.to_string());
259            } else {
260                // 如果当前字符是字母数字字符或下划线,则将其添加到当前令牌中
261                current_token.push(c);
262            }
263        }
264
265        // 如果最后一个令牌不为空,则将其添加到令牌列表中
266        if !current_token.is_empty() {
267            tokens.push(current_token);
268        }
269        TokenStream { pos: 0, tokens, node_types, string }
270    }
271
272    pub fn next(&self) -> Option<&str> {
273        self.tokens.get(self.pos).map(|s| s.as_str())
274    }
275
276    pub fn eat(
277        &mut self,
278        tok: &str,
279    ) -> bool {
280        if self.next() == Some(tok) {
281            self.pos += 1;
282            true
283        } else {
284            false
285        }
286    }
287
288    pub fn err(
289        &self,
290        str: &str,
291    ) -> ! {
292        panic!("{} (约束必须是 '{}')", str, self.string);
293    }
294}
295
296#[derive(Debug, Clone)]
297enum Expr {
298    Choice { exprs: Vec<Expr> },
299    Seq { exprs: Vec<Expr> },
300    Plus { expr: Box<Expr> },
301    Star { expr: Box<Expr> },
302    Opt { expr: Box<Expr> },
303    Range { min: usize, max: isize, expr: Box<Expr> },
304    Name { value: Box<NodeType> },
305}
306fn parse_expr(stream: &mut TokenStream) -> Expr {
307    let mut exprs = Vec::new();
308
309    loop {
310        exprs.push(parse_expr_seq(stream));
311        if !stream.eat("|") {
312            break;
313        }
314    }
315    if exprs.len() == 1 { exprs.pop().unwrap() } else { Expr::Choice { exprs } }
316}
317fn parse_expr_seq(stream: &mut TokenStream) -> Expr {
318    let mut exprs = Vec::new();
319
320    while let Some(next) = stream.next() {
321        if next == ")" || next == "|" {
322            break;
323        }
324        exprs.push(parse_expr_subscript(stream));
325    }
326    if exprs.len() == 1 { exprs.pop().unwrap() } else { Expr::Seq { exprs } }
327}
328
329fn parse_expr_subscript(stream: &mut TokenStream) -> Expr {
330    let mut expr = parse_expr_atom(stream);
331    loop {
332        if stream.eat("+") {
333            expr = Expr::Plus { expr: Box::new(expr) };
334        } else if stream.eat("*") {
335            expr = Expr::Star { expr: Box::new(expr) };
336        } else if stream.eat("?") {
337            expr = Expr::Opt { expr: Box::new(expr) };
338        } else if stream.eat("{") {
339            expr = parse_expr_range(stream, expr);
340        } else {
341            break;
342        }
343    }
344    expr
345}
346
347fn parse_num(stream: &mut TokenStream) -> usize {
348    let next = stream.next().unwrap();
349    if !next.chars().all(|c| c.is_ascii_digit()) {
350        stream.err(&format!("Expected number, got '{next}'"));
351    }
352    let result = next.parse().unwrap();
353    stream.pos += 1;
354    result
355}
356fn parse_expr_range(
357    stream: &mut TokenStream,
358    expr: Expr,
359) -> Expr {
360    let min = parse_num(stream);
361    let max = if stream.eat(",") {
362        if stream.next() != Some("}") { parse_num(stream) as isize } else { -1 }
363    } else {
364        min as isize
365    };
366    if !stream.eat("}") {
367        stream.err("Unclosed braced range");
368    }
369    Expr::Range { min, max, expr: Box::new(expr) }
370}
371
372fn resolve_name(
373    stream: &TokenStream,
374    name: &str,
375) -> Vec<NodeType> {
376    let types = &stream.node_types;
377    if let Some(type_) = types.get(name) {
378        return vec![type_.clone()];
379    }
380    let mut result = Vec::new();
381
382    for type_ in types.values() {
383        if type_.groups.contains(&name.to_string()) {
384            result.push(type_.clone());
385        }
386    }
387    if result.is_empty() {
388        stream.err(&format!("没找到类型 '{name}'"));
389    }
390    result
391}
392
393fn parse_expr_atom(stream: &mut TokenStream) -> Expr {
394    if stream.eat("(") {
395        let expr = parse_expr(stream);
396        if !stream.eat(")") {
397            stream.err("Missing closing paren");
398        }
399        expr
400    } else if let Some(next) = stream.next() {
401        if next.chars().all(|c| c.is_alphanumeric() || c == '_') {
402            let exprs: Vec<Expr> = resolve_name(stream, next)
403                .into_iter()
404                .map(|type_| Expr::Name { value: Box::new(type_) })
405                .collect();
406            stream.pos += 1;
407            if exprs.len() == 1 {
408                exprs.into_iter().next().unwrap()
409            } else {
410                Expr::Choice { exprs }
411            }
412        } else {
413            stream.err(&format!("Unexpected token '{next}'"));
414        }
415    } else {
416        stream.err("Unexpected end of input");
417    }
418}
419#[derive(Debug, Clone)]
420pub struct Edge {
421    term: Option<NodeType>,
422    to: Option<usize>,
423}
424fn dfa(nfa: Vec<Vec<Rc<RefCell<Edge>>>>) -> ContentMatch {
425    let mut labeled: HashMap<String, ContentMatch> = HashMap::new();
426
427    fn explore(
428        states: Vec<usize>,
429        nfa: &Vec<Vec<Rc<RefCell<Edge>>>>,
430        labeled: &mut HashMap<String, ContentMatch>,
431    ) -> ContentMatch {
432        let mut out: Vec<(NodeType, Vec<usize>)> = Vec::new();
433        for &node in &states {
434            for edge in &nfa[node] {
435                if edge.borrow().term.is_none() {
436                    continue;
437                }
438                let term = edge.borrow().term.clone().unwrap();
439                let mut set: Option<&mut Vec<usize>> = None;
440
441                for (t, s) in &mut out {
442                    if *t == term {
443                        set = Some(s);
444                        break;
445                    }
446                }
447
448                if set.is_none() {
449                    out.push((term.clone(), Vec::new()));
450                    set = Some(&mut out.last_mut().unwrap().1);
451                }
452                for &node in &null_from(nfa, edge.borrow().to.unwrap_or(0)) {
453                    set.as_mut().unwrap().push(node);
454                }
455            }
456        }
457        let mut state = ContentMatch {
458            next: Vec::new(),
459            wrap_cache: vec![],
460            valid_end: states.contains(&(nfa.len() - 1)),
461        };
462
463        let state_key =
464            states.iter().map(|&x| x.to_string()).collect::<Vec<_>>().join(",");
465        labeled.insert(state_key.clone(), state.clone());
466
467        for (term, states) in out {
468            let states_key = states
469                .iter()
470                .map(|&x| x.to_string())
471                .collect::<Vec<_>>()
472                .join(",");
473            let next_state = labeled
474                .get(&states_key)
475                .cloned()
476                .unwrap_or_else(|| explore(states, nfa, labeled));
477            labeled.insert(states_key, next_state.clone());
478            state.next.push(MatchEdge { node_type: term, next: next_state });
479        }
480
481        state
482    }
483
484    explore(null_from(&nfa, 0), &nfa, &mut labeled)
485}
486
487pub fn null_from(
488    nfa: &[Vec<Rc<RefCell<Edge>>>],
489    node: usize,
490) -> Vec<usize> {
491    let mut result = Vec::new();
492    fn scan(
493        nfa: &[Vec<Rc<RefCell<Edge>>>],
494        node: usize,
495        result: &mut Vec<usize>,
496    ) {
497        let edges = &nfa[node];
498        if edges.len() == 1 && edges[0].borrow().term.is_none() {
499            if let Some(to) = edges[0].borrow().to {
500                scan(nfa, to, result);
501            }
502            return;
503        }
504        if !result.contains(&node) {
505            result.push(node);
506        }
507        for edge in edges {
508            if edge.borrow().term.is_none() {
509                if let Some(to) = edge.borrow().to {
510                    if !result.contains(&to) {
511                        scan(nfa, to, result);
512                    }
513                }
514            }
515        }
516    }
517
518    scan(nfa, node, &mut result);
519    result.sort();
520    result
521}
522fn nfa(expr: Expr) -> Vec<Vec<Rc<RefCell<Edge>>>> {
523    let mut nfa: Vec<Vec<Rc<RefCell<Edge>>>> = vec![vec![]];
524    connect(&mut compile(expr, 0, &mut nfa), node(&mut nfa));
525    nfa
526}
527fn node(nfa: &mut Vec<Vec<Rc<RefCell<Edge>>>>) -> usize {
528    nfa.push(vec![]);
529    nfa.len() - 1
530}
531
532fn edge(
533    from: usize,
534    to: Option<usize>,
535    term: Option<NodeType>,
536    nfa: &mut [Vec<Rc<RefCell<Edge>>>],
537) -> Rc<RefCell<Edge>> {
538    let edge =
539        Rc::new(RefCell::new(Edge { term, to: Option::from(to.unwrap_or(0)) }));
540    nfa[from].push(edge.clone());
541    edge.clone()
542}
543fn connect(
544    edges: &mut [Rc<RefCell<Edge>>],
545    to: usize,
546) {
547    for edge in edges {
548        edge.borrow_mut().to = Some(to);
549    }
550}
551fn compile(
552    expr: Expr,
553    from: usize,
554    nfa: &mut Vec<Vec<Rc<RefCell<Edge>>>>,
555) -> Vec<Rc<RefCell<Edge>>> {
556    match expr {
557        Expr::Choice { exprs } => exprs
558            .into_iter()
559            .flat_map(|expr| compile(expr, from, nfa))
560            .collect(),
561        Expr::Seq { exprs } => {
562            let mut cur = from;
563            let mut last_edges = Vec::new();
564            let exprs_len = exprs.len();
565
566            for (i, expr) in exprs.into_iter().enumerate() {
567                let next = if i == exprs_len - 1 { cur } else { node(nfa) };
568
569                let mut edges = compile(expr, cur, nfa);
570                if i < exprs_len - 1 {
571                    connect(&mut edges, next);
572                    cur = next;
573                } else {
574                    last_edges = edges;
575                }
576            }
577
578            if last_edges.is_empty() {
579                vec![edge(cur, None, None, nfa)]
580            } else {
581                last_edges
582            }
583        },
584        Expr::Star { expr } => {
585            let loop_node = node(nfa);
586            edge(from, Some(loop_node), None, nfa);
587            let mut compiled_expr = compile(*expr, loop_node, nfa);
588            connect(&mut compiled_expr, loop_node);
589            vec![edge(loop_node, None, None, nfa)]
590        },
591        Expr::Plus { expr } => {
592            let loop_node = node(nfa);
593            connect(&mut compile(*expr.clone(), from, nfa), loop_node);
594            let mut compiled_expr = compile(*expr, loop_node, nfa);
595            connect(&mut compiled_expr, loop_node);
596            vec![edge(loop_node, None, None, nfa)]
597        },
598        Expr::Opt { expr } => {
599            let mut edges = vec![edge(from, None, None, nfa)];
600            edges.extend(compile(*expr, from, nfa));
601            edges
602        },
603        Expr::Range { expr, min, max } => {
604            let mut cur = from;
605            for _ in 0..min {
606                let next = node(nfa);
607                connect(&mut compile(*expr.clone(), cur, nfa), next);
608                cur = next;
609            }
610            if max == -1 {
611                connect(&mut compile(*expr, cur, nfa), cur);
612            } else {
613                for _ in min..max as usize {
614                    let next = node(nfa);
615                    edge(cur, Some(next), None, nfa);
616                    connect(&mut compile(*expr.clone(), cur, nfa), next);
617                    cur = next;
618                }
619            }
620            vec![edge(cur, None, None, nfa)]
621        },
622        Expr::Name { value } => {
623            vec![edge(from, None, Some((*value).clone()), nfa)]
624        },
625    }
626}
627
628#[cfg(test)]
629mod tests {
630    use super::*;
631    use crate::schema::{Schema, SchemaSpec};
632    use crate::node_type::NodeSpec;
633    use std::collections::HashMap;
634
635    #[test]
636    fn test_tablerow_plus_fill() {
637        // 创建一个简单的 schema
638        let mut nodes = HashMap::new();
639
640        // 定义 table 节点:内容为 "tablerow+"
641        nodes.insert(
642            "table".to_string(),
643            NodeSpec {
644                content: Some("tablerow+".to_string()),
645                marks: None,
646                group: None,
647                desc: Some("表格节点".to_string()),
648                attrs: None,
649            },
650        );
651
652        // 定义 tablerow 节点
653        nodes.insert(
654            "tablerow".to_string(),
655            NodeSpec {
656                content: Some("tablecell+".to_string()),
657                marks: None,
658                group: None,
659                desc: Some("表格行节点".to_string()),
660                attrs: None,
661            },
662        );
663
664        // 定义 tablecell 节点
665        nodes.insert(
666            "tablecell".to_string(),
667            NodeSpec {
668                content: Some("text*".to_string()),
669                marks: None,
670                group: None,
671                desc: Some("表格单元格节点".to_string()),
672                attrs: None,
673            },
674        );
675
676        // 定义 text 节点
677        nodes.insert(
678            "text".to_string(),
679            NodeSpec {
680                content: None,
681                marks: None,
682                group: None,
683                desc: Some("文本节点".to_string()),
684                attrs: None,
685            },
686        );
687
688        let schema_spec = SchemaSpec {
689            nodes,
690            marks: HashMap::new(),
691            top_node: Some("table".to_string()),
692        };
693
694        let schema = Schema::compile(schema_spec).unwrap();
695        let table_type = schema.nodes.get("table").unwrap();
696
697        // 测试:当 table 的内容为空时,fill 应该返回至少一个 tablerow
698        if let Some(content_match) = &table_type.content_match {
699            println!("Table content match: {content_match}");
700
701            // 测试空内容的情况
702            let empty_content: Vec<Node> = vec![];
703            let result = content_match.fill(&empty_content, true, &schema);
704
705            println!("Fill result for empty content: {result:?}");
706
707            if let Some(needed_types) = result {
708                println!("成功!需要的节点类型数量: {}", needed_types.len());
709                for (i, type_name) in needed_types.iter().enumerate() {
710                    println!("  第{}个需要的节点类型: {}", i + 1, type_name);
711                }
712            } else {
713                println!("填充返回了 None");
714            }
715        }
716    }
717
718    #[test]
719    fn test_table_create_and_fill() {
720        // 创建一个简单的 schema
721        let mut nodes = HashMap::new();
722
723        // 定义 table 节点:内容为 "tablerow+"
724        nodes.insert(
725            "table".to_string(),
726            NodeSpec {
727                content: Some("tablerow+".to_string()),
728                marks: None,
729                group: None,
730                desc: Some("表格节点".to_string()),
731                attrs: None,
732            },
733        );
734
735        // 定义 tablerow 节点
736        nodes.insert(
737            "tablerow".to_string(),
738            NodeSpec {
739                content: Some("tablecell+".to_string()),
740                marks: None,
741                group: None,
742                desc: Some("表格行节点".to_string()),
743                attrs: None,
744            },
745        );
746
747        // 定义 tablecell 节点
748        nodes.insert(
749            "tablecell".to_string(),
750            NodeSpec {
751                content: Some("text*".to_string()),
752                marks: None,
753                group: None,
754                desc: Some("表格单元格节点".to_string()),
755                attrs: None,
756            },
757        );
758
759        // 定义 text 节点
760        nodes.insert(
761            "text".to_string(),
762            NodeSpec {
763                content: None,
764                marks: None,
765                group: None,
766                desc: Some("文本节点".to_string()),
767                attrs: None,
768            },
769        );
770
771        let schema_spec = SchemaSpec {
772            nodes,
773            marks: HashMap::new(),
774            top_node: Some("table".to_string()),
775        };
776
777        let schema = Schema::compile(schema_spec).unwrap();
778        let table_type = schema.nodes.get("table").unwrap();
779
780        // 测试 create_and_fill 与空内容
781        println!("=== 测试 create_and_fill ===");
782        let empty_content: Vec<Node> = vec![];
783        let result = table_type.create_and_fill(
784            None,          // id
785            None,          // attrs
786            empty_content, // content
787            None,          // marks
788            &schema,       // schema
789        );
790
791        let (main_node, child_nodes) = result.into_parts();
792        println!("Main node: {main_node:?}");
793        println!("Child nodes count: {}", child_nodes.len());
794
795        for (i, child) in child_nodes.iter().enumerate() {
796            let (child_node, grandchildren) = child.clone().into_parts();
797            println!(
798                "  Child {}: type={}, id={}",
799                i + 1,
800                child_node.r#type,
801                child_node.id
802            );
803            println!("    Grandchildren count: {}", grandchildren.len());
804        }
805
806        // 验证是否创建了 tablerow
807        if !child_nodes.is_empty() {
808            let (first_child, _) = child_nodes[0].clone().into_parts();
809            println!("第一个子节点类型: {}", first_child.r#type);
810        } else {
811            println!("警告:没有创建任何子节点!");
812        }
813    }
814
815    #[test]
816    fn test_edge_cases() {
817        use crate::node::Node;
818
819        // 创建schema(与上面相同)
820        let mut nodes = HashMap::new();
821        nodes.insert(
822            "table".to_string(),
823            NodeSpec {
824                content: Some("tablerow+".to_string()),
825                marks: None,
826                group: None,
827                desc: Some("表格节点".to_string()),
828                attrs: None,
829            },
830        );
831        nodes.insert(
832            "tablerow".to_string(),
833            NodeSpec {
834                content: Some("tablecell+".to_string()),
835                marks: None,
836                group: None,
837                desc: Some("表格行节点".to_string()),
838                attrs: None,
839            },
840        );
841        nodes.insert(
842            "tablecell".to_string(),
843            NodeSpec {
844                content: Some("text*".to_string()),
845                marks: None,
846                group: None,
847                desc: Some("表格单元格节点".to_string()),
848                attrs: None,
849            },
850        );
851        nodes.insert(
852            "text".to_string(),
853            NodeSpec {
854                content: None,
855                marks: None,
856                group: None,
857                desc: Some("文本节点".to_string()),
858                attrs: None,
859            },
860        );
861
862        let schema_spec = SchemaSpec {
863            nodes,
864            marks: HashMap::new(),
865            top_node: Some("table".to_string()),
866        };
867        let schema = Schema::compile(schema_spec).unwrap();
868        let table_type = schema.nodes.get("table").unwrap();
869
870        println!("=== 边界情况测试 ===");
871
872        // 情况1: content_match 为 None
873        if table_type.content_match.is_none() {
874            println!("警告:table_type.content_match 为 None");
875            return;
876        }
877        let content_match = table_type.content_match.as_ref().unwrap();
878
879        // 情况2: match_fragment 返回 None
880        let empty_content: Vec<Node> = vec![];
881        let matched = content_match.match_fragment(&empty_content, &schema);
882        println!("match_fragment result: {:?}", matched.is_some());
883
884        if let Some(matched_state) = matched {
885            println!("matched state valid_end: {}", matched_state.valid_end);
886
887            // 情况3: fill 返回 None
888            let fill_result = matched_state.fill(&empty_content, true, &schema);
889            println!("fill result: {:?}", fill_result.is_some());
890
891            if let Some(needed_types) = fill_result {
892                println!("需要的类型数量: {}", needed_types.len());
893                for type_name in &needed_types {
894                    println!("  需要的类型: {type_name}");
895                }
896            }
897        }
898
899        // 情况4: 测试with to_end=false
900        if let Some(matched_state) = matched {
901            let fill_result_no_end =
902                matched_state.fill(&empty_content, false, &schema);
903            println!(
904                "fill result (to_end=false): {:?}",
905                fill_result_no_end.is_some()
906            );
907        }
908    }
909
910    #[test]
911    fn test_block_choice_problem() {
912        // 模拟 simple_demo.rs 中的问题场景
913        let mut nodes = HashMap::new();
914
915        // 定义 block 节点:内容为 "table paragraph list heading" (选择表达式)
916        nodes.insert(
917            "block".to_string(),
918            NodeSpec {
919                content: Some("table paragraph list heading".to_string()),
920                marks: None,
921                group: None,
922                desc: Some("块级节点".to_string()),
923                attrs: None,
924            },
925        );
926
927        // 定义其他节点
928        nodes.insert(
929            "table".to_string(),
930            NodeSpec {
931                content: Some("tablerow+".to_string()),
932                marks: None,
933                group: None,
934                desc: Some("表格节点".to_string()),
935                attrs: None,
936            },
937        );
938        nodes.insert(
939            "paragraph".to_string(),
940            NodeSpec {
941                content: Some("text*".to_string()),
942                marks: None,
943                group: None,
944                desc: Some("段落节点".to_string()),
945                attrs: None,
946            },
947        );
948        nodes.insert(
949            "list".to_string(),
950            NodeSpec {
951                content: Some("listitem+".to_string()),
952                marks: None,
953                group: None,
954                desc: Some("列表节点".to_string()),
955                attrs: None,
956            },
957        );
958        nodes.insert(
959            "heading".to_string(),
960            NodeSpec {
961                content: Some("text*".to_string()),
962                marks: None,
963                group: None,
964                desc: Some("标题节点".to_string()),
965                attrs: None,
966            },
967        );
968        nodes.insert(
969            "tablerow".to_string(),
970            NodeSpec {
971                content: Some("tablecell+".to_string()),
972                marks: None,
973                group: None,
974                desc: Some("表格行节点".to_string()),
975                attrs: None,
976            },
977        );
978        nodes.insert(
979            "tablecell".to_string(),
980            NodeSpec {
981                content: Some("text*".to_string()),
982                marks: None,
983                group: None,
984                desc: Some("表格单元格节点".to_string()),
985                attrs: None,
986            },
987        );
988        nodes.insert(
989            "listitem".to_string(),
990            NodeSpec {
991                content: Some("paragraph".to_string()),
992                marks: None,
993                group: None,
994                desc: Some("列表项节点".to_string()),
995                attrs: None,
996            },
997        );
998        nodes.insert(
999            "text".to_string(),
1000            NodeSpec {
1001                content: None,
1002                marks: None,
1003                group: None,
1004                desc: Some("文本节点".to_string()),
1005                attrs: None,
1006            },
1007        );
1008
1009        let schema_spec = SchemaSpec {
1010            nodes,
1011            marks: HashMap::new(),
1012            top_node: Some("block".to_string()),
1013        };
1014
1015        let schema = Schema::compile(schema_spec).unwrap();
1016        let block_type = schema.nodes.get("block").unwrap();
1017
1018        println!("=== 测试 Block 选择问题 ===");
1019
1020        if let Some(content_match) = &block_type.content_match {
1021            println!("Block content match: {content_match}");
1022
1023            // 检查默认类型
1024            let default_type = content_match.default_type();
1025            if let Some(def_type) = default_type {
1026                println!("默认类型: {}", def_type.name);
1027                println!(
1028                    "默认类型是否有必须属性: {}",
1029                    def_type.has_required_attrs()
1030                );
1031            } else {
1032                println!("没有默认类型");
1033            }
1034
1035            // 测试空内容的填充
1036            let empty_content: Vec<Node> = vec![];
1037            let result = content_match.fill(&empty_content, true, &schema);
1038
1039            println!("Fill result: {:?}", result.is_some());
1040            if let Some(needed_types) = result {
1041                println!("需要的类型数量: {}", needed_types.len());
1042                for (i, type_name) in needed_types.iter().enumerate() {
1043                    println!("  第{}个需要的节点类型: {}", i + 1, type_name);
1044                }
1045            }
1046
1047            // 测试 create_and_fill
1048            println!("=== 测试 Block create_and_fill ===");
1049            let result =
1050                block_type.create_and_fill(None, None, vec![], None, &schema);
1051
1052            let (main_node, child_nodes) = result.into_parts();
1053            println!("Main node type: {}", main_node.r#type);
1054            println!("Child nodes count: {}", child_nodes.len());
1055
1056            for (i, child) in child_nodes.iter().enumerate() {
1057                let (child_node, grandchildren) = child.clone().into_parts();
1058                println!("  Child {}: type={}", i + 1, child_node.r#type);
1059                if child_node.r#type == "table" {
1060                    println!(
1061                        "    Table 的 grandchildren count: {}",
1062                        grandchildren.len()
1063                    );
1064                    for (j, grandchild) in grandchildren.iter().enumerate() {
1065                        let (gc_node, _) = grandchild.clone().into_parts();
1066                        println!(
1067                            "      Grandchild {}: type={}",
1068                            j + 1,
1069                            gc_node.r#type
1070                        );
1071                    }
1072                }
1073            }
1074        }
1075    }
1076
1077    #[test]
1078    fn test_sequence_with_existing_nodes() {
1079        use crate::node::Node;
1080        use crate::attrs::Attrs;
1081
1082        // 创建 schema(与上面相同)
1083        let mut nodes = HashMap::new();
1084        nodes.insert(
1085            "block".to_string(),
1086            NodeSpec {
1087                content: Some("table paragraph".to_string()), // 简化的序列
1088                marks: None,
1089                group: None,
1090                desc: Some("块级节点".to_string()),
1091                attrs: None,
1092            },
1093        );
1094        nodes.insert(
1095            "table".to_string(),
1096            NodeSpec {
1097                content: Some("tablerow+".to_string()),
1098                marks: None,
1099                group: None,
1100                desc: Some("表格节点".to_string()),
1101                attrs: None,
1102            },
1103        );
1104        nodes.insert(
1105            "paragraph".to_string(),
1106            NodeSpec {
1107                content: Some("text*".to_string()),
1108                marks: None,
1109                group: None,
1110                desc: Some("段落节点".to_string()),
1111                attrs: None,
1112            },
1113        );
1114        nodes.insert(
1115            "tablerow".to_string(),
1116            NodeSpec {
1117                content: Some("tablecell+".to_string()),
1118                marks: None,
1119                group: None,
1120                desc: Some("表格行节点".to_string()),
1121                attrs: None,
1122            },
1123        );
1124        nodes.insert(
1125            "tablecell".to_string(),
1126            NodeSpec {
1127                content: Some("text*".to_string()),
1128                marks: None,
1129                group: None,
1130                desc: Some("表格单元格节点".to_string()),
1131                attrs: None,
1132            },
1133        );
1134        nodes.insert(
1135            "text".to_string(),
1136            NodeSpec {
1137                content: None,
1138                marks: None,
1139                group: None,
1140                desc: Some("文本节点".to_string()),
1141                attrs: None,
1142            },
1143        );
1144
1145        let schema_spec = SchemaSpec {
1146            nodes,
1147            marks: HashMap::new(),
1148            top_node: Some("block".to_string()),
1149        };
1150        let schema = Schema::compile(schema_spec).unwrap();
1151        let block_type = schema.nodes.get("block").unwrap();
1152
1153        println!("=== 测试序列中已存在节点的情况 ===");
1154
1155        // 创建一个已存在的 table 节点
1156        let existing_table = Node::new(
1157            "existing_table_123",
1158            "table".to_string(),
1159            Attrs::default(),
1160            vec!["existing_row_456".into()],
1161            vec![],
1162        );
1163
1164        // 创建一个已存在的 paragraph 节点
1165        let existing_paragraph = Node::new(
1166            "existing_para_789",
1167            "paragraph".to_string(),
1168            Attrs::default(),
1169            vec!["existing_text_000".into()],
1170            vec![],
1171        );
1172
1173        let existing_content = vec![existing_table, existing_paragraph];
1174
1175        println!("传入的现有内容:");
1176        for (i, node) in existing_content.iter().enumerate() {
1177            println!(
1178                "  第{}个现有节点: type={}, id={}, content={:?}",
1179                i + 1,
1180                node.r#type,
1181                node.id,
1182                node.content
1183            );
1184        }
1185
1186        // 测试 create_and_fill 对已存在节点的处理
1187        let result = block_type.create_and_fill(
1188            None,
1189            None,
1190            existing_content,
1191            None,
1192            &schema,
1193        );
1194
1195        let (main_node, child_nodes) = result.into_parts();
1196        println!(
1197            "Main node: type={}, content={:?}",
1198            main_node.r#type, main_node.content
1199        );
1200        println!("Child nodes count: {}", child_nodes.len());
1201
1202        for (i, child) in child_nodes.iter().enumerate() {
1203            let (child_node, grandchildren) = child.clone().into_parts();
1204            println!(
1205                "  Child {}: type={}, id={}",
1206                i + 1,
1207                child_node.r#type,
1208                child_node.id
1209            );
1210            println!("    Content: {:?}", child_node.content);
1211            println!("    Grandchildren count: {}", grandchildren.len());
1212
1213            for (j, grandchild) in grandchildren.iter().enumerate() {
1214                let (gc_node, _) = grandchild.clone().into_parts();
1215                println!(
1216                    "      Grandchild {}: type={}, id={}",
1217                    j + 1,
1218                    gc_node.r#type,
1219                    gc_node.id
1220                );
1221            }
1222        }
1223    }
1224
1225    #[test]
1226    fn test_table_creation_step_by_step() {
1227        // 创建一个简单的 schema,只有 table 和 tablerow
1228        let mut nodes = HashMap::new();
1229
1230        nodes.insert(
1231            "table".to_string(),
1232            NodeSpec {
1233                content: Some("tablerow+".to_string()),
1234                marks: None,
1235                group: None,
1236                desc: Some("表格节点".to_string()),
1237                attrs: None,
1238            },
1239        );
1240        nodes.insert(
1241            "tablerow".to_string(),
1242            NodeSpec {
1243                content: Some("tablecell+".to_string()),
1244                marks: None,
1245                group: None,
1246                desc: Some("表格行节点".to_string()),
1247                attrs: None,
1248            },
1249        );
1250        nodes.insert(
1251            "tablecell".to_string(),
1252            NodeSpec {
1253                content: Some("text*".to_string()),
1254                marks: None,
1255                group: None,
1256                desc: Some("表格单元格节点".to_string()),
1257                attrs: None,
1258            },
1259        );
1260        nodes.insert(
1261            "text".to_string(),
1262            NodeSpec {
1263                content: None,
1264                marks: None,
1265                group: None,
1266                desc: Some("文本节点".to_string()),
1267                attrs: None,
1268            },
1269        );
1270
1271        let schema_spec = SchemaSpec {
1272            nodes,
1273            marks: HashMap::new(),
1274            top_node: Some("table".to_string()),
1275        };
1276        let schema = Schema::compile(schema_spec).unwrap();
1277        let table_type = schema.nodes.get("table").unwrap();
1278
1279        println!("=== 逐步诊断 Table 创建过程 ===");
1280
1281        // 第1步:检查 content_match
1282        println!("第1步:检查 table 的 content_match");
1283        if let Some(content_match) = &table_type.content_match {
1284            println!("  ✅ content_match 存在");
1285            println!("  content_match: {content_match}");
1286        } else {
1287            println!("  ❌ content_match 不存在");
1288            return;
1289        }
1290
1291        // 第2步:测试 match_fragment
1292        println!("第2步:测试 match_fragment");
1293        let empty_content: Vec<Node> = vec![];
1294        let content_match = table_type.content_match.as_ref().unwrap();
1295
1296        let matched = content_match.match_fragment(&empty_content, &schema);
1297        if let Some(matched_state) = matched {
1298            println!("  ✅ match_fragment 成功");
1299            println!("  matched state valid_end: {}", matched_state.valid_end);
1300        } else {
1301            println!("  ❌ match_fragment 返回 None");
1302            return;
1303        }
1304
1305        // 第3步:测试 fill
1306        println!("第3步:测试 fill");
1307        let matched_state = matched.unwrap();
1308        let fill_result = matched_state.fill(&empty_content, true, &schema);
1309
1310        if let Some(needed_types) = fill_result {
1311            println!("  ✅ fill 成功,需要的类型数量: {}", needed_types.len());
1312            for (i, type_name) in needed_types.iter().enumerate() {
1313                println!("    第{}个需要的类型: {}", i + 1, type_name);
1314            }
1315        } else {
1316            println!("  ❌ fill 返回 None");
1317            return;
1318        }
1319
1320        // 第4步:测试完整的 create_and_fill
1321        println!("第4步:测试完整的 create_and_fill");
1322        let result = table_type.create_and_fill(
1323            None,
1324            None,
1325            vec![], // 空内容
1326            None,
1327            &schema,
1328        );
1329
1330        let (main_node, child_nodes) = result.into_parts();
1331        println!("  Main table node:");
1332        println!("    ID: {}", main_node.id);
1333        println!("    Content IDs: {:?}", main_node.content);
1334        println!("  Child nodes count: {}", child_nodes.len());
1335
1336        if child_nodes.is_empty() {
1337            println!("  ❌ 没有创建子节点!");
1338        } else {
1339            for (i, child) in child_nodes.iter().enumerate() {
1340                let (child_node, grandchildren) = child.clone().into_parts();
1341                println!(
1342                    "    Child {}: type={}, id={}",
1343                    i + 1,
1344                    child_node.r#type,
1345                    child_node.id
1346                );
1347                println!("      Content IDs: {:?}", child_node.content);
1348                println!("      Grandchildren count: {}", grandchildren.len());
1349
1350                if child_node.r#type == "tablerow" && grandchildren.is_empty() {
1351                    println!("      ❌ tablerow 没有创建 tablecell 子节点!");
1352                }
1353
1354                for (j, grandchild) in grandchildren.iter().enumerate() {
1355                    let (gc_node, great_grandchildren) =
1356                        grandchild.clone().into_parts();
1357                    println!(
1358                        "        Grandchild {}: type={}, id={}",
1359                        j + 1,
1360                        gc_node.r#type,
1361                        gc_node.id
1362                    );
1363                    println!("          Content IDs: {:?}", gc_node.content);
1364                    println!(
1365                        "          Great-grandchildren count: {}",
1366                        great_grandchildren.len()
1367                    );
1368                }
1369            }
1370        }
1371
1372        // 第5步:单独测试 tablerow 的创建
1373        println!("第5步:单独测试 tablerow 的创建");
1374        let tablerow_type = schema.nodes.get("tablerow").unwrap();
1375        let tablerow_result = tablerow_type.create_and_fill(
1376            None,
1377            None,
1378            vec![], // 空内容
1379            None,
1380            &schema,
1381        );
1382
1383        let (tr_node, tr_children) = tablerow_result.into_parts();
1384        println!("  Tablerow node:");
1385        println!("    ID: {}", tr_node.id);
1386        println!("    Content IDs: {:?}", tr_node.content);
1387        println!("    Children count: {}", tr_children.len());
1388
1389        if tr_children.is_empty() {
1390            println!("    ❌ tablerow 没有创建 tablecell 子节点!");
1391        } else {
1392            for (i, child) in tr_children.iter().enumerate() {
1393                let (child_node, _) = child.clone().into_parts();
1394                println!(
1395                    "      Child {}: type={}, id={}",
1396                    i + 1,
1397                    child_node.r#type,
1398                    child_node.id
1399                );
1400            }
1401        }
1402    }
1403
1404    #[test]
1405    fn test_sequence_table_problem() {
1406        // 重现 "table paragraph list heading" 序列表达式的问题
1407        let mut nodes = HashMap::new();
1408
1409        // 定义 block 节点:内容为 "table paragraph list heading" (序列表达式)
1410        nodes.insert(
1411            "block".to_string(),
1412            NodeSpec {
1413                content: Some("table paragraph list heading".to_string()),
1414                marks: None,
1415                group: None,
1416                desc: Some("块级节点".to_string()),
1417                attrs: None,
1418            },
1419        );
1420
1421        // 定义各个子节点
1422        nodes.insert(
1423            "table".to_string(),
1424            NodeSpec {
1425                content: Some("tablerow+".to_string()),
1426                marks: None,
1427                group: None,
1428                desc: Some("表格节点".to_string()),
1429                attrs: None,
1430            },
1431        );
1432        nodes.insert(
1433            "paragraph".to_string(),
1434            NodeSpec {
1435                content: Some("text*".to_string()),
1436                marks: None,
1437                group: None,
1438                desc: Some("段落节点".to_string()),
1439                attrs: None,
1440            },
1441        );
1442        nodes.insert(
1443            "list".to_string(),
1444            NodeSpec {
1445                content: Some("listitem+".to_string()),
1446                marks: None,
1447                group: None,
1448                desc: Some("列表节点".to_string()),
1449                attrs: None,
1450            },
1451        );
1452        nodes.insert(
1453            "heading".to_string(),
1454            NodeSpec {
1455                content: Some("text*".to_string()),
1456                marks: None,
1457                group: None,
1458                desc: Some("标题节点".to_string()),
1459                attrs: None,
1460            },
1461        );
1462        nodes.insert(
1463            "tablerow".to_string(),
1464            NodeSpec {
1465                content: Some("tablecell+".to_string()),
1466                marks: None,
1467                group: None,
1468                desc: Some("表格行节点".to_string()),
1469                attrs: None,
1470            },
1471        );
1472        nodes.insert(
1473            "tablecell".to_string(),
1474            NodeSpec {
1475                content: Some("text*".to_string()),
1476                marks: None,
1477                group: None,
1478                desc: Some("表格单元格节点".to_string()),
1479                attrs: None,
1480            },
1481        );
1482        nodes.insert(
1483            "listitem".to_string(),
1484            NodeSpec {
1485                content: Some("paragraph".to_string()),
1486                marks: None,
1487                group: None,
1488                desc: Some("列表项节点".to_string()),
1489                attrs: None,
1490            },
1491        );
1492        nodes.insert(
1493            "text".to_string(),
1494            NodeSpec {
1495                content: None,
1496                marks: None,
1497                group: None,
1498                desc: Some("文本节点".to_string()),
1499                attrs: None,
1500            },
1501        );
1502
1503        let schema_spec = SchemaSpec {
1504            nodes,
1505            marks: HashMap::new(),
1506            top_node: Some("block".to_string()),
1507        };
1508
1509        let schema = Schema::compile(schema_spec).unwrap();
1510        let block_type = schema.nodes.get("block").unwrap();
1511
1512        println!("=== 测试序列表达式中的 Table 问题 ===");
1513
1514        // 创建 block 节点
1515        let result = block_type.create_and_fill(
1516            None,
1517            None,
1518            vec![], // 空内容,让 fill 方法推导所需节点
1519            None,
1520            &schema,
1521        );
1522
1523        let (main_node, child_nodes) = result.into_parts();
1524        println!("Block 节点:");
1525        println!("  ID: {}", main_node.id);
1526        println!("  Content IDs: {:?}", main_node.content);
1527        println!("  子节点数量: {}", child_nodes.len());
1528
1529        // 检查每个子节点
1530        for (i, child) in child_nodes.iter().enumerate() {
1531            let (child_node, grandchildren) = child.clone().into_parts();
1532            println!(
1533                "  子节点 {}: type={}, id={}",
1534                i + 1,
1535                child_node.r#type,
1536                child_node.id
1537            );
1538            println!("    Content IDs: {:?}", child_node.content);
1539            println!("    孙节点数量: {}", grandchildren.len());
1540
1541            // 特别检查 table 节点
1542            if child_node.r#type == "table" {
1543                println!("    📋 这是 Table 节点:");
1544
1545                // 检查 table 的直接子节点 IDs
1546                if child_node.content.is_empty() {
1547                    println!("      ❌ Table 节点的 content IDs 是空的!");
1548                } else {
1549                    println!(
1550                        "      ✅ Table 节点包含 content IDs: {:?}",
1551                        child_node.content
1552                    );
1553                }
1554
1555                // 检查 table 的孙节点(tablerow)
1556                if grandchildren.is_empty() {
1557                    println!(
1558                        "      ❌ Table 节点没有创建任何孙节点(tablerow)!"
1559                    );
1560                } else {
1561                    println!(
1562                        "      ✅ Table 节点创建了 {} 个孙节点:",
1563                        grandchildren.len()
1564                    );
1565                    for (j, grandchild) in grandchildren.iter().enumerate() {
1566                        let (gc_node, great_grandchildren) =
1567                            grandchild.clone().into_parts();
1568                        println!(
1569                            "        孙节点 {}: type={}, id={}",
1570                            j + 1,
1571                            gc_node.r#type,
1572                            gc_node.id
1573                        );
1574                        println!(
1575                            "          Content IDs: {:?}",
1576                            gc_node.content
1577                        );
1578
1579                        // 检查 tablerow 的子节点(tablecell)
1580                        if gc_node.r#type == "tablerow" {
1581                            if great_grandchildren.is_empty() {
1582                                println!(
1583                                    "          ❌ tablerow 没有创建 tablecell 子节点!"
1584                                );
1585
1586                                // 深入调试 tablerow 的填充过程
1587                                println!(
1588                                    "          🔍 调试 tablerow 填充过程:"
1589                                );
1590                                let tablerow_type =
1591                                    schema.nodes.get("tablerow").unwrap();
1592                                if let Some(tr_content_match) =
1593                                    &tablerow_type.content_match
1594                                {
1595                                    println!(
1596                                        "            tablerow content_match: {tr_content_match}"
1597                                    );
1598
1599                                    let empty_content: Vec<Node> = vec![];
1600                                    let tr_matched = tr_content_match
1601                                        .match_fragment(
1602                                            &empty_content,
1603                                            &schema,
1604                                        );
1605                                    if let Some(tr_matched_state) = tr_matched {
1606                                        println!(
1607                                            "            tablerow match_fragment 成功"
1608                                        );
1609                                        println!(
1610                                            "            tablerow matched state valid_end: {}",
1611                                            tr_matched_state.valid_end
1612                                        );
1613
1614                                        let tr_fill_result = tr_matched_state
1615                                            .fill(
1616                                                &empty_content,
1617                                                true,
1618                                                &schema,
1619                                            );
1620                                        if let Some(tr_needed_types) =
1621                                            tr_fill_result
1622                                        {
1623                                            println!(
1624                                                "            tablerow 需要的类型数量: {}",
1625                                                tr_needed_types.len()
1626                                            );
1627                                            for (k, type_name) in
1628                                                tr_needed_types
1629                                                    .iter()
1630                                                    .enumerate()
1631                                            {
1632                                                println!(
1633                                                    "              需要的类型 {}: {}",
1634                                                    k + 1,
1635                                                    type_name
1636                                                );
1637                                            }
1638                                        } else {
1639                                            println!(
1640                                                "            ❌ tablerow fill 返回 None"
1641                                            );
1642                                        }
1643                                    } else {
1644                                        println!(
1645                                            "            ❌ tablerow match_fragment 返回 None"
1646                                        );
1647                                    }
1648                                } else {
1649                                    println!(
1650                                        "            ❌ tablerow 没有 content_match"
1651                                    );
1652                                }
1653                            } else {
1654                                println!(
1655                                    "          ✅ tablerow 创建了 {} 个 tablecell",
1656                                    great_grandchildren.len()
1657                                );
1658                                for (k, ggc) in
1659                                    great_grandchildren.iter().enumerate()
1660                                {
1661                                    let (ggc_node, _) =
1662                                        ggc.clone().into_parts();
1663                                    println!(
1664                                        "            曾孙节点 {}: type={}, id={}",
1665                                        k + 1,
1666                                        ggc_node.r#type,
1667                                        ggc_node.id
1668                                    );
1669                                }
1670                            }
1671                        }
1672                    }
1673                }
1674            }
1675        }
1676
1677        // 对比:单独创建 table 节点
1678        println!("\n=== 对比:单独创建 Table 节点 ===");
1679        let table_type = schema.nodes.get("table").unwrap();
1680        let standalone_table =
1681            table_type.create_and_fill(None, None, vec![], None, &schema);
1682
1683        let (st_node, st_children) = standalone_table.into_parts();
1684        println!("单独的 Table 节点:");
1685        println!("  ID: {}", st_node.id);
1686        println!("  Content IDs: {:?}", st_node.content);
1687        println!("  子节点数量: {}", st_children.len());
1688
1689        for (i, child) in st_children.iter().enumerate() {
1690            let (child_node, grandchildren) = child.clone().into_parts();
1691            println!(
1692                "    子节点 {}: type={}, id={}",
1693                i + 1,
1694                child_node.r#type,
1695                child_node.id
1696            );
1697            println!("      孙节点数量: {}", grandchildren.len());
1698        }
1699
1700        // 额外调试:单独创建 tablerow 节点
1701        println!("\n=== 额外调试:单独创建 tablerow 节点 ===");
1702        let tablerow_type = schema.nodes.get("tablerow").unwrap();
1703        let standalone_tablerow =
1704            tablerow_type.create_and_fill(None, None, vec![], None, &schema);
1705
1706        let (str_node, str_children) = standalone_tablerow.into_parts();
1707        println!("单独的 tablerow 节点:");
1708        println!("  ID: {}", str_node.id);
1709        println!("  Content IDs: {:?}", str_node.content);
1710        println!("  子节点数量: {}", str_children.len());
1711
1712        for (i, child) in str_children.iter().enumerate() {
1713            let (child_node, _) = child.clone().into_parts();
1714            println!(
1715                "    子节点 {}: type={}, id={}",
1716                i + 1,
1717                child_node.r#type,
1718                child_node.id
1719            );
1720        }
1721    }
1722}