src/Pure/General/symbol.scala
changeset 31939 ecfc667cac53
parent 31651 7d6a518b5a2b
child 34007 fc56cfc6906e
     1.1 --- a/src/Pure/General/symbol.scala	Fri Jul 03 21:14:46 2009 +0200
     1.2 +++ b/src/Pure/General/symbol.scala	Sat Jul 04 11:46:51 2009 +0200
     1.3 @@ -7,7 +7,7 @@
     1.4  package isabelle
     1.5  
     1.6  import scala.io.Source
     1.7 -import scala.collection.jcl
     1.8 +import scala.collection.{jcl, mutable}
     1.9  import scala.util.matching.Regex
    1.10  
    1.11  
    1.12 @@ -34,14 +34,59 @@
    1.13    def is_open(s: String): Boolean =
    1.14    {
    1.15      val len = s.length
    1.16 -    len == 1 && Character.isHighSurrogate(s(0)) ||
    1.17 +    len == 1 && Character.isLowSurrogate(s(0)) ||
    1.18      s == "\\" ||
    1.19      s == "\\<" ||
    1.20      len > 2 && s(len - 1) != '>'
    1.21    }
    1.22  
    1.23  
    1.24 -  /** Recoding **/
    1.25 +  /** Decoding offsets **/
    1.26 +
    1.27 +  class Index(text: String)
    1.28 +  {
    1.29 +    case class Entry(chr: Int, sym: Int)
    1.30 +    val index: Array[Entry] =
    1.31 +    {
    1.32 +      val length = text.length
    1.33 +      val matcher = regex.pattern.matcher(text)
    1.34 +      val buf = new mutable.ArrayBuffer[Entry]
    1.35 +      var chr = 0
    1.36 +      var sym = 0
    1.37 +      while (chr < length) {
    1.38 +        val c = text(chr)
    1.39 +        val len =
    1.40 +          if (c == '\\' || Character.isHighSurrogate(c)) {
    1.41 +            matcher.region(chr, length).lookingAt
    1.42 +            matcher.group.length
    1.43 +          } else 1
    1.44 +        chr += len
    1.45 +        sym += 1
    1.46 +        if (len > 1) buf += Entry(chr, sym)
    1.47 +      }
    1.48 +      buf.toArray
    1.49 +    }
    1.50 +    def decode(sym: Int): Int =
    1.51 +    {
    1.52 +      val end = index.length
    1.53 +      def bisect(a: Int, b: Int): Int =
    1.54 +      {
    1.55 +        if (a < b) {
    1.56 +          val c = (a + b) / 2
    1.57 +          if (sym < index(c).sym) bisect(a, c)
    1.58 +          else if (c + 1 == end || sym < index(c + 1).sym) c
    1.59 +          else bisect(c + 1, b)
    1.60 +        }
    1.61 +        else -1
    1.62 +      }
    1.63 +      val i = bisect(0, end)
    1.64 +      if (i < 0) sym
    1.65 +      else index(i).chr + sym - index(i).sym
    1.66 +    }
    1.67 +  }
    1.68 +
    1.69 +
    1.70 +  /** Recoding text **/
    1.71  
    1.72    private class Recoder(list: List[(String, String)])
    1.73    {
    1.74 @@ -71,8 +116,7 @@
    1.75        while (i < len) {
    1.76          val c = text(i)
    1.77          if (min <= c && c <= max) {
    1.78 -          matcher.region(i, len)
    1.79 -          matcher.lookingAt
    1.80 +          matcher.region(i, len).lookingAt
    1.81            val x = matcher.group
    1.82            result.append(table.get(x) getOrElse x)
    1.83            i = matcher.end