# HG changeset patch # User wenzelm # Date 1246704057 -7200 # Node ID 5fe21cac6bf7099e890d74e36cefc509c45261a9 # Parent e1ac7ab73bb154cf80b264a9877978ee0b9bf27f# Parent ecfc667cac53bfb4086f23bd1e0936aeb7dbd82d merged diff -r e1ac7ab73bb1 -r 5fe21cac6bf7 src/Pure/General/symbol.scala --- a/src/Pure/General/symbol.scala Sat Jul 04 07:58:34 2009 +0200 +++ b/src/Pure/General/symbol.scala Sat Jul 04 12:40:57 2009 +0200 @@ -7,7 +7,7 @@ package isabelle import scala.io.Source -import scala.collection.jcl +import scala.collection.{jcl, mutable} import scala.util.matching.Regex @@ -34,14 +34,59 @@ def is_open(s: String): Boolean = { val len = s.length - len == 1 && Character.isHighSurrogate(s(0)) || + len == 1 && Character.isLowSurrogate(s(0)) || s == "\\" || s == "\\<" || len > 2 && s(len - 1) != '>' } - /** Recoding **/ + /** Decoding offsets **/ + + class Index(text: String) + { + case class Entry(chr: Int, sym: Int) + val index: Array[Entry] = + { + val length = text.length + val matcher = regex.pattern.matcher(text) + val buf = new mutable.ArrayBuffer[Entry] + var chr = 0 + var sym = 0 + while (chr < length) { + val c = text(chr) + val len = + if (c == '\\' || Character.isHighSurrogate(c)) { + matcher.region(chr, length).lookingAt + matcher.group.length + } else 1 + chr += len + sym += 1 + if (len > 1) buf += Entry(chr, sym) + } + buf.toArray + } + def decode(sym: Int): Int = + { + val end = index.length + def bisect(a: Int, b: Int): Int = + { + if (a < b) { + val c = (a + b) / 2 + if (sym < index(c).sym) bisect(a, c) + else if (c + 1 == end || sym < index(c + 1).sym) c + else bisect(c + 1, b) + } + else -1 + } + val i = bisect(0, end) + if (i < 0) sym + else index(i).chr + sym - index(i).sym + } + } + + + /** Recoding text **/ private class Recoder(list: List[(String, String)]) { @@ -71,8 +116,7 @@ while (i < len) { val c = text(i) if (min <= c && c <= max) { - matcher.region(i, len) - matcher.lookingAt + matcher.region(i, len).lookingAt val x = matcher.group result.append(table.get(x) getOrElse x) i = matcher.end