Skip to content

Instantly share code, notes, and snippets.

@paulingham
Forked from augustl/engine.rb
Created June 24, 2009 20:30
Show Gist options
  • Save paulingham/135500 to your computer and use it in GitHub Desktop.
Save paulingham/135500 to your computer and use it in GitHub Desktop.
Fixed the typos - ie.. divition to division
module Less
class BuildHandler
attr_reader :variables, :rules
def initialize
@variables = {}
@rules = []
end
def to_css
rules.map {|r| r.to_css }.join("\n")
end
end
end
module Less
class Engine
attr_reader :css
attr_reader :parser, :build_handler, :root_node
def initialize(less)
@less = less.dup
@parser = LessGrammarParser.new
@build_handler = BuildHandler.new
parse
@css = build_handler.to_css
end
def parse
preparse_less
@root_node = parser.parse(@less)
if @root_node
@root_node.build(build_handler)
else
raise [parser.failure_column, parser.failure_index, parser.failure_line, parser.failure_reason].join(" -- ")
end
end
private
def preparse_less
# Remove comments
@less.gsub!(/\/\*[^\/\*]+\*\//, "")
# Remove void whitespace
@less.gsub!(/\s+/, " ")
end
end
end
require 'test_helper'
class EngineTest < Test::Unit::TestCase
def test_basic
less = ".haz {
color: red;
text-decoration:none;
}
@my_var: 5;
#foo {
background-color: red;
.bar {
text-decoration: none;
.haxor;
#baz {
color: red;
}
}
}"
@engine = Less::Engine.new(less)
p @engine.build_handler.rules
# => [#<Less::Engine::Rule:0x106ba48 @selector=".haz ">, #<Less::Engine::Rule:0x106b9e4 @selector="#foo ">, #<Less::Engine::Rule:0x106b944 @selector=".bar ">, #<Less::Engine::Rule:0x106b6d8 @selector="#baz ">]
p @engine.build_handler.variables
# => {"my_var"=>"5"}
end
end
grammar LessGrammar
rule primary
(css_rule / variable_declaration)+ {
def build(engine)
elements.each {|e| e.build(engine) }
end
}
end
rule variable_declaration
whitespace "@" variable_name ":" whitespace declaration_value ";" whitespace {
def build(engine)
engine.variables[variable_name.text_value] = declaration_value.text_value
end
}
end
rule variable_reference
"@" variable_name (whitespace variable_operation)?
end
rule variable_operation
operand whitespace number
end
rule variable_name
[a-zA-Z0-9\-_]+
end
rule css_rule
whitespace selectors rule_block whitespace {
def build(engine)
engine.rules << Less::Engine::Rule.new(selectors.text_value)
rule_block.build(engine)
end
}
end
rule selectors
[#\.a-zA-Z0-9<>\[\]='"~\|, ]+
end
rule rule_block
"{" rule_block_content "}" {
def build(engine)
rule_block_content.build(engine)
end
}
end
rule rule_block_content
(css_rule / declaration / [ ])+ {
def build(engine)
elements.each {|e| e.build(engine) if e.respond_to?(:build) }
end
}
end
rule declaration
whitespace (css_declaration / mixin) whitespace
end
rule css_declaration
declaration_key ":" whitespace (variable_reference / declaration_value) ";"
end
rule mixin
"." [a-zA-Z0-9\-_]+ ";"
end
rule declaration_key
[a-z\-]+
end
rule operand
addition / subtraction / multiplication / division
end
rule addition
"*"
end
rule subtraction
"-"
end
rule multiplication
"*"
end
rule division
"/"
end
rule number
[0-9]+
end
rule declaration_value
[^;]+
end
rule whitespace
[ ]*
end
end
module Less
class Engine
class Rule
attr_reader :selector
def initialize(selector)
@selector = selector
end
def to_css
"#{selector} { }"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment