themizer 0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/themizer.rb +177 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3372958d6e65407edac2be3db48203563f25a8e4
|
4
|
+
data.tar.gz: 7812ede3d4f58bafdb03037f36f0623d68178a4e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b86627d3296fbda93dbd41bc64033aec29aa06fe33ee7913aaeb01e1925a994779cf0c128e054df3c1e53034c8ebb3a0fac671e998f5f82d2cb1dfd1afca7618
|
7
|
+
data.tar.gz: 2e09d4261849854e4e74e65fc6f8af4f3eb344d0bcd6f41be6f3937778de22890b52a2f8a4a2da79ea71ad078450f3b0e3310e0657d4f2f50e32bb482dca7d29
|
data/lib/themizer.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
module Themizer
|
2
|
+
ARGUMENT_ERROR =
|
3
|
+
"Themizer: argument error in 'init(args)': "\
|
4
|
+
"args should be Hash, "\
|
5
|
+
"args should contain ':themes' key, "\
|
6
|
+
"args[:themes] should be Array of strings"
|
7
|
+
|
8
|
+
def init(args)
|
9
|
+
raise ARGUMENT_ERROR unless args.class == Hash
|
10
|
+
raise ARGUMENT_ERROR unless args[:themes]
|
11
|
+
raise ARGUMENT_ERROR unless args[:themes].class == Array
|
12
|
+
raise ARGUMENT_ERROR unless args[:themes].map { |e| e.to_s } == args[:themes]
|
13
|
+
@themes = args[:themes]
|
14
|
+
@debug = args[:debug] || false
|
15
|
+
end
|
16
|
+
|
17
|
+
def themize(action = :expand, theme = "\"\"", &block)
|
18
|
+
return unless block_given?
|
19
|
+
src_erb = _extract_block(block)
|
20
|
+
return unless src_erb
|
21
|
+
_debug(src_erb, "processing block")
|
22
|
+
src_sass = ERB.new(src_erb).result
|
23
|
+
|
24
|
+
case action
|
25
|
+
when :expand
|
26
|
+
maps, selectors = _mapize(src_sass)
|
27
|
+
src_sass_expanded = maps
|
28
|
+
unless selectors.strip.empty?
|
29
|
+
# if you add "\"\"" to @themes, sass won't compile
|
30
|
+
# because it cannot iterate through list with empty strings in it
|
31
|
+
# therefore, you have to process unthemed sass separately
|
32
|
+
src_sass_expanded << _expand_tilda(selectors, "\"\"")
|
33
|
+
|
34
|
+
# apply & sass operator
|
35
|
+
#
|
36
|
+
# ".form {
|
37
|
+
# ...
|
38
|
+
# }"
|
39
|
+
# =>
|
40
|
+
# "@each $theme in theme1, theme2 {
|
41
|
+
# #{$theme} { &
|
42
|
+
# ...
|
43
|
+
# }
|
44
|
+
# }"
|
45
|
+
src_sass_expanded << "\n@each $theme in #{@themes.join(', ')} {"
|
46
|
+
src_sass_expanded << ".\#{$theme} { & "
|
47
|
+
src_sass_expanded << _expand_tilda(selectors)
|
48
|
+
src_sass_expanded << "}}"
|
49
|
+
@themes.each do |theme|
|
50
|
+
src_sass_expanded.gsub!(".#{theme} body", "body.#{theme}")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
when :contract
|
55
|
+
src_sass_expanded = _contract_tilda(src_sass, theme)
|
56
|
+
end
|
57
|
+
|
58
|
+
_debug(src_sass_expanded, "resulting sass")
|
59
|
+
|
60
|
+
yield.gsub!(src_sass, src_sass_expanded)
|
61
|
+
end
|
62
|
+
|
63
|
+
def unthemize(theme = "\"\"", &block)
|
64
|
+
themize(:contract, theme, &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
# naive attempt to extract "themize do" block source
|
68
|
+
# considering there are probably other "do ... end" blocks inside;
|
69
|
+
def _extract_block(block)
|
70
|
+
src_file_path = block.source_location[0]
|
71
|
+
block_start_line_number = block.source_location[1]
|
72
|
+
|
73
|
+
src_file_content = File.open(src_file_path).read
|
74
|
+
lines_after_block_start = src_file_content.split("\n")[block_start_line_number..-1]
|
75
|
+
|
76
|
+
# block already starts with one "do"
|
77
|
+
do_counter = 1
|
78
|
+
# assuming that "do themize" and corresponding "end" placed on separate lines
|
79
|
+
block_end_index = 1
|
80
|
+
lines_after_block_start.each_with_index do |line, i|
|
81
|
+
# http://stackoverflow.com/a/11899069/6376451
|
82
|
+
do_counter += line.scan(/<%.*?do.*?%>/).size
|
83
|
+
do_counter -= line.scan(/<%.*?end.*?%>/).size
|
84
|
+
if line =~ /\s*<%\s*end\s*%>/ && do_counter == 0
|
85
|
+
block_end_index = i
|
86
|
+
break
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return nil if block_end_index == 0
|
90
|
+
|
91
|
+
lines_after_block_start[0..block_end_index-1].join("\n")
|
92
|
+
end
|
93
|
+
|
94
|
+
SASS_VAR_TILDA_IMPORTANT = /(?<sass_var>\$[^\s:~;]*)~(?<important>[^;]*);/
|
95
|
+
|
96
|
+
# expant tilda to if ... map-get
|
97
|
+
#
|
98
|
+
# "color: $form-color~;"
|
99
|
+
# =>
|
100
|
+
# "color: if(map-has-key($form-color, $theme), map-get($form-color, $theme), map-get($form-color, default));"
|
101
|
+
def _expand_tilda(sass, theme = "$theme", ending = ";")
|
102
|
+
# http://stackoverflow.com/a/28982676/6376451
|
103
|
+
sass.gsub(
|
104
|
+
SASS_VAR_TILDA_IMPORTANT,
|
105
|
+
"if("\
|
106
|
+
"map-has-key(\\k<sass_var>, #{theme}), "\
|
107
|
+
"map-get(\\k<sass_var>, #{theme}), "\
|
108
|
+
"map-get(\\k<sass_var>, \"\")"\
|
109
|
+
")\\k<important>#{ending}"
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
# reduce tilda to single map-get
|
114
|
+
#
|
115
|
+
# color: $form-color~;
|
116
|
+
# =>
|
117
|
+
# color: map-get($form-color, "\"\"");
|
118
|
+
def _contract_tilda(sass, theme)
|
119
|
+
sass.gsub(
|
120
|
+
SASS_VAR_TILDA_IMPORTANT,
|
121
|
+
"map-get(\\k<sass_var>, #{theme})\\k<important>;"
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
# expand sass vars denifitions with tildas into maps
|
126
|
+
#
|
127
|
+
# <% themize %>
|
128
|
+
# $table-border: $table-border-thickness solid $white~;
|
129
|
+
# .someclass { color: $table-border~; }
|
130
|
+
# <% end %>
|
131
|
+
# =>
|
132
|
+
# [
|
133
|
+
# "$table-border: (
|
134
|
+
# default: $table-border-thickness solid map-get($white, default);
|
135
|
+
# dark: $table-border-thickness solid map-get($white, dark);
|
136
|
+
# contrast: $table-border-thickness solid map-get($white, contrast);
|
137
|
+
# );",
|
138
|
+
# ".someclass { color: $table-border~; }"
|
139
|
+
# ]
|
140
|
+
def _mapize(sass)
|
141
|
+
maps = ""
|
142
|
+
|
143
|
+
# http://stackoverflow.com/a/18089658/6376451
|
144
|
+
expressions = sass.split(/(?<=[;])/).map { |e| e.strip }
|
145
|
+
themes_expanded = ["\"\""] + @themes
|
146
|
+
expressions.each_with_index do |expression, i|
|
147
|
+
if expression =~ /^(?<map_name>\$.*):(?<map_value>.*;)/
|
148
|
+
maps << "#{Regexp.last_match(:map_name)}: ("
|
149
|
+
themes_expanded.each do |theme|
|
150
|
+
maps << "#{theme}: #{_expand_tilda(Regexp.last_match(:map_value), theme, ',')}"
|
151
|
+
end
|
152
|
+
maps << ");"
|
153
|
+
expressions[i].clear
|
154
|
+
end
|
155
|
+
end
|
156
|
+
selectors = expressions
|
157
|
+
.map { |e| e.strip }
|
158
|
+
.reject { |e| e.empty? }
|
159
|
+
.join("\n")
|
160
|
+
|
161
|
+
[maps, selectors]
|
162
|
+
end
|
163
|
+
|
164
|
+
def _debug(message, description)
|
165
|
+
if @debug
|
166
|
+
puts "\n##########################################"
|
167
|
+
puts "# begin Themizer #{description}"
|
168
|
+
puts "\n\n#{message}\n\n"
|
169
|
+
puts "# end Themizer #{description}"
|
170
|
+
puts "##########################################\n"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
module_function :init, :themize, :unthemize,
|
175
|
+
:_mapize, :_expand_tilda, :_contract_tilda, :_extract_block, :_debug
|
176
|
+
private_class_method :_mapize, :_expand_tilda, :_contract_tilda, :_extract_block, :_debug
|
177
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: themizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.9'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Morozov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ruby_expect
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
description: Provides methods which expands you regular SASS in rails into themed
|
28
|
+
one using & operator and other cool SASS features.
|
29
|
+
email: ntcomp12@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- lib/themizer.rb
|
35
|
+
homepage: https://github.com/kengho/themizer
|
36
|
+
licenses:
|
37
|
+
- MIT
|
38
|
+
metadata: {}
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 2.5.2
|
56
|
+
signing_key:
|
57
|
+
specification_version: 4
|
58
|
+
summary: Gem for producing themed css from scss.erb
|
59
|
+
test_files: []
|