src/Pure/PIDE/markup_tree.scala
changeset 55620 19dffae33cde
parent 55618 995162143ef4
child 55622 ce575c2212fc
equal deleted inserted replaced
55619:c5aeeacdd2b1 55620:19dffae33cde
    43     val empty = new Elements(Set.empty)
    43     val empty = new Elements(Set.empty)
    44   }
    44   }
    45 
    45 
    46   final class Elements private(private val rep: Set[String])
    46   final class Elements private(private val rep: Set[String])
    47   {
    47   {
    48     def contains(name: String): Boolean = rep.contains(name)
    48     def exists(pred: String => Boolean): Boolean = rep.exists(pred)
    49 
    49 
    50     def + (name: String): Elements =
    50     def + (name: String): Elements =
    51       if (contains(name)) this
    51       if (rep(name)) this
    52       else new Elements(rep + name)
    52       else new Elements(rep + name)
    53 
    53 
    54     def + (elem: XML.Elem): Elements = this + elem.markup.name
    54     def + (elem: XML.Elem): Elements = this + elem.markup.name
    55     def ++ (elems: Iterable[XML.Elem]): Elements = (this /: elems.iterator)(_ + _)
    55     def ++ (elems: Iterable[XML.Elem]): Elements = (this /: elems.iterator)(_ + _)
    56 
    56 
   220   }
   220   }
   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, elements: String => Boolean,
   226     result: (A, Text.Markup) => Option[A]): List[Text.Info[A]] =
   226     result: (A, Text.Markup) => Option[A]): List[Text.Info[A]] =
   227   {
   227   {
   228     val notable: Elements => Boolean =
       
   229       result_elements match {
       
   230         case Some(res) => (elements: Elements) => res.exists(elements.contains)
       
   231         case None => (elements: Elements) => true
       
   232       }
       
   233 
       
   234     def results(x: A, entry: Entry): Option[A] =
   228     def results(x: A, entry: Entry): Option[A] =
   235     {
   229     {
   236       var y = x
   230       var y = x
   237       var changed = false
   231       var changed = false
   238       for {
   232       for {
   239         info <- entry.rev_markup // FIXME proper cumulation order (including status markup) (!?)
   233         elem <- entry.rev_markup // FIXME proper cumulation order (including status markup) (!?)
   240         y1 <- result(y, Text.Info(entry.range, info))
   234         if elements(elem.name)
       
   235         y1 <- result(y, Text.Info(entry.range, elem))
   241       } { y = y1; changed = true }
   236       } { y = y1; changed = true }
   242       if (changed) Some(y) else None
   237       if (changed) Some(y) else None
   243     }
   238     }
   244 
   239 
   245     def traverse(
   240     def traverse(
   248     {
   243     {
   249       stack match {
   244       stack match {
   250         case (parent, (range, entry) :: more) :: rest =>
   245         case (parent, (range, entry) :: more) :: rest =>
   251           val subrange = range.restrict(root_range)
   246           val subrange = range.restrict(root_range)
   252           val subtree =
   247           val subtree =
   253             if (notable(entry.subtree_elements))
   248             if (entry.subtree_elements.exists(elements))
   254               entry.subtree.overlapping(subrange).toList
   249               entry.subtree.overlapping(subrange).toList
   255             else Nil
   250             else Nil
   256           val start = subrange.start
   251           val start = subrange.start
   257 
   252 
   258           (if (notable(entry.elements)) results(parent.info, entry) else None) match {
   253           (if (entry.elements.exists(elements)) results(parent.info, entry) else None) match {
   259             case Some(res) =>
   254             case Some(res) =>
   260               val next = Text.Info(subrange, res)
   255               val next = Text.Info(subrange, res)
   261               val nexts = traverse(start, (next, subtree) :: (parent, more) :: rest)
   256               val nexts = traverse(start, (next, subtree) :: (parent, more) :: rest)
   262               if (last < start) parent.restrict(Text.Range(last, start)) :: nexts
   257               if (last < start) parent.restrict(Text.Range(last, start)) :: nexts
   263               else nexts
   258               else nexts