src/Tools/jEdit/src/token_markup.scala
author wenzelm
Sun Jun 19 14:11:06 2011 +0200 (2011-06-19)
changeset 43455 4b4b93672f15
parent 43452 5cf548485529
child 43458 b55a273ede18
permissions -rw-r--r--
some unicode chars for special control symbols;
wenzelm@43414
     1
/*  Title:      Tools/jEdit/src/token_markup.scala
wenzelm@43414
     2
    Author:     Makarius
wenzelm@43414
     3
wenzelm@43414
     4
Outer syntax token markup.
wenzelm@43414
     5
*/
wenzelm@43414
     6
wenzelm@43414
     7
package isabelle.jedit
wenzelm@43414
     8
wenzelm@43414
     9
wenzelm@43414
    10
import isabelle._
wenzelm@43414
    11
wenzelm@43452
    12
import org.gjt.sp.jedit.Mode
wenzelm@43452
    13
import org.gjt.sp.jedit.syntax.{Token => JEditToken, TokenMarker, TokenHandler,
wenzelm@43452
    14
  ParserRuleSet, ModeProvider, XModeHandler}
wenzelm@43452
    15
wenzelm@43414
    16
import javax.swing.text.Segment
wenzelm@43414
    17
wenzelm@43414
    18
wenzelm@43414
    19
object Token_Markup
wenzelm@43414
    20
{
wenzelm@43443
    21
  /* extended syntax styles */
wenzelm@43414
    22
wenzelm@43440
    23
  private val plain_range: Int = JEditToken.ID_COUNT
wenzelm@43414
    24
  private def check_range(i: Int) { require(0 <= i && i < plain_range) }
wenzelm@43414
    25
wenzelm@43414
    26
  def subscript(i: Byte): Byte = { check_range(i); (i + plain_range).toByte }
wenzelm@43414
    27
  def superscript(i: Byte): Byte = { check_range(i); (i + 2 * plain_range).toByte }
wenzelm@43414
    28
  val hidden: Byte = (3 * plain_range).toByte
wenzelm@43414
    29
wenzelm@43443
    30
  private def extended_styles(symbols: Symbol.Interpretation, text: CharSequence)
wenzelm@43443
    31
    : Map[Text.Offset, Byte => Byte] =
wenzelm@43443
    32
  {
wenzelm@43443
    33
    if (Isabelle.extended_styles) {
wenzelm@43455
    34
      // FIXME \\<^bsub> \\<^esub> \\<^bsup> \\<^esup>
wenzelm@43455
    35
      // FIXME \\<^bold> \\<^loc>
wenzelm@43455
    36
      def ctrl_style(sym: String): Option[Byte => Byte] =
wenzelm@43455
    37
        if (symbols.is_subscript_decoded(sym)) Some(subscript(_))
wenzelm@43455
    38
        else if (symbols.is_superscript_decoded(sym)) Some(superscript(_))
wenzelm@43455
    39
        else None
wenzelm@43455
    40
wenzelm@43443
    41
      var result = Map[Text.Offset, Byte => Byte]()
wenzelm@43443
    42
      def mark(start: Text.Offset, stop: Text.Offset, style: Byte => Byte)
wenzelm@43443
    43
      {
wenzelm@43443
    44
        for (i <- start until stop) result += (i -> style)
wenzelm@43443
    45
      }
wenzelm@43443
    46
      var offset = 0
wenzelm@43443
    47
      var ctrl = ""
wenzelm@43443
    48
      for (sym <- Symbol.iterator(text).map(_.toString)) {
wenzelm@43455
    49
        if (ctrl_style(sym).isDefined) ctrl = sym
wenzelm@43443
    50
        else if (ctrl != "") {
wenzelm@43443
    51
          if (symbols.is_controllable(sym)) {
wenzelm@43443
    52
            mark(offset - ctrl.length, offset, _ => hidden)
wenzelm@43455
    53
            mark(offset, offset + sym.length, ctrl_style(ctrl).get)
wenzelm@43443
    54
          }
wenzelm@43443
    55
          ctrl = ""
wenzelm@43443
    56
        }
wenzelm@43443
    57
        offset += sym.length
wenzelm@43443
    58
      }
wenzelm@43443
    59
      result
wenzelm@43443
    60
    }
wenzelm@43443
    61
    else Map.empty
wenzelm@43443
    62
  }
wenzelm@43443
    63
wenzelm@43414
    64
wenzelm@43414
    65
  /* token marker */
wenzelm@43414
    66
wenzelm@43414
    67
  private val isabelle_rules = new ParserRuleSet("isabelle", "MAIN")
wenzelm@43414
    68
wenzelm@43429
    69
  private class Line_Context(val context: Scan.Context)
wenzelm@43429
    70
    extends TokenMarker.LineContext(isabelle_rules, null)
wenzelm@43414
    71
  {
wenzelm@43414
    72
    override def hashCode: Int = context.hashCode
wenzelm@43414
    73
    override def equals(that: Any): Boolean =
wenzelm@43414
    74
      that match {
wenzelm@43414
    75
        case other: Line_Context => context == other.context
wenzelm@43414
    76
        case _ => false
wenzelm@43414
    77
      }
wenzelm@43414
    78
  }
wenzelm@43414
    79
wenzelm@43452
    80
  class Marker extends TokenMarker
wenzelm@43452
    81
  {
wenzelm@43452
    82
    override def markTokens(context: TokenMarker.LineContext,
wenzelm@43452
    83
        handler: TokenHandler, line: Segment): TokenMarker.LineContext =
wenzelm@43452
    84
    {
wenzelm@43452
    85
      val symbols = Isabelle.system.symbols
wenzelm@43452
    86
      val syntax = Isabelle.session.current_syntax()
wenzelm@43414
    87
wenzelm@43452
    88
      val ctxt =
wenzelm@43452
    89
        context match {
wenzelm@43452
    90
          case c: Line_Context => c.context
wenzelm@43452
    91
          case _ => Scan.Finished
wenzelm@43452
    92
        }
wenzelm@43452
    93
      val (tokens, ctxt1) = syntax.scan_context(line, ctxt)
wenzelm@43452
    94
      val context1 = new Line_Context(ctxt1)
wenzelm@43452
    95
wenzelm@43452
    96
      val extended = extended_styles(symbols, line)
wenzelm@43443
    97
wenzelm@43452
    98
      var offset = 0
wenzelm@43452
    99
      for (token <- tokens) {
wenzelm@43452
   100
        val style = Isabelle_Markup.token_markup(syntax, token)
wenzelm@43452
   101
        val length = token.source.length
wenzelm@43452
   102
        val end_offset = offset + length
wenzelm@43452
   103
        if ((offset until end_offset) exists extended.isDefinedAt) {
wenzelm@43452
   104
          for (i <- offset until end_offset) {
wenzelm@43452
   105
            val style1 =
wenzelm@43452
   106
              extended.get(i) match {
wenzelm@43452
   107
                case None => style
wenzelm@43452
   108
                case Some(ext) => ext(style)
wenzelm@43452
   109
              }
wenzelm@43452
   110
            handler.handleToken(line, style1, i, 1, context1)
wenzelm@43443
   111
          }
wenzelm@43414
   112
        }
wenzelm@43452
   113
        else handler.handleToken(line, style, offset, length, context1)
wenzelm@43452
   114
        offset += length
wenzelm@43452
   115
      }
wenzelm@43452
   116
      handler.handleToken(line, JEditToken.END, line.count, 0, context1)
wenzelm@43452
   117
wenzelm@43452
   118
      val context2 = context1.intern
wenzelm@43452
   119
      handler.setLineContext(context2)
wenzelm@43452
   120
      context2
wenzelm@43452
   121
    }
wenzelm@43452
   122
  }
wenzelm@43452
   123
wenzelm@43416
   124
wenzelm@43452
   125
  /* mode provider */
wenzelm@43452
   126
wenzelm@43452
   127
  class Mode_Provider(orig_provider: ModeProvider) extends ModeProvider
wenzelm@43452
   128
  {
wenzelm@43452
   129
    for (mode <- orig_provider.getModes) addMode(mode)
wenzelm@43452
   130
wenzelm@43452
   131
    val isabelle_token_marker = new Token_Markup.Marker
wenzelm@43452
   132
wenzelm@43452
   133
    override def loadMode(mode: Mode, xmh: XModeHandler)
wenzelm@43452
   134
    {
wenzelm@43452
   135
      super.loadMode(mode, xmh)
wenzelm@43452
   136
      if (mode.getName == "isabelle")
wenzelm@43452
   137
        mode.setTokenMarker(isabelle_token_marker)
wenzelm@43414
   138
    }
wenzelm@43452
   139
  }
wenzelm@43414
   140
}
wenzelm@43414
   141