221 |
221 |
222 def to_XML(text: CharSequence): XML.Body = |
222 def to_XML(text: CharSequence): XML.Body = |
223 to_XML(Text.Range(0, text.length), text, (_: XML.Elem) => true) |
223 to_XML(Text.Range(0, text.length), text, (_: XML.Elem) => true) |
224 |
224 |
225 def cumulate[A](root_range: Text.Range, root_info: A, result_elements: Option[Set[String]], |
225 def cumulate[A](root_range: Text.Range, root_info: A, result_elements: Option[Set[String]], |
226 result: (A, Text.Markup) => Option[A]): Stream[Text.Info[A]] = |
226 result: (A, Text.Markup) => Option[A]): List[Text.Info[A]] = |
227 { |
227 { |
228 val notable: Elements => Boolean = |
228 val notable: Elements => Boolean = |
229 result_elements match { |
229 result_elements match { |
230 case Some(res) => (elements: Elements) => res.exists(elements.contains) |
230 case Some(res) => (elements: Elements) => res.exists(elements.contains) |
231 case None => (elements: Elements) => true |
231 case None => (elements: Elements) => true |
240 y1 <- result(y, Text.Info(entry.range, info)) |
240 y1 <- result(y, Text.Info(entry.range, info)) |
241 } { y = y1; changed = true } |
241 } { y = y1; changed = true } |
242 if (changed) Some(y) else None |
242 if (changed) Some(y) else None |
243 } |
243 } |
244 |
244 |
245 def stream( |
245 def traverse( |
246 last: Text.Offset, |
246 last: Text.Offset, |
247 stack: List[(Text.Info[A], Stream[(Text.Range, Entry)])]): Stream[Text.Info[A]] = |
247 stack: List[(Text.Info[A], List[(Text.Range, Entry)])]): List[Text.Info[A]] = |
248 { |
248 { |
249 stack match { |
249 stack match { |
250 case (parent, (range, entry) #:: more) :: rest => |
250 case (parent, (range, entry) :: more) :: rest => |
251 val subrange = range.restrict(root_range) |
251 val subrange = range.restrict(root_range) |
252 val subtree = |
252 val subtree = |
253 if (notable(entry.subtree_elements)) |
253 if (notable(entry.subtree_elements)) |
254 entry.subtree.overlapping(subrange).toStream |
254 entry.subtree.overlapping(subrange).toList |
255 else Stream.empty |
255 else Nil |
256 val start = subrange.start |
256 val start = subrange.start |
257 |
257 |
258 (if (notable(entry.elements)) results(parent.info, entry) else None) match { |
258 (if (notable(entry.elements)) results(parent.info, entry) else None) match { |
259 case Some(res) => |
259 case Some(res) => |
260 val next = Text.Info(subrange, res) |
260 val next = Text.Info(subrange, res) |
261 val nexts = stream(start, (next, subtree) :: (parent, more) :: rest) |
261 val nexts = traverse(start, (next, subtree) :: (parent, more) :: rest) |
262 if (last < start) parent.restrict(Text.Range(last, start)) #:: nexts |
262 if (last < start) parent.restrict(Text.Range(last, start)) :: nexts |
263 else nexts |
263 else nexts |
264 case None => stream(last, (parent, subtree #::: more) :: rest) |
264 case None => traverse(last, (parent, subtree ::: more) :: rest) |
265 } |
265 } |
266 |
266 |
267 case (parent, Stream.Empty) :: rest => |
267 case (parent, Nil) :: rest => |
268 val stop = parent.range.stop |
268 val stop = parent.range.stop |
269 val nexts = stream(stop, rest) |
269 val nexts = traverse(stop, rest) |
270 if (last < stop) parent.restrict(Text.Range(last, stop)) #:: nexts |
270 if (last < stop) parent.restrict(Text.Range(last, stop)) :: nexts |
271 else nexts |
271 else nexts |
272 |
272 |
273 case Nil => |
273 case Nil => |
274 val stop = root_range.stop |
274 val stop = root_range.stop |
275 if (last < stop) Stream(Text.Info(Text.Range(last, stop), root_info)) |
275 if (last < stop) List(Text.Info(Text.Range(last, stop), root_info)) |
276 else Stream.empty |
276 else Nil |
277 } |
277 } |
278 } |
278 } |
279 stream(root_range.start, |
279 traverse(root_range.start, |
280 List((Text.Info(root_range, root_info), overlapping(root_range).toStream))) |
280 List((Text.Info(root_range, root_info), overlapping(root_range).toList))) |
281 } |
281 } |
282 } |
282 } |
283 |
283 |