class ToStylus

Public Class Methods

convert(file) click to toggle source
# File lib/sass2stylus/stylus.rb, line 11
def self.convert(file)
  engine = Sass::Engine.for_file(file, {})

  tree = engine.to_tree
  visit(tree)
end

Public Instance Methods

comment_out(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 224
def comment_out(node)
  node.to_sass.lines.each {|l| emit "//#{l}".chomp }
end
determine_support(node, is_value) click to toggle source
# File lib/sass2stylus/stylus.rb, line 42
def determine_support(node, is_value)
  is_value ? (node_class = node.value) : (node_class = node.expr)
  if node_class.is_a? Sass::Script::Tree::Funcall
    @@functions['disabled_functions'].each do |func|
      if !node_class.inspect.match(func.to_s).nil?
        @errors.push("//#{func}: line #{node.line} in your Sass file")
        emit "//Function #{func} is not supported in Stylus"
        return func
      end
    end
    return
  end
end
emit(line) click to toggle source
# File lib/sass2stylus/stylus.rb, line 117
def emit(line)
  line = ('  ' * @indent) + line
  @lines.push line
end
for_helper(node, from_or_to) click to toggle source
# File lib/sass2stylus/stylus.rb, line 196
def for_helper(node, from_or_to)
  @@functions['disabled_functions'].each do |func|
    unless (from_or_to).inspect.match(func.to_s).nil?
      @errors.push("//#{func}: line #{node.line} in your Sass file")
      emit "//Function #{func} is not supported in Stylus"
    end
  end
end
render_arg(arg) click to toggle source
# File lib/sass2stylus/stylus.rb, line 99
def render_arg(arg)
  if arg.is_a? Array
    var = arg[0]
    default = arg[1]
    if default
      "#{arg[0].to_sass} = #{arg[1].to_sass}"
    else
      var.to_sass
    end
  else
    arg.to_sass
  end
end
render_args(args) click to toggle source
# File lib/sass2stylus/stylus.rb, line 113
def render_args(args)
  args.map { |a| render_arg(a) }.join(', ')
end
visit(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 18
def visit(node)
  if self.class.respond_to? :node_name
    method = "visit_#{node.class.node_name}"
  else
    method = "visit_#{node_name node}"
  end
  return if node.is_a?(Sass::Tree::CharsetNode)
  if self.respond_to?(method, true)
    self.send(method, node) {visit_children(node)}
  else
    if self.class.respond_to? :node_name
      raise "unhandled node: '#{node.class.node_name}'"
    else
      raise "unhandled node: '#{node_name node}'"
    end
  end
end
visit_atroot(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 245
def visit_atroot(node)
  emit "//Stylus does not support @at-root"
  @errors.push("// @at-root: line #{node.line} in your Sass file")
  comment_out(node)
end
visit_children(node) click to toggle source
Calls superclass method
# File lib/sass2stylus/stylus.rb, line 36
def visit_children(node)
  @indent += 1
  super(node)
  @indent -= 1
end
visit_comment(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 137
def visit_comment(node)
  node.invisible? ? lines = node.to_sass.lines : lines = node.value.first.split("\n")
  lines.each { |line| emit line.tr("\n", "")}
end
visit_content(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 152
def visit_content(node)
  emit '{block}'
end
visit_cssimport(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 164
def visit_cssimport(node)
  if node.to_sass.include?("http://") && !node.to_sass.include?("url")
    emit "@import url(#{node.uri})"
  elsif(node.to_sass.index("\"http") || node.to_sass.index("\'http"))
    emit "#{node.to_sass}".chomp!
  elsif(node.to_sass.index("http"))
    emit "@import #{node.uri}".gsub("(", "(\"").gsub(")", "\")")
  else
    emit "#{node.to_sass}".chomp!
  end
end
visit_debug(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 251
def visit_debug(node)
  emit "//Stylus does not support @debug"
  @errors.push("// @debug: line #{node.line} in your Sass file")
  comment_out(node)
end
visit_directive(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 219
def visit_directive(node)
  emit "#{node.name}"
  visit_children node
end
visit_each(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 228
def visit_each(node)
  if node.vars.length == 1
    emit "for $#{node.vars.first} in #{node.list.to_sass}".gsub(",","")
    visit_children node
  else
    emit "//Cannot convert multi-variable each loops to Stylus"
    @errors.push("// @each: line #{node.line} in your Sass file")
    comment_out(node)
  end
end
visit_extend(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 176
def visit_extend(node)
  emit "#{node.to_sass}".gsub("%","$").chomp!
end
visit_for(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 205
def visit_for(node)
  (node.from.is_a? Sass::Script::Tree::Funcall) ? for_helper(node, node.from) : nil
  from = node.from.to_sass

  (node.to.is_a? Sass::Script::Tree::Funcall) ? for_helper(node, node.to) : nil
  temp_to = node.to.to_sass

  (node.to.is_a? Sass::Script::Tree::Literal) ? exclusive_to = temp_to.to_i - 1 : exclusive_to = "(#{temp_to}) - 1"
  node.exclusive ? to = exclusive_to : to = temp_to

  emit "for $#{node.var} in (#{from})..(#{to})"
  visit_children node
end
visit_function(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 180
def visit_function(node)
  if node.splat.nil?
    emit "#{node.name}(#{render_args(node.args)})"
  else
    node.args.push([node.splat, nil])
    emit "#{node.name}(#{render_args(node.args)}...)"
  end
  visit_children node
end
visit_if(node, isElse = false) click to toggle source
# File lib/sass2stylus/stylus.rb, line 122
def visit_if(node, isElse = false)
  line = []
  line.push 'else' if isElse
  line.push "if #{node.expr.to_sass}" if node.expr
  emit line.join(' ')
  visit_children(node)
  visit_if(node.else, true) if node.else
end
visit_import(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 160
def visit_import(node)
  emit "@import '#{node.imported_filename}'"
end
visit_media(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 147
def visit_media(node)
  emit "@media #{node.query.map{|i| i.inspect}.join}".gsub! /"/, ""
  visit_children node
end
visit_mixin(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 156
def visit_mixin(node)
  emit "#{node.name}(#{render_args(node.args)})"
end
visit_mixindef(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 142
def visit_mixindef(node)
  emit "#{node.name}(#{render_args(node.args)})"
  visit_children node
end
visit_prop(node, output="") click to toggle source
# File lib/sass2stylus/stylus.rb, line 56
def visit_prop(node, output="")
  func_support = determine_support(node, true)
  if !node.children.empty?
    output << "#{node.name.join('')}-"
    unless node.value.to_sass.empty?
      #for nested scss with values, change the last "-" in the output to a ":" to format output correctly
      if node.value.is_a? Sass::Script::Tree::Operation
        func_output = "#{output}(#{node.value.to_sass})".sub(/(.*)-/, '\1: ').gsub("\#{","{")
      elsif node.value.is_a?(Sass::Script::Tree::UnaryOperation) && node.value.operator.to_s == 'minus'
        func_output = "#{output}".sub(/(.*)-/, '\1: ') <<"-1*#{node.value.operand.inspect}".gsub("\#{","{")
      else
        func_output = "#{output}#{node.value.to_sass}".sub(/(.*)-/, '\1: ').gsub("\#{","{")
      end
      func_support.nil? ? (emit func_output) : (emit "//" << func_output)
    end
    node.children.each do |child|
      visit_prop(child,output)
    end
  else
    unless node.is_a? Sass::Tree::CommentNode
      "#{node.name.join("")[0]}" == "#" ?
        node_name = "#{output}{#{node.name-[""]}}:".tr('[]','') : node_name = "#{output}#{node.name.join('')}:"

      if node.value.is_a? Sass::Script::Tree::Operation
        func_output = node_name << " (#{node.value.to_sass})".gsub("\#{", "{")
      elsif node.value.is_a?(Sass::Script::Tree::UnaryOperation) && node.value.operator.to_s == 'minus'
        func_output = node_name << " -1*#{node.value.operand.inspect}"
      else
        func_output = node_name << " #{node.value.to_sass}".gsub("\#{", "{")
      end
      func_support.nil? ? (emit func_output) : (emit "//" << func_output)
    else
      visit(node)
    end
  end
end
visit_return(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 131
def visit_return(node)
  func_support = determine_support(node, false)
  output = node.expr.to_sass
  func_support.nil? ? (emit output) : (emit "//" << output)
end
visit_root(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 263
def visit_root(node)
  @indent = -1
  @errors = []
  @lines = []
  visit_children(node)
  unless @errors.empty?
    @errors.unshift("//Below is a list of the Sass rules that could not be converted to Stylus")
    @errors.push("\n")
    @lines.unshift(*@errors)
  end
  @lines.join("\n")
end
visit_rule(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 190
def visit_rule(node)
  rule = (node.rule.length == 1 && node.rule[0].is_a?(String)) ? node.rule[0] : node.to_sass.lines[0]
  emit "#{rule}".gsub("\#{", "{").gsub("%", "$").chomp
  visit_children node
end
visit_variable(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 93
def visit_variable(node)
  func_support = determine_support(node, false)
  output = "$#{node.name} = #{node.expr.to_sass}"
  func_support.nil? ? (emit output) : (emit "//" << output)
end
visit_warn(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 257
def visit_warn(node)
  emit "//Stylus does not support @warn"
  @errors.push("// @warn: line #{node.line} in your Sass file")
  comment_out(node)
end
visit_while(node) click to toggle source
# File lib/sass2stylus/stylus.rb, line 239
def visit_while(node)
  emit "//Stylus does not support while loops"
  @errors.push("// @while: line #{node.line} in your Sass file")
  comment_out(node)
end