1# -*- mode:ruby; indent-tabs-mode:nil; coding:utf-8 -*- 2# 3# ripper_decorator.rb 4# CocoaRepl 5# 6# Created by Fujimoto Hisa on 07/03/01. 7# Copyright (c) 2007 Fujimoto Hisa. All rights reserved. 8# 9require 'decorator' 10require 'langscan/ruby/compat/ripper' 11 12class RipperStyle < DecoratorStyle 13 install :ripper 14 15 style :comment, :color => :darkGrayColor, :italic => true 16 style :keyword, :color => :redColor, :bold => true 17 style :kw, :color => :redColor, :bold => true # Ripper 18 style :method, :color => '#077' 19 style :const, :color => '#074' # Ripper 20 style :class, :color => '#074' 21 style :module, :color => '#050' 22 style :punct, :color => '#447' 23 style :symbol, :color => '#099' 24 style :string, :color => '#944', :background => '#FFE' 25 style :char, :color => '#F07' 26 style :ident, :color => '#004' 27 style :constant, :color => '#07F' 28 style :regexp, :color => '#B66', :background => '#FEF' # Ripper 29 style :regex, :color => '#B66', :background => '#FEF' 30 style :number, :color => '#F99' 31 style :int, :color => '#F99' # Ripper 32 style :float, :color => '#F99' # Ripper 33 style :attribute, :color => '#7BB' 34 style :global, :color => '#7FB' 35 style :expr, :color => '#227' 36 style :escape, :color => '#277' 37end 38 39class RipperDecorator < Decorator 40 install :ripper 41 42 def RipperDecorator.instance 43 @instance = new if not defined? @instance 44 @instance 45 end 46 47 def initialize(style = :ripper) 48 super(style) 49 end 50 51 private 52 53 KWDMAP = { 54 :symbeg => :symbol, 55 :regexp_beg => :regexp, 56 :tstring_beg => :string, 57 :heredoc_beg => :string, 58 :qwords_beg => :string, 59 :words_beg => :string, 60 } 61 62 def _key_(k) KWDMAP[k] || k end 63 64 def each_token(source) 65 regions = [] 66 Ripper.lex(source).each do |ary, kwd, val| 67 token = nil 68 kwd = kwd.to_s.sub(/^on_/,'').to_sym 69 70 case kwd 71 when :symbeg then 72 regions.push( [Decorator::Token.new(_key_(kwd), val)] ) 73 74 when :tstring_beg, :heredoc_beg, :qwords_beg, :words_beg, :regexp_beg then 75 regions.push( [Decorator::Token.new(_key_(kwd), val)] ) 76 77 when :tstring_end, :heredoc_end, :regexp_end then 78 tokens = regions.pop 79 token = tokens.shift 80 token.value = tokens.inject(token.value) { |p,tkn| p << tkn.value } 81 token.value << val 82 83 when :ident then 84 if regions.empty? then 85 token = Decorator::Token.new(_key_(kwd), val) 86 else 87 last = regions.last 88 if last.size == 1 and last.first.kind == :symbol then 89 token = regions.pop.shift 90 token.value << val 91 else 92 regions.last.push( Decorator::Token.new(_key_(kwd), val) ) 93 end 94 end 95 96 else 97 if regions.empty? then 98 token = Decorator::Token.new(_key_(kwd), val) 99 else 100 regions.last.push( Decorator::Token.new(_key_(kwd), val) ) 101 end 102 end 103 yield(token) if token 104 end 105 end 106end 107