sassmagic 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/Readme.md CHANGED
@@ -15,6 +15,7 @@ sudo gem install sassmagic
15
15
 
16
16
  same to sass
17
17
 
18
+ eg: sassmagic --style nested --x test.scss test.css
18
19
 
19
20
  ### configuration
20
21
 
@@ -41,7 +42,8 @@ sassmagic.json 配置文件:
41
42
  "imageLoader": "imageuploader.js",
42
43
  "imagesPath": {
43
44
  },
44
- "remote":[]
45
+ "remoteStylesheet":"",
46
+ "tinypngKye",""
45
47
  }
46
48
 
47
49
  imageuploader.js
data/bin/sassmagic CHANGED
@@ -11,6 +11,7 @@ require 'sass/exec'
11
11
  require 'sassmagic/remote'
12
12
  require 'sassmagic/utils'
13
13
  require 'sassmagic/reset'
14
+ require 'sassmagic/installer'
14
15
  # require 'debugger'
15
16
 
16
17
 
@@ -29,6 +30,7 @@ class Engine
29
30
  end
30
31
  end
31
32
 
33
+ isneedcompile = true
32
34
  multiple = false
33
35
  # debugger
34
36
  # ARGV.each{|v|
@@ -37,18 +39,29 @@ multiple = false
37
39
  # end
38
40
  # }
39
41
 
42
+ if ARGV.include?'init'
43
+ Sassmagic::Installers::Base.new
44
+ isneedcompile = false
45
+ end
46
+
47
+ if ARGV.include?'creat'
48
+ Sassmagic::Installers::Base.new(ARGV[-1])
49
+ isneedcompile = false
50
+ end
51
+
40
52
  if ARGV.include?'--x'
41
53
  multiple = true
42
54
  end
43
55
 
44
56
 
45
57
  # Engine.new.go
46
- if multiple
47
- Engine.new.go
48
- else
49
- opts = Sass::Exec::SassScss.new(ARGV, :sass)
50
- opts.parse!
58
+ if isneedcompile
59
+ if multiple
60
+ Engine.new.go
61
+ else
62
+ opts = Sass::Exec::SassScss.new(ARGV, :sass)
63
+ opts.parse!
64
+ end
51
65
  end
52
66
 
53
67
 
54
-
@@ -0,0 +1,27 @@
1
+ var uploader = require('@ali/or-uploadimg');
2
+ var fs = require('fs');
3
+ var path = require('path');
4
+ var file = process.argv[2]
5
+ var imgList = process.argv[3] || []
6
+
7
+ fs.readFile(file, 'utf8', function(err, data) {
8
+ if(err) {
9
+ return console.log(err);
10
+ }
11
+ var config = JSON.parse(data);
12
+ config.imagesPath = config.imagesPath || {}
13
+ uploader(imgList, function (list) {
14
+ list.forEach(function(v,i){
15
+ for(var i in v){
16
+ config.imagesPath[i] = v[i].replace(/^https?:\/\//,'//')
17
+ }
18
+ })
19
+ //写文件
20
+ fs.writeFile(file, JSON.stringify(config,null,4), function(err) {
21
+ if(err) {
22
+ return console.log(err);
23
+ }
24
+ //console.log('writing done');
25
+ })
26
+ });
27
+ })
@@ -0,0 +1,16 @@
1
+ {
2
+ "isNeedPxToRem": true,
3
+ "browserDefaultFontSize": "75px",
4
+ "devicePixelRatio":"2",
5
+ "ignore": [
6
+ ],
7
+ "outputExtra": [
8
+ ],
9
+ "imageMaxSize": "",
10
+ "imageLoader": "../config/imageuploader.js",
11
+ "imagesPath": {
12
+
13
+ },
14
+ "remoteStylesheet": "",
15
+ "tinypngKye": "_opLq9BVg-AHRQn0Fh0WNapWX83K6gmH"
16
+ }
@@ -0,0 +1,301 @@
1
+ module Sassmagic
2
+ module Installers
3
+ class Base
4
+ # debugger
5
+ def initialize(projectname = '')
6
+ # Dir.mkdir("directory")
7
+ # txt = File.open("directory/a.txt","w+")
8
+ # txt.puts("hello world")
9
+ # txt.close
10
+ if projectname != ''
11
+ projectname ="#{projectname}/"
12
+ end
13
+ directory "#{projectname}sass"
14
+ directory "#{projectname}config"
15
+ directory "#{projectname}stylesheet"
16
+ directory "#{projectname}image"
17
+
18
+ # write_file 'a.txt','hi'
19
+ copy File.expand_path("#{File.dirname(__FILE__)}/config/imageuploader.js"),File.expand_path("#{Dir::pwd}/#{projectname}/config/imageuploader.js")
20
+ copy File.expand_path("#{File.dirname(__FILE__)}/config/sassmagic.json"),File.expand_path("#{Dir::pwd}/#{projectname}/config/sassmagic.json")
21
+ finalize
22
+ end
23
+ attr_writer :logger
24
+
25
+ def logger
26
+ @logger ||= Logger.new
27
+ end
28
+ # copy/process a template in the compass template directory to the project directory.
29
+ def copy(from, to, options = nil, binary = false)
30
+ options ||= self.options if self.respond_to?(:options)
31
+ if binary
32
+ contents = File.new(from,"rb").read
33
+ else
34
+ contents = File.new(from).read
35
+ end
36
+ write_file to, contents, options, binary
37
+ end
38
+
39
+ # create a directory and all the directories necessary to reach it.
40
+ def directory(dir, options = nil)
41
+ options ||= self.options if self.respond_to?(:options)
42
+ options ||= {}
43
+ if File.exists?(dir) && File.directory?(dir)
44
+ # do nothing
45
+ elsif File.exists?(dir)
46
+ msg = "#{basename(dir)} already exists and is not a directory."
47
+ raise Compass::FilesystemConflict.new(msg)
48
+ else
49
+ log_action :directory, separate("#{basename(dir)}/"), options
50
+ FileUtils.mkdir_p(dir)
51
+ end
52
+ end
53
+
54
+ # Write a file given the file contents as a string
55
+ def write_file(file_name, contents, options = nil, binary = false)
56
+ options ||= self.options if self.respond_to?(:options)
57
+ options ||= {}
58
+ skip_write = false
59
+ # debugger
60
+ # contents = process_erb(contents, options[:erb]) if options[:erb]
61
+ if File.exists?(file_name)
62
+ existing_contents = IO.read(file_name)
63
+ if existing_contents == contents
64
+ log_action :identical, basename(file_name), options
65
+ skip_write = true
66
+ elsif options[:force]
67
+ log_action :overwrite, basename(file_name), options
68
+ else
69
+ msg = "File #{basename(file_name)} already exists. Run with --force to force overwrite."
70
+ raise puts(msg)
71
+ end
72
+ else
73
+ log_action :create, basename(file_name), options
74
+ end
75
+ if skip_write
76
+ FileUtils.touch file_name
77
+ else
78
+ mode = "w"
79
+ mode << "b" if binary
80
+ open(file_name, mode) do |file|
81
+ file.write(contents)
82
+ end
83
+ end
84
+ end
85
+
86
+ def process_erb(contents, ctx = nil)
87
+ ctx = Object.new.instance_eval("binding") unless ctx.is_a? Binding
88
+ ERB.new(contents).result(ctx)
89
+ end
90
+
91
+ def remove(file_name)
92
+ file_name ||= ''
93
+ if File.directory?(file_name)
94
+ FileUtils.rm_rf file_name
95
+ log_action :remove, basename(file_name)+"/", options
96
+ elsif File.exists?(file_name)
97
+ File.unlink file_name
98
+ log_action :remove, basename(file_name), options
99
+ end
100
+ end
101
+
102
+ def basename(file)
103
+ relativize(file) {|f| File.basename(file)}
104
+ end
105
+
106
+ def relativize(path)
107
+ path = File.expand_path(path)
108
+ if block_given?
109
+ yield path
110
+ else
111
+ path
112
+ end
113
+ end
114
+
115
+ # Write paths like we're on unix and then fix it
116
+ def separate(path)
117
+ path.gsub(%r{/}, File::SEPARATOR)
118
+ end
119
+
120
+ # Removes the trailing separator, if any, from a path.
121
+ def strip_trailing_separator(path)
122
+ (path[-1..-1] == File::SEPARATOR) ? path[0..-2] : path
123
+ end
124
+
125
+ def log_action(action, file, options)
126
+ quiet = !!options[:quiet]
127
+ quiet = false if options[:loud] && options[:loud] == true
128
+ quiet = false if options[:loud] && options[:loud].is_a?(Array) && options[:loud].include?(action)
129
+ unless quiet
130
+ logger.record(action, file, options[:extra].to_s)
131
+ end
132
+ end
133
+
134
+
135
+ def finalize(options = {})
136
+ puts <<-NEXTSTEPS
137
+
138
+ *********************************************************************
139
+ Congratulations! Your compass project has been created.
140
+
141
+ You may now add sass stylesheets to the sass subdirectory of your project.
142
+
143
+ Sass files beginning with an underscore are called partials and won't be
144
+ compiled to CSS, but they can be imported into other sass stylesheets.
145
+
146
+ You can configure your project by editing the config.rb configuration file.
147
+
148
+ You must compile your sass stylesheets into CSS when they change.
149
+ This can be done in one of the following ways:
150
+ 1. To compile on demand:
151
+ sassmagic --x [input] [output]
152
+
153
+ More Resources:
154
+
155
+ NEXTSTEPS
156
+ end
157
+
158
+
159
+
160
+ end
161
+
162
+ # logger
163
+ class Logger
164
+
165
+ COLORS = { :clear => 0, :red => 31, :green => 32, :yellow => 33, :blue => 34 }
166
+
167
+ ACTION_COLORS = {
168
+ :error => :red,
169
+ :warning => :yellow,
170
+ :info => :green,
171
+ :compile => :green,
172
+ :overwrite => :yellow,
173
+ :modified => :yellow,
174
+ :clean => :yellow,
175
+ :write => :green,
176
+ :create => :green,
177
+ :remove => :yellow,
178
+ :delete => :yellow,
179
+ :deleted => :yellow,
180
+ :created => :yellow,
181
+ :exists => :green,
182
+ :directory => :green,
183
+ :identical => :green,
184
+ :convert => :green,
185
+ :unchanged => :yellow
186
+ }
187
+
188
+ DEFAULT_ACTIONS = ACTION_COLORS.keys
189
+
190
+ ACTION_CAN_BE_QUIET = {
191
+ :error => false,
192
+ :warning => true,
193
+ :info => true,
194
+ :compile => true,
195
+ :overwrite => true,
196
+ :modified => true,
197
+ :clean => true,
198
+ :write => true,
199
+ :create => true,
200
+ :remove => true,
201
+ :delete => true,
202
+ :deleted => true,
203
+ :created => true,
204
+ :exists => true,
205
+ :directory => true,
206
+ :identical => true,
207
+ :convert => true,
208
+ :unchanged => true
209
+ }
210
+
211
+ attr_accessor :actions, :options, :time
212
+
213
+ def initialize(*actions)
214
+ self.options = actions.last.is_a?(Hash) ? actions.pop : {}
215
+ @actions = DEFAULT_ACTIONS.dup
216
+ @actions += actions
217
+ end
218
+
219
+ # Record an action that has occurred
220
+ def record(action, *arguments)
221
+ return if options[:quiet] && ACTION_CAN_BE_QUIET[action]
222
+ msg = ""
223
+ if time
224
+ msg << Time.now.strftime("%I:%M:%S.%3N %p")
225
+ end
226
+ msg << color(ACTION_COLORS[action])
227
+ msg << "#{action_padding(action)}#{action}"
228
+ msg << color(:clear)
229
+ msg << " #{arguments.join(' ')}"
230
+ log msg
231
+ end
232
+
233
+ def green
234
+ wrap(:green) { yield }
235
+ end
236
+
237
+ def red
238
+ wrap(:red) { yield }
239
+ end
240
+
241
+ def yellow
242
+ wrap(:yellow) { yield }
243
+ end
244
+
245
+ def wrap(c, reset_to = :clear)
246
+ $stderr.write(color(c))
247
+ $stdout.write(color(c))
248
+ yield
249
+ ensure
250
+ $stderr.write(color(reset_to))
251
+ $stdout.write(color(reset_to))
252
+ $stdout.flush
253
+ end
254
+
255
+ def color(c)
256
+ if c && COLORS.has_key?(c.to_sym)
257
+ if defined?($boring) && $boring
258
+ ""
259
+ else
260
+ "\e[#{COLORS[c.to_sym]}m"
261
+ end
262
+ else
263
+ ""
264
+ end
265
+ end
266
+
267
+ # Emit a log message without a trailing newline
268
+ def emit(msg)
269
+ print msg
270
+ $stdout.flush
271
+ end
272
+
273
+ # Emit a log message with a trailing newline
274
+ def log(msg)
275
+ puts msg
276
+ $stdout.flush
277
+ end
278
+
279
+ # add padding to the left of an action that was performed.
280
+ def action_padding(action)
281
+ ' ' * [(max_action_length - action.to_s.length), 0].max
282
+ end
283
+
284
+ # the maximum length of all the actions known to the logger.
285
+ def max_action_length
286
+ @max_action_length ||= actions.inject(0){|memo, a| [memo, a.to_s.length].max}
287
+ end
288
+ end
289
+
290
+ class NullLogger < Logger
291
+ def record(*args)
292
+ end
293
+
294
+ def log(msg)
295
+ end
296
+
297
+ def emit(msg)
298
+ end
299
+ end
300
+ end
301
+ end
@@ -141,13 +141,14 @@ module Sass
141
141
  # print 'star compile file:'
142
142
  #加载json
143
143
  # 获取设置
144
- $configHash = ctx.load_json(File.expand_path("#{File.dirname(filename)}/sassmagic.json")) || {}
144
+ $configHash = ctx.load_json(File.expand_path("#{File.dirname(filename)}/../config/sassmagic.json")) || {}
145
145
  # puts $configHash
146
146
  options = args.last.is_a?(Hash) ? args.pop : {}
147
147
  options = options.merge $configHash
148
148
  css_filename = args.shift
149
149
  #是否写入loadpath
150
- if options.has_key?"remoteStylesheet"
150
+ # debugger
151
+ if (options.has_key?"remoteStylesheet") && (options["remoteStylesheet"] != '')
151
152
  RemoteSass.location = options["remoteStylesheet"]
152
153
  end
153
154
  #
@@ -438,6 +439,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
438
439
  end
439
440
  #属性重写开始
440
441
  def visit_prop(node)
442
+ # debugger
441
443
  opt = node.options
442
444
  if $configHash == nil || $configHash == {}
443
445
  #读取配置文件
@@ -445,7 +447,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
445
447
  #加载json
446
448
  # 获取设置
447
449
  filename = opt[:filename] || ''
448
- $configHash = ctx.load_json(File.expand_path("#{File.dirname(filename)}/sassmagic.json")) || {}
450
+ $configHash = ctx.load_json(File.expand_path("#{File.dirname(filename)}/../config/sassmagic.json")) || {}
449
451
  opt = opt.merge $configHash
450
452
  else
451
453
  opt = opt.merge $configHash
@@ -516,7 +518,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
516
518
  #'0 1px.jpg 1px 2px;3pxabc 4px'.scan(/([\.\d]+)+(px)+([;\s]+|$)/)
517
519
  #=> [["1", "px", " "], ["2", "px", ";"], ["4", "px", ""]]
518
520
  str.scan(/([\.\d]+)+(px)+([;\s]+|$)/i){ |c,v|
519
- if !(ignore.include? c+v) && (c != '1')
521
+ if !(ignore.include? c+v) && (c != '1') && c =~ /^[^0]+/
520
522
  ret = ret.gsub(c.to_s,(format("%.3f",c.to_f/rem).to_f).to_s).gsub(v,'rem')
521
523
  end
522
524
  }
@@ -549,7 +551,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
549
551
  #加载json
550
552
  # 获取设置
551
553
  filename = opt[:filename] || ''
552
- $configHash = ctx.load_json(File.expand_path("#{File.dirname(filename)}/sassmagic.json")) || {}
554
+ $configHash = ctx.load_json(File.expand_path("#{File.dirname(filename)}/../config/sassmagic.json")) || {}
553
555
  opt = opt.merge $configHash
554
556
  else
555
557
  opt = opt.merge $configHash
@@ -983,6 +985,11 @@ END
983
985
  puts("Sass #{Sass.version[:string]}")
984
986
  exit
985
987
  end
988
+
989
+ opts.on("creat", "--version", "Print the Sass version.") do
990
+ puts("Sass #{Sass.version[:string]}")
991
+ exit
992
+ end
986
993
  end
987
994
 
988
995
  def style(opts)
@@ -242,7 +242,7 @@ module Sass::Script::Functions
242
242
  # url('a.png', $base64: true) => url(data:image/png;base64,iVBORw...)
243
243
  def url(*paths)
244
244
  # debugger
245
- $configHash ||= load_json(File.expand_path("#{File.dirname(options[:filename])}/sassmagic.json")) || Hash.new
245
+ $configHash ||= load_json(File.expand_path("#{File.dirname(options[:filename])}/../config/sassmagic.json")) || Hash.new
246
246
  kwargs = paths.last.is_a?(Hash) ? paths.pop : {}
247
247
  raise Sass::SyntaxError, 'url() needs one path at least' if paths.empty?
248
248
 
@@ -262,49 +262,51 @@ module Sass::Script::Functions
262
262
  #图片压缩
263
263
  # debugger
264
264
  # 未设置tinypngKye或者url图片,则不优化
265
- if !$configHash.has_key?('tinypngKye') || path =~ /^(http:|https:)\/\//
266
- return
267
- end
268
- output = path.gsub(/\.(png|jpg)$/,'_tinypng.\1')
269
- if File.exist?(output)
270
- path.gsub!(/\.(png|jpg)$/,'_tinypng.\1')
271
- return
272
- end
265
+ if !$configHash.has_key?('tinypngKye') || $configHash['tinypngKye'] == '' || path =~ /^(http:|https:)\/\//
266
+
267
+ else
268
+ output = path.gsub(/\.(png|jpg)$/,'_tinypng.\1')
269
+ if File.exist?("#{File.dirname(options[:filename])}/#{output}")
270
+ path.gsub!(/\.(png|jpg)$/,'_tinypng.\1')
271
+ return
272
+ end
273
273
 
274
- require "net/https"
275
- require "uri"
274
+ require "net/https"
275
+ require "uri"
276
276
 
277
- key = $configHash['tinypngKye'] || ''
278
- input = path
279
- # real_path = File.expand_path("#{File.dirname(path)}/#{path}")
280
- # output = "tiny-output.png"
277
+ key = $configHash['tinypngKye'] || ''
278
+ input = path
279
+ # real_path = File.expand_path("#{File.dirname(path)}/#{path}")
280
+ # output = "tiny-output.png"
281
281
 
282
- uri = URI.parse("https://api.tinypng.com/shrink")
282
+ uri = URI.parse("https://api.tinypng.com/shrink")
283
283
 
284
- http = Net::HTTP.new(uri.host, uri.port)
285
- http.use_ssl = true
284
+ http = Net::HTTP.new(uri.host, uri.port)
285
+ http.use_ssl = true
286
286
 
287
- # Uncomment below if you have trouble validating our SSL certificate.
288
- # Download cacert.pem from: http://curl.haxx.se/ca/cacert.pem
289
- # http.ca_file = File.join(File.dirname(__FILE__), "cacert.pem")
287
+ # Uncomment below if you have trouble validating our SSL certificate.
288
+ # Download cacert.pem from: http://curl.haxx.se/ca/cacert.pem
289
+ # http.ca_file = File.join(File.dirname(__FILE__), "cacert.pem")
290
290
 
291
- request = Net::HTTP::Post.new(uri.request_uri)
292
- request.basic_auth("api", key)
291
+ request = Net::HTTP::Post.new(uri.request_uri)
292
+ request.basic_auth("api", key)
293
293
 
294
- response = http.request(request, File.binread(input))
295
- # debugger
296
- if response.code == "201"
297
- # Compression was successful, retrieve output from Location header.
294
+ response = http.request(request, File.binread("#{File.dirname(options[:filename])}/#{input}"))
298
295
  # debugger
299
- output = path
300
- path.gsub!(/\.(png|jpg)$/,'_tinypng.\1')
301
- # output['.png'] = '_tinypng.png'
302
- # output['.jpg'] = '_tinypng.jpg'
303
- File.binwrite(output, http.get(response["location"]).body)
304
- else
305
- # Something went wrong! You can parse the JSON body for details.
306
- puts "Compression failed"
296
+ if response.code == "201"
297
+ # Compression was successful, retrieve output from Location header.
298
+ # debugger
299
+ output = path
300
+ path.gsub!(/\.(png|jpg)$/,'_tinypng.\1')
301
+ # output['.png'] = '_tinypng.png'
302
+ # output['.jpg'] = '_tinypng.jpg'
303
+ File.binwrite("#{File.dirname(options[:filename])}/#{output}", http.get(response["location"]).body)
304
+ else
305
+ # Something went wrong! You can parse the JSON body for details.
306
+ puts "Compression failed"
307
+ end
307
308
  end
309
+
308
310
  end
309
311
  def timestamp(ts)
310
312
  # no kwargs
@@ -401,14 +403,17 @@ module Sass::Script::Functions
401
403
 
402
404
  # 调用上传任务
403
405
  # debugger
406
+ if (!$configHash.has_key?'imageLoader') || ($configHash["imageLoader"] == '')
407
+ return path
408
+ end
404
409
  nodetask = $configHash["imageLoader"] || false
405
410
  taskargs = File.expand_path("#{File.dirname(options[:filename])}/#{path}")
406
411
  # debugger
407
412
  if nodetask && File::exists?( File.expand_path("#{File.dirname(options[:filename])}/#{nodetask}") )
408
- task = system('node '+File.expand_path("#{File.dirname(options[:filename])}/#{nodetask}")+' '+File.expand_path("#{File.dirname(options[:filename])}/sassmagic.json")+' '+taskargs)
413
+ task = system('node '+File.expand_path("#{File.dirname(options[:filename])}/#{nodetask}")+' '+File.expand_path("#{File.dirname(options[:filename])}/../config/sassmagic.json")+' '+taskargs)
409
414
  if task
410
415
  # puts 'nodetask success'
411
- $configHash = load_json(File.expand_path("#{File.dirname(options[:filename])}/sassmagic.json"))
416
+ $configHash = load_json(File.expand_path("#{File.dirname(options[:filename])}/../config/sassmagic.json"))
412
417
  $configHash["imagesPath"] ||= Hash.new
413
418
  if $configHash["imagesPath"].has_key?(path)
414
419
  return $configHash["imagesPath"][path]
data/lib/sassmagic.rb CHANGED
@@ -18,6 +18,7 @@ require 'debugger'
18
18
  require 'sassmagic/utils'
19
19
  require 'sassmagic/remote'
20
20
  require 'sassmagic/reset'
21
+ require 'sassmagic/installer'
21
22
 
22
23
 
23
24
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sassmagic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-09 00:00:00.000000000 Z
12
+ date: 2015-02-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sass
@@ -41,6 +41,9 @@ extensions: []
41
41
  extra_rdoc_files: []
42
42
  files:
43
43
  - bin/sassmagic
44
+ - lib/sassmagic/config/imageuploader.js
45
+ - lib/sassmagic/config/sassmagic.json
46
+ - lib/sassmagic/installer.rb
44
47
  - lib/sassmagic/remote.rb
45
48
  - lib/sassmagic/reset.rb
46
49
  - lib/sassmagic/utils.rb