collin-fold 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+