collin-fold 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
data/Rakefile.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ namespace :spec do
5
+ task :prepare do
6
+ path = File.dirname(__FILE__)
7
+ p path
8
+ @specs= Dir.glob("#{path}/rspec/**/*.rb").join(' ')
9
+ end
10
+
11
+ task :all => :prepare do
12
+ system "spec #{@specs}"
13
+ end
14
+
15
+ task :doc => :prepare do
16
+ system "spec #{@specs} --format specdoc"
17
+ end
18
+ end
data/lib/fold.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'facets'
2
+
3
+ module Fold
4
+ require 'fold/engine'
5
+ require 'fold/abstract_fold'
6
+ require 'fold/fold_factory'
7
+ require 'fold/precompiler'
8
+ end
@@ -0,0 +1,26 @@
1
+ require 'ostruct'
2
+
3
+ module Fold
4
+ class AbstractFold < OpenStruct
5
+ Regex= //
6
+ def initialize source={}
7
+ attrs= {
8
+ :text => '',
9
+ :children => [],
10
+ :tabs => -1
11
+ }.merge(source)
12
+
13
+ attrs[:text].gsub! self.class::Regex, ''
14
+
15
+ super attrs
16
+ end
17
+
18
+ def render
19
+ text
20
+ end
21
+
22
+ def render_children
23
+ children.map{|child| child.render}
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ module Fold
2
+ class Engine
3
+ def initialize source
4
+ @source= source
5
+ prepare_source
6
+ end
7
+
8
+ def prepare_source
9
+ @prepared_source= true
10
+ end
11
+
12
+ def lines
13
+ @source.split(/\n/).reject{|line| line.blank?}
14
+ end
15
+
16
+ def render fold= precompiler.new.fold(lines)
17
+ fold.children.map{|child| child.render}
18
+ end
19
+
20
+ # *** me hard
21
+ def precompiler
22
+ @precompiler||= instance_eval "#{self.class.to_s.split(/::/).first}::Precompiler"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ module Fold
2
+ module FoldFactory
3
+ Indent= 2
4
+ class IndentationError < StandardError; end
5
+
6
+ def self.included klass
7
+ klass.extend ClassMethods
8
+ end
9
+
10
+ def produce line=''
11
+ tabs = count_soft_tabs(line)
12
+ line = line.sub(/^[ ]+/, '')
13
+ attrs= {
14
+ :text => line,
15
+ :tabs => tabs
16
+ }
17
+
18
+ if klass= detect_class(line)
19
+ klass.new attrs
20
+ else
21
+ AbstractFold.new attrs.merge(:tabs => -1)
22
+ end
23
+ end
24
+
25
+ def detect_class line
26
+ return nil if line.blank?
27
+ self.class.defined_folds.reverse.detect {|fold| fold::Regex and fold::Regex.match(line)}
28
+ end
29
+
30
+ def count_soft_tabs line
31
+ spaces= line.index(/([^ ]|$)/)
32
+ raise IndentationError if spaces.odd?
33
+ spaces / Indent
34
+ end
35
+
36
+ module ClassMethods
37
+ def folds id, regex=AbstractFold::Regex, &block
38
+ fold= Class.new(AbstractFold)
39
+ fold.const_set :Regex, regex
40
+
41
+ fold.send :define_method, :render, &block if block_given?
42
+
43
+ const_set id, fold
44
+ defined_folds << fold
45
+ end
46
+
47
+ def defined_folds
48
+ @folds||= []
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,52 @@
1
+ module Fold
2
+ class Precompiler
3
+ include Fold::FoldFactory
4
+
5
+ def fold lines
6
+ last_line= produce
7
+
8
+ parent_line= nil
9
+
10
+ parent_stack= []
11
+
12
+ lines.each do |text|
13
+ line = produce text
14
+
15
+ indent = line.tabs - last_line.tabs
16
+
17
+ raise IndentationError if indent > 1
18
+
19
+ if step_in? indent
20
+ parent_line = last_line
21
+ parent_line.children << line
22
+ parent_stack << parent_line
23
+ end
24
+
25
+ if step_aside? indent
26
+ parent_line.children << line
27
+ end
28
+
29
+ if step_out? indent
30
+ parent_stack= parent_stack.slice 0, parent_stack.length + indent
31
+ parent_line = parent_stack.last
32
+ parent_line.children << line
33
+ end
34
+
35
+ last_line= line
36
+ end
37
+ parent_stack.first
38
+ end
39
+
40
+ def step_in? indent
41
+ indent == 1
42
+ end
43
+
44
+ def step_out? indent
45
+ indent < 0
46
+ end
47
+
48
+ def step_aside? indent
49
+ indent == 0
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ family Modena
2
+ father Dave
3
+ mother Catherine
4
+ son Carl
5
+ daughter Tena
6
+
7
+ family Tarelo
8
+ father Tyson
9
+ mother Rheida
@@ -0,0 +1,58 @@
1
+ require "ostruct"
2
+ require 'rspec/fold_spec_helper'
3
+
4
+ describe Fold::AbstractFold do
5
+ it "inherits OpenStruct" do
6
+ Fold::AbstractFold.superclass.should == OpenStruct
7
+ end
8
+ end
9
+
10
+ describe Fold::AbstractFold, ".initialize" do
11
+ it "and sets the regex" do
12
+ Fold::Precompiler.folds :What, /what/
13
+ Fold::Precompiler::What::Regex.should == /what/
14
+ end
15
+ end
16
+
17
+ describe Fold::AbstractFold, ".render" do
18
+ it "renders cleanly" do
19
+ fold= Fold::AbstractFold.new(:text=>"LINE")
20
+ fold.render.should == "LINE"
21
+ end
22
+
23
+ it "renders from block" do
24
+ Fold::Precompiler.folds :What, /what/ do
25
+ "#{text}?"
26
+ end
27
+
28
+ what= Fold::Precompiler::What.new(:text=>'whatever')
29
+ what.render.should== "ever?"
30
+ end
31
+
32
+ it "renders children" do
33
+ Fold::Precompiler.folds :Parent, /^parent / do
34
+ "Hey, #{text} here, my children are: #{render_children.join(', ')}"
35
+ end
36
+
37
+ Fold::Precompiler.folds :Child, /^child /
38
+
39
+ will= Fold::Precompiler::Parent.new(:text=>"Will")
40
+ will.children << Fold::Precompiler::Child.new(:text=>"Tony")
41
+ will.children << Fold::Precompiler::Child.new(:text=>"Ace")
42
+
43
+ will.render.should == "Hey, Will here, my children are: Tony, Ace"
44
+ end
45
+ end
46
+
47
+ describe Fold::AbstractFold, ".render_children" do
48
+ it "renders cleanly" do
49
+ Fold::Precompiler.folds :Parent, /^parent /
50
+ Fold::Precompiler.folds :Child, /^child /
51
+
52
+ will= Fold::Precompiler::Parent.new(:text=>"Will")
53
+ will.children << Fold::Precompiler::Child.new(:text=>"Tony")
54
+ will.children << Fold::Precompiler::Child.new(:text=>"Ace")
55
+
56
+ will.render_children.should == ["Tony", "Ace"]
57
+ end
58
+ end
@@ -0,0 +1,52 @@
1
+ require 'rspec/fold_spec_helper'
2
+
3
+ describe Fold::Engine do
4
+ it "inherits Module" do
5
+ Fold::Engine.class.should == Class
6
+ end
7
+
8
+ describe "#initialize" do
9
+ before(:each) do
10
+ @path= "#{FoldFixtureRoot}/fixture.target.fold"
11
+ @engine= Fold::Engine.new File.read(@path)
12
+ end
13
+
14
+ it "sets fold content" do
15
+ @engine.instance_variable_get(:@source).should == File.read(@path)
16
+ end
17
+ end
18
+
19
+ describe "#prepare_fold" do
20
+ before(:each) do
21
+ @path= "#{FoldFixtureRoot}/fixture.target.fold"
22
+ @engine= Fold::Engine.new File.read(@path)
23
+ end
24
+
25
+ it "prepares fold content" do
26
+ @engine.instance_variable_get(:@prepared_source).should_not be_nil
27
+ end
28
+ end
29
+
30
+ describe "#lines" do
31
+ it "splits on line breaks" do
32
+ lines= 10
33
+ src= "LINE\n" * lines
34
+ en= Fold::Engine.new src
35
+ en.lines.length.should == lines
36
+ end
37
+
38
+ it "rejects whitespace only lines" do
39
+ src= "LINE\n \nLINE\n\t\n\t\nwhatup?"
40
+ en= Fold::Engine.new src
41
+ en.lines.length.should == 3
42
+ end
43
+ end
44
+
45
+ describe "#render" do
46
+ it "renders spec" do
47
+ Fold::Precompiler.folds :Line, //
48
+ source= File.read "#{FoldFixtureRoot}/fixture.target.fold"
49
+ en= Fold::Engine.new source
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,66 @@
1
+ require 'rspec/fold_spec_helper'
2
+
3
+ class Included; include Fold::FoldFactory end
4
+
5
+ describe Fold::FoldFactory do
6
+ it "inherits module" do
7
+ Fold::FoldFactory.class.should == Module
8
+ end
9
+ end
10
+
11
+ describe Fold::FoldFactory, ".count_soft_tabs" do
12
+ before(:each) {@it= Included.new}
13
+
14
+ it "counts one soft tabs" do
15
+ @it.count_soft_tabs(" LINE").should == 1
16
+ end
17
+
18
+ it "counts tree soft tabs" do
19
+ @it.count_soft_tabs(" " * 3 + "LINE").should == 3
20
+ end
21
+
22
+ it "raises IndentationError on odd spaced indentation" do
23
+ lambda {
24
+ @it.count_soft_tabs(" LINE")
25
+ }.should raise_error(Fold::Precompiler::IndentationError)
26
+ end
27
+ end
28
+
29
+ describe Fold::FoldFactory, ".produce" do
30
+ before(:each) {@it= Included.new}
31
+
32
+ it "folds abstractly" do
33
+ @it.produce.is_a?(Fold::AbstractFold).should == true
34
+ end
35
+
36
+ it "folds other folds" do
37
+ Included.folds :Location, /^\@/
38
+ @it.produce('@LINE').is_a?(Included::Location).should == true
39
+ end
40
+ end
41
+
42
+
43
+
44
+ #describe Fold::Precompiler::Action::Regex do
45
+ # it "matches !LINE" do
46
+ # Fold::Precompiler::Action::Regex.should match("!LINE")
47
+ # end
48
+ #end
49
+ #
50
+ #describe Fold::Precompiler::Selector::Regex do
51
+ # it "matches ?LINE" do
52
+ # Fold::Precompiler::Selector::Regex.should match("?LINE")
53
+ # end
54
+ #end
55
+ #
56
+ #describe Fold::Precompiler::Group::Regex do
57
+ # it "matches describe LINE" do
58
+ # Fold::Precompiler::Group::Regex.should match("describe LINE")
59
+ # end
60
+ #end
61
+ #
62
+ #describe Fold::Precompiler::Example::Regex do
63
+ # it "matches it LINE" do
64
+ # Fold::Precompiler::Example::Regex.should match("it LINE")
65
+ # end
66
+ #end
@@ -0,0 +1,108 @@
1
+ require 'rspec/fold_spec_helper'
2
+
3
+ describe Fold::Precompiler do
4
+ it "inherits module" do
5
+ Fold::Precompiler.class.should == Class
6
+ end
7
+ end
8
+
9
+ class Confused < Fold::Precompiler
10
+ folds :Line, //
11
+ folds :What, /what/
12
+ end
13
+
14
+ describe Fold::Precompiler, ".folds" do
15
+ it "generates AbstractFold subclasses" do
16
+ Confused::What.superclass.should == Fold::AbstractFold
17
+ end
18
+
19
+ it "in the appropriate namespace" do
20
+ Confused::What.should_not be_nil
21
+ end
22
+
23
+ it "pushes to defined_folds" do
24
+ Confused.defined_folds.should include(Confused::What)
25
+ end
26
+ end
27
+
28
+ describe Fold::Precompiler, ".fold" do
29
+ before(:each) do
30
+ @it= Confused.new
31
+ end
32
+
33
+ it "has notion of top level" do
34
+ en= Fold::Engine.new %{
35
+ LINE 1
36
+ LINE 2
37
+ LINE 3
38
+ LINE 4
39
+ LINE 5
40
+ LINE 6
41
+
42
+ LINE 7
43
+ LINE 8
44
+ LINE 9
45
+ }
46
+ @it.fold(en.lines).children.length.should == 3
47
+ end
48
+
49
+ it "barfs on innappropriate indentation" do
50
+ en= Fold::Engine.new %{
51
+ LINE 1
52
+ LINE 2
53
+ }
54
+ lambda {
55
+ @it.fold(en.lines)
56
+ }.should raise_error(Confused::IndentationError)
57
+ end
58
+ end
59
+
60
+ describe Fold::Precompiler, ".step_in?" do
61
+ before(:each) do
62
+ @it= Confused.new
63
+ end
64
+
65
+ it "must indent 1" do
66
+ @it.step_in?(1).should == true
67
+ end
68
+
69
+ it "no more" do
70
+ @it.step_in?(2).should == false
71
+ end
72
+
73
+ it "no less" do
74
+ @it.step_in?(0).should == false
75
+ end
76
+ end
77
+
78
+ describe Fold::Precompiler, ".step_out?" do
79
+ before(:each) do
80
+ @it= Confused.new
81
+ end
82
+
83
+ it "must indent < 0" do
84
+ @it.step_out?(-1).should == true
85
+ end
86
+
87
+ it "cannot indent > 0" do
88
+ @it.step_out?(0).should == false
89
+ end
90
+ end
91
+
92
+ describe Fold::Precompiler, ".step_aside?" do
93
+ before(:each) do
94
+ @it= Confused.new
95
+ end
96
+
97
+ it "must indent 0" do
98
+ @it.step_aside?(0).should == true
99
+ end
100
+
101
+ it "no more" do
102
+ @it.step_aside?(1).should == false
103
+ end
104
+
105
+ it "no less" do
106
+ @it.step_aside?(-1).should == false
107
+ end
108
+ end
@@ -0,0 +1,15 @@
1
+ require 'rspec/fold_spec_helper'
2
+
3
+ describe Fold do
4
+ it "inherits Module" do
5
+ Fold.class.should == Module
6
+ end
7
+
8
+ it "has an Engine Class" do
9
+ Fold.constants.should include("Engine")
10
+ end
11
+
12
+ it "has a precompiler class" do
13
+ Fold.constants.should include("Precompiler")
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ path = File.dirname(__FILE__)
3
+ FoldFixtureRoot= File.expand_path("#{path}/fixtures/fold")
4
+ require "#{path}/../lib/fold"
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: collin-fold
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Collin Miller
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-25 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: rspec
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ description: A toolkit for creating whitespace active mini-languages. Inspired by Haml, light on features.
34
+ email: collintmiller@gmail.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - README
43
+ - Rakefile.rb
44
+ - lib/fold
45
+ - lib/fold/fold_factory.rb
46
+ - lib/fold/precompiler.rb
47
+ - lib/fold/engine.rb
48
+ - lib/fold/abstract_fold.rb
49
+ - lib/fold.rb
50
+ - rspec/fold
51
+ - rspec/fold/precompiler_spec.rb
52
+ - rspec/fold/abstract_fold_spec.rb
53
+ - rspec/fold/engine_spec.rb
54
+ - rspec/fold/fold_factory_spec.rb
55
+ - rspec/fixtures
56
+ - rspec/fixtures/fold
57
+ - rspec/fixtures/fold/fixture.target.fold
58
+ - rspec/fold_spec.rb
59
+ - rspec/fold_spec_helper.rb
60
+ has_rdoc: false
61
+ homepage: http://github.com/collin/fold
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.2.0
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: A toolkit for creating whitespace active mini-languages. Inspired by Haml, light on features.
86
+ test_files: []
87
+