HTML-Microformats
view release on metacpan or search on metacpan
lib/HTML/Microformats/Format/hCard.pm view on Meta::CPAN
This method exports the hCard as a vCard XML. It requires L<RDF::vCard> and
L<XML::LibXML> to work, and will throw an error at run-time if it's not available.
=back
=cut
package HTML::Microformats::Format::hCard;
use base qw(HTML::Microformats::Format HTML::Microformats::Mixin::Parser);
use strict qw(subs vars); no warnings;
use 5.010;
use HTML::Microformats::Datatype::String;
use HTML::Microformats::Format::hCard::n;
use HTML::Microformats::Format::hCard::org;
use HTML::Microformats::Format::hCard::tel;
use HTML::Microformats::Format::hCard::email;
use HTML::Microformats::Format::hCard::label;
use HTML::Microformats::Format::hCard::impp;
use HTML::Microformats::Utilities qw(stringify searchClass);
use Scalar::Util qw();
use Object::AUTHORITY;
BEGIN {
$HTML::Microformats::Format::hCard::AUTHORITY = 'cpan:TOBYINK';
$HTML::Microformats::Format::hCard::VERSION = '0.105';
}
our $HAS_VCARD_EXPORT;
our $HAS_VCARD_XML_EXPORT;
BEGIN
{
local $@ = undef;
eval 'use RDF::vCard;';
$HAS_VCARD_EXPORT = 1
if RDF::vCard::Exporter->can('new');
eval {
$HAS_VCARD_XML_EXPORT = 1
if RDF::vCard::Exporter->can('new') && $RDF::vCard::WITH_XML;
};
}
sub new
{
my ($class, $element, $context, %options) = @_;
my $cache = $context->cache;
return $cache->get($context, $element, $class)
if defined $cache && $cache->get($context, $element, $class);
my $self = {
'element' => $element ,
'context' => $context ,
'cache' => $cache ,
'id' => $context->make_bnode($element) ,
'id.holder' => $context->make_bnode ,
};
$self->{'in_hcalendar'} = $options{'in_hcalendar'};
bless $self, $class;
my $clone = $element->cloneNode(1);
$self->_expand_patterns($clone);
$self->_simple_parse($clone);
# In hCalendar, 'cn' is used instead of 'fn'.
if ($self->{'in_hcalendar'})
{
$self->{'DATA'}->{'fn'} = $self->{'DATA'}->{'cn'}
if defined $self->{'DATA'}->{'cn'}
&& !defined $self->{'DATA'}->{'fn'};
}
# Find more complicated nested structures.
# These can't be handled by _simple_parse.
push @{ $self->{'DATA'}->{'n'} }, HTML::Microformats::Format::hCard::n->extract_all($clone, $context);
push @{ $self->{'DATA'}->{'org'} }, HTML::Microformats::Format::hCard::org->extract_all($clone, $context);
push @{ $self->{'DATA'}->{'tel'} }, HTML::Microformats::Format::hCard::tel->extract_all($clone, $context);
push @{ $self->{'DATA'}->{'email'} }, HTML::Microformats::Format::hCard::email->extract_all($clone, $context);
push @{ $self->{'DATA'}->{'impp'} }, HTML::Microformats::Format::hCard::impp->extract_all($clone, $context);
push @{ $self->{'DATA'}->{'label'} }, HTML::Microformats::Format::hCard::label->extract_all($clone, $context);
foreach my $p (qw(n org tel email impp label adr))
{
delete $self->{'DATA'}->{$p}
unless @{ $self->{'DATA'}->{$p} || [] };
}
# Fallback if no 'org' is found.
# Try looking directly for org-like properties in the hCard.
unless (defined $self->{'DATA'}->{'org'} and @{ $self->{'DATA'}->{'org'} })
{
my $org = HTML::Microformats::Format::hCard::org->new($element, $context);
$org->{'id'} = $context->make_bnode; # don't share ID with $self!!
if ($org->data->{'organization-name'} || $org->data->{'organization-unit'})
{
push @{ $self->{'DATA'}->{'org'} }, $org;
}
}
# Fallback if no 'n' is found.
# Try looking directly for N-like properties in the hCard.
unless (defined $self->{'DATA'}->{'n'} and @{ $self->{'DATA'}->{'n'} })
{
my $n = HTML::Microformats::Format::hCard::n->new($element, $context);
$n->{'id'} = $context->make_bnode; # don't share ID with $self!!
if (@{ $n->data->{'family-name'} }
|| @{ $n->data->{'given-name'} }
|| @{ $n->data->{'additional-name'} }
|| @{ $n->data->{'initial'} }
|| @{ $n->data->{'honorific-prefix'} }
|| @{ $n->data->{'honorific-suffix'} })
{
push @{ $self->{'DATA'}->{'n'} }, $n;
}
}
# Detect kind ('individual', 'org', etc)
$self->_detect_kind;
# Perform N-optimisation.
$self->_n_optimisation
if lc $self->data->{'kind'} eq 'individual';
$cache->set($context, $element, $class, $self)
lib/HTML/Microformats/Format/hCard.pm view on Meta::CPAN
['title', '*'],
['tz', '?', {'value-title'=>'allow'}],
['uid', 'U?'],
['url', 'u*'],
],
'options' => {
'rel-me' => '_has_relme',
'rel-tag' => 'category',
'hmeasure' => 'measures', #extension
'no-destroy' => ['adr', 'geo'],
},
'rdf:type' => ["${vcard}VCard"] ,
'rdf:property' => {
'adr' => { 'resource' => ["${vcard}adr"] } ,
'agent' => { 'resource' => ["${vcard}agent"] , 'literal' => ["${vx}agent-literal"] } ,
'anniversary' => { 'literal' => ["${vx}anniversary"] },
'bday' => { 'literal' => ["${vcard}bday"] },
'birth' => { 'resource' => ["${vx}birth"] , 'literal' => ["${vx}birth-literal"] },
'caladruri' => { 'resource' => ["${vx}caladruri"] },
'caluri' => { 'resource' => ["${vx}caluri"] },
'category' => { 'resource' => ["${vx}category", 'http://www.holygoat.co.uk/owl/redwood/0.1/tags/taggedWithTag'] , 'literal' => ["${vcard}category"]},
'class' => { 'literal' => ["${vcard}class"] },
'dday' => { 'literal' => ["${vx}dday"] },
'death' => { 'resource' => ["${vx}death"] , 'literal' => ["${vx}death-literal"] },
'email' => { 'resource' => ["${vcard}email"] },
'fn' => { 'literal' => ["${vcard}fn", "http://www.w3.org/2000/01/rdf-schema#label"] },
'fburl' => { 'resource' => ["${vx}fburl"] },
'gender' => { 'literal' => ["${vx}gender"] },
'geo' => { 'resource' => ["${vcard}geo"] } ,
'impp' => { 'resource' => ["${vx}impp"] },
'kind' => { 'literal' => ["${vx}kind"] },
'key' => { 'resource' => ["${vcard}key"] },
'label' => { 'resource' => ["${vcard}label"] },
'lang' => { 'literal' => ["${vx}lang"] },
'logo' => { 'resource' => ["${vcard}logo"] },
'mailer' => { 'literal' => ["${vcard}mailer"] },
'n' => { 'resource' => ["${vcard}n"] },
'nickname' => { 'literal' => ["${vcard}nickname"] },
'note' => { 'literal' => ["${vcard}note"] },
'org' => { 'resource' => ["${vcard}org"] },
'photo' => { 'resource' => ["${vcard}photo"] },
'rev' => { 'literal' => ["${vcard}rev"] },
'role' => { 'literal' => ["${vcard}role"] },
'sex' => { 'literal' => ["${vx}sex"] },
'sort-string' => { 'literal' => ["${vcard}sort-string"] },
'sound' => { 'resource' => ["${vcard}sound"] },
'species' => { 'resource' => ["${vx}x-species"] },
'tel' => { 'resource' => ["${vcard}tel"] },
'title' => { 'literal' => ["${vcard}title"] },
'tz' => { 'literal' => ["${vcard}tz"] },
'uid' => { 'resource' => ["${vcard}uid"], 'literal' => ["${vcard}uid"] },
'url' => { 'resource' => ["${vcard}url"] },
'cn' => { 'literal' => ["${ical}cn"] },
'cutype' => { 'literal' => ["${ical}cutype"] },
'rsvp' => { 'literal' => ["${ical}rsvp"] },
'delegated-from' => { 'resource' => ["${ix}delegatedFrom"] , 'literal' => ["${ical}delegatedFrom"] },
'sent-by' => { 'resource' => ["${ix}sentBy"] , 'literal' => ["${ical}sentBy"] },
},
};
if (ref $self and $self->{'in_hcalendar'})
{
push @{ $rv->{'classes'} }, ( # these are ALL extensions
['cn', '?'],
['cutype', '?'],
['member', '?'],
['rsvp', '?'],
['delegated-from', 'Mu*',{'embedded'=>'hCard'}],
['sent-by', 'Mu*', {'embedded'=>'hCard'}],
);
$rv->{'rdf:property'}->{'member'} = { 'resource' => ["${ix}member"] , 'literal' => ["${ix}member"] };
}
else
{
push @{ $rv->{'classes'} }, (
['member', 'Mu*', {'embedded'=>'hCard'}], #extension
);
$rv->{'rdf:property'}->{'member'} = { 'resource' => ["${vx}member"] , 'literal' => ["${vx}member"] };
}
return $rv;
}
sub add_to_model
{
my $self = shift;
my $model = shift;
$self->_simple_rdf($model);
foreach my $property (qw(n org adr geo agent tel email label impp birth caluri death fburl delegated-from sent-by member species))
{
foreach my $value (@{ $self->data->{$property} })
{
if (Scalar::Util::blessed($value) and $value->can('add_to_model'))
{
$value->add_to_model($model);
}
}
}
# From the vCard we can infer data about its holder.
{
$model->add_statement(RDF::Trine::Statement->new(
$self->id(1, 'holder'),
RDF::Trine::Node::Resource->new('http://purl.org/uF/hCard/terms/hasCard'),
$self->id(1),
));
if (lc $self->data->{'kind'} eq 'individual')
{
$model->add_statement(RDF::Trine::Statement->new(
$self->id(1, 'holder'),
RDF::Trine::Node::Resource->new('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
RDF::Trine::Node::Resource->new('http://xmlns.com/foaf/0.1/Person'),
));
}
elsif (lc $self->data->{'kind'} eq 'org')
{
$model->add_statement(RDF::Trine::Statement->new(
$self->id(1, 'holder'),
( run in 0.520 second using v1.01-cache-2.11-cpan-39bf76dae61 )