Permalink
Browse files

Add _native_ less.js support

* adds less gem as a dependency
* update Kss::Parser to work with less files
* add tests to make sure Styleguides can be extracted from LESS
  • Loading branch information...
1 parent fde61bc commit 99bd13f43e490da12b6a3d4a177a13f0a37c2fcf @lennart lennart committed Jan 10, 2012
View
@@ -1,6 +1,7 @@
source :rubygems
gem "sass", ">= 3.1"
+gem "less", ">= 2.0"
group :test do
gem "minitest", ">= 1.5.0"
View
@@ -1,4 +1,7 @@
source :rubygems
gem 'sinatra', '~> 1.3.1'
-gem 'kss', '~> 0.1.1'
+gem 'kss', '~> 0.1.1'
+
+
+gem 'less', ">= 2.0"
View
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
s.files += Dir.glob("test/**/*")
s.add_dependency "sass", ">= 3.1"
+ s.add_dependency "less", ">= 2.0"
s.description = <<desc
Inspired by TomDoc, KSS attempts to provide a methodology for writing
View
@@ -1,4 +1,6 @@
require 'sass'
+require 'v8'
+require 'less'
require 'kss/modifier'
require 'kss/parser'
View
@@ -12,9 +12,22 @@ def initialize(base_path)
@sections = {}
Dir["#{base_path}/**/*.*"].each do |filename|
- root_node = Sass::SCSS::Parser.new(File.read(filename), filename).parse
- parse_node(root_node, filename)
+ if File.extname(filename) == ".less"
+ tree = Less::Parser.new(:paths => [base_path], :filename => filename).
+ # HACK: get the internal JS tree object
+ parse(File.read(filename)).instance_variable_get "@tree"
+ # inject less.js into a new V8 context
+ less = Less.instance_variable_get "@less"
+ cxt = V8::Context.new
+ cxt['less'] = less
+
+ # parse node tree for comments
+ parse_v8_node(cxt, tree, filename)
+ else
+ root_node = Sass::SCSS::Parser.new(File.read(filename), filename).parse
+ parse_node(root_node, filename)
+ end
end
end
@@ -24,18 +37,40 @@ def parse_node parent_node, filename
parse_node(node, filename) if node.has_children
next
end
- comment_text = self.class.clean_comments node.value[0]
- if self.class.kss_block? comment_text
- base_name = File.basename(filename)
- section = Section.new(comment_text, base_name)
- @sections[section.section] = section
+ add_section node.value[0], filename
+ end
+
+ parent_node
+ end
+
+ def parse_v8_node cxt, parent_node, filename
+ parent_node.rules.each do |node|
+ # inject the current to into JS context
+ cxt['node'] = node
+
+ unless cxt.eval "node instanceof less.tree.Comment"
+ parse_v8_node(cxt, node, filename) if cxt.eval 'node.rules != null'
+
+ next
end
+
+ add_section node.value, filename
end
parent_node
end
+ def add_section comment, filename
+ comment_text = self.class.clean_comments comment
+
+ if self.class.kss_block? comment_text
+ base_name = File.basename(filename)
+ section = Section.new(comment_text, base_name)
+ @sections[section.section] = section
+ end
+ end
+
# Public: Takes a cleaned (no comment syntax like // or /* */) comment
# block and determines whether it is a KSS documentation block.
#
@@ -0,0 +1,10 @@
+/*
+A default form label
+
+Styleguide 5.0.0
+*/
+label {
+ display: block;
+ float: left;
+ width: 150px;
+}
@@ -0,0 +1,51 @@
+/*
+Your standard form button.
+
+:hover - Highlights when hovering.
+:disabled - Dims the button when disabled.
+.primary - Indicates button is the primary action.
+.smaller - A little bit smaller now.
+
+Styleguide 2.1.1.
+*/
+button, .button {
+ padding:5px 15px;
+
+ &.primary, &.primary:hover{
+ color:#fff;
+ }
+
+ &.smaller{
+ font-size:9px;
+ }
+
+ &:hover{
+ color:#337797;
+ }
+
+ &:disabled{
+ opacity:0.5;
+ }
+}
+
+/*
+A button suitable for giving stars to someone.
+
+.star-given - A highlight indicating you've already given a star.
+.disabled - Dims the button to indicate it cannot be used.
+
+Styleguide 2.2.1.
+*/
+a.button.star{
+ display:inline-block;
+
+ .star{ font-size:10px; }
+
+ &.star-given{
+ color:#ae7e00;
+ }
+
+ &.disabled{
+ opacity:0.5;
+ }
+}
@@ -0,0 +1,8 @@
+/*
+Your standard grid helper.
+
+Styleguide 4.0.0.
+*/
+.grid(@columns, @max: 10) {
+ width: (@columns / @max) * 960px;
+}
@@ -0,0 +1,17 @@
+@import "_label";
+/*
+Your standard form element.
+
+Styleguide 3.0.0
+*/
+form {
+
+ /*
+ Your standard text input box.
+
+ Styleguide 3.0.1
+ */
+ input[type="text"] {
+ border: 1px solid #ccc;
+ }
+}
View
@@ -5,6 +5,7 @@ class ParserTest < Kss::Test
def setup
@scss_parsed = Kss::Parser.new('test/fixtures/scss')
@css_parsed = Kss::Parser.new('test/fixtures/css')
+ @less_parsed = Kss::Parser.new('test/fixtures/less')
@css_comment = <<comment
/*
@@ -54,6 +55,11 @@ def setup
@scss_parsed.section('2.1.1').description
end
+ test "parsers KSS comments in LESS" do
+ assert_equal 'Your standard form button.',
+ @less_parsed.section('2.1.1').description
+ end
+
test "parses KSS comments in CSS" do
assert_equal 'Your standard form button.',
@css_parsed.section('2.1.1').description
@@ -73,4 +79,9 @@ def setup
assert_equal "Your standard text input box.", @scss_parsed.section('3.0.1').description
end
+ test "parses nested LESS documents" do
+ assert_equal "Your standard form element.", @less_parsed.section('3.0.0').description
+ assert_equal "Your standard text input box.", @less_parsed.section('3.0.1').description
+ end
+
end

0 comments on commit 99bd13f

Please sign in to comment.