taggart 0.0.3

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.
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: