topinambour 1.0.11 → 1.0.12

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/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