| Class | Haml::Exec::SassConvert |
| In: |
lib/haml/exec.rb
|
| Parent: | Generic |
The `sass-convert` executable.
@param args [Array<String>] The command-line arguments
# File lib/haml/exec.rb, line 627
627: def initialize(args)
628: super
629: require 'sass'
630: @options[:for_tree] = {}
631: @options[:for_engine] = {:cache => false, :read_cache => true}
632: end
Processes the options set by the command-line arguments, and runs the CSS compiler appropriately.
# File lib/haml/exec.rb, line 707
707: def process_result
708: require 'sass'
709:
710: if @options[:recursive]
711: process_directory
712: return
713: end
714:
715: super
716: input = @options[:input]
717: raise "Error: '#{input.path}' is a directory (did you mean to use --recursive?)" if File.directory?(input)
718: output = @options[:output]
719: output = input if @options[:in_place]
720: process_file(input, output)
721: end
Tells optparse how to parse the arguments.
@param opts [OptionParser]
# File lib/haml/exec.rb, line 637
637: def set_opts(opts)
638: opts.banner = "Usage: sass-convert [options] [INPUT] [OUTPUT]\n\nDescription:\n Converts between CSS, Sass, and SCSS files.\n E.g. converts from SCSS to Sass,\n or converts from CSS to SCSS (adding appropriate nesting).\n\nOptions:\n"
639:
640: opts.on('-F', '--from FORMAT',
641: 'The format to convert from. Can be css, scss, sass, less, or sass2.',
642: 'sass2 is the same as sass, but updates more old syntax to new.',
643: 'By default, this is inferred from the input filename.',
644: 'If there is none, defaults to css.') do |name|
645: @options[:from] = name.downcase.to_sym
646: unless [:css, :scss, :sass, :less, :sass2].include?(@options[:from])
647: raise "Unknown format for sass-convert --from: #{name}"
648: end
649: try_less_note if @options[:from] == :less
650: end
651:
652: opts.on('-T', '--to FORMAT',
653: 'The format to convert to. Can be scss or sass.',
654: 'By default, this is inferred from the output filename.',
655: 'If there is none, defaults to sass.') do |name|
656: @options[:to] = name.downcase.to_sym
657: unless [:scss, :sass].include?(@options[:to])
658: raise "Unknown format for sass-convert --to: #{name}"
659: end
660: end
661:
662: opts.on('-R', '--recursive',
663: 'Convert all the files in a directory. Requires --from and --to.') do
664: @options[:recursive] = true
665: end
666:
667: opts.on('-i', '--in-place',
668: 'Convert a file to its own syntax.',
669: 'This can be used to update some deprecated syntax.') do
670: @options[:in_place] = true
671: end
672:
673: opts.on('--dasherize', 'Convert underscores to dashes') do
674: @options[:for_tree][:dasherize] = true
675: end
676:
677: opts.on('--old', 'Output the old-style ":prop val" property syntax.',
678: 'Only meaningful when generating Sass.') do
679: @options[:for_tree][:old] = true
680: end
681:
682: opts.on('-C', '--no-cache', "Don't cache to sassc files.") do
683: @options[:for_engine][:read_cache] = false
684: end
685:
686: unless ::Haml::Util.ruby1_8?
687: opts.on('-E encoding', 'Specify the default encoding for Sass and CSS files.') do |encoding|
688: Encoding.default_external = encoding
689: end
690: end
691:
692: super
693: end
# File lib/haml/exec.rb, line 725
725: def process_directory
726: unless input = @options[:input] = @args.shift
727: raise "Error: directory required when using --recursive."
728: end
729:
730: output = @options[:output] = @args.shift
731: raise "Error: --from required when using --recursive." unless @options[:from]
732: raise "Error: --to required when using --recursive." unless @options[:to]
733: raise "Error: '#{@options[:input]}' is not a directory" unless File.directory?(@options[:input])
734: if @options[:output] && File.exists?(@options[:output]) && !File.directory?(@options[:output])
735: raise "Error: '#{@options[:output]}' is not a directory"
736: end
737: @options[:output] ||= @options[:input]
738:
739: from = @options[:from]
740: from = :sass if from == :sass2
741: if @options[:to] == @options[:from] && !@options[:in_place]
742: fmt = @options[:from]
743: raise "Error: converting from #{fmt} to #{fmt} without --in-place"
744: end
745:
746: ext = @options[:from]
747: ext = :sass if ext == :sass2
748: Dir.glob("#{@options[:input]}/**/*.#{ext}") do |f|
749: output =
750: if @options[:in_place]
751: f
752: elsif @options[:output]
753: output_name = f.gsub(/\.(c|sa|sc|le)ss$/, ".#{@options[:to]}")
754: output_name[0...@options[:input].size] = @options[:output]
755: output_name
756: else
757: f.gsub(/\.(c|sa|sc|le)ss$/, ".#{@options[:to]}")
758: end
759:
760: unless File.directory?(File.dirname(output))
761: puts_action :directory, :green, File.dirname(output)
762: FileUtils.mkdir_p(File.dirname(output))
763: end
764: puts_action :convert, :green, f
765: if File.exists?(output)
766: puts_action :overwrite, :yellow, output
767: else
768: puts_action :create, :green, output
769: end
770:
771: input = open_file(f)
772: output = @options[:in_place] ? input : open_file(output, "w")
773: process_file(input, output)
774: end
775: end
# File lib/haml/exec.rb, line 777
777: def process_file(input, output)
778: if input.is_a?(File)
779: @options[:from] ||=
780: case input.path
781: when /\.scss$/; :scss
782: when /\.sass$/; :sass
783: when /\.less$/; :less
784: when /\.css$/; :css
785: end
786: elsif @options[:in_place]
787: raise "Error: the --in-place option requires a filename."
788: end
789:
790: if output.is_a?(File)
791: @options[:to] ||=
792: case output.path
793: when /\.scss$/; :scss
794: when /\.sass$/; :sass
795: end
796: end
797:
798: if @options[:from] == :sass2
799: @options[:from] = :sass
800: @options[:for_engine][:sass2] = true
801: end
802:
803: @options[:from] ||= :css
804: @options[:to] ||= :sass
805: @options[:for_engine][:syntax] = @options[:from]
806:
807: out =
808: ::Haml::Util.silence_haml_warnings do
809: if @options[:from] == :css
810: require 'sass/css'
811: ::Sass::CSS.new(input.read, @options[:for_tree]).render(@options[:to])
812: elsif @options[:from] == :less
813: require 'sass/less'
814: try_less_note
815: input = input.read if input.is_a?(IO) && !input.is_a?(File) # Less is dumb
816: Less::Engine.new(input).to_tree.to_sass_tree.send("to_#{@options[:to]}", @options[:for_tree])
817: else
818: if input.is_a?(File)
819: ::Sass::Files.tree_for(input.path, @options[:for_engine])
820: else
821: ::Sass::Engine.new(input.read, @options[:for_engine]).to_tree
822: end.send("to_#{@options[:to]}", @options[:for_tree])
823: end
824: end
825:
826: output = File.open(input.path, 'w') if @options[:in_place]
827: output.write(out)
828: rescue ::Sass::SyntaxError => e
829: raise e if @options[:trace]
830: file = " of #{e.sass_filename}" if e.sass_filename
831: raise "Error on line #{e.sass_line}#{file}: #{e.message}\n Use --trace for backtrace"
832: rescue LoadError => err
833: handle_load_error(err)
834: end
# File lib/haml/exec.rb, line 837
837: def try_less_note
838: return if @@less_note_printed
839: @@less_note_printed = true
840: warn "* NOTE: Sass and Less are different languages, and they work differently.\n* I'll do my best to translate, but some features -- especially mixins --\n* should be checked by hand.\n"
841: end