fragment 0.0.2 → 1.0.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.
- data/README.md +11 -8
- data/fragment.gemspec +3 -3
- data/lib/fragment.rb +29 -20
- data/test/spec_fragment.rb +61 -28
- metadata +35 -54
data/README.md
CHANGED
@@ -5,14 +5,11 @@ Fragment is an HTML builder heavily based on Gestalt from the Ramaze framework.
|
|
5
5
|
Its main purpose is to create fragments of HTML (hence the name),
|
6
6
|
but is perfectly suited for building full pages.
|
7
7
|
|
8
|
-
In essence, Fragment works more or less like any builder
|
9
|
-
is reduce to the minimum. Instead of trying to be universal, I would rather keep the
|
10
|
-
code as simple as possible and concentrate on small problems I have everyday when trying to
|
11
|
-
write HTML via Ruby.
|
8
|
+
In essence, Fragment works more or less like any builder.
|
12
9
|
|
13
10
|
First, how to install:
|
14
11
|
|
15
|
-
|
12
|
+
gem install fragment
|
16
13
|
|
17
14
|
Then you can require Fragment and use it that way:
|
18
15
|
|
@@ -20,7 +17,7 @@ Then you can require Fragment and use it that way:
|
|
20
17
|
|
21
18
|
default = 'HTML'
|
22
19
|
|
23
|
-
html = Fragment.
|
20
|
+
html = Fragment.create do
|
24
21
|
doctype
|
25
22
|
html(:lang=>'en') do
|
26
23
|
head { title { "My Choice" } }
|
@@ -40,7 +37,7 @@ Then you can require Fragment and use it that way:
|
|
40
37
|
If you try this example, you might notice a couple of things:
|
41
38
|
|
42
39
|
First of all, you have a `doctype` helper which only creates an HTML5 doctype.
|
43
|
-
If you want something else, you can use the `write`
|
40
|
+
If you want something else, you can use the `write` method which lets you write directly in place:
|
44
41
|
|
45
42
|
write "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'"
|
46
43
|
write " 'http://www.w3.org/TR/html4/strict.dtd'>"
|
@@ -62,7 +59,13 @@ This is what I did on the long example above for marking the default option.
|
|
62
59
|
|
63
60
|
Nothing fancy but quite good to be aware of.
|
64
61
|
|
62
|
+
If you do something and want to keep the scope you are in, you can use `create_here` instead of `here`. You then have access to the methods through the fragment object passed to the block:
|
63
|
+
|
64
|
+
html = Fragment.create_here do |f|
|
65
|
+
f.h1 { "" }
|
66
|
+
end
|
67
|
+
|
65
68
|
Do not hesitate to fork the project if you want to help me improve it.
|
66
69
|
|
67
70
|
Thanx
|
68
|
-
Mig
|
71
|
+
Mig
|
data/fragment.gemspec
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'fragment'
|
3
|
-
s.version = "0.0
|
3
|
+
s.version = "1.0.0"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
|
-
s.summary = "
|
5
|
+
s.summary = "Lightweight HTML builder"
|
6
6
|
s.description = "An HTML builder heavily based on Gestalt from the Ramaze framework. Its main purpose is to create fragments (hence the name), but is perfectly suited for building full pages."
|
7
7
|
s.files = `git ls-files`.split("\n").sort
|
8
8
|
s.require_path = './lib'
|
9
9
|
s.author = "Mickael Riga"
|
10
|
-
s.email = "mig@
|
10
|
+
s.email = "mig@mypeplum.com"
|
11
11
|
s.homepage = "https://github.com/mig-hub/fragment"
|
12
12
|
s.add_development_dependency(%q<bacon>, "~> 1.1.0")
|
13
13
|
end
|
data/lib/fragment.rb
CHANGED
@@ -1,43 +1,52 @@
|
|
1
1
|
class Fragment
|
2
|
-
attr_accessor :
|
2
|
+
attr_accessor :to_s
|
3
3
|
|
4
|
-
def self.
|
4
|
+
def self.create(&block); self.new(false,&block).to_s; end
|
5
|
+
def self.create_here(&block); self.new(true,&block).to_s; end
|
5
6
|
|
6
|
-
def initialize
|
7
|
-
@
|
8
|
-
|
7
|
+
def initialize outer_scope=false, &block
|
8
|
+
@to_s = ""
|
9
|
+
return self unless block_given?
|
10
|
+
unless outer_scope
|
11
|
+
instance_eval(&block)
|
12
|
+
else
|
13
|
+
block.call(self)
|
14
|
+
end
|
15
|
+
self
|
9
16
|
end
|
10
17
|
|
11
18
|
def method_missing(meth, args={}, &block); tag(meth, args, &block); end
|
12
19
|
|
13
|
-
def tag
|
14
|
-
@
|
20
|
+
def tag name, attributes={}
|
21
|
+
@to_s << "<#{name}"
|
15
22
|
if attributes.kind_of?(String)
|
16
|
-
@
|
23
|
+
@to_s << ' ' << attributes
|
17
24
|
else
|
18
|
-
@
|
25
|
+
@to_s << attributes.delete_if{|k,v| v.nil? or v==false }.map{|(k,v)| " #{k}='#{_fragment_escape_html(v)}'" }.join
|
19
26
|
end
|
20
27
|
if block_given?
|
21
|
-
@
|
28
|
+
@to_s << ">"
|
22
29
|
text = yield
|
23
|
-
@
|
24
|
-
@
|
30
|
+
@to_s << text.to_str if text != @to_s and text.respond_to?(:to_str)
|
31
|
+
@to_s << "</#{name}>"
|
25
32
|
else
|
26
|
-
@
|
33
|
+
@to_s << ' />'
|
27
34
|
end
|
28
35
|
end
|
29
36
|
|
30
|
-
def _fragment_escape_entities(s)
|
31
|
-
s.to_s.gsub(/&/, '&').gsub(/"/, '"').gsub(/'/, ''').gsub(/</, '<').gsub(/>/, '>')
|
32
|
-
end
|
33
|
-
|
34
37
|
# Override Kernel methods
|
38
|
+
|
35
39
|
def p(args={}, &block); tag(:p, args, &block); end
|
36
40
|
def select(args={}, &block); tag(:select, args, &block); end
|
37
41
|
|
38
|
-
#
|
39
|
-
|
42
|
+
# Helpers
|
43
|
+
|
44
|
+
def write(s=''); @to_s << s; end
|
40
45
|
def doctype; write "<!DOCTYPE html>\n"; end
|
41
46
|
def comment(s=''); write "\n<!-- #{s} -->\n"; end
|
47
|
+
def _fragment_escape_html(s)
|
48
|
+
s.to_s.gsub(/&/, '&').gsub(/"/, '"').gsub(/'/, ''').gsub(/</, '<').gsub(/>/, '>')
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
42
52
|
|
43
|
-
end
|
data/test/spec_fragment.rb
CHANGED
@@ -1,31 +1,28 @@
|
|
1
|
-
|
2
|
-
require 'bacon'
|
1
|
+
# encoding: utf-8
|
3
2
|
|
4
|
-
|
5
|
-
$:.unshift
|
6
|
-
require
|
3
|
+
require 'bacon'
|
4
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
5
|
+
require "fragment"
|
7
6
|
|
8
|
-
describe
|
7
|
+
describe 'Fragment' do
|
9
8
|
|
10
|
-
def fragment &block
|
11
|
-
Fragment.please(&block)
|
12
|
-
end
|
9
|
+
def fragment(&block); Fragment.new(&block).to_s; end
|
13
10
|
|
14
|
-
it "simple
|
11
|
+
it "Builds simple tags" do
|
15
12
|
fragment{ br }.should == '<br />'
|
16
13
|
fragment{ p }.should == '<p />'
|
17
14
|
end
|
18
15
|
|
19
|
-
it "
|
16
|
+
it "Opens and closes tags" do
|
20
17
|
fragment{ p{} }.should == '<p></p>'
|
21
18
|
fragment{ div{} }.should == '<div></div>'
|
22
19
|
end
|
23
20
|
|
24
|
-
it "
|
21
|
+
it "Nests tags" do
|
25
22
|
fragment{ p{ br } }.should == '<p><br /></p>'
|
26
23
|
end
|
27
24
|
|
28
|
-
it "
|
25
|
+
it "Builds deeply nested tags" do
|
29
26
|
fragment do
|
30
27
|
p do
|
31
28
|
div do
|
@@ -37,7 +34,7 @@ describe "Fragment" do
|
|
37
34
|
end.should == '<p><div><ol><li /></ol></div></p>'
|
38
35
|
end
|
39
36
|
|
40
|
-
it "
|
37
|
+
it "Builds deeply nested tags with repetition" do
|
41
38
|
fragment do
|
42
39
|
p do
|
43
40
|
div do
|
@@ -54,7 +51,7 @@ describe "Fragment" do
|
|
54
51
|
end.should == '<p><div><ol><li /><li /></ol><ol><li /><li /></ol></div></p>'
|
55
52
|
end
|
56
53
|
|
57
|
-
it "
|
54
|
+
it "Builds deeply nested tags with strings" do
|
58
55
|
fragment do
|
59
56
|
p do
|
60
57
|
div {'Hello, World'}
|
@@ -62,13 +59,13 @@ describe "Fragment" do
|
|
62
59
|
end.should == '<p><div>Hello, World</div></p>'
|
63
60
|
end
|
64
61
|
|
65
|
-
it "
|
62
|
+
it "Allows to write directly if needed" do
|
66
63
|
fragment do
|
67
64
|
write "<!DOCTYPE html>"
|
68
65
|
end.should == '<!DOCTYPE html>'
|
69
66
|
end
|
70
67
|
|
71
|
-
it "
|
68
|
+
it "Builds a full HTML page" do
|
72
69
|
fragment do
|
73
70
|
doctype
|
74
71
|
html do
|
@@ -82,7 +79,7 @@ describe "Fragment" do
|
|
82
79
|
end.should == "<!DOCTYPE html>\n<html><head><title>Hello World</title></head><body><h1>Hello World</h1></body></html>"
|
83
80
|
end
|
84
81
|
|
85
|
-
it "some ruby inside" do
|
82
|
+
it "Builds with some ruby inside" do
|
86
83
|
fragment do
|
87
84
|
table do
|
88
85
|
tr do
|
@@ -94,7 +91,7 @@ describe "Fragment" do
|
|
94
91
|
end.should == '<table><tr><td>one</td><td>two</td><td>three</td></tr></table>'
|
95
92
|
end
|
96
93
|
|
97
|
-
it "escapeable attributes" do
|
94
|
+
it "Builds escapeable attributes" do
|
98
95
|
fragment {
|
99
96
|
a(:href => "http://example.org/?a=one&b=two") {
|
100
97
|
"Click here"
|
@@ -102,29 +99,29 @@ describe "Fragment" do
|
|
102
99
|
}.should == "<a href='http://example.org/?a=one&b=two'>Click here</a>"
|
103
100
|
end
|
104
101
|
|
105
|
-
it "
|
102
|
+
it "Should accept attributes in a string" do
|
106
103
|
fragment{ input("type='text'") }.should == "<input type='text' />"
|
107
104
|
end
|
108
105
|
|
109
|
-
it '
|
106
|
+
it 'Should accept symbols as attributes' do
|
110
107
|
input = fragment{ input(:type => :text, :value => :one) }
|
111
108
|
|
112
109
|
input.should =~ /type='text'/
|
113
110
|
input.should =~ /value='one'/
|
114
111
|
end
|
115
112
|
|
116
|
-
it 'tags with prefix' do
|
113
|
+
it 'Builds tags with prefix' do
|
117
114
|
fragment{ tag "prefix:local" }.should == '<prefix:local />'
|
118
115
|
end
|
119
116
|
|
120
|
-
it 'tags with a variety of characters' do
|
117
|
+
it 'Builds tags with a variety of characters' do
|
121
118
|
# with "-"
|
122
119
|
fragment{ tag "hello-world" }.should == '<hello-world />'
|
123
120
|
# with Hiragana
|
124
121
|
fragment{ tag "あいうえお" }.should == '<あいうえお />'
|
125
122
|
end
|
126
123
|
|
127
|
-
it "
|
124
|
+
it "Has a practicle way to add attributes like 'selected' based on boolean" do
|
128
125
|
@selected = false
|
129
126
|
fragment do
|
130
127
|
option({:name => 'opt', :selected => @selected})
|
@@ -133,11 +130,11 @@ describe "Fragment" do
|
|
133
130
|
end.should == "<option name='opt' /><option name='opt' selected='true' /><option name='opt' />"
|
134
131
|
end
|
135
132
|
|
136
|
-
it "
|
133
|
+
it "Builds a more complex HTML page with a variable in the outer scope" do
|
137
134
|
|
138
135
|
default = 'HTML'
|
139
136
|
|
140
|
-
html = Fragment.
|
137
|
+
html = Fragment.new do
|
141
138
|
doctype
|
142
139
|
html(:lang=>'en') do
|
143
140
|
head { title { "My Choice" } }
|
@@ -152,9 +149,45 @@ describe "Fragment" do
|
|
152
149
|
write "\n<!-- like Google Analytics or including another fragment -->\n"
|
153
150
|
end
|
154
151
|
end
|
155
|
-
end
|
152
|
+
end.to_s
|
156
153
|
|
157
154
|
html.should == "<!DOCTYPE html>\n<html lang='en'><head><title>My Choice</title></head><body>\n<!-- Here starts the body -->\n<select name='language'><option value='JS'>JS</option><option value='HTML' selected='true'>HTML</option><option value='CSS'>CSS</option></select>\n<!-- This allows to write HTML directly when using a snippet -->\n\n<!-- like Google Analytics or including another fragment -->\n</body></html>"
|
158
155
|
|
159
156
|
end
|
160
|
-
|
157
|
+
|
158
|
+
it 'Can be used inside the scope of an object' do
|
159
|
+
class Stranger
|
160
|
+
attr_accessor :name, :comment
|
161
|
+
def show_comment
|
162
|
+
Fragment.new(true) do |b|
|
163
|
+
b.p{ self.comment }
|
164
|
+
end.to_s
|
165
|
+
end
|
166
|
+
def show_summary
|
167
|
+
Fragment.create_here do |b|
|
168
|
+
b.article do
|
169
|
+
b.h1{ self.name }
|
170
|
+
b.p{ self.comment }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
def fail_summary
|
175
|
+
Fragment.create do
|
176
|
+
article do
|
177
|
+
h1{ self.name }
|
178
|
+
p{ self.comment }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
s = Stranger.new
|
185
|
+
s.name = 'The Doors'
|
186
|
+
s.comment = 'Strange days'
|
187
|
+
s.show_comment.should=='<p>Strange days</p>'
|
188
|
+
s.show_summary.should=='<article><h1>The Doors</h1><p>Strange days</p></article>'
|
189
|
+
s.fail_summary.should=="<article><h1><name /></h1><p>\n<!-- -->\n</p></article>"
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
metadata
CHANGED
@@ -1,87 +1,68 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: fragment
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 2
|
10
|
-
version: 0.0.2
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Mickael Riga
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2014-10-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: bacon
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
18
|
+
requirements:
|
27
19
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 19
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 1
|
33
|
-
- 0
|
20
|
+
- !ruby/object:Gem::Version
|
34
21
|
version: 1.1.0
|
35
22
|
type: :development
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.1.0
|
30
|
+
description: An HTML builder heavily based on Gestalt from the Ramaze framework. Its
|
31
|
+
main purpose is to create fragments (hence the name), but is perfectly suited for
|
32
|
+
building full pages.
|
33
|
+
email: mig@mypeplum.com
|
39
34
|
executables: []
|
40
|
-
|
41
35
|
extensions: []
|
42
|
-
|
43
36
|
extra_rdoc_files: []
|
44
|
-
|
45
|
-
files:
|
37
|
+
files:
|
46
38
|
- .gitignore
|
47
39
|
- MIT_LICENCE
|
48
40
|
- README.md
|
49
41
|
- fragment.gemspec
|
50
42
|
- lib/fragment.rb
|
51
43
|
- test/spec_fragment.rb
|
52
|
-
has_rdoc: true
|
53
44
|
homepage: https://github.com/mig-hub/fragment
|
54
45
|
licenses: []
|
55
|
-
|
56
46
|
post_install_message:
|
57
47
|
rdoc_options: []
|
58
|
-
|
59
|
-
require_paths:
|
48
|
+
require_paths:
|
60
49
|
- ./lib
|
61
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
51
|
none: false
|
63
|
-
requirements:
|
64
|
-
- -
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
|
67
|
-
|
68
|
-
- 0
|
69
|
-
version: "0"
|
70
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
57
|
none: false
|
72
|
-
requirements:
|
73
|
-
- -
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
76
|
-
segments:
|
77
|
-
- 0
|
78
|
-
version: "0"
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
79
62
|
requirements: []
|
80
|
-
|
81
63
|
rubyforge_project:
|
82
|
-
rubygems_version: 1.
|
64
|
+
rubygems_version: 1.8.23
|
83
65
|
signing_key:
|
84
66
|
specification_version: 3
|
85
|
-
summary:
|
67
|
+
summary: Lightweight HTML builder
|
86
68
|
test_files: []
|
87
|
-
|