sass2stylus 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fae9a9dea69f31f1999c91b863e94dcb3aef9458
4
+ data.tar.gz: 1aee6050e16553358bc375e74f4671116009352e
5
+ SHA512:
6
+ metadata.gz: a6c36c4a333353e8f6f2c78d5408e1c62773855e7245d5866b59d648fc8ec20759af164098c79b57fae90f90873f313b082b237622f4ee2a234b8e3523392704
7
+ data.tar.gz: eeca69753143a0ee8b97e6cf21e93e2b9941593cabfe27d39bc9638fb35f0c1d28a8dc80772f0c5937cabc467a2c87c4bf32301d6311f7c5d74e294787581a7e
@@ -0,0 +1,20 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.sass-cache
16
+ .sass-cache
17
+ .DS_Store
18
+ *.scss
19
+ *.sass
20
+ *.styl
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sass2stylus.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Paul C Pederson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ # Sass2stylus
2
+
3
+ Convert any number of sass files to stylus files in a ruby script or on the command line. If you're looking for an online option, you should use [sass2stylus.com](http://sass2stylus.com/). This project is essentially an all-ruby version of [@mojotech's work](https://github.com/mojotech/sass2stylus/) meant to be used on the command line.
4
+
5
+ ## Installation
6
+
7
+ To use Sass2Stylus as a command line utility, install the gem:
8
+
9
+ ```bash
10
+ $ gem install sass2stylus
11
+ ```
12
+
13
+ To use in your ruby project, add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'sass2stylus'
17
+ ```
18
+
19
+ And then install with your other dependencies:
20
+
21
+ ```bash
22
+ $ bundle install
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```bash
28
+ $ sass2stylus sass/folder/**/*.scss stylus/folder
29
+ ```
30
+
31
+ First argument is a glob-formatted pattern which explains where the sass files are. These can be `.sass` or `.scss` files. Use the `**` pattern to recursively search a directory for sass files.
32
+
33
+ The second argument is a folder where you'd like to dump the generated stylus files. **Note** The folder structure of the sass folder will be preserved in the stylus folder.
34
+
35
+ ## Usage in Ruby Project
36
+
37
+ To use this gem in a ruby project, just import it and set up a new instance of the `Sass2stylus::Utitlities` class and pass a blob of sass files into stylus by calling:
38
+
39
+ ```ruby
40
+ require 'sass2stylus'
41
+ util = Sass2stylus::Utilities.new
42
+ util.batch(Pathname.pwd, '**/*.scss', 'stylus')
43
+ ```
44
+
45
+ Pass in the base directory, the path to the sass files, and the relative path to the folder you'd like to use for output. (If you supply a folder that doesn't exist, the script will make it for you.)
46
+
47
+ ## Contributing
48
+
49
+ 1. Fork it ( https://github.com/paulcpederson/sass2stylus/fork )
50
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
51
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
52
+ 4. Push to the branch (`git push origin my-new-feature`)
53
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sass2stylus'
4
+
5
+ if ARGV.length < 2
6
+ puts "You must pass a glob and a output folder."
7
+ puts "Example: sass2stylus **/*.scss styl"
8
+ exit
9
+ end
10
+
11
+ util = Sass2stylus::Utilities.new
12
+ util.batch(Pathname.pwd, ARGV[0], ARGV[1])
@@ -0,0 +1,57 @@
1
+ require "sass2stylus/version"
2
+ require "sass2stylus/stylus"
3
+ require "sass"
4
+
5
+ module Sass2stylus
6
+
7
+ class Utilities
8
+
9
+ def write_file(raw, sass_path, styl_path)
10
+
11
+ FileUtils.mkdir_p styl_path.to_s + File.dirname(raw).to_s
12
+ full_path = styl_path.to_s + raw.to_s + '.styl'
13
+
14
+ File.open(full_path, 'w+') { |f|
15
+ f.puts(ToStylus::convert(sass_path))
16
+ }
17
+
18
+ end
19
+
20
+ # Accepts a sass file and returns a stylus file
21
+ def s2s(directory, filename, styl_dir)
22
+
23
+ raw_filename = filename.gsub(directory.to_s, '').gsub('.scss', '').gsub('.sass', '')
24
+ sass_file = filename.gsub('.scss', '.sass')
25
+
26
+ if filename.include? ".scss"
27
+ `sass-convert #{filename} #{sass_file}`
28
+ write_file(raw_filename, sass_file, styl_dir)
29
+ File.delete(sass_file)
30
+ elsif filename.include? ".sass"
31
+ write_file(raw_filename, sass_file, styl_dir)
32
+ else
33
+ puts "#{filname} is not a sass file"
34
+ puts "You can specify that in your glob: sass2stylus *.scss"
35
+ end
36
+
37
+ end
38
+
39
+ # Accepts a base file path, a glob pattern, and a folder name (relative) for output
40
+ def batch(base, pattern, styl)
41
+
42
+ glob = Dir.glob(base + pattern)
43
+
44
+ if glob.empty?
45
+ puts "The pattern '#{pattern}' didn't match any sass files."
46
+ puts "Use globs like: sass2stylus **/*.scss styl"
47
+ else
48
+ glob.each do |file|
49
+ s2s(base, file, base + styl)
50
+ end;
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,36 @@
1
+ disabled_functions:
2
+ - adjust-color
3
+ - adjust-hue
4
+ - append
5
+ - call
6
+ - change-color
7
+ - comparable
8
+ - fade-in
9
+ - fade-out
10
+ - feature-exists
11
+ - function-exists
12
+ - global-variable-exists
13
+ - ie-hex-str
14
+ - index
15
+ - keywords
16
+ - list-separator
17
+ - map-get
18
+ - map-remove
19
+ - mixin-exists
20
+ - nth
21
+ - opacify
22
+ - percentage
23
+ - quote
24
+ - random
25
+ - scale-color
26
+ - str-index
27
+ - str-insert
28
+ - str-length
29
+ - str-slice
30
+ - to-lower-case
31
+ - to-upper-case
32
+ - transparentize
33
+ - unique-id
34
+ - unitless
35
+ - variable-exists
36
+ - zip
@@ -0,0 +1,276 @@
1
+ #!/usr/bin/env ruby
2
+ # Convert SASS/SCSS to Stylus
3
+ # Initial work by Andrey Popp (https://github.com/andreypopp)
4
+
5
+ require 'sass'
6
+ require 'yaml'
7
+
8
+ class ToStylus < Sass::Tree::Visitors::Base
9
+ @@functions = YAML::load_file(File.join(__dir__ , 'functions.yml'))
10
+
11
+ def self.convert(file)
12
+ engine = Sass::Engine.for_file(file, {})
13
+
14
+ tree = engine.to_tree
15
+ visit(tree)
16
+ end
17
+
18
+ def visit(node)
19
+ if self.class.respond_to? :node_name
20
+ method = "visit_#{node.class.node_name}"
21
+ else
22
+ method = "visit_#{node_name node}"
23
+ end
24
+ return if node.is_a?(Sass::Tree::CharsetNode)
25
+ if self.respond_to?(method, true)
26
+ self.send(method, node) {visit_children(node)}
27
+ else
28
+ if self.class.respond_to? :node_name
29
+ raise "unhandled node: '#{node.class.node_name}'"
30
+ else
31
+ raise "unhandled node: '#{node_name node}'"
32
+ end
33
+ end
34
+ end
35
+
36
+ def visit_children(node)
37
+ @indent += 1
38
+ super(node)
39
+ @indent -= 1
40
+ end
41
+
42
+ def determine_support(node, is_value)
43
+ is_value ? (node_class = node.value) : (node_class = node.expr)
44
+ if node_class.is_a? Sass::Script::Tree::Funcall
45
+ @@functions['disabled_functions'].each do |func|
46
+ if !node_class.inspect.match(func.to_s).nil?
47
+ @errors.push("//#{func}: line #{node.line} in your Sass file")
48
+ emit "//Function #{func} is not supported in Stylus"
49
+ return func
50
+ end
51
+ end
52
+ return
53
+ end
54
+ end
55
+
56
+ def visit_prop(node, output="")
57
+ func_support = determine_support(node, true)
58
+ if !node.children.empty?
59
+ output << "#{node.name.join('')}-"
60
+ unless node.value.to_sass.empty?
61
+ #for nested scss with values, change the last "-" in the output to a ":" to format output correctly
62
+ if node.value.is_a? Sass::Script::Tree::Operation
63
+ func_output = "#{output}(#{node.value.to_sass})".sub(/(.*)-/, '\1: ').gsub("\#{","{")
64
+ elsif node.value.is_a?(Sass::Script::Tree::UnaryOperation) && node.value.operator.to_s == 'minus'
65
+ func_output = "#{output}".sub(/(.*)-/, '\1: ') <<"-1*#{node.value.operand.inspect}".gsub("\#{","{")
66
+ else
67
+ func_output = "#{output}#{node.value.to_sass}".sub(/(.*)-/, '\1: ').gsub("\#{","{")
68
+ end
69
+ func_support.nil? ? (emit func_output) : (emit "//" << func_output)
70
+ end
71
+ node.children.each do |child|
72
+ visit_prop(child,output)
73
+ end
74
+ else
75
+ unless node.is_a? Sass::Tree::CommentNode
76
+ "#{node.name.join("")[0]}" == "#" ?
77
+ node_name = "#{output}{#{node.name-[""]}}:".tr('[]','') : node_name = "#{output}#{node.name.join('')}:"
78
+
79
+ if node.value.is_a? Sass::Script::Tree::Operation
80
+ func_output = node_name << " (#{node.value.to_sass})".gsub("\#{", "{")
81
+ elsif node.value.is_a?(Sass::Script::Tree::UnaryOperation) && node.value.operator.to_s == 'minus'
82
+ func_output = node_name << " -1*#{node.value.operand.inspect}"
83
+ else
84
+ func_output = node_name << " #{node.value.to_sass}".gsub("\#{", "{")
85
+ end
86
+ func_support.nil? ? (emit func_output) : (emit "//" << func_output)
87
+ else
88
+ visit(node)
89
+ end
90
+ end
91
+ end
92
+
93
+ def visit_variable(node)
94
+ func_support = determine_support(node, false)
95
+ output = "$#{node.name} = #{node.expr.to_sass}"
96
+ func_support.nil? ? (emit output) : (emit "//" << output)
97
+ end
98
+
99
+ def render_arg(arg)
100
+ if arg.is_a? Array
101
+ var = arg[0]
102
+ default = arg[1]
103
+ if default
104
+ "#{arg[0].to_sass} = #{arg[1].to_sass}"
105
+ else
106
+ var.to_sass
107
+ end
108
+ else
109
+ arg.to_sass
110
+ end
111
+ end
112
+
113
+ def render_args(args)
114
+ args.map { |a| render_arg(a) }.join(', ')
115
+ end
116
+
117
+ def emit(line)
118
+ line = (' ' * @indent) + line
119
+ @lines.push line
120
+ end
121
+
122
+ def visit_if(node, isElse = false)
123
+ line = []
124
+ line.push 'else' if isElse
125
+ line.push "if #{node.expr.to_sass}" if node.expr
126
+ emit line.join(' ')
127
+ visit_children(node)
128
+ visit_if(node.else, true) if node.else
129
+ end
130
+
131
+ def visit_return(node)
132
+ func_support = determine_support(node, false)
133
+ output = node.expr.to_sass
134
+ func_support.nil? ? (emit output) : (emit "//" << output)
135
+ end
136
+
137
+ def visit_comment(node)
138
+ node.invisible? ? lines = node.to_sass.lines : lines = node.value.first.split("\n")
139
+ lines.each { |line| emit line.tr("\n", "")}
140
+ end
141
+
142
+ def visit_mixindef(node)
143
+ emit "#{node.name}(#{render_args(node.args)})"
144
+ visit_children node
145
+ end
146
+
147
+ def visit_media(node)
148
+ emit "@media #{node.query.map{|i| i.inspect}.join}".gsub! /"/, ""
149
+ visit_children node
150
+ end
151
+
152
+ def visit_content(node)
153
+ emit '{block}'
154
+ end
155
+
156
+ def visit_mixin(node)
157
+ emit "#{node.name}(#{render_args(node.args)})"
158
+ end
159
+
160
+ def visit_import(node)
161
+ emit "@import '#{node.imported_filename}'"
162
+ end
163
+
164
+ def visit_cssimport(node)
165
+ if node.to_sass.include?("http://") && !node.to_sass.include?("url")
166
+ emit "@import url(#{node.uri})"
167
+ elsif(node.to_sass.index("\"http") || node.to_sass.index("\'http"))
168
+ emit "#{node.to_sass}".chomp!
169
+ elsif(node.to_sass.index("http"))
170
+ emit "@import #{node.uri}".gsub("(", "(\"").gsub(")", "\")")
171
+ else
172
+ emit "#{node.to_sass}".chomp!
173
+ end
174
+ end
175
+
176
+ def visit_extend(node)
177
+ emit "#{node.to_sass}".gsub("%","$").chomp!
178
+ end
179
+
180
+ def visit_function(node)
181
+ if node.splat.nil?
182
+ emit "#{node.name}(#{render_args(node.args)})"
183
+ else
184
+ node.args.push([node.splat, nil])
185
+ emit "#{node.name}(#{render_args(node.args)}...)"
186
+ end
187
+ visit_children node
188
+ end
189
+
190
+ def visit_rule(node)
191
+ rule = (node.rule.length == 1 && node.rule[0].is_a?(String)) ? node.rule[0] : node.to_sass.lines[0]
192
+ emit "#{rule}".gsub("\#{", "{").gsub("%", "$").chomp
193
+ visit_children node
194
+ end
195
+
196
+ def for_helper(node, from_or_to)
197
+ @@functions['disabled_functions'].each do |func|
198
+ unless (from_or_to).inspect.match(func.to_s).nil?
199
+ @errors.push("//#{func}: line #{node.line} in your Sass file")
200
+ emit "//Function #{func} is not supported in Stylus"
201
+ end
202
+ end
203
+ end
204
+
205
+ def visit_for(node)
206
+ (node.from.is_a? Sass::Script::Tree::Funcall) ? for_helper(node, node.from) : nil
207
+ from = node.from.to_sass
208
+
209
+ (node.to.is_a? Sass::Script::Tree::Funcall) ? for_helper(node, node.to) : nil
210
+ temp_to = node.to.to_sass
211
+
212
+ (node.to.is_a? Sass::Script::Tree::Literal) ? exclusive_to = temp_to.to_i - 1 : exclusive_to = "(#{temp_to}) - 1"
213
+ node.exclusive ? to = exclusive_to : to = temp_to
214
+
215
+ emit "for $#{node.var} in (#{from})..(#{to})"
216
+ visit_children node
217
+ end
218
+
219
+ def visit_directive(node)
220
+ emit "#{node.name}"
221
+ visit_children node
222
+ end
223
+
224
+ def comment_out(node)
225
+ node.to_sass.lines.each {|l| emit "//#{l}".chomp }
226
+ end
227
+
228
+ def visit_each(node)
229
+ if node.vars.length == 1
230
+ emit "for $#{node.vars.first} in #{node.list.to_sass}".gsub(",","")
231
+ visit_children node
232
+ else
233
+ emit "//Cannot convert multi-variable each loops to Stylus"
234
+ @errors.push("// @each: line #{node.line} in your Sass file")
235
+ comment_out(node)
236
+ end
237
+ end
238
+
239
+ def visit_while(node)
240
+ emit "//Stylus does not support while loops"
241
+ @errors.push("// @while: line #{node.line} in your Sass file")
242
+ comment_out(node)
243
+ end
244
+
245
+ def visit_atroot(node)
246
+ emit "//Stylus does not support @at-root"
247
+ @errors.push("// @at-root: line #{node.line} in your Sass file")
248
+ comment_out(node)
249
+ end
250
+
251
+ def visit_debug(node)
252
+ emit "//Stylus does not support @debug"
253
+ @errors.push("// @debug: line #{node.line} in your Sass file")
254
+ comment_out(node)
255
+ end
256
+
257
+ def visit_warn(node)
258
+ emit "//Stylus does not support @warn"
259
+ @errors.push("// @warn: line #{node.line} in your Sass file")
260
+ comment_out(node)
261
+ end
262
+
263
+ def visit_root(node)
264
+ @indent = -1
265
+ @errors = []
266
+ @lines = []
267
+ visit_children(node)
268
+ unless @errors.empty?
269
+ @errors.unshift("//Below is a list of the Sass rules that could not be converted to Stylus")
270
+ @errors.push("\n")
271
+ @lines.unshift(*@errors)
272
+ end
273
+ @lines.join("\n")
274
+ end
275
+
276
+ end
@@ -0,0 +1,3 @@
1
+ module Sass2stylus
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sass2stylus/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sass2stylus"
8
+ spec.version = Sass2stylus::VERSION
9
+ spec.authors = ["Paul C Pederson"]
10
+ spec.email = ["paul.c.pederson@gmail.com"]
11
+ spec.summary = %q{Convert Sass to Stylus}
12
+ spec.description = %q{Convert any number of sass files to stylus files in a ruby script or on the command line.}
13
+ spec.homepage = "https://github.com/paulcpederson/sass2stylus"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = ["sass2stylus"]
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_runtime_dependency "sass", '3.4.9'
24
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sass2stylus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Paul C Pederson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sass
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.4.9
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.4.9
55
+ description: Convert any number of sass files to stylus files in a ruby script or
56
+ on the command line.
57
+ email:
58
+ - paul.c.pederson@gmail.com
59
+ executables:
60
+ - sass2stylus
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/sass2stylus
70
+ - lib/sass2stylus.rb
71
+ - lib/sass2stylus/functions.yml
72
+ - lib/sass2stylus/stylus.rb
73
+ - lib/sass2stylus/version.rb
74
+ - sass2stylus.gemspec
75
+ homepage: https://github.com/paulcpederson/sass2stylus
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.4.1
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Convert Sass to Stylus
99
+ test_files: []