10 |
10 |
11 import javax.swing.tree.DefaultMutableTreeNode |
11 import javax.swing.tree.DefaultMutableTreeNode |
12 |
12 |
13 |
13 |
14 |
14 |
15 class Markup_Node(val start: Int, val stop: Int, val info: Any) |
15 case class Markup_Node(val start: Int, val stop: Int, val info: Any) |
16 { |
16 { |
17 def fits_into(that: Markup_Node): Boolean = |
17 def fits_into(that: Markup_Node): Boolean = |
18 that.start <= this.start && this.stop <= that.stop |
18 that.start <= this.start && this.stop <= that.stop |
19 } |
19 } |
20 |
20 |
21 |
21 |
22 class Markup_Tree(val node: Markup_Node, val branches: List[Markup_Tree]) |
22 case class Markup_Tree(val node: Markup_Node, val branches: List[Markup_Tree]) |
23 { |
23 { |
24 def set_branches(bs: List[Markup_Tree]): Markup_Tree = new Markup_Tree(node, bs) |
24 private def add(branch: Markup_Tree) = // FIXME avoid sort |
|
25 copy(branches = (branch :: branches).sortWith((a, b) => a.node.start < b.node.start)) |
25 |
26 |
26 private def add(branch: Markup_Tree) = // FIXME avoid sort |
27 private def remove(bs: List[Markup_Tree]) = |
27 set_branches((branch :: branches).sortWith((a, b) => a.node.start < b.node.start)) |
28 copy(branches = branches.filterNot(bs.contains(_))) |
28 |
|
29 private def remove(bs: List[Markup_Tree]) = set_branches(branches -- bs) |
|
30 |
29 |
31 def + (new_tree: Markup_Tree): Markup_Tree = |
30 def + (new_tree: Markup_Tree): Markup_Tree = |
32 { |
31 { |
33 val new_node = new_tree.node |
32 val new_node = new_tree.node |
34 if (new_node fits_into node) { |
33 if (new_node fits_into node) { |
44 // new_tree did not fit into children of this |
43 // new_tree did not fit into children of this |
45 // -> insert between this and its branches |
44 // -> insert between this and its branches |
46 val fitting = branches filter(_.node fits_into new_node) |
45 val fitting = branches filter(_.node fits_into new_node) |
47 (this remove fitting) add ((new_tree /: fitting)(_ + _)) |
46 (this remove fitting) add ((new_tree /: fitting)(_ + _)) |
48 } |
47 } |
49 else set_branches(new_branches) |
48 else copy(branches = new_branches) |
50 } |
49 } |
51 else { |
50 else { |
52 System.err.println("ignored nonfitting markup: " + new_node) |
51 System.err.println("ignored nonfitting markup: " + new_node) |
53 this |
52 this |
54 } |
53 } |
75 } |
74 } |
76 } |
75 } |
77 } |
76 } |
78 |
77 |
79 |
78 |
80 class Markup_Text(val markup: List[Markup_Tree], val content: String) |
79 case class Markup_Text(val markup: List[Markup_Tree], val content: String) |
81 { |
80 { |
82 private lazy val root = |
81 private lazy val root = |
83 new Markup_Tree(new Markup_Node(0, content.length, None), markup) |
82 new Markup_Tree(new Markup_Node(0, content.length, None), markup) |
84 |
83 |
85 def + (new_tree: Markup_Tree): Markup_Text = |
84 def + (new_tree: Markup_Tree): Markup_Text = |
88 def filter(pred: Markup_Node => Boolean): Markup_Text = |
87 def filter(pred: Markup_Node => Boolean): Markup_Text = |
89 { |
88 { |
90 def filt(tree: Markup_Tree): List[Markup_Tree] = |
89 def filt(tree: Markup_Tree): List[Markup_Tree] = |
91 { |
90 { |
92 val branches = tree.branches.flatMap(filt(_)) |
91 val branches = tree.branches.flatMap(filt(_)) |
93 if (pred(tree.node)) List(tree.set_branches(branches)) |
92 if (pred(tree.node)) List(tree.copy(branches = branches)) |
94 else branches |
93 else branches |
95 } |
94 } |
96 new Markup_Text(markup.flatMap(filt(_)), content) |
95 new Markup_Text(markup.flatMap(filt(_)), content) |
97 } |
96 } |
98 |
97 |