topinambour 1.0.11 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
data/lib/css_handler.rb DELETED
@@ -1,241 +0,0 @@
1
- # Copyright 2016 Cedric LE MOIGNE, cedlemo@gmx.com
2
- # This file is part of Topinambour.
3
- #
4
- # Topinambour is free software: you can redistribute it and/or modify
5
- # it under the terms of the GNU General Public License as published by
6
- # the Free Software Foundation, either version 3 of the License, or
7
- # any later version.
8
- #
9
- # Topinambour is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with Topinambour. If not, see <http://www.gnu.org/licenses/>.
16
-
17
- ##
18
- # This module contains all the methods needed to read, parse
19
- # and modify css file.
20
- # Sass is used to read, parse and get informations about
21
- # css selectors or properties
22
- # The modifying or addition of css properties are done
23
- # with ruby strings facilities
24
- module CssHandler
25
- def self.css_file?(filename)
26
- filename =~ /^.*\.css$/ ? true : false
27
- end
28
-
29
- def self.scss_file?(filename)
30
- filename =~ /^.*\.scss$/ ? true : false
31
- end
32
-
33
- def self.sass_file?(filename)
34
- filename =~ /^.*\.sass$/ ? true : false
35
- end
36
-
37
- def self.to_css(filename)
38
- content = File.open(filename, "r").read
39
- if css_file?(filename) || scss_file?(filename)
40
- Sass::Engine.new(content, :syntax => :scss).render
41
- elsif sass_file?(filename)
42
- Sass::Engine.new(content, :syntax => :sass).render
43
- else
44
- puts "Your theme file must be a css, scss or sass file"
45
- exit 1
46
- end
47
- end
48
-
49
- def self.to_engine(filename)
50
- content = File.open(filename, "r").read
51
- if css_file?(filename) || scss_file?(filename)
52
- Sass::Engine.new(content, :syntax => :scss)
53
- elsif sass_file?(filename)
54
- Sass::Engine.new(content, :syntax => :sass)
55
- else
56
- puts "Your theme file must be a css, scss or sass file"
57
- exit 1
58
- end
59
- end
60
-
61
- def self.reload_engine(engine, css_content)
62
- Sass::Engine.new(css_content, :syntax => engine.options[:syntax])
63
- end
64
-
65
- def self.color_property?(value)
66
- parsed_color = nil
67
- begin
68
- parsed_color = Gdk::RGBA.parse(value)
69
- rescue
70
- parsed_color = nil
71
- end
72
- parsed_color ? true : false
73
- end
74
-
75
- def self.value_to_css_value(value)
76
- if value.class == String && color_property?(value)
77
- "#{value}"
78
- elsif value.class == String
79
- %("#{value}")
80
- else
81
- "#{value}"
82
- end
83
-
84
- end
85
-
86
- def self.property_to_css_instructions(name, value)
87
- "#{name}: #{value_to_css_value(value)}"
88
- end
89
-
90
- def self.props_with_name(tree, prop_name)
91
- props = []
92
- tree.children.each do |node|
93
- node.each do |prop|
94
- next if prop.class != Sass::Tree::PropNode
95
- name = prop.name[0]
96
- props << prop if name == prop_name
97
- end
98
- end
99
- props
100
- end
101
-
102
- def self.prop_position(prop)
103
- source_range = prop.source_range
104
- [source_range.start_pos, source_range.end_pos]
105
- end
106
-
107
- def self.property_defined?(tree, name)
108
- tree.children.each do |node|
109
- node.each do |prop|
110
- next if prop.class != Sass::Tree::PropNode
111
- next if prop.class == Sass::Tree::CommentNode
112
- return true if prop.name[0] == name
113
- end
114
- end
115
- false
116
- end
117
-
118
- def self.modify_in_ranges(line, line_number, start_range, end_range, value)
119
- if line_number < start_range.line || line_number > end_range.line
120
- line
121
- else
122
- tmp = ""
123
- if line_number == start_range.line
124
- tmp += line[0..(start_range.offset - 2)] + value_to_css_value(value)
125
- end
126
- tmp += line[(end_range.offset - 1)..-1] if line_number == end_range.line
127
- tmp
128
- end
129
- end
130
-
131
- def self.modify_property_value(file_content, property, value)
132
- start_range = property.value_source_range.start_pos
133
- end_range = property.value_source_range.end_pos
134
- tmp = ""
135
- line_number = 1
136
- file_content.each_line do |line|
137
- tmp += modify_in_ranges(line, line_number, start_range, end_range, value)
138
- line_number += 1
139
- end
140
- tmp
141
- end
142
-
143
- def self.modify_each_property_values(css_content, engine, prop)
144
- engine = engine
145
- tree = engine.to_tree
146
- props = props_with_name(tree, prop[:name])
147
- new_css = css_content
148
- (0..(props.size - 1)).each do |i|
149
- new_css = modify_property_value(new_css, props[i], prop[:value])
150
- engine = reload_engine(engine, new_css)
151
- tree = engine.to_tree
152
- props = props_with_name(tree, prop[:name])
153
- end
154
- new_css
155
- end
156
-
157
- def self.append_new_property_after_line(line, prop, indent)
158
- tmp = line.gsub(/\;[^\;]*$/, ";\n")
159
- new_prop = property_to_css_instructions(prop[:name], prop[:value])
160
- tmp += (indent + new_prop + (Regexp.last_match(0) || ";\n"))
161
- tmp
162
- end
163
-
164
- def self.last_child_which_is_not_comment(selector)
165
- son = nil
166
- selector.children.each do |child|
167
- son = child unless child.class == Sass::Tree::CommentNode
168
- end
169
- son
170
- end
171
-
172
- def self.compute_position_to_append(selector, element)
173
- indent = last_line = nil
174
- if element
175
- indent = " " * (element.name_source_range.start_pos.offset - 1) || ""
176
- last_line = element.value_source_range.end_pos.line
177
- else # If we don 't have any property in selector, use sel offset
178
- indent = " " * (selector.source_range.start_pos.offset - 1) || ""
179
- last_line = selector.source_range.start_pos.line
180
- end
181
- [indent, last_line]
182
- end
183
-
184
- def self.append_property_in_universal_selector(css_content, engine, prop)
185
- last_selector = selectors_with_name(engine.to_tree, "*").last
186
- last_prop = last_child_which_is_not_comment(last_selector)
187
- indent, last_line = compute_position_to_append(last_selector, last_prop)
188
- tmp = ""
189
- line_number = 1
190
- css_content.each_line do |line|
191
- if last_line == line_number
192
- tmp += append_new_property_after_line(line, prop, indent)
193
- else
194
- tmp += line
195
- end
196
- line_number += 1
197
- end
198
- tmp
199
- end
200
-
201
- def self.rule_node_name_is?(node, name)
202
- if node.rule.include?(name)
203
- true
204
- elsif node.parsed_rules.to_s == name
205
- true
206
- elsif node.resolved_rules == name
207
- true
208
- else
209
- false
210
- end
211
- end
212
-
213
- def self.selectors_with_name(tree, sel_name)
214
- selectors = []
215
- tree.children.each do |node|
216
- next unless node.class == Sass::Tree::RuleNode
217
- selectors << node if rule_node_name_is?(node, sel_name)
218
- end
219
- selectors
220
- end
221
-
222
- def self.update_css_with_new_property(content, engine, prop)
223
- if property_defined?(engine.to_tree, prop[:name])
224
- modify_each_property_values(content, engine, prop)
225
- else
226
- append_property_in_universal_selector(content, engine, prop)
227
- end
228
- end
229
-
230
- def self.update_css(filename, properties)
231
- engine = to_engine(filename)
232
- new_css = nil
233
- content = File.open(filename, "r").read
234
- properties.each do |prop|
235
- new_css = update_css_with_new_property(content, engine, prop)
236
- engine = reload_engine(engine, new_css)
237
- content = new_css
238
- end
239
- new_css
240
- end
241
- end
@@ -1,171 +0,0 @@
1
- # Copyright 2016 Cedric LE MOIGNE, cedlemo@gmx.com
2
- # This file is part of Topinambour.
3
- #
4
- # Topinambour is free software: you can redistribute it and/or modify
5
- # it under the terms of the GNU General Public License as published by
6
- # the Free Software Foundation, either version 3 of the License, or
7
- # any later version.
8
- #
9
- # Topinambour is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with Topinambour. If not, see <http://www.gnu.org/licenses/>.
16
-
17
- module TopinambourStyleProperties
18
- def generate_string_rw_property(name, args)
19
- GLib::Param::String.new(name.downcase,
20
- name.capitalize,
21
- name.upcase,
22
- args,
23
- GLib::Param::READABLE |
24
- GLib::Param::WRITABLE)
25
- end
26
-
27
- def generate_boolean_rw_property(name, args)
28
- GLib::Param::Boolean.new(name.downcase,
29
- name.capitalize,
30
- name.upcase,
31
- args,
32
- GLib::Param::READABLE |
33
- GLib::Param::WRITABLE)
34
- end
35
-
36
- def generate_int_rw_property(name, args)
37
- GLib::Param::Int.new(name.downcase,
38
- name.capitalize,
39
- name.upcase,
40
- *args,
41
- GLib::Param::READABLE |
42
- GLib::Param::WRITABLE)
43
- end
44
-
45
- def generate_enum_rw_property(name, args)
46
- GLib::Param::Enum.new(name.downcase,
47
- name.capitalize,
48
- name.upcase,
49
- *args,
50
- GLib::Param::READABLE |
51
- GLib::Param::WRITABLE)
52
- end
53
-
54
- def generate_boxed_rw_property(name, args)
55
- GLib::Param::Boxed.new(name.downcase,
56
- name.capitalize,
57
- name.upcase,
58
- args,
59
- GLib::Param::READABLE |
60
- GLib::Param::WRITABLE)
61
- end
62
-
63
- def generate_rw_property(type, name, args)
64
- type = type.to_s.downcase
65
- method_name = "generate_#{type}_rw_property"
66
- return false unless methods.include?(method_name.to_sym)
67
- method(method_name.to_sym).call(name, args)
68
- end
69
-
70
- def install_style(type, name, args)
71
- property = generate_rw_property(type, name, args)
72
- install_style_property(property) if property
73
- end
74
- end
75
-
76
- TERMINAL_COLOR_NAMES = [:foreground, :background, :black, :red, :green, :yellow,
77
- :blue, :magenta, :cyan, :white, :brightblack,
78
- :brightred, :brightgreen, :brightyellow, :brightblue,
79
- :brightmagenta, :brightcyan, :brightwhite
80
- ]
81
- DEFAULT_TERMINAL_COLORS = %w(#aeafad #323232 #000000 #b9214f #A6E22E #ff9800
82
- #3399ff #8e33ff #06a2dc #B0B0B0 #5D5D5D #ff5c8d
83
- #CDEE69 #ffff00 #9CD9F0 #FBB1F9 #77DFD8 #F7F7F7)
84
- DEFAULT_TERMINAL_FONT = "Monospace 11"
85
-
86
- class TopinambourTerminal < Vte::Terminal
87
- extend TopinambourStyleProperties
88
- type_register
89
- TERMINAL_COLOR_NAMES.each_with_index do |c|
90
- name = c.to_s
91
- install_style("boxed",
92
- name,
93
- GLib::Type["GdkRGBA"])
94
- end
95
- install_style("boxed", "font",
96
- GLib::Type["PangoFontDescription"])
97
- install_style("boolean", "audible-bell", false)
98
- install_style("boolean", "allow-bold", true)
99
- install_style("boolean", "scroll-on-output", true)
100
- install_style("boolean", "scroll-on-keystroke", true)
101
- install_style("boolean", "rewrap-on-resize", true)
102
- install_style("boolean", "mouse-autohide", true)
103
- install_style("enum", "cursor-shape", [GLib::Type["VteCursorShape"],
104
- Vte::CursorShape::BLOCK])
105
- install_style("enum", "cursor-blink-mode", [GLib::Type["VteCursorBlinkMode"],
106
- Vte::CursorBlinkMode::SYSTEM])
107
- install_style("enum", "backspace-binding", [GLib::Type["VteEraseBinding"],
108
- Vte::EraseBinding::AUTO])
109
- install_style("enum", "delete-binding", [GLib::Type["VteEraseBinding"],
110
- Vte::EraseBinding::AUTO])
111
- def load_properties
112
- %w(audible_bell allow_bold scroll_on_output scroll_on_keystroke
113
- rewrap_on_resize mouse_autohide).each do |prop|
114
- send("#{prop}=", style_get_property(prop.gsub(/_/,"-")))
115
- end
116
- %w(cursor_shape cursor_blink_mode backspace_binding delete_binding).each do |prop|
117
- send("#{prop}=", style_get_property(prop.gsub(/_/,"-")))
118
- end
119
- @colors = css_colors
120
- apply_colors
121
- set_font(css_font)
122
- end
123
-
124
- def parse_css_color(color_name)
125
- color_index = TERMINAL_COLOR_NAMES.index(color_name.to_sym)
126
- color_value = DEFAULT_TERMINAL_COLORS[color_index]
127
- default_color = Gdk::RGBA.parse(color_value)
128
- color_from_css = style_get_property(color_name)
129
- color = color_from_css ? color_from_css : default_color
130
- color
131
- end
132
-
133
- def css_colors
134
- colors = []
135
- background = parse_css_color(TERMINAL_COLOR_NAMES[0].to_s)
136
- foreground = parse_css_color(TERMINAL_COLOR_NAMES[1].to_s)
137
- TERMINAL_COLOR_NAMES[2..-1].each do |c|
138
- colors << parse_css_color(c.to_s)
139
- end
140
- [background, foreground] + colors
141
- end
142
-
143
- def css_font
144
- font = style_get_property("font")
145
- font = Pango::FontDescription.new(DEFAULT_TERMINAL_FONT) unless font
146
- font
147
- end
148
-
149
- def apply_colors
150
- set_colors(@colors[0], @colors[1], @colors[2..-1])
151
- end
152
- end
153
-
154
- class TopinambourWindow < Gtk::ApplicationWindow
155
- extend TopinambourStyleProperties
156
- type_register
157
- install_style("string", "shell", "/usr/bin/fish")
158
- install_style("int", "width", [-1, 2000, 1000])
159
- install_style("int", "height", [-1, 2000, 500])
160
-
161
- def load_properties
162
- _w, _h = self.size
163
- w = style_get_property("width")
164
- h = style_get_property("height")
165
- w = _w if w == -1
166
- h = _h if h == -1
167
- self.resize(w, h)
168
- self.set_default_size(w, h)
169
- @shell = style_get_property("shell")
170
- end
171
- end