html-schema 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +76 -0
- data/lib/html-schema.rb +83 -0
- data/lib/html-schema/api.rb +253 -0
- data/lib/html-schema/api/attribute.rb +54 -0
- data/lib/html-schema/api/object.rb +26 -0
- data/lib/html-schema/attribute.rb +43 -0
- data/lib/html-schema/configuration.rb +10 -0
- data/lib/html-schema/dsl.rb +23 -0
- data/lib/html-schema/helper.rb +10 -0
- data/lib/html-schema/microdata.rb +450 -0
- data/lib/html-schema/microdata/attribute.rb +9 -0
- data/lib/html-schema/microdata/object.rb +13 -0
- data/lib/html-schema/microformat.rb +218 -0
- data/lib/html-schema/microformat/attribute.rb +9 -0
- data/lib/html-schema/microformat/object.rb +9 -0
- data/lib/html-schema/object.rb +63 -0
- data/spec/schema_spec.rb +86 -0
- data/spec/spec_helper.rb +14 -0
- metadata +71 -0
@@ -0,0 +1,218 @@
|
|
1
|
+
class HTMLSchema
|
2
|
+
class Microformat
|
3
|
+
extend HTMLSchema::DSL
|
4
|
+
|
5
|
+
type :object do
|
6
|
+
attribute :name
|
7
|
+
attribute :title
|
8
|
+
attribute :url
|
9
|
+
attribute :description
|
10
|
+
attribute :image
|
11
|
+
|
12
|
+
type :address, :as => :adr do
|
13
|
+
#adr type: INTL, POSTAL, PARCEL, WORK, dom, home, pref
|
14
|
+
#tel type: VOICE, home, msg, work, pref, fax, cell, video, pager, bbs, modem, car, isdn, pcs
|
15
|
+
#email type: INTERNET, x400, pref
|
16
|
+
|
17
|
+
attribute :street, :as => :"street-address"
|
18
|
+
attribute :suite, :as => :"extended-address"
|
19
|
+
attribute :city, :as => :locality
|
20
|
+
attribute :state, :as => :region
|
21
|
+
attribute :postal_code, :as => :"postal-code"
|
22
|
+
attribute :post_office_box, :as => :"post-office-box"
|
23
|
+
attribute :country, :as => :"country-name"
|
24
|
+
end
|
25
|
+
|
26
|
+
type :composition, :as => :hentry do
|
27
|
+
attribute :feed, :as => :hfeed
|
28
|
+
attribute :title, :as => :"entry-title", :required => true
|
29
|
+
attribute :body, :as => :"entry-content"
|
30
|
+
attribute :description, :as => :"entry-summary"
|
31
|
+
attribute :updated_at, :as => :updated, :type => :date, :required => true
|
32
|
+
attribute :published_at, :as => :published, :type => :date
|
33
|
+
attribute :author, :type => :person, :required => true
|
34
|
+
attribute :bookmark
|
35
|
+
attribute :tag, :rel => :tag
|
36
|
+
|
37
|
+
type :article do #, :as => :hnews
|
38
|
+
attribute :organization, :as => :"source-org", :type => :organization
|
39
|
+
attribute :location, :as => :"dateline", :type => :place
|
40
|
+
attribute :coordinates, :as => :geo, :type => :coordinates
|
41
|
+
attribute :license, :as => :"item-license"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
type :event, :as => :vevent do
|
46
|
+
attribute :feed, :as => :vcalendar
|
47
|
+
attribute :description, :as => :summary
|
48
|
+
attribute :start_date, :as => :dtstart, :type => :date
|
49
|
+
attribute :end_date, :as => :dtend, :type => :date # ISO date
|
50
|
+
attribute :location, :as => :location, :type => :address
|
51
|
+
attribute :url
|
52
|
+
attribute :rdate
|
53
|
+
attribute :rrule
|
54
|
+
attribute :category
|
55
|
+
attribute :description
|
56
|
+
attribute :uid
|
57
|
+
attribute :coordinates, :as => :geo, :type => :coordinates
|
58
|
+
attribute :attendee, :type => :person
|
59
|
+
attribute :contact, :type => :person
|
60
|
+
attribute :organizer, :type => :person
|
61
|
+
attribute :image, :as => :attach, :type => :image
|
62
|
+
attribute :status
|
63
|
+
end
|
64
|
+
|
65
|
+
type :license, :as => :item do
|
66
|
+
attribute :link, :as => :"item-license"
|
67
|
+
attribute :url, :as => :"item-url"
|
68
|
+
attribute :author, :as => :attribution, :type => :person
|
69
|
+
attribute :organization, :as => :attribution, :type => :organization
|
70
|
+
end
|
71
|
+
|
72
|
+
type :measurement, :as => :hmeasure do
|
73
|
+
type :angle, :as => :hangle
|
74
|
+
type :money, :as => :hmoney
|
75
|
+
|
76
|
+
attribute :value, :as => :num
|
77
|
+
attribute :unit
|
78
|
+
attribute :item # (text | hCard | hCalendar)
|
79
|
+
# attribute :type, :as => type ? (text, e.g. "height", "width", "weight")
|
80
|
+
end
|
81
|
+
|
82
|
+
type :media, :as => :hmedia do
|
83
|
+
# http://weborganics.co.uk/ns/2009/09/media/0.1/
|
84
|
+
attribute :name, :as => :fn
|
85
|
+
attribute :author, :as => :contributor, :type => :person
|
86
|
+
attribute :url, :as => :photo
|
87
|
+
attribute :player
|
88
|
+
attribute :link, :as => :enclosure # download
|
89
|
+
attribute :duration
|
90
|
+
|
91
|
+
type :audio
|
92
|
+
type :image
|
93
|
+
type :video
|
94
|
+
end
|
95
|
+
|
96
|
+
type :offer, :as => :hlisting do
|
97
|
+
attribute :version
|
98
|
+
attribute :action # class == sell | rent | trade | meet | announce | offer | wanted | event | service
|
99
|
+
attribute :lister, :type => :person, :required => true
|
100
|
+
attribute :published_at, :as => :dtlisted, :type => :date
|
101
|
+
attribute :expires_at, :as => :dtexpired, :type => :date
|
102
|
+
attribute :price
|
103
|
+
attribute :item, :type => :article
|
104
|
+
# <span class="item"><span class="fn">Parking space</span></span>, :required => true
|
105
|
+
# <span class="tel"><span class="type">home</span><span class="value">14981948194</span></span>
|
106
|
+
attribute :description
|
107
|
+
attribute :tag
|
108
|
+
attribute :link, :as => :permalink
|
109
|
+
end
|
110
|
+
|
111
|
+
type :person, :as => :vcard do
|
112
|
+
attribute :name, :as => :fn
|
113
|
+
attribute :address, :as => :adr, :type => :address
|
114
|
+
attribute :agent
|
115
|
+
attribute :birthday, :as => :bday
|
116
|
+
attribute :category
|
117
|
+
attribute :class
|
118
|
+
attribute :email
|
119
|
+
attribute :coordinates, :as => :geo, :type => :coordinates
|
120
|
+
attribute :key
|
121
|
+
attribute :label
|
122
|
+
attribute :logo
|
123
|
+
attribute :mailer
|
124
|
+
attribute :nickname
|
125
|
+
attribute :note
|
126
|
+
attribute :organization, :as => :org, :type => :organization
|
127
|
+
attribute :photo
|
128
|
+
attribute :rev
|
129
|
+
attribute :role
|
130
|
+
attribute :"sort-string"
|
131
|
+
attribute :sound
|
132
|
+
attribute :tel
|
133
|
+
attribute :job_title, :as => :title
|
134
|
+
attribute :tz
|
135
|
+
attribute :uid
|
136
|
+
attribute :url
|
137
|
+
|
138
|
+
type :author, :rel => :author
|
139
|
+
type :acquaintance, :rel => :acquaintance
|
140
|
+
type :child, :rel => :child
|
141
|
+
type :colleague, :rel => :colleague
|
142
|
+
type :contact, :rel => :contact
|
143
|
+
type :roommate, :rel => :"co-resident"
|
144
|
+
type :coworker, :rel => :"co-worker"
|
145
|
+
type :crush, :rel => :crush
|
146
|
+
type :date, :rel => :date
|
147
|
+
type :editor, :rel => :editor
|
148
|
+
type :fan, :rel => :fan
|
149
|
+
type :friend, :rel => :friend
|
150
|
+
type :kin, :rel => :kin
|
151
|
+
type :me, :rel => :me
|
152
|
+
type :met, :rel => :met
|
153
|
+
type :muse, :rel => :muse
|
154
|
+
type :neighbor, :rel => :neighbor
|
155
|
+
type :sibling, :rel => :sibling
|
156
|
+
type :spouse, :rel => :spouse
|
157
|
+
type :sweetheart, :rel => :sweetheart
|
158
|
+
type :member, :rel => :member
|
159
|
+
type :sponsor, :rel => :sponsor
|
160
|
+
type :user, :rel => :user
|
161
|
+
end
|
162
|
+
|
163
|
+
type :organization, :as => :org do
|
164
|
+
attribute :name, :as => :"organization-name"
|
165
|
+
attribute :unit, :as => :"organization-unit"
|
166
|
+
end
|
167
|
+
|
168
|
+
type :product, :as => :hProduct do
|
169
|
+
attribute :brand, :as => :organization
|
170
|
+
attribute :category
|
171
|
+
attribute :price
|
172
|
+
attribute :description
|
173
|
+
attribute :name, :as => :fn
|
174
|
+
attribute :image, :as => :photo
|
175
|
+
attribute :url
|
176
|
+
attribute :review, :type => :review
|
177
|
+
attribute :listing, :type => :offer
|
178
|
+
attribute :uid, :as => :identifier
|
179
|
+
end
|
180
|
+
|
181
|
+
type :rating do
|
182
|
+
attribute :best
|
183
|
+
attribute :worst
|
184
|
+
attribute :value
|
185
|
+
end
|
186
|
+
|
187
|
+
type :resume, :as => :hresume do
|
188
|
+
attribute :description, :as => :summary
|
189
|
+
attribute :contact, :type => :person
|
190
|
+
attribute :education, :type => :event
|
191
|
+
attribute :experience, :type => :event
|
192
|
+
attribute :skill
|
193
|
+
attribute :affiliation, :type => :organization
|
194
|
+
attribute :citation, :type => :citation
|
195
|
+
end
|
196
|
+
|
197
|
+
type :review, :as => :hReview do
|
198
|
+
attribute :version
|
199
|
+
attribute :summary
|
200
|
+
attribute :kind, :as => :type # product | business | event | person | place | website | url
|
201
|
+
attribute :event, :as => :item, :type => :event
|
202
|
+
attribute :item, :type => :person
|
203
|
+
attribute :reviewer, :type => :person
|
204
|
+
attribute :reviewed_at, :as => :dtreviewed, :type => :date
|
205
|
+
attribute :rating, :type => :rating
|
206
|
+
attribute :description
|
207
|
+
attribute :tag, :rel => :tag
|
208
|
+
attribute :url, :as => :permalink, :rel => :bookmark
|
209
|
+
attribute :license
|
210
|
+
end
|
211
|
+
|
212
|
+
type :value do
|
213
|
+
attribute :kind, :as => :type
|
214
|
+
attribute :value
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class HTMLSchema
|
2
|
+
class Object
|
3
|
+
attr_accessor :parent, :source, :as, :types, :attributes, :_name
|
4
|
+
attr_accessor :classes
|
5
|
+
|
6
|
+
def initialize(name, options = {}, &block)
|
7
|
+
@_name = name
|
8
|
+
@attributes = {}
|
9
|
+
@types = {}
|
10
|
+
@parent = options[:parent]
|
11
|
+
@as = options[:as]
|
12
|
+
@as ||= @parent ? @parent.as : name
|
13
|
+
@classes = Array(as).map(&:to_s)
|
14
|
+
|
15
|
+
# inherit parent attributes
|
16
|
+
@parent.attributes.each do |key, attribute|
|
17
|
+
self.attribute key, attribute.value
|
18
|
+
end if @parent
|
19
|
+
|
20
|
+
instance_eval(&block) if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
def attribute(name, options = {})
|
24
|
+
create_attribute name, options
|
25
|
+
end
|
26
|
+
|
27
|
+
def type(name, options = {}, &block)
|
28
|
+
create_type name, options, &block
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
"#<#{self.class.name} name: #{_name.inspect}, attributes: #{attributes.inspect} parent: #{(parent.present? ? parent._name : nil).inspect}, types: #{types.keys.inspect}>"
|
33
|
+
end
|
34
|
+
|
35
|
+
def [](key)
|
36
|
+
attributes[key]
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
def format_class
|
41
|
+
@format_class ||= "#{self.class.name.split("::")[0..-2].join("::")}".constantize
|
42
|
+
end
|
43
|
+
|
44
|
+
def attribute_class
|
45
|
+
@attribute_class ||= "#{format_class.name}::Attribute".constantize
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_attribute(name, options = {})
|
49
|
+
attributes[name] = attribute_class.new(name, options.merge(:parent => _name))
|
50
|
+
|
51
|
+
self.class.send :define_method, name do
|
52
|
+
self.attributes[name]
|
53
|
+
end unless self.respond_to?(name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_type(name, options = {}, &block)
|
57
|
+
types[name] = format_class[name] = self.class.new(name, options.reverse_merge(:parent => self), &block)
|
58
|
+
self.class.send :define_method, name do
|
59
|
+
self.types[name]
|
60
|
+
end unless self.respond_to?(name)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/spec/schema_spec.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HTMLSchema do
|
4
|
+
context ":output" do
|
5
|
+
before do
|
6
|
+
@schema = HTMLSchema.instance
|
7
|
+
end
|
8
|
+
|
9
|
+
context ":organization" do
|
10
|
+
before do
|
11
|
+
@organization = @schema.organization
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have attributes" do
|
15
|
+
@organization.to_hash.should == {
|
16
|
+
:itemscope => "itemscope",
|
17
|
+
:itemtype => "http://schema.org/Organization",
|
18
|
+
:class => "org"
|
19
|
+
}
|
20
|
+
|
21
|
+
@organization.name.to_hash.should == {:itemprop => "name", :class => "organization-name"}
|
22
|
+
@organization.description.to_hash.should == {:itemprop => "description", :class => "description"}
|
23
|
+
@organization.url.to_hash.should == {:itemprop => "url", :class => "url"}
|
24
|
+
@organization.image.to_hash.should == {:itemprop => "image", :class => "image"}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context ":person" do
|
29
|
+
before do
|
30
|
+
@person = @schema.person
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have attributes" do
|
34
|
+
@person.to_hash.should == {
|
35
|
+
#:itemprop => "person",
|
36
|
+
:itemscope => "itemscope",
|
37
|
+
:itemtype => "http://schema.org/Person",
|
38
|
+
:class => "vcard"
|
39
|
+
}
|
40
|
+
@person.name.to_hash.should == {:itemprop => "name", :class => "fn"}
|
41
|
+
@person.url.to_hash.should == {:itemprop => "url", :class => "url"}
|
42
|
+
@person.image.to_hash.should == {:itemprop => "image", :class => "image"}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context ":address" do
|
47
|
+
before do
|
48
|
+
@address = @schema.address
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have attributes" do
|
52
|
+
@address.to_hash.should == {
|
53
|
+
#:itemprop => "address",
|
54
|
+
:itemscope => "itemscope",
|
55
|
+
:itemtype => "http://schema.org/PostalAddress",
|
56
|
+
:class => "adr"
|
57
|
+
}
|
58
|
+
@address.name.to_hash.should == {:itemprop => "name", :class => "name"}
|
59
|
+
@address.url.to_hash.should == {:itemprop => "url", :class => "url"}
|
60
|
+
@address.image.to_hash.should == {:itemprop => "image", :class => "image"}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context ":article" do
|
65
|
+
before do
|
66
|
+
@article = @schema.article
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have attributes" do
|
70
|
+
@article.to_hash.should == {
|
71
|
+
:itemscope => "itemscope",
|
72
|
+
:itemtype => "http://schema.org/Article",
|
73
|
+
:class => "hentry"
|
74
|
+
}
|
75
|
+
|
76
|
+
@article.title.to_hash.should == {:itemprop => "title", :class => "entry-title"}
|
77
|
+
@article.tag.to_hash.should == {:itemprop => "keywords", :rel => "tag", :class => "tag"}
|
78
|
+
@article.description.to_hash.should == {:itemprop => "description", :class => "entry-summary"}
|
79
|
+
@article.body.to_hash.should == {:itemprop => "articleBody", :class => "entry-content"}
|
80
|
+
@article.published_at.to_hash.should == {:itemprop => "datePublished", :class => "published"}
|
81
|
+
@article.author.to_hash.should == {:itemprop => "author", :class => "author"}
|
82
|
+
@article.url.to_hash.should == {:itemprop => "url", :class => "url"}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
# rspec spec/microdata/base_spec.rb
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
$:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
13
|
+
|
14
|
+
require 'html-schema'
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: html-schema
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Lance Pollard
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-11 00:00:00 Z
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Unified Ruby API for HTML5 Microdata and Microformats
|
17
|
+
email: lancejpollard@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- Rakefile
|
26
|
+
- lib/html-schema/api/attribute.rb
|
27
|
+
- lib/html-schema/api/object.rb
|
28
|
+
- lib/html-schema/api.rb
|
29
|
+
- lib/html-schema/attribute.rb
|
30
|
+
- lib/html-schema/configuration.rb
|
31
|
+
- lib/html-schema/dsl.rb
|
32
|
+
- lib/html-schema/helper.rb
|
33
|
+
- lib/html-schema/microdata/attribute.rb
|
34
|
+
- lib/html-schema/microdata/object.rb
|
35
|
+
- lib/html-schema/microdata.rb
|
36
|
+
- lib/html-schema/microformat/attribute.rb
|
37
|
+
- lib/html-schema/microformat/object.rb
|
38
|
+
- lib/html-schema/microformat.rb
|
39
|
+
- lib/html-schema/object.rb
|
40
|
+
- lib/html-schema.rb
|
41
|
+
- spec/schema_spec.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
homepage: http://github.com/viatropos/html-schema
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project: html-schema
|
66
|
+
rubygems_version: 1.7.2
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: Unified Ruby API for HTML5 Microdata and Microformats
|
70
|
+
test_files: []
|
71
|
+
|