fragment 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Mickael Riga
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,68 @@
1
+ FRAGMENT
2
+ ========
3
+
4
+ Fragment is an HTML builder heavily based on Gestalt from the Ramaze framework.
5
+ Its main purpose is to create fragments of HTML (hence the name),
6
+ but is perfectly suited for building full pages.
7
+
8
+ In essence, Fragment works more or less like any builder except that the code
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.
12
+
13
+ First, how to install:
14
+
15
+ sudo gem install fragment
16
+
17
+ Them you can require Fragment and use it that way:
18
+
19
+ require 'fragment'
20
+
21
+ default = 'HTML'
22
+
23
+ html = Fragment.please do
24
+ doctype
25
+ html(:lang=>'en') do
26
+ head { title { "My Choice" } }
27
+ body do
28
+ comment "Here starts the body"
29
+ select(:name => 'language') do
30
+ ['JS', 'HTML', 'CSS'].each do |l|
31
+ option(:value => l, :selected => l==default) { l }
32
+ end
33
+ end
34
+ write "\n<!-- This allows to write HTML directly when using a snippet -->\n"
35
+ write "\n<!-- like Google Analytics or including another fragment -->\n"
36
+ end
37
+ end
38
+ end
39
+
40
+ If you try this example, you might notice a couple of things:
41
+
42
+ 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` function which lets you write directly in place:
44
+
45
+ write "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'"
46
+ write " 'http://www.w3.org/TR/html4/strict.dtd'>"
47
+
48
+ The major difference with Gestalt (if you used it) is that it does not accept content
49
+ in the arguments. This simplifies the code a lot for a very small sacrifice.
50
+ So the argument is either a Hash that represents the attributes, or a string like
51
+ you would write in the HTML code.
52
+
53
+ One problem I had when creating fragments of HTML from code with a Hash for attributes
54
+ is for attributes like 'selected' or 'checked' which are a bit annoying because they do
55
+ not have a negative value (not that I know of), so you cannot write things like:
56
+
57
+ selected='not_selected'
58
+
59
+ I find this slightly irritating.
60
+ So what I did is that in the Hash, when a value is false, its key is removed.
61
+ This is what I did on the long example above for marking the default option.
62
+
63
+ Nothing fancy but quite good to be aware of.
64
+
65
+ Do not hesitate to fork the project if you want to help me improve it.
66
+
67
+ Thanx
68
+ Mig
@@ -0,0 +1,13 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'fragment'
3
+ s.version = "0.0.1"
4
+ s.platform = Gem::Platform::RUBY
5
+ s.summary = "Another HTML builder"
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
+ s.files = `git ls-files`.split("\n").sort
8
+ s.require_path = './lib'
9
+ s.author = "Mickael Riga"
10
+ s.email = "mig@campbellhay.com"
11
+ s.homepage = "http://www.campbellhay.com"
12
+ s.add_development_dependency(%q<bacon>, "~> 1.1.0")
13
+ end
@@ -0,0 +1,43 @@
1
+ class Fragment
2
+ attr_accessor :out
3
+
4
+ def self.please(&block); self.new(&block).out; end
5
+
6
+ def initialize(&block)
7
+ @out = ""
8
+ instance_eval(&block) if block_given?
9
+ end
10
+
11
+ def method_missing(meth, args={}, &block); tag(meth, args, &block); end
12
+
13
+ def tag(name, attributes={})
14
+ @out << "<#{name}"
15
+ if attributes.kind_of?(String)
16
+ @out << ' ' << attributes
17
+ else
18
+ @out << attributes.delete_if{|k,v| v.nil? or v==false }.map{|(k,v)| " #{k}='#{_fragment_escape_entities(v)}'" }.join
19
+ end
20
+ if block_given?
21
+ @out << ">"
22
+ text = yield
23
+ @out << text.to_str if text != @out and text.respond_to?(:to_str)
24
+ @out << "</#{name}>"
25
+ else
26
+ @out << ' />'
27
+ end
28
+ end
29
+
30
+ def _fragment_escape_entities(s)
31
+ s.to_s.gsub(/&/, '&amp;').gsub(/"/, '&quot;').gsub(/'/, '&apos;').gsub(/</, '&lt;').gsub(/>/, '&gt;')
32
+ end
33
+
34
+ # Override Kernel methods
35
+ def p(args={}, &block); tag(:p, args, &block); end
36
+ def select(args={}, &block); tag(:select, args, &block); end
37
+
38
+ # More
39
+ def write(s=''); @out << s; end
40
+ def doctype; write "<!DOCTYPE html>\n"; end
41
+ def comment(s=''); write "\n<!-- #{s} -->\n"; end
42
+
43
+ end
@@ -0,0 +1,160 @@
1
+ require 'rubygems'
2
+ require 'bacon'
3
+
4
+ ROOT = ::File.dirname(__FILE__)+'/..'
5
+ $:.unshift ROOT+'/lib'
6
+ require 'fragment'
7
+
8
+ describe "Fragment" do
9
+
10
+ def fragment &block
11
+ Fragment.please(&block)
12
+ end
13
+
14
+ it "simple tag" do
15
+ fragment{ br }.should == '<br />'
16
+ fragment{ p }.should == '<p />'
17
+ end
18
+
19
+ it "open close tags" do
20
+ fragment{ p{} }.should == '<p></p>'
21
+ fragment{ div{} }.should == '<div></div>'
22
+ end
23
+
24
+ it "nested tags" do
25
+ fragment{ p{ br } }.should == '<p><br /></p>'
26
+ end
27
+
28
+ it "deep nested tags" do
29
+ fragment do
30
+ p do
31
+ div do
32
+ ol do
33
+ li
34
+ end
35
+ end
36
+ end
37
+ end.should == '<p><div><ol><li /></ol></div></p>'
38
+ end
39
+
40
+ it "deep nested tags with repetition" do
41
+ fragment do
42
+ p do
43
+ div do
44
+ ol do
45
+ li
46
+ li
47
+ end
48
+ ol do
49
+ li
50
+ li
51
+ end
52
+ end
53
+ end
54
+ end.should == '<p><div><ol><li /><li /></ol><ol><li /><li /></ol></div></p>'
55
+ end
56
+
57
+ it "deep nested tags with strings" do
58
+ fragment do
59
+ p do
60
+ div {'Hello, World'}
61
+ end
62
+ end.should == '<p><div>Hello, World</div></p>'
63
+ end
64
+
65
+ it "allows to write directly if needed" do
66
+ fragment do
67
+ write "<!DOCTYPE html>"
68
+ end.should == '<!DOCTYPE html>'
69
+ end
70
+
71
+ it "some simple example" do
72
+ fragment do
73
+ doctype
74
+ html do
75
+ head do
76
+ title {"Hello World"}
77
+ end
78
+ body do
79
+ h1 {"Hello World"}
80
+ end
81
+ end
82
+ end.should == "<!DOCTYPE html>\n<html><head><title>Hello World</title></head><body><h1>Hello World</h1></body></html>"
83
+ end
84
+
85
+ it "some ruby inside" do
86
+ fragment do
87
+ table do
88
+ tr do
89
+ %w[one two three].each do |s|
90
+ td{s}
91
+ end
92
+ end
93
+ end
94
+ end.should == '<table><tr><td>one</td><td>two</td><td>three</td></tr></table>'
95
+ end
96
+
97
+ it "escapeable attributes" do
98
+ fragment {
99
+ a(:href => "http://example.org/?a=one&b=two") {
100
+ "Click here"
101
+ }
102
+ }.should == "<a href='http://example.org/?a=one&amp;b=two'>Click here</a>"
103
+ end
104
+
105
+ it "should accept attributes in a string" do
106
+ fragment{ input("type='text'") }.should == "<input type='text' />"
107
+ end
108
+
109
+ it 'should accept symbols as attributes' do
110
+ input = fragment{ input(:type => :text, :value => :one) }
111
+
112
+ input.should =~ /type='text'/
113
+ input.should =~ /value='one'/
114
+ end
115
+
116
+ it 'tags with prefix' do
117
+ fragment{ tag "prefix:local" }.should == '<prefix:local />'
118
+ end
119
+
120
+ it 'tags with a variety of characters' do
121
+ # with "-"
122
+ fragment{ tag "hello-world" }.should == '<hello-world />'
123
+ # with Hiragana
124
+ fragment{ tag "あいうえお" }.should == '<あいうえお />'
125
+ end
126
+
127
+ it "has a practicle way to add attributes like 'selected' based on boolean" do
128
+ @selected = false
129
+ fragment do
130
+ option({:name => 'opt', :selected => @selected})
131
+ option(:name => 'opt', :selected => !@selected)
132
+ option(:name => 'opt', :selected => @i_am_nil)
133
+ end.should == "<option name='opt' /><option name='opt' selected='true' /><option name='opt' />"
134
+ end
135
+
136
+ it "Pass the Readme example" do
137
+
138
+ default = 'HTML'
139
+
140
+ html = Fragment.please do
141
+ doctype
142
+ html(:lang=>'en') do
143
+ head { title { "My Choice" } }
144
+ body do
145
+ comment "Here starts the body"
146
+ select(:name => 'language') do
147
+ ['JS', 'HTML', 'CSS'].each do |l|
148
+ option(:value => l, :selected => l==default) { l }
149
+ end
150
+ end
151
+ write "\n<!-- This allows to write HTML directly when using a snippet -->\n"
152
+ write "\n<!-- like Google Analytics or including another fragment -->\n"
153
+ end
154
+ end
155
+ end
156
+
157
+ 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
+
159
+ end
160
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fragment
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Mickael Riga
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-12-14 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: bacon
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 19
30
+ segments:
31
+ - 1
32
+ - 1
33
+ - 0
34
+ version: 1.1.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ 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.
38
+ email: mig@campbellhay.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - MIT_LICENCE
47
+ - README.md
48
+ - fragment-0.0.1.gem
49
+ - fragment.gemspec
50
+ - lib/fragment.rb
51
+ - test/spec_fragment.rb
52
+ has_rdoc: true
53
+ homepage: http://www.campbellhay.com
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options: []
58
+
59
+ require_paths:
60
+ - ./lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.4.2
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Another HTML builder
86
+ test_files: []
87
+