tamale 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 69c3ea40f44ddfe39d514a8d03c9eaa338ff9180
4
+ data.tar.gz: 0cb42e2e2fcd1bddded53f1fe8132b28cb237540
5
+ SHA512:
6
+ metadata.gz: 326cc04edbb8fe4243cdec771f4fd311942be7d4a1da0239466e562b6ce385af34a9d4ee1b46fda34c81a5537a4495b872122eb58473ac6d02d9791063b0815e
7
+ data.tar.gz: 1a52ed8d6267a2b07f6c19605b341b258c852abe1432bd8ea2b3c9e6a5a09c3bcc6be76b0bc33f072d63f1e85d3b82e3af5740bd52235836291478d5ffdc340c
data/.gitignore ADDED
@@ -0,0 +1,55 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+
52
+ ## Specific to macOS:
53
+
54
+ .DS_Store
55
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,17 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tamale (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+
10
+ PLATFORMS
11
+ ruby
12
+
13
+ DEPENDENCIES
14
+ tamale!
15
+
16
+ BUNDLED WITH
17
+ 1.14.6
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Tamale
2
+
3
+ Tamale is a DSL for generating HTML.
4
+
5
+ ## Installation
6
+
7
+ For use with bundler, add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'tamale'
11
+ ```
12
+
13
+ And then run bundle from the command line:
14
+
15
+ $ bundle
16
+
17
+ ## Usage
18
+
19
+ ```ruby
20
+ template = Tamale.new { |title|
21
+ div(id: 'app') {
22
+ h1 { text title }
23
+ }
24
+ }
25
+
26
+ template.render('Hot Tamale!')
27
+ ```
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ task :spec do
2
+ Dir.glob('./spec/**/*_spec.rb').each { |file| require file }
3
+ end
4
+
5
+ task default: :spec
data/lib/tamale.rb ADDED
@@ -0,0 +1,236 @@
1
+ class Tamale
2
+ def initialize(&template)
3
+ @template = template
4
+ end
5
+
6
+ def render(*args)
7
+ Context.new(@template, *args).call
8
+ end
9
+
10
+ private
11
+
12
+ module Tags
13
+ module Normal
14
+ TAGS = [
15
+ :a,
16
+ :abbr,
17
+ :acronym,
18
+ :address,
19
+ :applet,
20
+ :article,
21
+ :aside,
22
+ :audio,
23
+ :b,
24
+ :basefont,
25
+ :bdi,
26
+ :bdo,
27
+ :bgsound,
28
+ :big,
29
+ :blink,
30
+ :blockquote,
31
+ :body,
32
+ :button,
33
+ :canvas,
34
+ :caption,
35
+ :center,
36
+ :cite,
37
+ :code,
38
+ :colgroup,
39
+ :command,
40
+ :content,
41
+ :data,
42
+ :datalist,
43
+ :dd,
44
+ :del,
45
+ :details,
46
+ :dfn,
47
+ :dialog,
48
+ :dir,
49
+ :div,
50
+ :dl,
51
+ :dt,
52
+ :element,
53
+ :em,
54
+ :fieldset,
55
+ :figcaption,
56
+ :figure,
57
+ :font,
58
+ :footer,
59
+ :form,
60
+ :frame,
61
+ :frameset,
62
+ :h1,
63
+ :h2,
64
+ :h3,
65
+ :h4,
66
+ :h5,
67
+ :h6,
68
+ :head,
69
+ :header,
70
+ :hgroup,
71
+ :html,
72
+ :i,
73
+ :iframe,
74
+ :image,
75
+ :ins,
76
+ :isindex,
77
+ :kbd,
78
+ :label,
79
+ :legend,
80
+ :li,
81
+ :listing,
82
+ :main,
83
+ :map,
84
+ :mark,
85
+ :marquee,
86
+ :menu,
87
+ :meter,
88
+ :multicol,
89
+ :nav,
90
+ :nobr,
91
+ :noembed,
92
+ :noframes,
93
+ :noscript,
94
+ :object,
95
+ :ol,
96
+ :optgroup,
97
+ :option,
98
+ :output,
99
+ :p,
100
+ :picture,
101
+ :plaintext,
102
+ :pre,
103
+ :progress,
104
+ :q,
105
+ :rp,
106
+ :rt,
107
+ :rtc,
108
+ :ruby,
109
+ :s,
110
+ :samp,
111
+ :script,
112
+ :section,
113
+ :select,
114
+ :shadow,
115
+ :slot,
116
+ :small,
117
+ :spacer,
118
+ :span,
119
+ :strike,
120
+ :strong,
121
+ :style,
122
+ :sub,
123
+ :summary,
124
+ :sup,
125
+ :table,
126
+ :tbody,
127
+ :td,
128
+ :template,
129
+ :textarea,
130
+ :tfoot,
131
+ :th,
132
+ :thead,
133
+ :time,
134
+ :title,
135
+ :tr,
136
+ :tt,
137
+ :u,
138
+ :ul,
139
+ :var,
140
+ :video,
141
+ :xmp,
142
+ ]
143
+
144
+ def self.format(opening, contents, closing)
145
+ "<#{opening}>#{contents}</#{closing}>"
146
+ end
147
+ end
148
+
149
+ module Void
150
+ TAGS = [
151
+ :area,
152
+ :base,
153
+ :br,
154
+ :col,
155
+ :embed,
156
+ :hr,
157
+ :img,
158
+ :input,
159
+ :keygen,
160
+ :link,
161
+ :menuitem,
162
+ :meta,
163
+ :param,
164
+ :source,
165
+ :track,
166
+ :wbr,
167
+ ]
168
+
169
+ def self.format(opening, contents, closing)
170
+ "<#{opening} />"
171
+ end
172
+ end
173
+ end
174
+
175
+ class Builder
176
+ def initialize(type)
177
+ @type = type
178
+ end
179
+
180
+ def tags
181
+ @type.const_get(:TAGS)
182
+ end
183
+
184
+ def build(tag, attributes, contents = nil)
185
+ opening = build_opening(tag, attributes)
186
+
187
+ @type.format(opening, contents, tag)
188
+ end
189
+
190
+ private
191
+
192
+ def build_opening(tag, attributes)
193
+ attributes.keys.inject(tag) { |acc, key| acc << " #{key}=\"#{attributes[key]}\"" }
194
+ end
195
+ end
196
+
197
+ class Context
198
+ @@normal_builder = Builder.new(Tags::Normal).tap do |builder|
199
+ builder.tags.each do |tag|
200
+ class_eval <<-RUBY
201
+ def #{tag}(attributes = {})
202
+ contents = Context.new(Proc.new).call if block_given?
203
+
204
+ @acc << @@normal_builder.build('#{tag}', attributes, contents)
205
+ end
206
+ RUBY
207
+ end
208
+ end
209
+
210
+ @@void_builder = Builder.new(Tags::Void).tap do |builder|
211
+ builder.tags.each do |tag|
212
+ class_eval <<-RUBY
213
+ def #{tag}(attributes = {})
214
+ @acc << @@void_builder.build('#{tag}', attributes)
215
+ end
216
+ RUBY
217
+ end
218
+ end
219
+
220
+ def initialize(template, *args)
221
+ @template = template
222
+ @args = args
223
+ @acc = ''
224
+ end
225
+
226
+ def call
227
+ instance_exec(*@args, &@template)
228
+ end
229
+
230
+ private
231
+
232
+ def text(val)
233
+ @acc << val.to_s
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,3 @@
1
+ module Tamale
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,83 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/tamale'
3
+
4
+ describe 'Tamale#render' do
5
+ before do
6
+ @template = Tamale.new { |left, right|
7
+ text "#{left}#{right}"
8
+ }
9
+ end
10
+
11
+ it 'calls template with arguments' do
12
+ assert_equal('foobar', @template.render('foo', 'bar'))
13
+ end
14
+ end
15
+
16
+ describe 'Text elements' do
17
+ before do
18
+ @template = Tamale.new { |value|
19
+ div { text 'simple' }
20
+ }
21
+ end
22
+
23
+ it 'renders an html string' do
24
+ assert_equal('<div>simple</div>', @template.render)
25
+ end
26
+ end
27
+
28
+ describe 'Nested elements' do
29
+ before do
30
+ @template = Tamale.new {
31
+ ul {
32
+ li { text 'one' }
33
+ li { text 'two' }
34
+ }
35
+ }
36
+ end
37
+
38
+ it 'renders in proper context' do
39
+ assert_equal('<ul><li>one</li><li>two</li></ul>', @template.render)
40
+ end
41
+ end
42
+
43
+ describe 'Multinested elements' do
44
+ before do
45
+ @template = Tamale.new {
46
+ ul {
47
+ li {
48
+ text 'one'; text 'two'
49
+ }
50
+ }
51
+ }
52
+ end
53
+
54
+ it 'renders in proper context' do
55
+ assert_equal('<ul><li>onetwo</li></ul>', @template.render)
56
+ end
57
+ end
58
+
59
+ describe 'Void elements' do
60
+ before do
61
+ @template = Tamale.new {
62
+ div {
63
+ input(type: 'text')
64
+ }
65
+ }
66
+ end
67
+
68
+ it 'never prints a closing tag' do
69
+ assert_equal('<div><input type="text" /></div>', @template.render)
70
+ end
71
+ end
72
+
73
+ describe 'Normal elements' do
74
+ before do
75
+ @template = Tamale.new {
76
+ div { div }
77
+ }
78
+ end
79
+
80
+ it 'always prints a closing tag' do
81
+ assert_equal('<div><div></div></div>', @template.render)
82
+ end
83
+ end
data/tamale.gemspec ADDED
@@ -0,0 +1,12 @@
1
+ require_relative './lib/tamale/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'tamale'
5
+ s.summary = 'Tamale'
6
+ s.version = Tamale::VERSION
7
+ s.authors = ['Steve Weiss']
8
+ s.email = ['weissst@mail.gvsu.edu']
9
+ s.homepage = 'https://github.com/sirscriptalot/tamale'
10
+ s.license = 'MIT'
11
+ s.files = `git ls-files`.split("\n")
12
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tamale
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Steve Weiss
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - weissst@mail.gvsu.edu
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - README.md
24
+ - Rakefile
25
+ - lib/tamale.rb
26
+ - lib/tamale/version.rb
27
+ - spec/tamale_spec.rb
28
+ - tamale.gemspec
29
+ homepage: https://github.com/sirscriptalot/tamale
30
+ licenses:
31
+ - MIT
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 2.6.8
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: Tamale
53
+ test_files: []