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.
- data/lib/tm2jed/jedit_theme_writer.rb +89 -0
- data/lib/tm2jed/rack_app.rb +41 -0
- data/lib/tm2jed/textmate_theme_reader.rb +166 -0
- data/rack/config.ru +4 -0
- data/tm2jed.rb +3 -0
- metadata +58 -0
@@ -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
data/tm2jed.rb
ADDED
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
|
+
|