equal
deleted
inserted
replaced
4 Untyped XML trees and basic data representation. |
4 Untyped XML trees and basic data representation. |
5 */ |
5 */ |
6 |
6 |
7 package isabelle |
7 package isabelle |
8 |
8 |
|
9 import scala.annotation.tailrec |
|
10 |
9 |
11 |
10 object XML { |
12 object XML { |
11 /** XML trees **/ |
13 /** XML trees **/ |
12 |
14 |
13 /* datatype representation */ |
15 /* datatype representation */ |
14 |
16 |
15 type Attribute = Properties.Entry |
17 type Attribute = Properties.Entry |
16 type Attributes = Properties.T |
18 type Attributes = Properties.T |
17 |
19 |
18 sealed abstract class Tree { override def toString: String = string_of_tree(this) } |
20 trait Trav |
|
21 case class End(name: String) extends Trav |
|
22 |
|
23 sealed abstract class Tree extends Trav { |
|
24 override def toString: String = string_of_tree(this) |
|
25 } |
19 type Body = List[Tree] |
26 type Body = List[Tree] |
20 case class Elem(markup: Markup, body: Body) extends Tree { |
27 case class Elem(markup: Markup, body: Body) extends Tree with Trav { |
21 private lazy val hash: Int = (markup, body).hashCode() |
28 private lazy val hash: Int = (markup, body).hashCode() |
22 override def hashCode(): Int = hash |
29 override def hashCode(): Int = hash |
23 |
30 |
24 def name: String = markup.name |
31 def name: String = markup.name |
25 |
32 |
27 if (more_attributes.isEmpty) this |
34 if (more_attributes.isEmpty) this |
28 else Elem(markup.update_properties(more_attributes), body) |
35 else Elem(markup.update_properties(more_attributes), body) |
29 |
36 |
30 def + (att: Attribute): Elem = Elem(markup + att, body) |
37 def + (att: Attribute): Elem = Elem(markup + att, body) |
31 } |
38 } |
32 case class Text(content: String) extends Tree { |
39 case class Text(content: String) extends Tree with Trav { |
33 private lazy val hash: Int = content.hashCode() |
40 private lazy val hash: Int = content.hashCode() |
34 override def hashCode(): Int = hash |
41 override def hashCode(): Int = hash |
35 } |
42 } |
36 |
43 |
37 def elem(markup: Markup): XML.Elem = XML.Elem(markup, Nil) |
44 def elem(markup: Markup): XML.Elem = XML.Elem(markup, Nil) |
49 trait Traversal { |
56 trait Traversal { |
50 def text(s: String): Unit |
57 def text(s: String): Unit |
51 def elem(markup: Markup, end: Boolean = false): Unit |
58 def elem(markup: Markup, end: Boolean = false): Unit |
52 def end_elem(name: String): Unit |
59 def end_elem(name: String): Unit |
53 |
60 |
54 def tree(t: Tree): Unit = |
61 def traverse(trees: List[Tree]): Unit = { |
55 t match { |
62 @tailrec def trav(list: List[Trav]): Unit = |
56 case Text(s) => text(s) |
63 list match { |
57 case Elem(markup, Nil) => elem(markup, end = true) |
64 case Nil => |
58 case Elem(markup, ts) => elem(markup); trees(ts); end_elem(markup.name) |
65 case Text(s) :: rest => text(s); trav(rest) |
59 } |
66 case Elem(markup, Nil) :: rest => elem(markup, end = true); trav(rest) |
60 def trees(ts: Iterable[Tree]): Unit = ts.foreach(tree) |
67 case Elem(markup, body) :: rest => elem(markup); trav(body ::: End(markup.name) :: rest) |
|
68 case End(name) :: rest => end_elem(name); trav(rest) |
|
69 case _ :: _ => ??? |
|
70 } |
|
71 trav(trees) |
|
72 } |
61 } |
73 } |
62 |
74 |
63 |
75 |
64 /* name space */ |
76 /* name space */ |
65 |
77 |
178 builder += '/' |
190 builder += '/' |
179 builder ++= name |
191 builder ++= name |
180 builder += '>' |
192 builder += '>' |
181 } |
193 } |
182 |
194 |
183 def result(ts: Iterable[Tree]): String = { trees(ts); builder.toString } |
195 def result(ts: List[Tree]): String = { traverse(ts); builder.toString } |
184 def result(t: Tree): String = { tree(t); builder.toString } |
|
185 } |
196 } |
186 |
197 |
187 def string_of_body(body: Body): String = |
198 def string_of_body(body: Body): String = |
188 if (body.isEmpty) "" |
199 if (body.isEmpty) "" |
189 else new Output(new StringBuilder).result(body) |
200 else new Output(new StringBuilder).result(body) |