WhiteCloth 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -12,6 +12,10 @@ source "http://rubygems.org"
12
12
 
13
13
  # Additional data structures
14
14
  gem "algorithms"
15
+ gem "rubytree", "~> 0.8.1"
16
+
17
+ # Log Library
18
+ gem "log4r", "~> 1.1.9"
15
19
 
16
20
  # GUID library
17
21
  gem "uuidtools"
@@ -16,6 +16,7 @@ GEM
16
16
  bundler (~> 1.0.0)
17
17
  git (>= 1.2.5)
18
18
  rake
19
+ log4r (1.1.9)
19
20
  minitest (2.1.0)
20
21
  rake (0.8.7)
21
22
  rcov (0.9.9)
@@ -32,6 +33,7 @@ GEM
32
33
  sexp_processor (~> 3.0)
33
34
  ruby_parser (2.0.6)
34
35
  sexp_processor (~> 3.0)
36
+ rubytree (0.8.1)
35
37
  sexp_processor (3.0.5)
36
38
  uuidtools (2.1.2)
37
39
  vclog (1.8.1)
@@ -51,11 +53,13 @@ DEPENDENCIES
51
53
  gibberish
52
54
  hiredis (~> 0.3.1)
53
55
  jeweler (~> 1.6.0)
56
+ log4r (~> 1.1.9)
54
57
  minitest
55
58
  rcov
56
59
  redis (~> 2.2.0)
57
60
  reek (~> 1.2.8)
58
61
  riot
62
+ rubytree (~> 0.8.1)
59
63
  uuidtools
60
64
  vclog
61
65
  yard (~> 0.6.0)
data/HISTORY CHANGED
@@ -1,5 +1,22 @@
1
1
  RELEASE HISTORY
2
2
 
3
+ v0.0.2 / 2011-05-16
4
+
5
+ Regenerate gemspec for version 0.0.2 (David Love david@homeunix.org.uk)
6
+
7
+ Changes:
8
+
9
+ * 2 Patch Enhancements
10
+
11
+ * Update the HISTORY
12
+ * Update the gemspec with the correct project information
13
+
14
+ * 2 General Enhancements
15
+
16
+ * Version bump to 0.0.2
17
+ * Regenerate gemspec for version 0.0.1
18
+
19
+
3
20
  v0.0.1 / 2011-05-16
4
21
 
5
22
  Regenerate gemspec for version 0.0.1 (David Love david@homeunix.org.uk)
@@ -17,17 +34,21 @@ Changes:
17
34
  * Initial commit to WhiteCloth.
18
35
 
19
36
 
20
- HEAD / 2011-05-17
37
+ HEAD / 2011-05-18
21
38
 
22
39
  Current Development (David Love)
23
40
 
24
41
  Changes:
25
42
 
26
- * 1 Patch Enhancements
43
+ * 5 Patch Enhancements
27
44
 
28
- * Update the gemspec with the correct project information
45
+ * Added foundations for the Standard Tree, including tests.
46
+ * Add a next function to UUIDTools::UUID to allow the generation of sequential UUID's
47
+ * Added basic sanity tests for the Gibberish library
48
+ * Update HISTORY file after tagging a version
49
+ * Remove FluxTuna from the testing namespace
29
50
 
30
51
  * 1 General Enhancements
31
52
 
32
- * Regenerate gemspec for version 0.0.1
53
+ * Regenerate gemspec for version 0.0.2
33
54
 
data/Rakefile CHANGED
@@ -68,7 +68,11 @@ task :test do
68
68
 
69
69
  "test/data/data_test.rb",
70
70
 
71
- "test/dir_walk/create_witness_test.rb"]
71
+ "test/data_structures/uuid_test.rb",
72
+ "test/data_structures/basic_tree_test.rb",
73
+ "test/data_structures/standard_tree_test.rb",
74
+
75
+ "test/projections/project_file_test.rb"]
72
76
  end
73
77
  end
74
78
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.4
@@ -4,12 +4,12 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{FluxTuna}
8
- s.version = "0.0.1"
7
+ s.name = %q{WhiteCloth}
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Love"]
12
- s.date = %q{2011-05-16}
12
+ s.date = %q{2011-05-17}
13
13
  s.default_executable = %q{whitecloth}
14
14
  s.description = %q{See: http://research.homeunix.org.uk}
15
15
  s.email = %q{david@homeunix.org.uk}
@@ -28,9 +28,19 @@ Gem::Specification.new do |s|
28
28
  "README.rdoc",
29
29
  "Rakefile",
30
30
  "VERSION",
31
+ "WhiteCloth.gemspec",
31
32
  "bin/whitecloth",
32
33
  "lib/LICENSE",
33
34
  "lib/WhiteCloth.rb",
35
+ "lib/data_structures.rb",
36
+ "lib/data_structures/standard_node.rb",
37
+ "lib/data_structures/standard_tree.rb",
38
+ "lib/data_structures/white_node.rb",
39
+ "lib/helpers/tree_builder.rb",
40
+ "lib/helpers/uuid.rb",
41
+ "lib/projections.rb",
42
+ "lib/projections/project_dir.rb",
43
+ "lib/projections/project_file.rb",
34
44
  "lib/whitecloth/cli.rb",
35
45
  "lib/whitecloth/cli/base.rb",
36
46
  "lib/whitecloth/cli/commands.rb",
@@ -51,10 +61,13 @@ Gem::Specification.new do |s|
51
61
  "test/data/bayeux/Welcome.byx",
52
62
  "test/data/bayeux/Welcome.yaml",
53
63
  "test/data/data_test.rb",
54
- "test/dir_walk/create_witness_test.rb",
55
- "test/init_test.rb"
64
+ "test/data_structures/basic_tree_test.rb",
65
+ "test/data_structures/standard_tree_test.rb",
66
+ "test/data_structures/uuid_test.rb",
67
+ "test/init_test.rb",
68
+ "test/projections/project_file_test.rb"
56
69
  ]
57
- s.homepage = %q{http://github.com/dlove24/FluxTuna}
70
+ s.homepage = %q{http://github.com/dlove24/WhiteCloth}
58
71
  s.licenses = ["ISC"]
59
72
  s.require_paths = ["lib"]
60
73
  s.rubygems_version = %q{1.6.2}
@@ -65,6 +78,8 @@ Gem::Specification.new do |s|
65
78
 
66
79
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
67
80
  s.add_runtime_dependency(%q<algorithms>, [">= 0"])
81
+ s.add_runtime_dependency(%q<rubytree>, ["~> 0.8.1"])
82
+ s.add_runtime_dependency(%q<log4r>, ["~> 1.1.9"])
68
83
  s.add_runtime_dependency(%q<uuidtools>, [">= 0"])
69
84
  s.add_runtime_dependency(%q<hiredis>, ["~> 0.3.1"])
70
85
  s.add_runtime_dependency(%q<em-synchrony>, [">= 0"])
@@ -82,6 +97,8 @@ Gem::Specification.new do |s|
82
97
  s.add_development_dependency(%q<reek>, ["~> 1.2.8"])
83
98
  else
84
99
  s.add_dependency(%q<algorithms>, [">= 0"])
100
+ s.add_dependency(%q<rubytree>, ["~> 0.8.1"])
101
+ s.add_dependency(%q<log4r>, ["~> 1.1.9"])
85
102
  s.add_dependency(%q<uuidtools>, [">= 0"])
86
103
  s.add_dependency(%q<hiredis>, ["~> 0.3.1"])
87
104
  s.add_dependency(%q<em-synchrony>, [">= 0"])
@@ -100,6 +117,8 @@ Gem::Specification.new do |s|
100
117
  end
101
118
  else
102
119
  s.add_dependency(%q<algorithms>, [">= 0"])
120
+ s.add_dependency(%q<rubytree>, ["~> 0.8.1"])
121
+ s.add_dependency(%q<log4r>, ["~> 1.1.9"])
103
122
  s.add_dependency(%q<uuidtools>, [">= 0"])
104
123
  s.add_dependency(%q<hiredis>, ["~> 0.3.1"])
105
124
  s.add_dependency(%q<em-synchrony>, [">= 0"])
@@ -0,0 +1,25 @@
1
+ # Copyright (c) 2011 David Love
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for
4
+ # any purpose with or without fee is hereby granted, provided that the
5
+ # above copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ #
15
+
16
+ # @author David Love
17
+
18
+ # Namespace for all the valid data structures used by {WhiteCloth} mutations
19
+ # and projections
20
+ module WhiteCloth::DataStructures
21
+
22
+ # Load the known data structures
23
+ require "data_structures/standard_tree"
24
+ require "data_structures/standard_node"
25
+ end
@@ -0,0 +1,64 @@
1
+ # Copyright (c) 2010-2011 David Love
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for
4
+ # any purpose with or without fee is hereby granted, provided that the
5
+ # above copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ #
15
+
16
+ # @author David Love
17
+
18
+ module WhiteCloth::DataStructures
19
+
20
+ # Load the base tree data structure
21
+ require "tree"
22
+
23
+ class StandardNode < Tree::TreeNode
24
+
25
+ ###
26
+ ### Constructors
27
+ ###
28
+
29
+ def initialize(node_id, content)
30
+ super(node_id, content)
31
+ end
32
+
33
+ ###
34
+ ### Operators
35
+ ###
36
+
37
+ # Add a new child node to the current node.
38
+ def << (child_node)
39
+ self.add(child_node)
40
+ end
41
+
42
+ # Look for the designated block within tree starting at the current node.
43
+ def [] (block_name)
44
+
45
+ # We need to work out which node has the right content. Since
46
+ # the nodes are effectively unordered, we have to look (potentially)
47
+ # at every node
48
+ self.each{|child|
49
+ if child.content === block_name then
50
+ return child
51
+ end
52
+ }
53
+
54
+ end
55
+
56
+ ###
57
+ ### Accessors
58
+ ###
59
+
60
+ # State that +id+ is an alias for the node name.
61
+ alias :id :name
62
+ end
63
+
64
+ end
@@ -0,0 +1,99 @@
1
+ # Copyright (c) 2010-2011 David Love
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for
4
+ # any purpose with or without fee is hereby granted, provided that the
5
+ # above copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ #
15
+
16
+ # @author David Love
17
+
18
+ module WhiteCloth::DataStructures
19
+
20
+ # The {StandardTree} is, as the name implies, the basic data structure for a realm.
21
+ # All mutations operate over a {StandardTree}, and all projections to and from the
22
+ # void create or imply a {StandardTree} as a result.
23
+ class StandardTree
24
+
25
+ ###
26
+ ### Constructors
27
+ ###
28
+
29
+ # Default constructor. Create a new tree, with a single node at the root.
30
+ def initialize(root_id = nil)
31
+ # Create the root id from supplied +root_id+, or a random one if the
32
+ # +root_id+ is missing
33
+ unless root_id.nil?
34
+ begin
35
+ @root_id = UUIDTools::UUID.parse(root_id)
36
+ rescue
37
+ @root_id = UUIDTools::UUID.random_create
38
+ end
39
+ else
40
+ @root_id = UUIDTools::UUID.random_create
41
+ end
42
+ @next_id = @root_id.next
43
+
44
+ # Create the root node for the tree
45
+ @nodes = StandardNode.new(@root_id.to_s, nil)
46
+ end
47
+
48
+ ###
49
+ ### Operators
50
+ ###
51
+
52
+ # Adds the specified nodes to the tree. The +node_list+ is a block, which is taken
53
+ # to be a hash of node names/node identities and the contents to add to the identified
54
+ # nodes.
55
+ def << (node_list)
56
+ Hash[*node_list.flatten].each{|parent, contents|
57
+ add_child(parent, contents)
58
+ }
59
+ end
60
+
61
+ # Look for the designated block within tree starting at the current node.
62
+ def [] (block_name)
63
+ return @nodes[block_name]
64
+ end
65
+
66
+ ###
67
+ ### Helper functions
68
+ ###
69
+
70
+ # Adds a new node to the tree, below the +parent+ node and with the specified
71
+ # +contents+.
72
+ def add_child(parent, contents)
73
+
74
+ # Find the parent node
75
+ if parent.nil? then
76
+ # Add to the root node
77
+ @nodes << StandardNode.new(@next_id.to_s, contents)
78
+ else
79
+ # Add to the relevant node
80
+ @nodes[parent] << StandardNode.new(@next_id.to_s, contents)
81
+ end
82
+
83
+ # Increment the node index
84
+ @next_id = @next_id.next
85
+
86
+ end
87
+
88
+ ###
89
+ ### Query functions
90
+ ###
91
+
92
+ # Is the tree 'empty' (i.e. it has only the root node)?
93
+ def empty?
94
+ return !@nodes.has_children?
95
+ end
96
+
97
+ end
98
+
99
+ end
@@ -0,0 +1,201 @@
1
+ class ParaBlock
2
+
3
+ # Default contructor
4
+ def initialize(type, content = "", target = nil)
5
+ @orig_type = type
6
+ @type = normalise_type(type)
7
+
8
+ @content = content
9
+ @target = target
10
+ end
11
+
12
+ ###
13
+ ### Accessors
14
+ ###
15
+
16
+ def type=(type)
17
+ @type = normalise_type(type)
18
+ end
19
+ def type
20
+ @type
21
+ end
22
+
23
+ def content=(content)
24
+ @content = content
25
+ end
26
+ def content
27
+ @content
28
+ end
29
+
30
+ def target=(target)
31
+ @target = target
32
+ end
33
+ def target
34
+ @target
35
+ end
36
+
37
+ ###
38
+ ### Convenience functions
39
+ ###
40
+
41
+ def <<(value)
42
+ @content << value
43
+ end
44
+
45
+ def empty?
46
+ return (@content.empty? or (/\S/ !~ @content))
47
+ end
48
+
49
+ def clear
50
+ @content.clear
51
+ end
52
+
53
+ # Returns the length of the type and target, as they were
54
+ # written out _in the original document_. For the current
55
+ # type length, see type_length
56
+ def orig_type_length
57
+ @orig_type.to_s.length + @target.to_s.length + 1
58
+ end
59
+
60
+ # Returns the length of the type and target, as they would
61
+ # be written out (including the separator), e.g as
62
+ # 'figure:L3'.length
63
+ def type_length
64
+ @type.to_s.length + @target.to_s.length + 1
65
+ end
66
+
67
+ # Take the current contents as a block
68
+ # type, and reset the content
69
+ def content_to_type!
70
+
71
+ unless @content =~ /\s+/ then
72
+ header = @content.split(':')
73
+
74
+ if header[0].nil? then
75
+
76
+ # If we can't work out the type, set everything
77
+ # to null
78
+ @type = :none
79
+ @target = nil
80
+
81
+ else
82
+
83
+ # Attempt to coerce the content to a type
84
+ block_type = header[0].to_sym
85
+ unless block_type.nil? then
86
+ @orig_type = block_type
87
+ @type = normalise_type(block_type)
88
+ else
89
+ @orig_type = :none
90
+ @type = :none
91
+ end
92
+
93
+ @target = header[1]
94
+
95
+ end
96
+
97
+ else
98
+ @type = :none
99
+ end
100
+
101
+ @content.clear
102
+ end
103
+
104
+ ###
105
+ ### Helper functions
106
+ ###
107
+
108
+ # Do type mapping if needed, otherwise
109
+ # pass on the contents as the type
110
+ def normalise_type(type)
111
+ case type
112
+ when :e
113
+ return :emph
114
+ when :s
115
+ return :strong
116
+ when :quote
117
+ return :block_quote
118
+ else
119
+ return type
120
+ end
121
+ end
122
+
123
+ ###
124
+ ### Type conversions
125
+ ###
126
+
127
+ def self.from_s(string)
128
+
129
+ unless string =~ /\s+/ then
130
+ header = string.split(':')
131
+
132
+ if header[0].nil? then
133
+
134
+ # If we can't work out the type, set everything
135
+ # to null
136
+ type = :none
137
+ target = nil
138
+
139
+ else
140
+
141
+ # Attempt to coerce the content to a type
142
+ block_type = header[0].to_sym
143
+ unless block_type.nil? then
144
+ type = block_type
145
+ else
146
+ type = :none
147
+ end
148
+
149
+ target = header[1]
150
+
151
+ end
152
+
153
+ else
154
+ type = :none
155
+ end
156
+
157
+ return ParaBlock.new(type, "", target)
158
+ end
159
+
160
+ def to_s
161
+ @content.to_s
162
+ end
163
+
164
+ def to_debug_s
165
+ return "block type: #{type}, content: #{content}"
166
+ end
167
+
168
+ def to_sym
169
+ @content.to_sym
170
+ end
171
+
172
+ def to_json(*a)
173
+ begin
174
+ require 'json'
175
+
176
+ json_hash = {
177
+ "type" => @name,
178
+ "content" => @content,
179
+ "target" => @target,
180
+ JSON.create_id => self.class.name
181
+ }
182
+
183
+ return json_hash.to_json
184
+
185
+ rescue LoadError
186
+ warn "The JSON gem couldn't be loaded, and so the JSON representation could not be generated"
187
+ end
188
+ end
189
+
190
+ def self.json_create(json_hash)
191
+ begin
192
+ require 'json'
193
+
194
+ block = new(json_hash["type"], json_hash["content"], json_hash["target"])
195
+ return block
196
+
197
+ rescue LoadError
198
+ warn "The JSON gem couldn't be loaded, and so the JSON representation could not be generated"
199
+ end
200
+ end
201
+ end