├── .gitignore
├── CHANGELOG.rdoc
├── lib
├── microformats.rb
├── calendar.rb
├── formatting_helpers.rb
├── helpers.rb
├── address.rb
├── event.rb
└── vcard.rb
├── README.md
├── spec
├── spec_helper.rb
├── formatting_helpers_spec.rb
├── calendar_spec.rb
├── helpers_spec.rb
├── address_spec.rb
├── event_spec.rb
└── vcard_spec.rb
├── microformats.gemspec
├── Rakefile
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | doc
--------------------------------------------------------------------------------
/CHANGELOG.rdoc:
--------------------------------------------------------------------------------
1 | = Microformats CHANGELOG
2 |
3 | == Version 0.1
4 | * Initial Implementation of Vcard
5 | * Implements hCard microformat
6 | * Implements Google's Person microdata http://www.data-vocabulary.org/Person/
--------------------------------------------------------------------------------
/lib/microformats.rb:
--------------------------------------------------------------------------------
1 | module Microformats
2 |
3 | end
4 |
5 | require 'time'
6 |
7 | require 'formatting_helpers'
8 | require 'vcard'
9 | require 'address'
10 | require 'calendar'
11 | require 'event'
12 | require 'helpers'
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # END OF LIFE : 2010-10-25
2 | # Microformats Tag Rails Helper
3 |
4 | **NO LONGER IN DEVELOPMENT. As of 2017-05-16, this repo is archived and unsupported. Use at your own risk.**
5 |
6 | **If you're looking for the Microformats Ruby Parser, you're in the wrong place. Go here instead: [https://github.com/indieweb/microformats2-ruby](github.com/indieweb/microformats2-ruby)**
7 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require File.join(File.dirname(__FILE__), '..', 'lib', 'microformats.rb')
3 |
4 | # We need to be able to test what Vcard is outputting using the
5 | # concat method. The output method just lets us check this.
6 | class MockTemplate
7 | def concat(str)
8 | @output ||= ''
9 | @output << str
10 | end
11 |
12 | def output
13 | @output
14 | end
15 | end
--------------------------------------------------------------------------------
/microformats.gemspec:
--------------------------------------------------------------------------------
1 | Gem::Specification.new do |s|
2 | s.name = 'microformats'
3 | s.version = '0.3'
4 | s.author = 'Chris Powers'
5 | s.date = "2010-09-11"
6 | s.homepage = 'http://github.com/chrisjpowers/microformats'
7 | s.email = 'chrisjpowers@gmail.com'
8 | s.summary = 'The Microformats gem gives you helper methods for richly marking up your HTML with microformats and HTML5 microdata.'
9 | s.files = [ 'README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'Rakefile', 'lib/address.rb',
10 | 'lib/calendar.rb', 'lib/event.rb', 'lib/formatting_helpers.rb',
11 | 'lib/helpers.rb', 'lib/microformats.rb', 'lib/vcard.rb']
12 | s.require_paths = ["lib"]
13 | s.has_rdoc = true
14 | end
15 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'rake'
3 | require 'rake/rdoctask'
4 | # require 'rake/gempackagetask'
5 | # require 'rcov/rcovtask'
6 | # require 'date'
7 |
8 | require 'spec/rake/spectask'
9 |
10 | desc 'Default: run the specs.'
11 | task :default => :spec
12 |
13 | Spec::Rake::SpecTask.new do |t|
14 | t.warning = true
15 | end
16 |
17 | namespace :doc do
18 | desc "Generate documentation for the gem."
19 | Rake::RDocTask.new("gem") { |rdoc|
20 | rdoc.rdoc_dir = 'doc'
21 | rdoc.title = "Microformats"
22 | rdoc.options << '--line-numbers' << '--inline-source'
23 | rdoc.options << '--charset' << 'utf-8'
24 | rdoc.rdoc_files.include('README.rdoc')
25 | rdoc.rdoc_files.include('lib/**/*.rb')
26 | }
27 | end
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 Chris Powers
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/lib/calendar.rb:
--------------------------------------------------------------------------------
1 | class Microformats::Calendar
2 | include Microformats::FormattingHelpers
3 |
4 | def initialize(template)
5 | @template = template
6 | @default_tag = :span
7 | end
8 |
9 | # You can directly initialize and run this class, but it's easier
10 | # to use the Microformats::Helpers#vcalendar helper method.
11 | #
12 | # OPTIONS:
13 | # * :tag - The HTML wrapper element (defaults to :div)
14 | # * Any other passed options will be treated as HTML attributes.
15 | #
16 | def run(opts = {}, &block)
17 | opts[:class] = combine_class_names('vcalendar', opts[:class])
18 | opts[:tag] ||= :div
19 | concat_tag(opts) do
20 | block.call(self)
21 | end
22 | end
23 |
24 | # Creates a vEvent with the given options and a block.
25 | #
26 | # OPTIONS:
27 | # * :tag - The HTML wrapper element (defaults to :div)
28 | # * Any other passed options will be treated as HTML attributes.
29 | #
30 | # EXAMPLE:
31 | # <% calendar.event :id => 'my_event' do |event| %>
32 | # This event is called <%= event.name "Cool Event" %>.
33 | # <% end %>
34 | #
35 | def event(opts = {}, &block)
36 | ev = Microformats::Event.new(@template)
37 | opts[:class] = combine_class_names('vevent', opts[:class])
38 | ev.run(opts, &block)
39 | end
40 | end
--------------------------------------------------------------------------------
/spec/formatting_helpers_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe Microformats::FormattingHelpers do
4 | class Tester
5 | include Microformats::FormattingHelpers
6 | def initialize
7 | @default_tag = :span
8 | end
9 | end
10 |
11 | before(:each) do
12 | @tester = Tester.new
13 | end
14 |
15 | describe "combine_class_names" do
16 | it "should join the args with spaces alphebetized" do
17 | @tester.combine_class_names('one', 'two', 'three').should == "one three two"
18 | end
19 |
20 | it "should join arrays of class names" do
21 | out = @tester.combine_class_names(['one', 'two'], 'three', ['four', 'five'])
22 | out.should == "five four one three two"
23 | end
24 |
25 | it "should not include nils" do
26 | @tester.combine_class_names('one', [nil, 'two']).should == "one two"
27 | end
28 |
29 | it "should return nil if no classes" do
30 | @tester.combine_class_names(nil, nil).should == nil
31 | end
32 | end
33 |
34 | describe "content_tag" do
35 | it "should output default tag with attrs in alphabetical order" do
36 | out = @tester.content_tag('hello', :id => 'my_id', :class => 'klass')
37 | out.should == "hello"
38 | end
39 |
40 | it "should not include attrs with nil values" do
41 | out = @tester.content_tag('hello', :id => 'my_id', :class => nil)
42 | out.should == "hello"
43 | end
44 | end
45 | end
--------------------------------------------------------------------------------
/lib/formatting_helpers.rb:
--------------------------------------------------------------------------------
1 | # These are all internal methods used for formatting, no need
2 | # to use any of them explicitly.
3 | #
4 | module Microformats::FormattingHelpers # :nodoc:
5 | def content_tag(content, opts={}) # :nodoc:
6 | tag = opts.delete(:tag) || @default_tag
7 | attrs = opts.inject([]) do |out, tuple|
8 | k,v = tuple
9 | out << "#{k}='#{v}'" if v
10 | out
11 | end
12 | attr_string = attrs.sort.join(' ')
13 | open_tag = attr_string == '' ? tag : "#{tag} #{attr_string}"
14 | if [:img].include?(tag)
15 | "<#{open_tag} />"
16 | else
17 | "<#{open_tag}>#{content}#{tag}>"
18 | end
19 | end
20 |
21 | def concat_tag(opts={}) # :nodoc:
22 | tag = opts.delete(:tag) || @default_tag
23 | attrs = opts.inject([]) do |out, tuple|
24 | k,v = tuple
25 | out << "#{k}='#{v}'"
26 | end
27 | attr_string = attrs.sort.join(' ')
28 | open_tag = attr_string == '' ? tag : "#{tag} #{attr_string}"
29 | concat "<#{open_tag}>\n"
30 | yield
31 | concat "#{tag}>\n"
32 | end
33 |
34 | def merge_html_attrs(base_attrs, overriding_attrs) # :nodoc:
35 | classes = combine_class_names(base_attrs.delete(:class), overriding_attrs.delete(:class))
36 | attrs = base_attrs.merge(overriding_attrs)
37 | attrs[:class] = classes unless classes == ''
38 | attrs
39 | end
40 |
41 | def concat(str) # :nodoc:
42 | @template.concat(str)
43 | end
44 |
45 | def encode_time(t) # :nodoc:
46 | t.strftime("%Y-%m-%dT%H:%M%z").gsub(/00$/, ":00")
47 | end
48 |
49 | def humanize_time(t) # :nodoc:
50 | t.strftime("%b %d, %Y at %I:%M%p").gsub(/\s0/, ' ')
51 | end
52 |
53 | def combine_class_names(*classes) # :nodoc:
54 | str = classes.flatten.compact.sort.join(' ').gsub(/\s+/, ' ')
55 | (str =~ /\w/) ? str : nil
56 | end
57 | end
--------------------------------------------------------------------------------
/spec/calendar_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe Microformats::Calendar do
4 | before(:each) do
5 | @template = MockTemplate.new
6 | @cal = Microformats::Calendar.new(@template)
7 | end
8 |
9 | describe "run" do
10 | it "should wrap the block with a .vcalendar div" do
11 | @cal.run do |cal|
12 | cal.concat "Hello"
13 | end
14 | @template.output.should == "
\nHello
\n"
15 | end
16 |
17 | it "should add passed attributes to .vcalendar element" do
18 | @cal.run(:id => 'my_cal', :class => 'extra', :tag => 'section') do |cal|
19 | cal.concat "Hello"
20 | end
21 | @template.output.should == "\nHello\n"
22 | end
23 | end
24 |
25 | describe "event" do
26 | before(:each) do
27 | @event = Microformats::Event.new(@template)
28 | Microformats::Event.should_receive(:new).with(@template).and_return(@event)
29 | end
30 |
31 | it "should run the block on a new event" do
32 | @event.should_receive(:run).with(:class => 'vevent')
33 | @cal.event do |e|
34 | # won't get run in test because #run is stubbed
35 | end
36 | end
37 |
38 | it "should use the given tag" do
39 | @event.should_receive(:run).with(:class => 'vevent', :tag => :section)
40 | @cal.event(:tag => :section) do |e|
41 | # won't get run in test because #run is stubbed
42 | end
43 | end
44 |
45 | it "should pass along html opts" do
46 | @event.should_receive(:run).with(:class => 'extra vevent', :id => 'my_event')
47 | @cal.event(:class => 'extra', :id => 'my_event') do |e|
48 | # won't get run in test because #run is stubbed
49 | end
50 | end
51 | end
52 | end
--------------------------------------------------------------------------------
/lib/helpers.rb:
--------------------------------------------------------------------------------
1 | # Include this file into your view layer. For example, in Rails:
2 | #
3 | # module ApplicationHelper
4 | # include Microformats::Helpers
5 | # end
6 | #
7 | module Microformats::Helpers
8 | # Creates a vCard with the given options and a block.
9 | #
10 | # OPTIONS:
11 | # * :tag - The HTML wrapper element (defaults to :div)
12 | # * Any other passed options will be treated as HTML attributes.
13 | #
14 | # EXAMPLE:
15 | # <% vcard :id => 'my_vcard' do |card| %>
16 | # Hello, my name is <%= card.name "Chris" %>!
17 | # <% end %>
18 | #
19 | def vcard(opts = {}, &block)
20 | card = Microformats::Vcard.new(self)
21 | card.run(opts, &block)
22 | end
23 |
24 | # Creates a vAddress with the given options and a block.
25 | #
26 | # OPTIONS:
27 | # * :type - A string that specifies the type of address('home', 'work', etc)
28 | # * :tag - The HTML wrapper element (defaults to :div)
29 | # * Any other passed options will be treated as HTML attributes.
30 | #
31 | # EXAMPLE:
32 | # <% vaddress :type => 'work', :id => 'my_adr' do |adr| %>
33 | # I live at <%= adr.street "123 Main St" %>.
34 | # <% end %>
35 | #
36 | def vaddress(opts = {}, &block)
37 | address = Microformats::Address.new(self)
38 | address.run(opts, &block)
39 | end
40 |
41 | # Creates a vEvent with the given options and a block.
42 | #
43 | # OPTIONS:
44 | # * :tag - The HTML wrapper element (defaults to :div)
45 | # * Any other passed options will be treated as HTML attributes.
46 | #
47 | # EXAMPLE:
48 | # <% vevent :id => 'my_event' do |event| %>
49 | # This event is called <%= event.name "Cool Event" %>.
50 | # <% end %>
51 | #
52 | def vevent(opts = {}, &block)
53 | event = Microformats::Event.new(self)
54 | event.run(opts, &block)
55 | end
56 |
57 | # Creates a vCalendar with the given options and a block.
58 | #
59 | # OPTIONS:
60 | # * :tag - The HTML wrapper element (defaults to :div)
61 | # * Any other passed options will be treated as HTML attributes.
62 | #
63 | # EXAMPLE:
64 | # <% vcalendar :id => 'my_cal' do |cal| %>
65 | # <% cal.event :id => 'my_event' do |event| %>
66 | # This event is called <%= event.name "Cool Event" %>.
67 | # <% end %>
68 | # <% end %>
69 | #
70 | def vcalendar(opts = {}, &block)
71 | cal = Microformats::Calendar.new(self)
72 | cal.run(opts, &block)
73 | end
74 | end
--------------------------------------------------------------------------------
/lib/address.rb:
--------------------------------------------------------------------------------
1 | class Microformats::Address
2 | include Microformats::FormattingHelpers
3 |
4 | def initialize(template)
5 | @template = template
6 | @default_tag = :span
7 | end
8 |
9 | # You can directly initialize and run this class, but it's easier
10 | # to use the Microformats::Helpers#vaddress helper method or the
11 | # Microformats::Vcard#address method.
12 | #
13 | # OPTIONS:
14 | # * :type - A string that specifies the type of address('home', 'work', etc)
15 | # * :tag - The HTML wrapper element (defaults to :div)
16 | # * Any other passed options will be treated as HTML attributes.
17 | #
18 | def run(opts = {}, &block)
19 | type = opts[:type] ? self.type(opts.delete(:type)) : nil
20 | opts[:class] = combine_class_names('adr', opts[:class])
21 | opts[:itemscope] = 'itemscope'
22 | opts[:itemtype] = 'http://data-vocabulary.org/Address'
23 | opts[:tag] ||= :div
24 | concat_tag(opts) do
25 | concat type if type
26 | block.call(self)
27 | end
28 | end
29 |
30 | # Outputs markup for the type of address ('work', 'home', etc.)
31 | # There will be no visible text unless provided with the :text option.
32 | #
33 | # NOTE: You get this for free with the :type option of
34 | # Microformats::Helpers#vaddress, Microformats::Vcard#address and #run methods.
35 | #
36 | # OPTIONS
37 | # * :text - String, the text you want displayed as a text node (default is '')
38 | # * Any other passed options will be treated as HTML attributes.
39 | #
40 | def type(str, opts = {})
41 | inner = content_tag('', :class => 'value-title', :title => str)
42 | text = opts.delete(:text) || ''
43 | content_tag(inner + text, merge_html_attrs({:class => 'type'}, opts))
44 | end
45 |
46 | # Outputs the passed string as a street address.
47 | #
48 | # OPTIONS
49 | # * :tag - The HTML wrapper element (defaults to :span)
50 | # * Any other passed options will be treated as HTML attributes.
51 | #
52 | def street(str, opts = {})
53 | content_tag(str, merge_html_attrs({:class => 'street-address', :itemprop => 'street-address'}, opts))
54 | end
55 |
56 | # Outputs the passed string as a city.
57 | #
58 | # OPTIONS
59 | # * :tag - The HTML wrapper element (defaults to :span)
60 | # * Any other passed options will be treated as HTML attributes.
61 | #
62 | def city(str, opts = {})
63 | content_tag(str, merge_html_attrs({:class => 'locality', :itemprop => 'locality'}, opts))
64 | end
65 |
66 | # Outputs the passed string as a state.
67 | #
68 | # OPTIONS
69 | # * :tag - The HTML wrapper element (defaults to :span)
70 | # * Any other passed options will be treated as HTML attributes.
71 | #
72 | def state(str, opts = {})
73 | content_tag(str, merge_html_attrs({:class => 'region', :itemprop => 'region'}, opts))
74 | end
75 |
76 | # Outputs the passed string as a postal code.
77 | #
78 | # OPTIONS
79 | # * :tag - The HTML wrapper element (defaults to :span)
80 | # * Any other passed options will be treated as HTML attributes.
81 | #
82 | def zip(str, opts = {})
83 | content_tag(str, merge_html_attrs({:class => 'postal-code', :itemprop => 'postal-code'}, opts))
84 | end
85 | alias_method :postal_code, :zip
86 |
87 | # Outputs the passed string as a country.
88 | #
89 | # OPTIONS
90 | # * :tag - The HTML wrapper element (defaults to :span)
91 | # * Any other passed options will be treated as HTML attributes.
92 | #
93 | def country(str, opts = {})
94 | content_tag(str, merge_html_attrs({:class => 'country-name', :itemprop => 'country-name'}, opts))
95 | end
96 |
97 | end
--------------------------------------------------------------------------------
/spec/helpers_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Microformats::Helpers do
4 |
5 | class MockTemplateWithHelpers < MockTemplate
6 | include Microformats::Helpers
7 | end
8 |
9 | before(:each) do
10 | @template = MockTemplateWithHelpers.new
11 | end
12 |
13 | describe "vcard" do
14 | it "should wrap a block in a vcard div" do
15 | @template.should_receive(:do_something)
16 | @template.vcard do |card|
17 | card.is_a?(Microformats::Vcard).should be_true
18 | @template.do_something
19 | end
20 | @template.output.should == "
\n
\n"
21 | end
22 |
23 | it "should use passed html attrs" do
24 | @template.should_receive(:do_something)
25 | @template.vcard(:class => 'extra', :id => 'my_card') do |card|
26 | card.is_a?(Microformats::Vcard).should be_true
27 | @template.do_something
28 | end
29 | @template.output.should == "
\n
\n"
30 | end
31 | end
32 |
33 | describe "vaddress" do
34 | context "with type" do
35 | it "should wrap the block in an adr div and output the type" do
36 | @template.should_receive(:do_something)
37 | @template.vaddress :type => 'work' do
38 | @template.do_something
39 | end
40 | @template.output.should == "
\n
\n"
41 | end
42 |
43 | it "should use passed html attrs" do
44 | @template.should_receive(:do_something)
45 | @template.vaddress :type => 'work', :class => 'extra', :id => 'my_address' do
46 | @template.do_something
47 | end
48 | @template.output.should == "
\n
\n"
49 | end
50 | end
51 |
52 | context "without type" do
53 | it "should wrap the block in an adr div" do
54 | @template.should_receive(:do_something)
55 | @template.vaddress do |adr|
56 | adr.is_a?(Microformats::Address).should be_true
57 | @template.do_something
58 | end
59 | @template.output.should == "
\n
\n"
60 | end
61 | end
62 | end
63 |
64 | describe "vevent" do
65 | it "should wrap the block with a .vevent div" do
66 | @template.should_receive(:do_something)
67 | @template.vevent do |event|
68 | event.is_a?(Microformats::Event).should be_true
69 | @template.do_something
70 | end
71 | @template.output.should == "
\n
\n"
72 | end
73 |
74 | it "should add passed attributes to .vevent element" do
75 | @template.should_receive(:do_something)
76 | @template.vevent(:id => 'my_event', :class => 'extra', :tag => 'section') do |event|
77 | @template.do_something
78 | end
79 | @template.output.should == "\n\n"
80 | end
81 | end
82 |
83 | describe "vcalendar" do
84 | it "should wrap the block with a .vcalendar div" do
85 | @template.should_receive(:do_something)
86 | @template.vcalendar do |cal|
87 | cal.is_a?(Microformats::Calendar).should be_true
88 | @template.do_something
89 | end
90 | @template.output.should == "
\n
\n"
91 | end
92 |
93 | it "should add passed attributes to .vcalendar element" do
94 | @template.should_receive(:do_something)
95 | @template.vcalendar(:id => 'my_cal', :class => 'extra', :tag => 'section') do |cal|
96 | @template.do_something
97 | end
98 | @template.output.should == "\n\n"
99 | end
100 | end
101 | end
102 |
--------------------------------------------------------------------------------
/spec/address_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Microformats::Address do
4 | before(:each) do
5 | @template = MockTemplate.new
6 | @address = Microformats::Address.new(@template)
7 | end
8 |
9 | describe "run" do
10 | it "should wrap the block with an .adr div" do
11 | @address.run do |adr|
12 | adr.concat "Hello"
13 | end
14 | @template.output.should == "
\nHello
\n"
15 | end
16 |
17 | it "should add passed attributes to .adr div" do
18 | @address.run(:id => 'my_address', :class => 'extra') do |adr|
19 | adr.concat "Hello"
20 | end
21 | @template.output.should == "
\nHello
\n"
22 | end
23 | end
24 |
25 | describe "type" do
26 | it "should output the type string as a hidden value" do
27 | @address.type('home').should == ""
28 | end
29 |
30 | it "should include text passed with :text option" do
31 | @address.type('home', :text => "Where I Live").should == "Where I Live"
32 | end
33 | end
34 |
35 | describe "street" do
36 | it "should wrap the string with street-address" do
37 | e = "123 Main"
38 | @address.street("123 Main").should == e
39 | end
40 |
41 | it "should use passed html attrs" do
42 | e = "123 Main"
43 | @address.street("123 Main", :class => 'extra', :id => 'my_street').should == e
44 | end
45 |
46 | it "should use the given tag" do
47 | e = "123 Main"
48 | @address.street("123 Main", :tag => :strong).should == e
49 | end
50 | end
51 |
52 | describe "city" do
53 | it "should wrap the string with locality" do
54 | @address.city("Chicago").should == "Chicago"
55 | end
56 |
57 | it "should use passed html attrs" do
58 | e = "Chicago"
59 | @address.city("Chicago", :class => 'extra', :id => 'my_city').should == e
60 | end
61 |
62 | it "should use the given tag" do
63 | @address.city("Chicago", :tag => :strong).should == "Chicago"
64 | end
65 | end
66 |
67 | describe "state" do
68 | it "should wrap the string with region" do
69 | @address.state("IL").should == "IL"
70 | end
71 |
72 | it "should use passed html attrs" do
73 | e = "IL"
74 | @address.state("IL", :class => 'extra', :id => 'my_state').should == e
75 | end
76 |
77 | it "should use the given tag" do
78 | @address.state("IL", :tag => :strong).should == "IL"
79 | end
80 | end
81 |
82 | describe "zip" do
83 | it "should wrap the string with postal-code" do
84 | @address.zip("60085").should == "60085"
85 | end
86 |
87 | it "should use passed html attrs" do
88 | e = "60085"
89 | @address.zip("60085", :class => 'extra', :id => 'my_zip').should == e
90 | end
91 |
92 | it "should use the given tag" do
93 | @address.zip("60085", :tag => :strong).should == "60085"
94 | end
95 | end
96 |
97 | describe "country" do
98 | it "should wrap the string with country-name" do
99 | @address.country("USA").should == "USA"
100 | end
101 |
102 | it "should use passed html attrs" do
103 | e = "USA"
104 | @address.country("USA", :class => 'extra', :id => 'my_country').should == e
105 | end
106 |
107 | it "should use the given tag" do
108 | @address.country("USA", :tag => :strong).should == "USA"
109 | end
110 | end
111 | end
112 |
--------------------------------------------------------------------------------
/lib/event.rb:
--------------------------------------------------------------------------------
1 | class Microformats::Event
2 | include Microformats::FormattingHelpers
3 |
4 | def initialize(template)
5 | @template = template
6 | @default_tag = :span
7 | end
8 |
9 | # You can directly initialize and run this class, but it's easier
10 | # to use the Microformats::Helpers#vevent helper method or the
11 | # Microformats::Calendar#event method.
12 | #
13 | # OPTIONS:
14 | # * :tag - The HTML wrapper element (defaults to :div)
15 | # * Any other passed options will be treated as HTML attributes.
16 | #
17 | def run(opts = {}, &block)
18 | opts[:class] = combine_class_names('vevent', opts[:class])
19 | opts[:itemscope] = 'itemscope'
20 | opts[:itemtype] = 'http://data-vocabulary.org/Event'
21 | opts[:tag] ||= :div
22 | concat_tag(opts) do
23 | block.call(self)
24 | end
25 | end
26 |
27 | # Marks up an event's name.
28 | #
29 | # OPTIONS:
30 | # * :tag - The HTML wrapper element (defaults to :span)
31 | # * Any other passed options will be treated as HTML attributes.
32 | #
33 | def name(str, opts={})
34 | content_tag(str, merge_html_attrs({:itemprop => 'summary', :class => 'summary'}, opts))
35 | end
36 |
37 | # Marks up the event's URL. By default, it will output an tag using
38 | # the passed in string as both the href and the text. If the :href option
39 | # is passed, then the string argument is treated as text.
40 | #
41 | # OPTIONS:
42 | # * :href - If passed, the string argument will be treated as the text node.
43 | # * :tag - The HTML wrapper element (defaults to :span)
44 | # * Any other passed options will be treated as HTML attributes.
45 | #
46 | # EXAMPLES:
47 | # event.url('http://google.com') #=> http://google.com
48 | # event.url('Google', :href => 'http://google.com') #=> Google
49 | # event.url('http://google.com', :tag => :span) #=> http://google.com
50 | #
51 | def url(str, opts = {})
52 | if opts[:href]
53 | content_tag(str, merge_html_attrs({:tag => :a, :class => 'url', :itemprop => 'url'}, opts))
54 | elsif opts[:tag]
55 | content_tag(str, merge_html_attrs({:class => 'url', :itemprop => 'url'}, opts))
56 | else
57 | content_tag(str, merge_html_attrs({:tag => :a, :class => 'url', :href => str, :itemprop => 'url'}, opts))
58 | end
59 | end
60 |
61 | # Marks up the event photo as an tag. Takes the image URL as the first argument.
62 | #
63 | # OPTIONS
64 | # * :size - Pass a string with WIDTHxHEIGHT like "200x100" in lieu of the :width and :height options.
65 | # * Any other passed options will be treated as HTML attributes.
66 | #
67 | def photo(str, opts = {})
68 | if size = opts.delete(:size)
69 | opts[:width], opts[:height] = size.split('x')
70 | end
71 | content_tag(nil, merge_html_attrs({:tag => :img, :class => 'photo', :itemprop => 'photo', :src => str}, opts))
72 | end
73 |
74 | # Marks up an event's description.
75 | #
76 | # OPTIONS:
77 | # * :tag - The HTML wrapper element (defaults to :span)
78 | # * Any other passed options will be treated as HTML attributes.
79 | #
80 | def description(str, opts={})
81 | content_tag(str, merge_html_attrs({:itemprop => 'description', :class => 'description'}, opts))
82 | end
83 |
84 | # Marks up the event's start time/date. Accepts either a Time object
85 | # or a time String as the first argument. By default, the text node
86 | # will be the date and time output like "Oct 20, 2010 at 7:30PM", but
87 | # this can be overridden by the :text option.
88 | #
89 | # OPTIONS:
90 | # * :text - String, will be displayed as the text node.
91 | # * Any other passed options will be treated as HTML attributes.
92 | #
93 | def starts_at(time_or_str, opts={})
94 | if time_or_str.is_a?(String)
95 | time = Time.parse(time_or_str)
96 | encoded_time = encode_time(time)
97 | humanized_time = opts.delete(:text) || time_or_str
98 | else
99 | encoded_time = encode_time(time_or_str)
100 | humanized_time = opts.delete(:text) || humanize_time(time_or_str)
101 | end
102 | inner_span = content_tag('', :class => 'value-title', :title => encoded_time)
103 | content_tag(inner_span + humanized_time, merge_html_attrs({:tag => :time, :itemprop => 'startDate', :class => 'dtstart', :datetime => encoded_time}, opts))
104 | end
105 |
106 | # Marks up the event's end time/date. Accepts either a Time object
107 | # or a time String as the first argument. By default, the text node
108 | # will be the date and time output like "Oct 20, 2010 at 7:30PM", but
109 | # this can be overridden by the :text option.
110 | #
111 | # OPTIONS:
112 | # * :text - String, will be displayed as the text node.
113 | # * Any other passed options will be treated as HTML attributes.
114 | #
115 | def ends_at(time_or_str, opts={})
116 | if time_or_str.is_a?(String)
117 | time = Time.parse(time_or_str)
118 | encoded_time = encode_time(time)
119 | humanized_time = opts.delete(:text) || time_or_str
120 | else
121 | encoded_time = encode_time(time_or_str)
122 | humanized_time = opts.delete(:text) || humanize_time(time_or_str)
123 | end
124 | inner_span = content_tag('', :class => 'value-title', :title => encoded_time)
125 | content_tag(inner_span + humanized_time, merge_html_attrs({:tag => :time, :itemprop => 'endDate', :class => 'dtend', :datetime => encoded_time}, opts))
126 | end
127 |
128 | # Marks up an event's category name.
129 | #
130 | # OPTIONS:
131 | # * :tag - The HTML wrapper element (defaults to :span)
132 | # * Any other passed options will be treated as HTML attributes.
133 | #
134 | def category(str, opts = {})
135 | content_tag(str, merge_html_attrs({:itemprop => 'eventType', :class => 'category'}, opts))
136 | end
137 |
138 | # Creates a vCard with the given options and a block to represent
139 | # the event's location.
140 | #
141 | # OPTIONS:
142 | # * :tag - The HTML wrapper element (defaults to :div)
143 | # * Any other passed options will be treated as HTML attributes.
144 | #
145 | # EXAMPLE:
146 | # <% event.location :id => 'my_location' do |card| %>
147 | # We will be meeting at the <%= card.company "Obtiva" %> office.
148 | # <% end %>
149 | #
150 | def location(opts = {}, &block)
151 | card = Microformats::Vcard.new(@template)
152 | opts[:class] = combine_class_names('location', opts[:class])
153 | card.run(opts, &block)
154 | end
155 |
156 | end
--------------------------------------------------------------------------------
/lib/vcard.rb:
--------------------------------------------------------------------------------
1 | class Microformats::Vcard
2 | include Microformats::FormattingHelpers
3 |
4 | # You can directly initialize and runthis class, but it's easier
5 | # to use the Microformats::Helpers#vcard helper method.
6 | def initialize(template)
7 | @template = template
8 | @default_tag = :span
9 | end
10 |
11 | # You can directly initialize and runthis class, but it's easier
12 | # to use the Microformats::Helpers#vcard helper method.
13 | #
14 | # OPTIONS:
15 | # * :tag - The HTML wrapper element (defaults to :div)
16 | # * Any other passed options will be treated as HTML attributes.
17 | #
18 | def run(opts = {}, &block)
19 | opts[:class] = combine_class_names('vcard', opts[:class])
20 | opts[:itemscope] = 'itemscope'
21 | opts[:itemtype] = 'http://data-vocabulary.org/Person'
22 | opts[:tag] ||= :div
23 | concat_tag(opts) do
24 | block.call(self)
25 | end
26 | end
27 |
28 | # Marks up a person's name.
29 | #
30 | # OPTIONS:
31 | # * :tag - The HTML wrapper element (defaults to :span)
32 | # * Any other passed options will be treated as HTML attributes.
33 | #
34 | def name(str, opts = {})
35 | content_tag(str, merge_html_attrs({:class => 'fn', :itemprop => 'name'}, opts))
36 | end
37 |
38 | # Marks up a company name. If this vCard represents a company
39 | # rather than an individual person that works at a company, set
40 | # the :is_company option to true.
41 | #
42 | # OPTIONS:
43 | # * :is_company - Boolean, true if this is a company vCard (defaults to false)
44 | # * :tag - The HTML wrapper element (defaults to :span)
45 | # * Any other passed options will be treated as HTML attributes.
46 | #
47 | def company(str, opts = {})
48 | classes = opts.delete(:is_company) ? 'fn org' : 'org'
49 | content_tag(str, merge_html_attrs({:class => classes, :itemprop => 'affiliation'}, opts))
50 | end
51 | alias_method :organization, :company
52 |
53 | # Marks up the person's URL. By default, it will output an tag using
54 | # the passed in string as both the href and the text. If the :href option
55 | # is passed, then the string argument is treated as text.
56 | #
57 | # OPTIONS:
58 | # * :href - If passed, the string argument will be treated as the text node.
59 | # * :tag - The HTML wrapper element (defaults to :span)
60 | # * Any other passed options will be treated as HTML attributes.
61 | #
62 | # EXAMPLES:
63 | # card.url('http://google.com') #=> http://google.com
64 | # card.url('Google', :href => 'http://google.com') #=> Google
65 | # card.url('http://google.com', :tag => :span) #=> http://google.com
66 | #
67 | def url(str, opts = {})
68 | if opts[:href]
69 | content_tag(str, merge_html_attrs({:tag => :a, :class => 'url', :itemprop => 'url'}, opts))
70 | elsif opts[:tag]
71 | content_tag(str, merge_html_attrs({:class => 'url', :itemprop => 'url'}, opts))
72 | else
73 | content_tag(str, merge_html_attrs({:tag => :a, :class => 'url', :href => str, :itemprop => 'url'}, opts))
74 | end
75 | end
76 |
77 | # Marks up the vCard photo as an tag. Takes the image URL as the first argument.
78 | #
79 | # OPTIONS
80 | # * :size - Pass a string with WIDTHxHEIGHT like "200x100" in lieu of the :width and :height options.
81 | # * Any other passed options will be treated as HTML attributes.
82 | #
83 | def photo(str, opts = {})
84 | if size = opts.delete(:size)
85 | opts[:width], opts[:height] = size.split('x')
86 | end
87 | content_tag(nil, merge_html_attrs({:tag => :img, :class => 'photo', :itemprop => 'photo', :src => str}, opts))
88 | end
89 |
90 | # Marks up a phone number, takes the phone number as a string.
91 | #
92 | # OPTIONS
93 | # * :type - A string that specifies the type of phone number ('home', 'work', etc)
94 | # * :tag - The HTML wrapper element (defaults to :span)
95 | # * Any other passed options will be treated as HTML attributes.
96 | #
97 | def phone(str, opts = {})
98 | type = if opts[:type].to_s != ''
99 | type_inner_span = content_tag('', :class => 'value-title', :title => opts.delete(:type))
100 | content_tag(type_inner_span, :class => 'type')
101 | else
102 | ''
103 | end
104 | content_tag(type + str, merge_html_attrs({:class => 'tel'}, opts))
105 | end
106 |
107 | # Marks up an email address, takes the email as a string.
108 | #
109 | # OPTIONS
110 | # * :type - A string that specifies the type of phone number ('home', 'work', etc)
111 | # * :tag - The HTML wrapper element (defaults to :a)
112 | # * Any other passed options will be treated as HTML attributes.
113 | #
114 | def email(str, opts = {})
115 | opts[:tag] ||= :a
116 | type = if opts[:type].to_s != ''
117 | type_inner_span = content_tag('', :class => 'value-title', :title => opts.delete(:type))
118 | content_tag(type_inner_span, :class => 'type')
119 | else
120 | ''
121 | end
122 | if opts[:tag] == :a
123 | content_tag(type + str, merge_html_attrs({:class => 'email', :href => "mailto:#{str}"}, opts))
124 | else
125 | content_tag(type + str, merge_html_attrs({:class => 'email'}, opts))
126 | end
127 | end
128 |
129 | # Accepts latitude and longitude as arguments. It will only output a
130 | # visible text node if you provide the :text option.
131 | #
132 | # OPTIONS
133 | # * :text - String, the text will be be displayed inside the 'geo' wrapper
134 | #
135 | def coordinates(lat, lng, opts = {})
136 | lat_meta = content_tag('', :tag => :meta, :itemprop => 'latitude', :content => lat)
137 | lng_meta = content_tag('', :tag => :meta, :itemprop => 'longitude', :content => lng)
138 | lat_span = content_tag(content_tag('', :class => 'value-title', :title => lat), :class => 'latitude')
139 | lng_span = content_tag(content_tag('', :class => 'value-title', :title => lng), :class => 'longitude')
140 | text = opts[:text] || ''
141 | content_tag(lat_meta + lng_meta + lat_span + lng_span + text, :class => 'geo', :itemprop => 'geo', :itemscope => 'itemscope', :itemtype => 'http://data-vocabulary.org/Geo')
142 | end
143 |
144 | # Outputs a link to h2vx.com that will let the user download the vcard
145 | # at the passed URL.
146 | #
147 | # OPTIONS
148 | # * :text - The link text (default is "Download vCard")
149 | # * Any other passed options will be treated as HTML attributes.
150 | #
151 | # EXAMPLE
152 | # <%# In Rails, request.request_uri returns the URL of this page %>
153 | # <%= card.download_link request.request_uri %>
154 | #
155 | def download_link(url, opts = {})
156 | str = opts.delete(:text) || "Download vCard"
157 | new_url = "http://h2vx.com/vcf/" + url.gsub("http://", '')
158 | content_tag(str, merge_html_attrs({:tag => :a, :href => new_url, :type => 'text/directory'}, opts))
159 | end
160 |
161 | # Opens a new block for a nested vAddress.
162 | #
163 | # OPTIONS:
164 | # * :type - A string that specifies the type of address('home', 'work', etc)
165 | # * :tag - The HTML wrapper element (defaults to :div)
166 | # * Any other passed options will be treated as HTML attributes.
167 | #
168 | # EXAMPLE:
169 | # <% card.address :type => 'work', :id => 'my_adr' do |adr| %>
170 | # I live at <%= adr.street "123 Main St" %>.
171 | # <% end %>
172 | #
173 | def address(opts = {}, &block)
174 | adr = Microformats::Address.new(@template)
175 | adr.run(opts, &block)
176 | end
177 | end
--------------------------------------------------------------------------------
/spec/event_spec.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2 |
3 | describe Microformats::Event do
4 | before(:each) do
5 | @template = MockTemplate.new
6 | @event = Microformats::Event.new(@template)
7 | end
8 |
9 | describe "run" do
10 | it "should wrap the block with a .vevent div" do
11 | @event.run do |event|
12 | event.concat "Hello"
13 | end
14 | @template.output.should == "
\nHello
\n"
15 | end
16 |
17 | it "should add passed attributes to .vevent element" do
18 | @event.run(:id => 'my_event', :class => 'extra', :tag => 'section') do |event|
19 | event.concat "Hello"
20 | end
21 | @template.output.should == "\nHello\n"
22 | end
23 | end
24 |
25 | describe "name" do
26 | it "should wrap the string with summary" do
27 | @event.name("My Event").should == "My Event"
28 | end
29 |
30 | it "should use arbitrary html attrs" do
31 | e = "My Event"
32 | @event.name("My Event", :class => 'extra', :id => 'my_event').should == e
33 | end
34 |
35 | it "should use the given tag" do
36 | @event.name("My Event", :tag => :strong).should == "My Event"
37 | end
38 | end
39 |
40 | describe "url" do
41 | it "should default to a tag with url class, using the URL for text and href" do
42 | @event.url("http://google.com").should == "http://google.com"
43 | end
44 |
45 | it "should take arbitrary html attrs" do
46 | e = "http://google.com"
47 | @event.url("http://google.com", :class => 'extra', :id => 'my_url').should == e
48 | end
49 |
50 | it "should use given href" do
51 | @event.url('Google', :href => "http://google.com").should == "Google"
52 | end
53 |
54 | it "should use given tag" do
55 | @event.url('http://google.com', :tag => :strong).should == "http://google.com"
56 | end
57 | end
58 |
59 | describe "photo" do
60 | it "should create an image tag using the passed string as the src, adding itemprop photo" do
61 | @event.photo("/images/event.png").should == ""
62 | end
63 |
64 | it "should use arbitrary html attrs" do
65 | e = ""
66 | @event.photo("/images/event.png", :class => 'extra', :id => 'my_photo').should == e
67 | end
68 |
69 | it "should use :size option to set width and height" do
70 | @event.photo("/images/event.png", :size => "200x100").should == ""
71 | end
72 |
73 | it "should pass through options" do
74 | @event.photo("/images/event.png", :height => 100, :width => 200).should == ""
75 | end
76 | end
77 |
78 | describe "description" do
79 | it "should wrap the string with description" do
80 | @event.description("My Event").should == "My Event"
81 | end
82 |
83 | it "should use arbitrary html attrs" do
84 | e = "My Event"
85 | @event.description("My Event", :class => 'extra', :id => 'my_desc').should == e
86 | end
87 |
88 | it "should use the given tag" do
89 | @event.description("My Event", :tag => :strong).should == "My Event"
90 | end
91 | end
92 |
93 | describe "starts_at" do
94 | it "should output the time wrapped in a time tag with encoded time" do
95 | t = Time.local(2010, 10, 20, 19, 30) # Oct 20, 2010 at 7:30pm
96 | @event.starts_at(t).should == ""
97 | end
98 |
99 | it "should use arbitrary html attrs" do
100 | t = Time.local(2010, 10, 20, 19, 30) # Oct 20, 2010 at 7:30pm
101 | e = ""
102 | @event.starts_at(t, :class => 'extra', :id => 'my_start').should == e
103 | end
104 |
105 | it "should accept a datetime string instead of a time object" do
106 | @event.starts_at("October 20, 2010 7:30pm").should == ""
107 | end
108 |
109 | it "should accept a time object with a display string as :text" do
110 | t = Time.local(2010, 10, 20, 19, 30) # Oct 20, 2010 at 7:30pm
111 | @event.starts_at(t, :text => "Sometime").should == ""
112 | end
113 | end
114 |
115 | describe "ends_at" do
116 | it "should output the time wrapped in a time tag with encoded time" do
117 | t = Time.local(2010, 10, 20, 19, 30) # Oct 20, 2010 at 7:30pm
118 | @event.ends_at(t).should == ""
119 | end
120 |
121 | it "should use arbitrary html attrs" do
122 | t = Time.local(2010, 10, 20, 19, 30) # Oct 20, 2010 at 7:30pm
123 | e = ""
124 | @event.ends_at(t, :class => 'extra', :id => 'my_end').should == e
125 | end
126 |
127 | it "should accept a datetime string instead of a time object" do
128 | @event.ends_at("October 20, 2010 7:30pm").should == ""
129 | end
130 |
131 | it "should accept a time object with a display string as :text" do
132 | t = Time.local(2010, 10, 20, 19, 30) # Oct 20, 2010 at 7:30pm
133 | @event.ends_at(t, :text => "Sometime").should == ""
134 | end
135 | end
136 |
137 | describe "category" do
138 | it "should wrap the string with category class and eventType itemprop" do
139 | @event.category("Geekfest").should == "Geekfest"
140 | end
141 |
142 | it "should should use arbitrary html attrs" do
143 | e = "Geekfest"
144 | @event.category("Geekfest", :class => 'extra', :id => 'my_category').should == e
145 | end
146 |
147 | it "should use the given tag" do
148 | @event.category("Geekfest", :tag => :strong).should == "Geekfest"
149 | end
150 | end
151 |
152 | describe "location" do
153 | before(:each) do
154 | @card = Microformats::Vcard.new(@template)
155 | Microformats::Vcard.should_receive(:new).with(@template).and_return(@card)
156 | end
157 | it "should run the block on a new vcard" do
158 | @card.should_receive(:run).with(:class => 'location')
159 | @event.location do |card|
160 | # won't get run in test because #run is stubbed
161 | end
162 | end
163 |
164 | it "should pass along html opts" do
165 | @card.should_receive(:run).with(:class => 'extra location', :id => 'my_location')
166 | @event.location(:class => 'extra', :id => 'my_location') do |card|
167 | # won't get run in test because #run is stubbed
168 | end
169 | end
170 | end
171 |
172 | end
--------------------------------------------------------------------------------
/spec/vcard_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Microformats::Vcard do
4 | before(:each) do
5 | @template = MockTemplate.new
6 | @vcard = Microformats::Vcard.new(@template)
7 | end
8 |
9 | describe "run" do
10 | it "should wrap the block in a .vcard div" do
11 | @vcard.run do |card|
12 | card.concat "Hello"
13 | end
14 | @template.output.should == "
\nHello
\n"
15 | end
16 |
17 | it "should should apply id and extra classes to .vcard div" do
18 | @vcard.run(:id => 'my_vcard', :class => 'extra') do |card|
19 | card.concat "Hello"
20 | end
21 | @template.output.should == "
\nHello
\n"
22 | end
23 | end
24 |
25 | describe "name" do
26 | it "should wrap a string with fn class, default to span" do
27 | @vcard.name("John Doe").should == "John Doe"
28 | end
29 |
30 | it "should use arbitrary html attrs" do
31 | e = "John Doe"
32 | @vcard.name("John Doe", :class => 'extra', :id => 'my_name').should == e
33 | end
34 |
35 | it "should use the given tag" do
36 | @vcard.name("John Doe", :tag => :strong).should == "John Doe"
37 | end
38 | end
39 |
40 | describe "company" do
41 | it "should wrap a string with org class, default to span" do
42 | @vcard.company("Acme Co.").should == "Acme Co."
43 | end
44 |
45 | it "should use arbitrary html attrs" do
46 | e = "Acme Co."
47 | @vcard.company("Acme Co.", :class => 'extra', :id => 'my_company').should == e
48 | end
49 |
50 | it "should use the given tag" do
51 | @vcard.company("Acme Co.", :tag => :strong).should == "Acme Co."
52 | end
53 |
54 | it "should have fn class if passed :is_company => true" do
55 | @vcard.company("Acme Co.", :is_company => true).should == "Acme Co."
56 | end
57 | end
58 |
59 | describe "url" do
60 | it "should default to a tag with url class, using the URL for text and href" do
61 | @vcard.url("http://google.com").should == "http://google.com"
62 | end
63 |
64 | it "should use arbitrary html attrs" do
65 | e = "http://google.com"
66 | @vcard.url("http://google.com", :class => 'extra', :id => 'my_url').should == e
67 | end
68 |
69 | it "should use given href" do
70 | @vcard.url('Google', :href => "http://google.com").should == "Google"
71 | end
72 |
73 | it "should use given tag" do
74 | @vcard.url('http://google.com', :tag => :strong).should == "http://google.com"
75 | end
76 | end
77 |
78 | describe "photo" do
79 | it "should create an image tag using the passed string as the src, adding itemprop photo" do
80 | @vcard.photo("/images/me.png").should == ""
81 | end
82 |
83 | it "should use arbitrary html attrs" do
84 | e = ""
85 | @vcard.photo("/images/me.png", :class => 'extra', :id => 'my_photo').should == e
86 | end
87 |
88 | it "should use :size option to set width and height" do
89 | @vcard.photo("/images/me.png", :size => "200x100").should == ""
90 | end
91 |
92 | it "should pass through options" do
93 | @vcard.photo("/images/me.png", :height => 100, :width => 200).should == ""
94 | end
95 | end
96 |
97 | describe "phone" do
98 | it "should wrap string with a tel class" do
99 | @vcard.phone('123.456.7890').should == "123.456.7890"
100 | end
101 |
102 | it "should use arbitrary html attrs" do
103 | e = "123.456.7890"
104 | @vcard.phone('123.456.7890', :class => 'extra', :id => 'my_phone').should == e
105 | end
106 |
107 | it "should add a type span if given" do
108 | out = @vcard.phone('123.456.7890', :type => 'work')
109 | out.should == "123.456.7890"
110 | end
111 |
112 | it "should use the given tag" do
113 | out = @vcard.phone('123.456.7890', :type => 'work', :tag => :strong)
114 | out.should == "123.456.7890"
115 | end
116 | end
117 |
118 | describe "email" do
119 | it "should use mailto and default to 'a' tag" do
120 | out = @vcard.email('john@doe.com')
121 | out.should == "john@doe.com"
122 | end
123 |
124 | it "should wrap string with passed tag" do
125 | @vcard.email('john@doe.com', :tag => :span).should == "john@doe.com"
126 | end
127 |
128 | it "should use arbitrary html attrs" do
129 | e = "john@doe.com"
130 | @vcard.email('john@doe.com', :class => 'extra', :id => 'my_email').should == e
131 | end
132 |
133 | it "should add a type span if given" do
134 | out = @vcard.email('john@doe.com', :type => 'work')
135 | out.should == "john@doe.com"
136 | end
137 |
138 | it "should use the given tag" do
139 | out = @vcard.email('john@doe.com', :type => 'work', :tag => :strong)
140 | out.should == "john@doe.com"
141 | end
142 | end
143 |
144 | describe "coordinates" do
145 | it "should output a geo container with meta and spans for lat and long" do
146 | out = @vcard.coordinates(37.774929, -122.419416)
147 | out.should == ""
148 | end
149 |
150 | it "should output text in .geo span if in options" do
151 | out = @vcard.coordinates(37.774929, -122.419416, :text => "My Location")
152 | out.should == "My Location"
153 | end
154 | end
155 |
156 | describe "download_link" do
157 | it "should output a link to h2vx.com using the passed url" do
158 | out = @vcard.download_link('mydomain.com/page')
159 | out.should == "Download vCard"
160 | end
161 |
162 | it "should use arbitrary html attrs" do
163 | out = @vcard.download_link('mydomain.com/page', :class => 'extra', :id => 'my_link')
164 | out.should == "Download vCard"
165 | end
166 |
167 | it "should strip the protocol from a passed url" do
168 | out = @vcard.download_link('http://mydomain.com/page')
169 | out.should == "Download vCard"
170 | end
171 |
172 | it "should use :text option as text node if present" do
173 | out = @vcard.download_link('mydomain.com/page', :text => "Download Me Now")
174 | out.should == "Download Me Now"
175 | end
176 | end
177 |
178 | describe "address" do
179 | before(:each) do
180 | @adr = Microformats::Address.new(@template)
181 | Microformats::Address.should_receive(:new).with(@template).and_return(@adr)
182 | end
183 |
184 | it "should run the block on a new vaddress" do
185 | @adr.should_receive(:run)
186 | @vcard.address do |adr|
187 | # won't get run in test because #run is stubbed
188 | end
189 | end
190 |
191 | it "should pass along html opts" do
192 | @adr.should_receive(:run).with(:class => 'extra', :id => 'my_address')
193 | @vcard.address(:class => 'extra', :id => 'my_address') do |adr|
194 | # won't get run in test because #run is stubbed
195 | end
196 | end
197 | end
198 | end
199 |
--------------------------------------------------------------------------------