taggart 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/README +57 -0
  2. data/Rakefile +3 -0
  3. data/lib/taggart.rb +217 -0
  4. data/spec/taggart_spec.rb +139 -0
  5. data/taggart.gemspec +15 -0
  6. metadata +65 -0
data/README ADDED
@@ -0,0 +1,57 @@
1
+ Taggart is a proof-of-concept to "decorate" strings with HTML tags.
2
+ ===================================================================
3
+ Background:
4
+ It's not particularly nice to write "<strong>#{my_variable}</strong>" when
5
+ One could simply write my_variable.strong. The more complex the Ruby code
6
+ is, the nicer it is to not have ", #, { or } soiling the code.
7
+
8
+
9
+ Playtime:
10
+ Install the gem:
11
+ gem install taggart
12
+ Then load Taggart with:
13
+ require 'taggart'
14
+ Taggart is now active, which means you can play around.
15
+ Try:
16
+ "Hello World".h1
17
+ Or (typographically bad taste):
18
+ "Important".em.strong
19
+ Or do some proper nesting:
20
+ ("Label".td + "Value".td)._tr.table
21
+ Add attributes
22
+ "hello".span(class: 'stuff', id: 'thing')
23
+ How about a table using arrays?:
24
+ (%w(r1c1 r1c2 r1c3).td.tr + %w(r2c1 r2c2 r2c3).td.tr).table
25
+ We can also do single tags.
26
+ "Gimme a".br
27
+
28
+ Issues:
29
+ - "hello"._sub('world', 'world') returns
30
+ "<sub world world>hello</sub>"
31
+ Not really perfect
32
+
33
+ Future??? (with your blessing)
34
+ - Extending to other HTML elements. "/images/company_logo.jpg".img (could check file, size, etc.)
35
+ "/pages/about_us.html".href
36
+
37
+ History
38
+ - Created Gem
39
+ - Pushed code to Git.
40
+ - Created test Gem.
41
+ - Added files to create Gem and reorganised the file structure.
42
+ - Made dual_sub pass all the tests, and added the examples from .tr (translate) Ruby docs to the test.
43
+ - More work on the "dynamic namespace clash resolver", in other words, tr and sub work in both classic and Taggart way.
44
+ - Initial version of "dynamic namespace clash resolver" to fix issues with .tr
45
+ - Added basic RSpec test.
46
+ - Added namespacing for Strings and Arrays
47
+ - Implemented arrays; ["Label", "Value"].td.tr.table and ["First", "Second", "Third"].li.ol
48
+ - Tidied up things a bit.
49
+ - Added a version of attributes ("Red".span(class: 'red'))
50
+ - First version. Basic tags.
51
+
52
+ Feedback welcome!!
53
+
54
+ Author: Jocke Selin <jocke@selincite.com>
55
+ Date: 2012-02-16
56
+ Version: 0.0.3 Build 008
57
+ Github: https://github.com/jocke/taggart
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require 'rspec/core/rake_task'
2
+ RSpec::Core::RakeTask.new('spec')
3
+ task :default => :spec
data/lib/taggart.rb ADDED
@@ -0,0 +1,217 @@
1
+ # Taggart is a proof-of-concept to "decorate" strings with HTML tags.
2
+ # ===================================================================
3
+ # Background:
4
+ # It's not particularly nice to write "<strong>#{my_variable}</strong>" when
5
+ # One could simply write my_variable.strong. The more complex the Ruby code
6
+ # is, the nicer it is to not have ", #, { or } soiling the code.
7
+ #
8
+ #
9
+ # Playtime:
10
+ # Install the gem:
11
+ # gem install taggart
12
+ # Then load Taggart with:
13
+ # require 'taggart'
14
+ # Taggart is now active, which means you can play around.
15
+ # Try:
16
+ # "Hello World".h1
17
+ # Or (typographically bad taste):
18
+ # "Important".em.strong
19
+ # Or do some proper nesting:
20
+ # ("Label".td + "Value".td)._tr.table
21
+ # Add attributes
22
+ # "hello".span(class: 'stuff', id: 'thing')
23
+ # How about a table using arrays?:
24
+ # (%w(r1c1 r1c2 r1c3).td.tr + %w(r2c1 r2c2 r2c3).td.tr).table
25
+ # We can also do single tags.
26
+ # "Gimme a".br
27
+ #
28
+ # Issues:
29
+ # - "hello"._sub('world', 'world') returns
30
+ # "<sub world world>hello</sub>"
31
+ # Not really perfect
32
+ #
33
+ # Future??? (with your blessing)
34
+ # - Extending to other HTML elements. "/images/company_logo.jpg".img (could check file, size, etc.)
35
+ # "/pages/about_us.html".href
36
+ #
37
+ # History
38
+ # - Created Gem
39
+ # - Pushed code to Git.
40
+ # - Created test Gem.
41
+ # - Added files to create Gem and reorganised the file structure.
42
+ # - Made dual_sub pass all the tests, and added the examples from .tr (translate) Ruby docs to the test.
43
+ # - More work on the "dynamic namespace clash resolver", in other words, tr and sub work in both classic and Taggart way.
44
+ # - Initial version of "dynamic namespace clash resolver" to fix issues with .tr
45
+ # - Added basic RSpec test.
46
+ # - Added namespacing for Strings and Arrays
47
+ # - Implemented arrays; ["Label", "Value"].td.tr.table and ["First", "Second", "Third"].li.ol
48
+ # - Tidied up things a bit.
49
+ # - Added a version of attributes ("Red".span(class: 'red'))
50
+ # - First version. Basic tags.
51
+ #
52
+ # Feedback welcome!!
53
+ #
54
+ # Author: Jocke Selin <jocke@selincite.com>
55
+ # Date: 2012-02-16
56
+ # Version: 0.0.3 Build 008s
57
+ # Github: https://github.com/jocke/taggart
58
+
59
+ module Taggart
60
+ module String
61
+
62
+ DEBUG = false
63
+
64
+ # Redefining <tr> to work with both translate-tr and tag-tr
65
+ def dual_tr(*args)
66
+ puts "Args size: #{args.size}" if DEBUG
67
+ if ((args.size == 2) && (args[0].is_a? String) && (args[1].is_a? String))
68
+ puts "Send '#{args[0]}', '#{args[1]}' to translate-tr" if DEBUG
69
+ self.translate(args[0], args[1])
70
+ else
71
+ puts "Send to tag-tr" if DEBUG
72
+ self._tr(args.first)
73
+ end
74
+ end
75
+
76
+
77
+ # Redefining <sub> to work with both substitute-sub and tag-sub
78
+ def dual_sub(*args, &block)
79
+ puts "Args size: #{args.size}" if DEBUG
80
+ if (args[0].is_a? Hash)
81
+ puts "Send to tag-sub" if DEBUG
82
+ self._sub(args.first)
83
+ elsif args.empty?
84
+ self._sub
85
+ else
86
+ puts "Send '#{args[0]}', '#{args[1]}' to substitute-sub" if DEBUG
87
+ if block_given?
88
+ self.substitute(args[0]) { |*args| block.call(*args) }
89
+ else
90
+ self.substitute(args[0], args[1])
91
+ end
92
+ end
93
+ end
94
+
95
+
96
+ private
97
+
98
+ # Parses the options for the tags
99
+ def parse_options(args)
100
+ # puts "parse_options: args #{args.inspect})" if DEBUG
101
+ return "" if args.nil?
102
+ output = []
103
+ args.each do |argument|
104
+ if argument.nil? # Do nothing
105
+ elsif argument.is_a? String
106
+ output << " " + argument
107
+ elsif argument.is_a? Hash
108
+ argument.each do |key, value|
109
+ output << "#{key.to_s}=\"#{value}\""
110
+ end
111
+ else
112
+ puts "Argument of type #{argument.class.name} is not implemented"
113
+ end
114
+ end
115
+ return "" if output.empty?
116
+ " " + output.join(' ')
117
+ end
118
+
119
+
120
+ # Defines a single tag, such as <br /> or <hr />
121
+ def self.single_attribute_tag(tag)
122
+ puts "Defining single-tag '#{tag}'" if DEBUG
123
+ define_method(tag) do |*args|
124
+ option_str = parse_options(args)
125
+ "#{self}<#{tag}#{option_str} />"
126
+ end
127
+ end
128
+
129
+
130
+ # Defines a standard tag that can have attributes
131
+ def self.attribute_tag(tag, tag_name = nil)
132
+ tag_name ||= tag
133
+ puts "Defining tag '#{(tag + "',").ljust(12)} with method name: '#{tag_name}'" if DEBUG
134
+ define_method(tag_name) do |*args|
135
+ option_str = parse_options(args)
136
+ "<#{tag}#{option_str}>#{self}</#{tag}>"
137
+ end
138
+ end
139
+
140
+
141
+ standard_tags = %w{ h1 h2 h3 h4 h5 h6 strong p em title table thead tbody th td tfoot div span abbr acronym address dd dl dt li ol ul tt pre sup }
142
+ special_tags = [['tr', '_tr'], ['sub', '_sub']]
143
+ tags = standard_tags + special_tags
144
+ puts "Tag definitions: #{tags.inspect}" if DEBUG
145
+ tags.each do |tag|
146
+ if tag.class.name == 'String'
147
+ self.attribute_tag(tag)
148
+ else
149
+ self.attribute_tag(tag[0], tag[1])
150
+ end
151
+ end
152
+
153
+ %w{br hr}.each do |tag|
154
+ self.single_attribute_tag(tag)
155
+ end
156
+
157
+ end # End String module
158
+
159
+
160
+ module Array
161
+
162
+ DEBUG = false
163
+
164
+ # Defines a standard tag that can create attributes
165
+ def self.array_attribute_tag(tag, tag_name = nil)
166
+ tag_name ||= tag
167
+ puts "Defining array tag '#{(tag + "',").ljust(12)} with method name: '#{tag_name}'" if DEBUG
168
+ define_method(tag_name) do |*args|
169
+ args = args.first if args # Only using the first of the array
170
+ puts "Array:#{tag_name} (with args #{args.inspect})" if DEBUG
171
+ result = []
172
+ self.each do |object|
173
+ puts "Object: #{object.inspect} (Type: #{object.class.name})" if DEBUG
174
+ if object.is_a? String
175
+ result << object.send(tag_name.to_sym, args)
176
+ elsif object.is_a? Symbol
177
+ result << object.to_s.send(tag_name.to_sym, args)
178
+ elsif object.is_a? Array # I don't know why you'd want to do this, but here it is.
179
+ result << (object.send(tag_name.to_sym, args)).send(tag_name.to_sym, args)
180
+ end
181
+ end
182
+ result.join
183
+ end
184
+ end
185
+
186
+ # Test examples:
187
+ # [:aaa, 'hellloooo'].td
188
+ # [:aaaa, [:bbb, :ccc, :ddd], :fff, :ggg].td
189
+ # ["Joe", "Marcus", "Chris", "Jim", "Aaron"]
190
+ # %w{One Two Three Four}.td(class: :numbers)
191
+ %w{td li}.each do |tag|
192
+ self.array_attribute_tag(tag)
193
+ end
194
+
195
+
196
+ end # End Array module
197
+ end
198
+
199
+
200
+ class String
201
+ alias_method :translate, :tr
202
+ alias_method :substitute, :sub
203
+ include Taggart::String
204
+
205
+ def tr(*args)
206
+ dual_tr(*args)
207
+ end
208
+
209
+ def sub(*args, &block)
210
+ dual_sub(*args, &block)
211
+ end
212
+ end
213
+
214
+
215
+ class Array
216
+ include Taggart::Array
217
+ end
@@ -0,0 +1,139 @@
1
+ # Run with: rspec -fd -c taggart_spec.rb
2
+ require 'taggart.rb'
3
+
4
+ describe Taggart::String, "#attribute_tags" do
5
+
6
+ it "returns a standard tag without any attributes" do
7
+ "hello world".h1.should == '<h1>hello world</h1>'
8
+ end
9
+
10
+ it "returns a standard tag with one attribute" do
11
+ "hello world".h1(class: :header).should == "<h1 class=\"header\">hello world</h1>"
12
+ end
13
+
14
+ it "returns a standard tag with two attribute" do
15
+ "hello world".h1(class: :header, id: :title).should == "<h1 class=\"header\" id=\"title\">hello world</h1>"
16
+ end
17
+ end
18
+
19
+
20
+ describe Taggart::String, "#single_attribute_tag" do
21
+
22
+ it "returns a single tag without any attributes" do
23
+ "hello world".br.should == 'hello world<br />'
24
+ end
25
+
26
+ it "returns a standard tag with one attribute" do
27
+ "hello world".br(class: :header).should == "hello world<br class=\"header\" />"
28
+ end
29
+
30
+ it "returns a standard tag with two attribute" do
31
+ "hello world".br(class: :header, id: :title).should == "hello world<br class=\"header\" id=\"title\" />"
32
+ end
33
+ end
34
+
35
+ describe Taggart::Array, "#array_attribute_tag" do
36
+
37
+ it "returns a the array elements as tags without any attributes" do
38
+ %w{one two three}.li.should == "<li>one</li><li>two</li><li>three</li>"
39
+ end
40
+
41
+ it "returns a the array elements as tags with one attribute" do
42
+ %w{one two three}.td(class: :programmers).should == "<td class=\"programmers\">one</td><td class=\"programmers\">two</td><td class=\"programmers\">three</td>"
43
+ end
44
+
45
+ it "returns a the array elements as tags with two attribute" do
46
+ %w{one two three}.td(class: :programmers, id: :unpossible).should == "<td class=\"programmers\" id=\"unpossible\">one</td><td class=\"programmers\" id=\"unpossible\">two</td><td class=\"programmers\" id=\"unpossible\">three</td>"
47
+ end
48
+
49
+ it "returns a the array symbol elements as tags without attributes" do
50
+ [:one, :two, :three].td.should == "<td>one</td><td>two</td><td>three</td>"
51
+ end
52
+
53
+ it "returns a the nested array elements as tags without attributes" do
54
+ [:one, [:nine, :eight, :seven], :two, :three].td.should == "<td>one</td><td><td>nine</td><td>eight</td><td>seven</td></td><td>two</td><td>three</td>"
55
+ end
56
+
57
+
58
+ describe Taggart::String, "#dual_tr" do
59
+ it "executes translate-tr when two parameters of string is passed in" do
60
+ "Jolly Roger".tr('J','G').tr('R', 'B').should == "Golly Boger"
61
+ end
62
+
63
+ it "executes tag-tr when no parameters are passed in" do
64
+ "Jolly Roger".tr.should == "<tr>Jolly Roger</tr>"
65
+ end
66
+
67
+ it "executes tag-tr when hash parameters are passed in" do
68
+ "Jolly Roger".tr(id: :jolly_roger).should == "<tr id=\"jolly_roger\">Jolly Roger</tr>"
69
+ end
70
+
71
+ it "executes translate-tr when the first example from the Ruby documentation is executed" do
72
+ "hello".tr('el', 'ip').should == "hippo"
73
+ end
74
+
75
+ it "executes translate-tr when the second example from the Ruby documentation is executed" do
76
+ "hello".tr('aeiou', '*').should == "h*ll*"
77
+ end
78
+
79
+ it "executes translate-tr when the third example from the Ruby documentation is executed" do
80
+ "hello".tr('a-y', 'b-z').should == "ifmmp"
81
+ end
82
+
83
+ it "executes translate-tr when the fourth example from the Ruby documentation is executed" do
84
+ "hello".tr('^aeiou', '*').should == "*e**o"
85
+ end
86
+ end
87
+
88
+
89
+ describe Taggart::String, "#dual_sub" do
90
+ it "executes substitute-sub when the first example from the documentation is passed in" do
91
+ "hello".sub(/[aeiou]/, '*').should == "h*llo"
92
+ end
93
+
94
+ it "executes substitute-sub when the 2nd example from the documentation is passed in" do
95
+ "hello".sub(/([aeiou])/, '<\1>').should == "h<e>llo"
96
+ end
97
+
98
+ it "executes substitute-sub when a simple block is provided" do
99
+ "hello".sub(/./) {|s| "-#{s}-" }.should == "-h-ello"
100
+ end
101
+
102
+ it "executes substitute-sub when the third example, with a block, from the documentation is passed in" do
103
+ "hello".sub(/./) {|s| s.ord.to_s + ' ' }.should == "104 ello"
104
+ end
105
+
106
+ it "executes substitute-sub when the fourth example, with a regexp, from the documentation is passed in" do
107
+ 'Is SHELL your preferred shell?'.sub(/[[:upper:]]{2,}/, ENV).should == "Is /bin/bash your preferred shell?"
108
+ end
109
+
110
+ it "executes substitute-sub when the fifth example, with a regexp, from the documentation is passed in" do
111
+ "hello".sub(/(?<foo>[aeiou])/, '*\k<foo>*').should == "h*e*llo"
112
+ end
113
+
114
+ it "executes tag-sub when no parameters are passed in" do
115
+ "You're just a substitute".sub.should == "<sub>You're just a substitute</sub>"
116
+ end
117
+
118
+ it "executes tag-sub when a hash of attribute-values are passed in" do
119
+ "You're just a substitute".sub(id: :thingy).should == "<sub id=\"thingy\">You're just a substitute</sub>"
120
+ end
121
+
122
+ it "executes tag-sub when a hash of two attribute-values are passed in" do
123
+ "You're just a substitute".sub(id: :thingy, class: :lowlowlow).should == "<sub id=\"thingy\" class=\"lowlowlow\">You're just a substitute</sub>"
124
+ end
125
+ end
126
+
127
+
128
+ describe Taggart::String, "More complex use" do
129
+ it "builds a small table HTML" do
130
+ row_1 = %w(r1c1 r1c2 r1c3)
131
+ row_2 = %w(r2c1 r2c2 r2c3)
132
+ (row_1.td.tr + row_2.td.tr).table.should == "<table><tr><td>r1c1</td><td>r1c2</td><td>r1c3</td></tr><tr><td>r2c1</td><td>r2c2</td><td>r2c3</td></tr></table>"
133
+ end
134
+
135
+ it "builds an ordered list HTML" do
136
+ %w(First Second Third Fourth Fifth Sizt Seventh).li.ol.should == "<ol><li>First</li><li>Second</li><li>Third</li><li>Fourth</li><li>Fifth</li><li>Sizt</li><li>Seventh</li></ol>"
137
+ end
138
+ end
139
+ end
data/taggart.gemspec ADDED
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "taggart"
3
+ s.version = "0.0.3"
4
+ s.date = "2012-02-16"
5
+ s.summary = "Simple HTML tag by String extension."
6
+ s.description = "Tag your strings in a simple and easy way by running \"Hello World\".h1 for example."
7
+ s.authors = ["Jocke Selin"]
8
+ s.email = ["jocke@selincite.com"]
9
+ s.homepage = "https://github.com/jocke/taggart"
10
+ s.require_paths = ["lib"]
11
+ s.files = ["lib/taggart.rb", "Rakefile", "taggart.gemspec", "README"]
12
+ s.test_files = ["spec/taggart_spec.rb"]
13
+ s.add_development_dependency "rspec"
14
+ s.post_install_message = "Thanks for showing interest in Taggart! Please provide feedback to jocke@selincite.com!"
15
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: taggart
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jocke Selin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70231726621400 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70231726621400
25
+ description: Tag your strings in a simple and easy way by running "Hello World".h1
26
+ for example.
27
+ email:
28
+ - jocke@selincite.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/taggart.rb
34
+ - Rakefile
35
+ - taggart.gemspec
36
+ - README
37
+ - spec/taggart_spec.rb
38
+ homepage: https://github.com/jocke/taggart
39
+ licenses: []
40
+ post_install_message: Thanks for showing interest in Taggart! Please provide feedback
41
+ to jocke@selincite.com!
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.16
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Simple HTML tag by String extension.
63
+ test_files:
64
+ - spec/taggart_spec.rb
65
+ has_rdoc: