sickill-tm2jed 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,89 @@
1
+
2
+ class JEditThemeWriter
3
+ def initialize(theme)
4
+ @theme = theme
5
+ @lines = []
6
+ prepare
7
+ end
8
+
9
+ def escape_value(val)
10
+ val.gsub(/:/, '\:').gsub(/#/, '\#')
11
+ end
12
+
13
+ def prepare_color(col)
14
+ col.downcase
15
+ end
16
+
17
+ def add_comment(comment)
18
+ @lines << "\##{comment}"
19
+ end
20
+
21
+ def add_prop(name, value)
22
+ @lines << "#{name}=#{escape_value(value).strip}"
23
+ end
24
+
25
+ def add_style(name, style)
26
+ if style.to_s =~ /missing prop/ || style.nil?
27
+ return
28
+ end
29
+
30
+ s = ""
31
+ s << " color:#{prepare_color(style[:foreground])}" if style[:foreground]
32
+ s << " bgColor:#{prepare_color(style[:background])}" if style[:background]
33
+ if s.size > 1 && style[:fontStyle]
34
+ s << " style:"
35
+ s << "b" if style[:fontStyle] =~ /bold/
36
+ # s << "u" if style[:fontStyle] =~ /underline/
37
+ s << "i" if style[:fontStyle] =~ /italic/
38
+ end
39
+ add_prop(name, s) if s.size > 1
40
+ end
41
+
42
+ def prepare
43
+ add_comment "#{@theme.name} jEdit Editor Scheme"
44
+ add_comment "generated from textmate theme with tm2jed (http://github.com/sickill/tm2jed/tree/master)\n"
45
+
46
+ add_prop "scheme.name", @theme.name
47
+ #add_prop "console.font", "Monospaced"
48
+ add_prop "view.fgColor", @theme.foreground
49
+ add_prop "view.bgColor", @theme.background
50
+ add_prop "view.caretColor", @theme.caret
51
+ add_prop "view.selectionColor", @theme.selection
52
+ add_prop "view.eolMarkerColor", @theme.eol_marker
53
+ add_prop "view.lineHighlightColor", @theme.line_highlight
54
+
55
+ # #foo
56
+ add_style "view.style.comment1", @theme.comment
57
+ # "foo"
58
+ add_style "view.style.literal1", @theme.string
59
+ # :foo
60
+ add_style "view.style.label", @theme.label
61
+ # 123
62
+ add_style "view.style.digit", @theme.number
63
+ # class, def, if, end
64
+ add_style "view.style.keyword1", @theme.keyword
65
+ # require, include
66
+ add_style "view.style.keyword2", @theme.keyword
67
+ # true, false, nil
68
+ add_style "view.style.keyword3", @theme.keyword2
69
+ # @foo
70
+ add_style "view.style.keyword4", @theme.variable
71
+ # = < + -
72
+ add_style "view.style.operator", @theme.operator
73
+ # def foo
74
+ add_style "view.style.function", @theme.function
75
+ # /jola/
76
+ add_style "view.style.literal3", @theme.regexp
77
+ # MyClass, USER_SPACE
78
+ #add_style "view.style.literal4", @theme.constant
79
+ # <div>
80
+ add_style "view.style.markup", @theme.markup
81
+
82
+ #TODO: gutter etc
83
+ end
84
+
85
+ def get_theme
86
+ @lines.join("\n")+"\n"
87
+ end
88
+ end
89
+
@@ -0,0 +1,41 @@
1
+ require 'sinatra/base'
2
+
3
+ module TextmateToJEditConverter
4
+ class Application < Sinatra::Default
5
+
6
+ set :run, false
7
+ use_in_file_templates!
8
+
9
+ get '/' do
10
+ erb :index
11
+ end
12
+
13
+ post '/' do
14
+ @result = JEditThemeWriter.new(TextmateThemeReader.new(params[:input]).get_theme).get_theme
15
+ erb :result
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+ __END__
22
+
23
+ @@ layout
24
+ <html>
25
+ <head>
26
+ </head>
27
+ <bodu>
28
+ <%= yield %>
29
+ </bodu>
30
+ </html>
31
+
32
+ @@ index
33
+ This is index:
34
+ <form action="/" method="POST">
35
+ <textarea name="input" style="width: 600px; height: 500px;"></textarea>
36
+ <input type="submit" value="Convert!" />
37
+ </form>
38
+
39
+ @@ result
40
+ This is result:
41
+ <pre><%= @result %></pre>
@@ -0,0 +1,166 @@
1
+ require 'rexml/document'
2
+ require 'ostruct'
3
+
4
+ class GlobHash
5
+ def initialize(hash)
6
+ @hash = hash
7
+ end
8
+
9
+ def find_key(key)
10
+ to_check = []
11
+ elems = key.split(".")
12
+ elems.size.times do |i|
13
+ to_check << "(^|,\\s*)"+Regexp.escape(elems[0..i].join("."))+"(\\s*,|$)"
14
+ end
15
+ to_check << "^#{Regexp.escape(key)}$"
16
+ to_check.reverse!
17
+ #p to_check
18
+ to_check.each do |r|
19
+ regexp = Regexp.new(r)
20
+ newkey = @hash.keys.grep(regexp).first
21
+ puts "found key #{newkey} for #{key}" if newkey && $DEBUG
22
+ return newkey if newkey
23
+ end
24
+ puts "key #{key} not found" if $DEBUG
25
+ key
26
+ end
27
+
28
+ def [](key)
29
+ key = find_key(key) if key.is_a?(String)
30
+ @hash[key] # || "missing prop #{key}"
31
+ end
32
+
33
+ def method_missing(name, *args)
34
+ @hash.send(name, *args)
35
+ end
36
+ end
37
+
38
+ class TextmateThemeReader
39
+ include REXML
40
+
41
+ def initialize(source)
42
+ @source = source
43
+ @xml = Document.new(@source)
44
+ root = parse_hash(@xml.root.elements[1])
45
+ @name = root[:name]
46
+ @src_theme = root[:settings]
47
+ global_settings = @src_theme.delete_at(0)[:settings]
48
+ @src_theme = @src_theme.map { |s| { s[:scope] => s[:settings] } }.inject({}) { |v,a| a.merge(v) }
49
+ @multi_keys = @src_theme.keys.select { |k| k.is_a?(String) && k.index(",") }
50
+ @multi_keys.each do |key|
51
+ keys = key.split(",").map { |k| k.strip }
52
+ value = @src_theme.delete(key)
53
+ keys.each do |new_key|
54
+ @src_theme[new_key] = value
55
+ end
56
+ end
57
+ @src_theme = @src_theme.merge(global_settings)
58
+ @src_theme = GlobHash.new(@src_theme)
59
+ end
60
+
61
+ def get_theme
62
+ theme = OpenStruct.new
63
+ theme.name = @name
64
+ theme.foreground = normalize_color(@src_theme[:foreground])
65
+ theme.background = normalize_color(@src_theme[:background])
66
+ theme.caret = normalize_color(@src_theme[:caret])
67
+ theme.selection = normalize_color(@src_theme[:selection], theme.background)
68
+ theme.eol_marker = normalize_color(@src_theme[:invisibles], theme.background)
69
+ theme.line_highlight = normalize_color(@src_theme[:lineHighlight], theme.background)
70
+
71
+ # #foo
72
+ theme.comment = @src_theme["comment"]
73
+
74
+ # "foo"
75
+ theme.string = @src_theme["string"]
76
+
77
+ # :foo
78
+ theme.label = @src_theme["constant"]
79
+
80
+ # 123
81
+ theme.number = @src_theme["constant.numeric"]
82
+
83
+ # class, def, if, end
84
+ theme.keyword = @src_theme["keyword.control"]
85
+
86
+ # true, false, nil
87
+ theme.keyword2 = @src_theme["constant.language"]
88
+
89
+ # @foo
90
+ theme.variable = @src_theme["variable"] || @src_theme["variable.other"]
91
+
92
+ # = < + -
93
+ theme.operator = @src_theme["keyword.operator"]
94
+
95
+ # def foo, maybe MyClass??
96
+ theme.function = @src_theme["entity.name.function"]
97
+
98
+ # /jola/
99
+ theme.regexp = @src_theme["string.regexp"]
100
+
101
+ # UserSpace, CGI, JOLA_MISIO
102
+ #theme.constant = @src_theme["support"]
103
+
104
+ # <div>
105
+ theme.markup = @src_theme["meta.tag"]
106
+
107
+ theme
108
+ end
109
+
110
+ private
111
+
112
+ def blend(col_a, col_b, alpha)
113
+ newcol = []
114
+ [0,1,2].each do |i|
115
+ newcol[i] = (1.0 - alpha) * col_a[i] + alpha * col_b[i]
116
+ end
117
+ newcol
118
+ end
119
+
120
+ def color_to_triplet(color)
121
+ color.slice(1,6).scan(/.{2}/).map { |x| x.hex.to_f / 255.0 }
122
+ end
123
+
124
+ def normalize_color(color, bg=nil)
125
+ alpha = color.slice(7,9).to_i(16)
126
+ if bg && (1..254).include?(alpha)
127
+ bg = color_to_triplet(bg)
128
+ color = color_to_triplet(color)
129
+ result = blend(bg, color, alpha.to_f / 255.0)
130
+ value = "%02x%02x%02x" % result.map { |x| (x*255.0).to_i }
131
+ else
132
+ value = color.slice(1,6).downcase
133
+ end
134
+ "\##{value}"
135
+ end
136
+
137
+ def parse_element(e)
138
+ return nil unless e
139
+ if e.name == "dict"
140
+ return parse_hash(e)
141
+ elsif e.name == "array"
142
+ return parse_array(e)
143
+ elsif e.name == "string"
144
+ return e.text.to_s.strip
145
+ end
146
+ nil
147
+ end
148
+
149
+ def parse_hash(elem)
150
+ h = {}
151
+ elem.elements.each("key") do |e|
152
+ h[e.text.to_sym] = parse_element(e.next_element)
153
+ end
154
+ h
155
+ end
156
+
157
+ def parse_array(elem)
158
+ a = []
159
+ elem.elements.each do |e|
160
+ a << parse_element(e)
161
+ end
162
+ a
163
+ end
164
+
165
+ end
166
+
data/rack/config.ru ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'tm2jed'
3
+
4
+ run TextmateToJEditConverter::Application.new
data/tm2jed.rb ADDED
@@ -0,0 +1,3 @@
1
+ require File.join(File.dirname(__FILE__), 'lib', 'tm2jed', 'jedit_theme_writer')
2
+ require File.join(File.dirname(__FILE__), 'lib', 'tm2jed', 'textmate_theme_reader')
3
+ require File.join(File.dirname(__FILE__), 'lib', 'tm2jed', 'rack_app')
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sickill-tm2jed
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Marcin Kulik
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-29 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: marcin.kulik@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - tm2jed.rb
26
+ - lib/tm2jed/jedit_theme_writer.rb
27
+ - lib/tm2jed/textmate_theme_reader.rb
28
+ - lib/tm2jed/rack_app.rb
29
+ - rack/config.ru
30
+ has_rdoc: false
31
+ homepage: http://sickill.net
32
+ licenses:
33
+ post_install_message:
34
+ rdoc_options: []
35
+
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project:
53
+ rubygems_version: 1.3.5
54
+ signing_key:
55
+ specification_version: 2
56
+ summary: Textmate to JEdit colour scheme converter
57
+ test_files: []
58
+