63 } |
64 } |
64 |
65 |
65 |
66 |
66 /* XML representation */ |
67 /* XML representation */ |
67 |
68 |
|
69 // FIXME decode markup body |
68 @tailrec private def strip_elems(markups: List[Markup], body: XML.Body): (List[Markup], XML.Body) = |
70 @tailrec private def strip_elems(markups: List[Markup], body: XML.Body): (List[Markup], XML.Body) = |
69 body match { |
71 body match { |
70 case List(XML.Elem(markup1, body1)) => strip_elems(markup1 :: markups, body1) |
72 case List(XML.Elem(markup1, body1)) => strip_elems(markup1 :: markups, body1) |
71 case _ => (markups, body) |
73 case _ => (markups, body) |
72 } |
74 } |
140 } |
142 } |
141 } |
143 } |
142 } |
144 } |
143 } |
145 } |
144 |
146 |
|
147 def to_XML(root_range: Text.Range, text: CharSequence, filter: XML.Elem => Boolean): XML.Body = |
|
148 { |
|
149 def make_text(start: Text.Offset, stop: Text.Offset): XML.Body = |
|
150 if (start == stop) Nil |
|
151 else List(XML.Text(text.subSequence(start, stop).toString)) |
|
152 |
|
153 def make_elems(rev_markups: List[XML.Elem], body: XML.Body): XML.Body = |
|
154 (body /: rev_markups) { |
|
155 case (b, elem) => // FIXME encode markup body |
|
156 if (filter(elem)) List(XML.Elem(elem.markup, b)) else b |
|
157 } |
|
158 |
|
159 def make_body(elem_range: Text.Range, elem_markup: List[XML.Elem], entries: Branches.T) |
|
160 : XML.Body = |
|
161 { |
|
162 val body = new mutable.ListBuffer[XML.Tree] |
|
163 var last = elem_range.start |
|
164 for ((range, entry) <- entries) { |
|
165 val subrange = range.restrict(elem_range) |
|
166 body ++= make_text(last, subrange.start) |
|
167 body ++= make_body(subrange, entry.rev_markup, entry.subtree.overlapping(subrange)) |
|
168 last = subrange.stop |
|
169 } |
|
170 body ++= make_text(last, elem_range.stop) |
|
171 make_elems(elem_markup, body.toList) |
|
172 } |
|
173 make_body(root_range, Nil, overlapping(root_range)) |
|
174 } |
|
175 |
|
176 def to_XML(text: CharSequence): XML.Body = |
|
177 to_XML(Text.Range(0, text.length), text, (_: XML.Elem) => true) |
|
178 |
145 def cumulate[A](root_range: Text.Range, root_info: A, result_elements: Option[Set[String]], |
179 def cumulate[A](root_range: Text.Range, root_info: A, result_elements: Option[Set[String]], |
146 result: PartialFunction[(A, Text.Markup), A]): Stream[Text.Info[A]] = |
180 result: PartialFunction[(A, Text.Markup), A]): Stream[Text.Info[A]] = |
147 { |
181 { |
148 def results(x: A, entry: Entry): Option[A] = |
182 def results(x: A, entry: Entry): Option[A] = |
149 if (result_elements match { case Some(es) => es.exists(entry.elements) case None => true }) { |
183 if (result_elements match { case Some(es) => es.exists(entry.elements) case None => true }) { |
150 val (y, changed) = |
184 val (y, changed) = |
151 (entry.markup :\ (x, false))((info, res) => |
185 ((x, false) /: entry.rev_markup)((res, info) => // FIXME proper order!? |
152 { |
186 { |
153 val (y, changed) = res |
187 val (y, changed) = res |
154 val arg = (y, Text.Info(entry.range, info)) |
188 val arg = (y, Text.Info(entry.range, info)) |
155 if (result.isDefinedAt(arg)) (result(arg), true) |
189 if (result.isDefinedAt(arg)) (result(arg), true) |
156 else res |
190 else res |