src/Pure/PIDE/markup_tree.scala
changeset 49614 0009a6ebc83b
parent 49608 ce1c34c98eeb
child 49650 9fad6480300d
equal deleted inserted replaced
49613:2f6986e2ef06 49614:0009a6ebc83b
    10 
    10 
    11 import java.lang.System
    11 import java.lang.System
    12 import javax.swing.tree.DefaultMutableTreeNode
    12 import javax.swing.tree.DefaultMutableTreeNode
    13 
    13 
    14 import scala.collection.immutable.SortedMap
    14 import scala.collection.immutable.SortedMap
       
    15 import scala.collection.mutable
    15 import scala.annotation.tailrec
    16 import scala.annotation.tailrec
    16 
    17 
    17 
    18 
    18 object Markup_Tree
    19 object Markup_Tree
    19 {
    20 {
    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