Sha256: 76a6aa8d55b683a46a62b271be3e72218e43cc6cbd0d90bff9312ce2d88c0096

Contents?: true

Size: 2 KB

Versions: 3

Compression:

Stored size: 2 KB

Contents

module Precssious

  class Preprocessor
  
    def initialize(input)
      @tokens = []
      
      Preprocessor.tokenize(Preprocessor.strip_comments(input)) do |t|
        @tokens << t
      end
    end
  
  
    def pull(type = nil) 
      result = @tokens.shift
      if type && result.type != type
        raise 'Unexpected token (#{result}, #{@tokens[0]}, #{@tokens[1]}, #{@tokens[2]}, #{@tokens[3]})' 
      end
      result
    end
    def peek; @tokens[0]; end
    def peek2; @tokens[1] if @tokens.length > 1; end
    def consume(type)
      t = pull
      if t.type != type
        raise "Unexpected token (#{t.data}, #{@tokens[0]}, #{@tokens[1]}, #{@tokens[2]}, #{@tokens[3]}) #{t.type}, expected #{type}"  
      end
    end
  
  
    def rules
      result = []
      while peek
        result << rule
      end
      result
    end
  
    def rule
      Rule.new pull(:text).data, rule_value
    end
  
    def rule_value
      consume :lbrace
      result = any
      consume :rbrace
      result
    end
  
    def any
      result = []
      while (peek.type != :rbrace)
        if peek2 && peek2.type == :lbrace
          result << rule 
        else
          if peek2 && peek2.type == :semicolon
            result << value 
          else
            raise 'Unexpected CSS syntax (missing ;?)'
          end
        end
      end
      result
    end
  
    def value
      l = pull(:text)
      consume(:semicolon)
      Value.new l.data
    end
  
    def self.tokenize(input)
      current = []
      input.each_char do |c|
        if %W({ } ;).include? c.to_s
          prev = current.join('').strip
          current.clear

          yield Token.new(:text, prev) if prev.length > 0
          yield Token.new(:lbrace, nil) if c.to_s == '{'
          yield Token.new(:rbrace, nil) if c.to_s == '}'
          yield Token.new(:semicolon, nil) if c.to_s == ';'
        else
          current << c
        end
      end
    end
    
    def self.strip_comments(input)
      input.gsub /\/\*.*?\*\//, ''
    end
    
  end
end

Version data entries

3 entries across 3 versions & 2 rubygems

Version Path
erikhansson-precssious-0.1.0 lib/precssious/preprocessor.rb
erikhansson-precssious-0.1.1 lib/precssious/preprocessor.rb
precssious-0.1.1 lib/precssious/preprocessor.rb