themizer 0.9
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.
- 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: []
|