src/Pure/General/symbol.scala
changeset 44569 5130dfe1b7be
parent 44550 8252d51d70e2
child 44570 58bb7ca5c7a2
equal deleted inserted replaced
44565:93dcfcf91484 44569:5130dfe1b7be
    83       }
    83       }
    84     }
    84     }
    85   }
    85   }
    86 
    86 
    87 
    87 
    88   /* efficient iterators */
    88   /* iterator */
    89 
    89 
    90   private val char_symbols: Array[String] =
    90   private val char_symbols: Array[String] =
    91     (0 until 256).iterator.map(i => new String(Array(i.toChar))).toArray
    91     (0 until 256).iterator.map(i => new String(Array(i.toChar))).toArray
    92 
    92 
    93   def iterator(text: CharSequence): Iterator[String] =
    93   def iterator(text: CharSequence): Iterator[String] =
   201     }
   201     }
   202   }
   202   }
   203 
   203 
   204 
   204 
   205 
   205 
   206   /** Symbol interpretation **/
   206   /** symbol interpretation **/
   207 
   207 
   208   class Interpretation(symbol_decls: List[String])
   208   private lazy val symbols =
       
   209     new Interpretation(
       
   210       Isabelle_System.try_read(Path.split(Isabelle_System.getenv_strict("ISABELLE_SYMBOLS"))))
       
   211 
       
   212   private class Interpretation(symbols_spec: String)
   209   {
   213   {
   210     /* read symbols */
   214     /* read symbols */
   211 
   215 
   212     private val empty = new Regex("""(?xs) ^\s* (?: \#.* )? $ """)
   216     private val empty = new Regex("""(?xs) ^\s* (?: \#.* )? $ """)
   213     private val key = new Regex("""(?xs) (.+): """)
   217     private val key = new Regex("""(?xs) (.+): """)
   231       }
   235       }
   232     }
   236     }
   233 
   237 
   234     private val symbols: List[(String, Map[String, String])] =
   238     private val symbols: List[(String, Map[String, String])] =
   235       Map((
   239       Map((
   236         for (decl <- symbol_decls if !empty.pattern.matcher(decl).matches)
   240         for (decl <- split_lines(symbols_spec) if !empty.pattern.matcher(decl).matches)
   237           yield read_decl(decl)): _*) toList
   241           yield read_decl(decl)): _*) toList
   238 
   242 
   239 
   243 
   240     /* misc properties */
   244     /* misc properties */
   241 
   245 
   297           yield (sym -> props("font"))): _*)
   301           yield (sym -> props("font"))): _*)
   298 
   302 
   299     val font_names: List[String] = Set(fonts.toList.map(_._2): _*).toList
   303     val font_names: List[String] = Set(fonts.toList.map(_._2): _*).toList
   300     val font_index: Map[String, Int] = Map((font_names zip (0 until font_names.length).toList): _*)
   304     val font_index: Map[String, Int] = Map((font_names zip (0 until font_names.length).toList): _*)
   301 
   305 
   302     def lookup_font(sym: String): Option[Int] = fonts.get(sym).map(font_index(_))
       
   303 
       
   304 
   306 
   305     /* classification */
   307     /* classification */
   306 
   308 
   307     private val letters = recode_set(
   309     val letters = recode_set(
   308       "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
   310       "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
   309       "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
   311       "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
   310       "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
   312       "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
   311       "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
   313       "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
   312 
   314 
   337       "\\<Xi>", "\\<Pi>", "\\<Sigma>", "\\<Upsilon>", "\\<Phi>",
   339       "\\<Xi>", "\\<Pi>", "\\<Sigma>", "\\<Upsilon>", "\\<Phi>",
   338       "\\<Psi>", "\\<Omega>",
   340       "\\<Psi>", "\\<Omega>",
   339 
   341 
   340       "\\<^isub>", "\\<^isup>")
   342       "\\<^isub>", "\\<^isup>")
   341 
   343 
   342     private val blanks =
   344     val blanks =
   343       recode_set(space, "\t", "\n", "\u000B", "\f", "\r", "\\<spacespace>", "\\<^newline>")
   345       recode_set(space, "\t", "\n", "\u000B", "\f", "\r", "\\<spacespace>", "\\<^newline>")
   344 
   346 
   345     private val sym_chars =
   347     val sym_chars =
   346       Set("!", "#", "$", "%", "&", "*", "+", "-", "/", "<", "=", ">", "?", "@", "^", "_", "|", "~")
   348       Set("!", "#", "$", "%", "&", "*", "+", "-", "/", "<", "=", ">", "?", "@", "^", "_", "|", "~")
   347 
   349 
   348     def is_letter(sym: String): Boolean = letters.contains(sym)
       
   349     def is_digit(sym: String): Boolean = sym.length == 1 && '0' <= sym(0) && sym(0) <= '9'
       
   350     def is_quasi(sym: String): Boolean = sym == "_" || sym == "'"
       
   351     def is_letdig(sym: String): Boolean = is_letter(sym) || is_digit(sym) || is_quasi(sym)
       
   352     def is_blank(sym: String): Boolean = blanks.contains(sym)
       
   353     def is_symbolic_char(sym: String): Boolean = sym_chars.contains(sym)
       
   354     def is_symbolic(sym: String): Boolean =
       
   355       sym.startsWith("\\<") && sym.endsWith(">") && !sym.startsWith("\\<^")
       
   356 
       
   357 
   350 
   358     /* control symbols */
   351     /* control symbols */
   359 
   352 
   360     private val ctrl_decoded: Set[String] =
   353     val ctrl_decoded: Set[String] =
   361       Set((for ((sym, _) <- symbols if sym.startsWith("\\<^")) yield decode(sym)): _*)
   354       Set((for ((sym, _) <- symbols if sym.startsWith("\\<^")) yield decode(sym)): _*)
   362 
   355 
   363     def is_ctrl(sym: String): Boolean =
   356     val subscript_decoded = Set(decode("\\<^sub>"), decode("\\<^isub>"))
   364       sym.startsWith("\\<^") || ctrl_decoded.contains(sym)
   357     val superscript_decoded = Set(decode("\\<^sup>"), decode("\\<^isup>"))
   365 
       
   366     def is_controllable(sym: String): Boolean =
       
   367       !is_blank(sym) && !is_ctrl(sym) && !is_malformed(sym)
       
   368 
       
   369     private val subscript_decoded = Set(decode("\\<^sub>"), decode("\\<^isub>"))
       
   370     private val superscript_decoded = Set(decode("\\<^sup>"), decode("\\<^isup>"))
       
   371     def is_subscript_decoded(sym: String): Boolean = subscript_decoded.contains(sym)
       
   372     def is_superscript_decoded(sym: String): Boolean = superscript_decoded.contains(sym)
       
   373 
   358 
   374     val bold_decoded = decode("\\<^bold>")
   359     val bold_decoded = decode("\\<^bold>")
   375     val bsub_decoded = decode("\\<^bsub>")
   360     val bsub_decoded = decode("\\<^bsub>")
   376     val esub_decoded = decode("\\<^esub>")
   361     val esub_decoded = decode("\\<^esub>")
   377     val bsup_decoded = decode("\\<^bsup>")
   362     val bsup_decoded = decode("\\<^bsup>")
   378     val esup_decoded = decode("\\<^esup>")
   363     val esup_decoded = decode("\\<^esup>")
   379   }
   364   }
       
   365 
       
   366 
       
   367   /* tables */
       
   368 
       
   369   def names: Map[String, String] = symbols.names
       
   370   def abbrevs: Map[String, String] = symbols.abbrevs
       
   371 
       
   372   def decode(text: String): String = symbols.decode(text)
       
   373   def encode(text: String): String = symbols.encode(text)
       
   374 
       
   375   def fonts: Map[String, String] = symbols.fonts
       
   376   def font_names: List[String] = symbols.font_names
       
   377   def font_index: Map[String, Int] = symbols.font_index
       
   378   def lookup_font(sym: String): Option[Int] = symbols.fonts.get(sym).map(font_index(_))
       
   379 
       
   380 
       
   381   /* classification */
       
   382 
       
   383   def is_letter(sym: String): Boolean = symbols.letters.contains(sym)
       
   384   def is_digit(sym: String): Boolean = sym.length == 1 && '0' <= sym(0) && sym(0) <= '9'
       
   385   def is_quasi(sym: String): Boolean = sym == "_" || sym == "'"
       
   386   def is_letdig(sym: String): Boolean = is_letter(sym) || is_digit(sym) || is_quasi(sym)
       
   387   def is_blank(sym: String): Boolean = symbols.blanks.contains(sym)
       
   388   def is_symbolic_char(sym: String): Boolean = symbols.sym_chars.contains(sym)
       
   389   def is_symbolic(sym: String): Boolean =
       
   390     sym.startsWith("\\<") && sym.endsWith(">") && !sym.startsWith("\\<^")
       
   391 
       
   392 
       
   393   /* control symbols */
       
   394 
       
   395   def is_ctrl(sym: String): Boolean =
       
   396     sym.startsWith("\\<^") || symbols.ctrl_decoded.contains(sym)
       
   397 
       
   398   def is_controllable(sym: String): Boolean =
       
   399     !is_blank(sym) && !is_ctrl(sym) && !is_malformed(sym)
       
   400 
       
   401   def is_subscript_decoded(sym: String): Boolean = symbols.subscript_decoded.contains(sym)
       
   402   def is_superscript_decoded(sym: String): Boolean = symbols.superscript_decoded.contains(sym)
       
   403   def is_bold_decoded(sym: String): Boolean = sym == symbols.bold_decoded
       
   404   def is_bsub_decoded(sym: String): Boolean = sym == symbols.bsub_decoded
       
   405   def is_esub_decoded(sym: String): Boolean = sym == symbols.esub_decoded
       
   406   def is_bsup_decoded(sym: String): Boolean = sym == symbols.bsup_decoded
       
   407   def is_esup_decoded(sym: String): Boolean = sym == symbols.esup_decoded
   380 }
   408 }