src/Pure/PIDE/markup_tree.scala
changeset 52900 d29bf6db8a2d
parent 52889 ea3338812e67
child 55618 995162143ef4
equal deleted inserted replaced
52899:3ff23987f316 52900:d29bf6db8a2d
   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