sickill-tm2jed 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+