html-schema 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,76 @@
1
+ require 'rake'
2
+ require "rake/rdoctask"
3
+ require 'rake/gempackagetask'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = "html-schema"
7
+ s.authors = ["Lance Pollard"]
8
+ s.version = "0.2.0"
9
+ s.description = "Unified Ruby API for HTML5 Microdata and Microformats"
10
+ s.summary = "Unified Ruby API for HTML5 Microdata and Microformats"
11
+ s.homepage = "http://github.com/viatropos/html-schema"
12
+ s.email = "lancejpollard@gmail.com"
13
+ s.rubyforge_project = "html-schema"
14
+ s.platform = Gem::Platform::RUBY
15
+ s.files = %w(Rakefile) + Dir["{lib,rails,spec}/**/*"] - Dir["spec/tmp"]
16
+ s.require_path = "lib"
17
+ end
18
+
19
+ Rake::GemPackageTask.new(spec) do |pkg|
20
+ pkg.gem_spec = spec
21
+ end
22
+
23
+ desc 'run unit tests'
24
+ task :test do
25
+ Dir["test/**/*"].each do |file|
26
+ next unless File.basename(file) =~ /test_/
27
+ next unless File.extname(file) == ".rb"
28
+ system "ruby #{file}"
29
+ end
30
+ end
31
+
32
+ desc "Create .gemspec file (useful for github)"
33
+ task :gemspec do
34
+ File.open("#{spec.name}.gemspec", "w") do |f|
35
+ f.puts spec.to_ruby
36
+ end
37
+ end
38
+
39
+ desc "Build the gem into the current directory"
40
+ task :gem => :gemspec do
41
+ `gem build #{spec.name}.gemspec`
42
+ end
43
+
44
+ desc "Publish gem to rubygems"
45
+ task :publish => [:package] do
46
+ %x[gem push #{spec.name}-#{spec.version}.gem]
47
+ end
48
+
49
+ desc "Print a list of the files to be put into the gem"
50
+ task :manifest do
51
+ File.open("Manifest", "w") do |f|
52
+ spec.files.each do |file|
53
+ f.puts file
54
+ end
55
+ end
56
+ end
57
+
58
+ desc "Install the gem locally"
59
+ task :install => [:package] do
60
+ File.mkdir("pkg") unless File.exists?("pkg")
61
+ command = "gem install pkg/#{spec.name}-#{spec.version} --no-ri --no-rdoc"
62
+ command = "sudo #{command}" if ENV["SUDO"] == true
63
+ sh %{#{command}}
64
+ end
65
+
66
+ desc "Generate the rdoc"
67
+ Rake::RDocTask.new do |rdoc|
68
+ files = ["README.md", "lib/**/*.rb"]
69
+ rdoc.rdoc_files.add(files)
70
+ rdoc.main = "README.md"
71
+ rdoc.title = spec.summary
72
+ end
73
+
74
+ task :yank do
75
+ `gem yank #{spec.name} -v #{spec.version}`
76
+ end
@@ -0,0 +1,83 @@
1
+ require 'active_support/core_ext'
2
+
3
+ $:.unshift File.dirname(File.expand_path(__FILE__)) + "/html-schema"
4
+
5
+ class HTMLSchema
6
+ class << self
7
+ def root
8
+ @root ||= File.dirname(File.expand_path(__FILE__))
9
+ end
10
+
11
+ def configure(&block)
12
+ yield configuration
13
+ end
14
+
15
+ def configuration
16
+ @configuration ||= HTMLSchema::Configuration.new
17
+ end
18
+
19
+ def [](key)
20
+ api[key]
21
+ end
22
+
23
+ def instance
24
+ @instance ||= new
25
+ end
26
+
27
+ def instance=(value)
28
+ @instance = value
29
+ end
30
+
31
+ def bootstrap!(format)
32
+ format_name = format == :api ? "API" : format.to_s.camelize
33
+ Dir["#{HTMLSchema.root}/html-schema/#{format}/**/*.rb"].inject({}) do |hash, file|
34
+ name = ::File.basename(file, File.extname(file))
35
+ hash[name.to_sym] = "::HTMLSchema::#{format_name}::#{name.camelize}".constantize.new if name !~ /^(base|feed|attribute)$/
36
+ hash
37
+ end
38
+ end
39
+ end
40
+
41
+ def initialize(types = {})
42
+ self.class.instance = self
43
+ api.types.keys.each { |key| define_api_method(key) }
44
+ end
45
+
46
+ def api
47
+ @api ||= HTMLSchema::API
48
+ end
49
+
50
+ def microdata
51
+ @microdata ||= HTMLSchema::Microdata
52
+ end
53
+
54
+ def microformat
55
+ @microformat ||= HTMLSchema::Microformat
56
+ end
57
+
58
+ # todo, iterate through tree, so you can visualize it however you want.
59
+ def each(&block)
60
+
61
+ end
62
+
63
+ protected
64
+ def define_api_method(name)
65
+ self.class.send :define_method, name do
66
+ self.api[name]
67
+ end unless self.respond_to?(name)
68
+ end
69
+ end
70
+
71
+ require 'object'
72
+ require 'attribute'
73
+ require 'configuration'
74
+ require 'dsl'
75
+ require 'api/object'
76
+ require 'api/attribute'
77
+ require 'microdata/object'
78
+ require 'microdata/attribute'
79
+ require 'microformat/object'
80
+ require 'microformat/attribute'
81
+ require 'api'
82
+ require 'microdata'
83
+ require 'microformat'
@@ -0,0 +1,253 @@
1
+ class HTMLSchema
2
+ class API
3
+ extend HTMLSchema::DSL
4
+
5
+ type :object do
6
+ attribute :id
7
+ attribute :title
8
+ attribute :name
9
+ attribute :url
10
+ attribute :description
11
+ attribute :image
12
+
13
+ type :address do
14
+ attribute :street
15
+ attribute :suite
16
+ attribute :city
17
+ attribute :state
18
+ attribute :country
19
+ attribute :postal_code
20
+ attribute :post_office_box
21
+ end
22
+
23
+ type :composition do
24
+ attribute :abstract, :type => [:person, :organization]
25
+ attribute :average_rating, :type => :rating
26
+ attribute :award
27
+ attribute :rating, :type => :rating
28
+ attribute :genre
29
+ attribute :headline
30
+ attribute :language
31
+ attribute :interaction_count
32
+ attribute :family_friendly, :type => :boolean
33
+ attribute :keyword
34
+ attribute :offer, :type => :offer
35
+ attribute :review, :type => :review
36
+ attribute :editor, :type => :person
37
+ attribute :author, :type => :person
38
+ attribute :organization, :type => :organization
39
+ attribute :publisher, :type => :organization
40
+ attribute :location, :type => :address
41
+ attribute :videa, :type => :media
42
+ attribute :encoding, :type => :media
43
+ attribute :audio, :type => :media
44
+ attribute :tag
45
+ attribute :published_at, :type => :date
46
+
47
+ type :article do
48
+ attribute :body
49
+ attribute :section
50
+ end
51
+
52
+ type :media do
53
+ attribute :bitrate
54
+ attribute :size
55
+ attribute :url
56
+ attribute :embed_url
57
+ attribute :composition, :type => :article
58
+ attribute :format
59
+ attribute :player
60
+ attribute :allowed_in, :type => :address
61
+ attribute :subscription_required, :type => :boolean
62
+ attribute :expires_at, :type => :date
63
+ attribute :uploaded_at, :type => :date
64
+ attribute :duration, :as => :measurement
65
+ attribute :height, :type => :measurement
66
+ attribute :width, :type => :measurement
67
+
68
+ type :audio
69
+ type :image
70
+ type :video
71
+ end
72
+ end
73
+
74
+ type :coordinates do
75
+ attribute :elevation, :type => :measurement
76
+ attribute :latitude
77
+ attribute :longitude
78
+ end
79
+
80
+ type :event do
81
+ attribute :child_event, :type => :event
82
+ attribute :parent_event, :type => :event
83
+ attribute :start_date, :type => :date
84
+ attribute :end_date, :type => :date
85
+ attribute :location, :type => :address
86
+ attribute :duration, :type => :measurement
87
+ attribute :offer, :type => :offer
88
+ attribute :attendee, :type => :person
89
+ attribute :performer, :type => :person
90
+ attribute :organization, :type => :organization
91
+ end
92
+
93
+ type :figure do
94
+ attribute :image
95
+ attribute :legend
96
+ attribute :author, :type => [:person, :organization]
97
+ attribute :subject
98
+ end
99
+
100
+ type :item do
101
+ attribute :type
102
+ attribute :value
103
+ end
104
+
105
+ type :measurement do
106
+ attribute :value
107
+ attribute :unit
108
+ attribute :item, :type => [:text, :person, :organization, :media, :event]
109
+ end
110
+
111
+ type :offer do
112
+ attribute :rating, :type => :rating
113
+ attribute :availability
114
+ attribute :condition
115
+ attribute :item, :type => :product
116
+ attribute :price, :type => :measurement
117
+ attribute :min_price, :type => :measurement
118
+ attribute :max_price, :type => :measurement
119
+ attribute :currency
120
+ attribute :valid_until_date, :type => :date
121
+ attribute :review, :type => :review
122
+ attribute :seller, :type => :organization
123
+ attribute :count
124
+ end
125
+
126
+ type :organization do
127
+ attribute :address, :type => :address
128
+ attribute :average_rating, :type => :rating
129
+ attribute :contact, :type => [:person, :organization]
130
+ attribute :email
131
+ attribute :employee, :type => :person
132
+ attribute :event, :type => :event
133
+ attribute :fax
134
+ attribute :founder, :type => :person
135
+ attribute :founded_at, :type => :date
136
+
137
+ type :vendor do
138
+ attribute :branch_of, :type => :organization
139
+ attribute :hours
140
+ attribute :currency
141
+ attribute :payment_method
142
+ attribute :price_range
143
+ attribute :menu
144
+ attribute :reservations
145
+ attribute :cuisine
146
+ end
147
+ end
148
+
149
+ type :person do
150
+ attribute :address, :type => :address
151
+ attribute :home_address, :type => :address
152
+ attribute :work_address, :type => :address
153
+
154
+ # organizations
155
+ attribute :organization, :type => :organization
156
+ attribute :education, :type => :organization
157
+ attribute :membership, :type => :organization
158
+ attribute :company, :type => :organization
159
+
160
+ # events
161
+ attribute :performer_in, :type => :event
162
+
163
+ # dates
164
+ attribute :born_at, :type => :date
165
+ attribute :died_at, :type => :date
166
+
167
+ # relationships
168
+ attribute :children, :type => :person
169
+ attribute :parents, :type => :person
170
+ attribute :siblings, :type => :person
171
+ attribute :spouse, :type => :person
172
+ attribute :relationship, :type => :person
173
+ attribute :colleagues, :type => :person
174
+ # unidirectional
175
+ attribute :follows, :type => :person
176
+ # bidirectional
177
+ attribute :knows, :type => :person
178
+
179
+ # info
180
+ attribute :contact_info, :type => :contact
181
+ attribute :email
182
+ attribute :phone
183
+ attribute :fax
184
+ attribute :gender
185
+ attribute :interaction_count
186
+ attribute :job_title
187
+ attribute :nationality, :type => :place
188
+
189
+ type :author
190
+ type :acquaintance
191
+ type :child
192
+ type :colleague
193
+ type :contact
194
+ type :roommate
195
+ type :coworker
196
+ type :crush
197
+ type :date
198
+ type :editor
199
+ type :fan
200
+ type :friend
201
+ type :kin
202
+ type :me
203
+ type :met
204
+ type :muse
205
+ type :neighbor
206
+ type :sibling
207
+ type :spouse
208
+ type :sweetheart
209
+ type :member
210
+ type :sponsor
211
+ type :user
212
+ end
213
+
214
+ type :place do
215
+ attribute :address, :type => :address
216
+ attribute :rating, :type => :rating
217
+ attribute :surrounding, :type => :place
218
+ attribute :event, :type => :event
219
+ attribute :fax
220
+ attribute :coordinates, :type => :coordinates
221
+ attribute :interaction_count
222
+ attribute :map
223
+ attribute :image, :type => :media
224
+ attribute :review, :type => :review
225
+ attribute :phone
226
+ end
227
+
228
+ type :product do
229
+ attribute :rating, :type => :rating
230
+ attribute :brand, :type => :organization
231
+ attribute :manufacturer, :type => :organization
232
+ attribute :model
233
+ attribute :offer, :type => :offer
234
+ attribute :review, :type => :review
235
+ end
236
+
237
+ type :rating do
238
+ attribute :best
239
+ attribute :value
240
+ attribute :worst
241
+ attribute :item, :type => [:person, :event, :media, :place, :organization]
242
+ attribute :rating_count
243
+ attribute :review_count
244
+ end
245
+
246
+ type :review do
247
+ attribute :body
248
+ attribute :item, :type => [:person, :event, :media, :place, :organization]
249
+ attribute :rating, :type => :rating
250
+ end
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,54 @@
1
+ class HTMLSchema
2
+ class API
3
+ class Attribute < HTMLSchema::Attribute
4
+ def microdata
5
+ if @microdata.nil?
6
+ object = HTMLSchema.instance.microdata[parent]
7
+ object = object[_name] if object
8
+ object = false if object.blank?
9
+ @microdata = object
10
+ end
11
+
12
+ @microdata
13
+ end
14
+
15
+ def microdata?
16
+ !!microdata
17
+ end
18
+
19
+ def microformat
20
+ if @microformat.nil?
21
+ object = HTMLSchema.instance.microformat[parent]
22
+ object = object[_name] if object
23
+ object = false if object.blank?
24
+ @microformat = object
25
+ end
26
+ @microformat
27
+ end
28
+
29
+ def microformat?
30
+ !!microformat
31
+ end
32
+
33
+ def to_microdata
34
+ microdata.to_hash
35
+ end
36
+
37
+ def to_microformat
38
+ microformat.to_hash
39
+ end
40
+
41
+ def to_hash
42
+ if microdata? && microformat?
43
+ to_microdata.merge(to_microformat)
44
+ elsif microdata?
45
+ to_microdata
46
+ elsif microformat?
47
+ to_microformat
48
+ else
49
+ {}
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end