11 type Attributes = List[(String, String)] |
11 type Attributes = List[(String, String)] |
12 |
12 |
13 abstract class Tree |
13 abstract class Tree |
14 case class Elem(name: String, attributes: Attributes, body: List[Tree]) extends Tree |
14 case class Elem(name: String, attributes: Attributes, body: List[Tree]) extends Tree |
15 case class Text(content: String) extends Tree |
15 case class Text(content: String) extends Tree |
|
16 |
|
17 |
|
18 /* iterator over content */ |
|
19 |
|
20 private type State = Option[(String, List[Tree])] |
|
21 |
|
22 private def get_next(tree: Tree): State = tree match { |
|
23 case Elem(_, _, body) => get_nexts(body) |
|
24 case Text(content) => Some(content, Nil) |
|
25 } |
|
26 private def get_nexts(trees: List[Tree]): State = trees match { |
|
27 case Nil => None |
|
28 case t :: ts => get_next(t) match { |
|
29 case None => get_nexts(ts) |
|
30 case Some((s, r)) => Some((s, r ::: ts)) |
|
31 } |
|
32 } |
|
33 |
|
34 def content(tree: Tree) = new Iterator[String] { |
|
35 private var state = get_next(tree) |
|
36 def hasNext() = state.isDefined |
|
37 def next() = state match { |
|
38 case Some((s, rest)) => { state = get_nexts(rest); s } |
|
39 case None => throw new NoSuchElementException("next on empty iterator") |
|
40 } |
|
41 } |
|
42 |
16 } |
43 } |