Commits

Toby Inkster  committed fb2b920

Some vCard 4.0 support.

  • Participants
  • Parent commits a1f0f66

Comments (0)

Files changed (7)

   homepage: http://search.cpan.org/dist/RDF-vCard/
   license: http://dev.perl.org/licenses/
   repository: http://goddamn.co.uk/viewvc/perlmods/RDF-vCard/
-version: 0.004
+version: 0.005
+
 use lib "lib";
+use lib "../HTML-Microformats/lib";
 use RDF::TrineShortcuts;
 use HTML::Microformats;
 use RDF::vCard;
 	<body>
 		<div class="vcard">
 			<h1><a href="/" class="fn url">Alice Jones</a></h1>
-			<p class="adr"><span class="locality">Lewes</span>, <span class="region">East Sussex</span></p>
+			<p class="adr">
+				<span class="locality">Lewes</span>,
+				<span class="region">East Sussex</span>
+				(<span class="geo">50.87363;0.01133</span>)
+			</p>
 			<div class="agent vcard">
 				<span class="role">Secretary</span>
 				<a class="fn email" href="mailto:bob@example.com">Bob Smith</a>
 <http://example.net/taxo/Quux> rdf:value "Quux" .
 
   <http://example.com/> a v:VCard ;
-     v:fn "Example.Com LLC" ;
+     v:fn "Example.Com LLC"@en ;
      v:org
          [   v:organisation-name "Example.Com LLC" ;
              v:organisation-unit "Corporate Division"
              v:longitude "55.45"
          ] ;
      v:tel
-         [ a v:Fax, v:Work ;
+         [ a v:Fax, v:Work , v:Pref ;
              rdf:value "+61 7 5555 0000"
          ] ; 
      v:email <mailto:info@example.com> ;
 #print rdf_string($model => 'rdfxml');
 #print "#######\n";
 
-my $exporter = RDF::vCard::Exporter->new;
+my $exporter = RDF::vCard::Exporter->new(vcard_version=>4);
 my @cards = $exporter->export_cards($model);
 foreach my $c (@cards)
 {

File lib/RDF/vCard.pm

 use RDF::vCard::Exporter;
 use RDF::vCard::Importer;
 
-our $VERSION = '0.004';
+our $VERSION = '0.005';
 
 1;
 

File lib/RDF/vCard/Entity.pm

 use namespace::clean;
 
 use overload '""' => \&to_string;
-our $VERSION = '0.004';
+our $VERSION = '0.005';
 
 sub new
 {

File lib/RDF/vCard/Exporter.pm

 
 use namespace::clean;
 
-our $VERSION = '0.004';
+our $VERSION = '0.005';
 our $PRODID  = sprintf("+//IDN cpan.org//NONSGML %s v %s//EN", __PACKAGE__, $VERSION);
 
 our %dispatch = (
 	bless { %options }, $class;
 }
 
+sub is_v4
+{
+	my ($self) = @_;
+	return ($self->{vcard_version}) ? 4 : 0;
+}
+
+sub is_v3
+{
+	my ($self) = @_;
+	return $self->is_v4 ? 0 : 3;
+}
+
 sub export_cards
 {
 	my ($self, $model, %options) = @_;
 	$card->add(
 		RDF::vCard::Line->new(
 			property        => 'version',
-			value           => '3.0',
+			value           => $self->is_v4 ? '4.0' : '3.0',
 			)
 		);
 		
 	delete $types->{ADDRESS};
 	delete $types->{LABEL};
 	
-	if (%$types)
+	my @geos;
+	my $iter = $model->get_statements($triple->object, rdf_resource(VX('geo')), undef);
+	while (my $st = $iter->next)
+	{
+		my $gline = $self->_prop_export_geo($model, $st);
+		push @geos, $gline->_unescape_value($gline->value_to_string);
+	}
+	if (@geos)
+	{
+		$params->{geo} = \@geos;
+	}
+	
+	if (%$types and $self->is_v4)
+	{
+		$params->{type} = [sort grep { !/^pref$/i } keys %$types];
+		$params->{pref} = 1 if $types->{PREF};
+	}
+	elsif (%$types)
 	{
 		$params->{type} = [sort keys %$types];
 	}
 		push @$g, ($values[0] || '');
 	}
 	
-	return RDF::vCard::Line->new(
-		property => 'geo',
-		value    => $g,
-		);
+	if ($self->is_v4)
+	{
+		return RDF::vCard::Line->new(
+			property => 'geo',
+			value    => sprintf('geo:%f,%f', @$g),
+			type_parameters => { value=>'URI' },
+			);
+	}
+	else
+	{
+		return RDF::vCard::Line->new(
+			property => 'geo',
+			value    => $g,
+			type_parameters => { value=>'TEXT' },
+			);
+	}
 }
 
 # tel, email, label and impp may be typed
 	}
 	elsif ($prop eq 'tel' and $value =~ /^(tel|fax|modem):(.+)$/i)
 	{
-		$value = $2;
+		if ($self->is_v4) #v4 telephone numbers are URIs
+		{
+			$params = { value=>'URI' };
+		}
+		else #v3 telephone numbers are text (well VALUE=PHONE-NUMBER technically)
+		{
+			$value = $2;
+		}
 		$types->{FAX}   = 1 if lc $1 eq 'fax';
 		$types->{MODEM} = 1 if lc $1 eq 'modem';
 	}
 	delete $types->{ADDRESS};
 	delete $types->{LABEL};
 	
-	if (%$types)
+	if (%$types and $self->is_v4)
+	{
+		$params->{type} = [sort grep { !/^pref$/i } keys %$types];
+		$params->{pref} = 1 if $types->{PREF};
+	}
+	elsif (%$types)
 	{
 		$params->{type} = [sort keys %$types];
 	}
 	$params = undef unless %$params;
 
-	if (uc $prop eq 'TEL')
+	if ($prop eq 'tel')
 	{
 		$params->{'value'} ||= 'PHONE-NUMBER';
+		
+		if ($self->is_v4 and $params->{'value'} ne 'URI' and $value =~ /^\+[0-9\s\-]+$/)
+		{
+			$value =~ s/\s/-/g;
+			$value = "tel:${value}";
+			$params->{'value'} = 'URI';
+		}
 	}
 
 	return RDF::vCard::Line->new(
 	my ($self, $model, $triple) = @_;
 	my $line = $self->_prop_export_simple($model, $triple);
 	
-	if ($line->value->[0] =~ /^data:\S+$/)
+	if ($self->is_v3 and $line->value->[0] =~ /^data:\S+$/)
 	{
 		my $data_uri = URI->new( $line->value->[0] );
 		my $data     = $data_uri->data;
  use RDF::vCard;
  
  my $input    = "http://example.com/contact-data.rdf";
- my $exporter = RDF::vCard::Exporter->new;
+ my $exporter = RDF::vCard::Exporter->new(vcard_version => 3);
  
  print $_ foreach $exporter->export_cards($input);
 
 
 Returns a new RDF::vCard::Exporter object.
 
-There are no valid options at the moment - the hash is reserved
-for future use.
+Options:
+
+=over
+
+=item * B<vcard_version> - '3' or '4'. This module will happily use
+vCard 3.0 constructs in vCard 4.0 and vice versa. But in certain places
+it can lean one way or the other. This option allows you to influence
+that.
+
+=back
 
 =back
 
 URI instead of a literal) it can pretty easily descend into exporting
 junk, non-compliant vCards.
 
-There is support for a smattering of vCard 4.0 features such as the
-IMPP and KIND properties.
+Many vCard 4.0 properties, such as the IMPP and KIND, are also supported.
+
+The B<vcard_version> constructor option allows you to influence how some
+properties like GEO and TEL (which differ between 3.0 and 4.0) are output.
 
 =head1 SEE ALSO
 

File lib/RDF/vCard/Importer.pm

 
 use namespace::clean;
 
-our $VERSION = '0.004';
+our $VERSION = '0.005';
 
 sub new
 {

File lib/RDF/vCard/Line.pm

 use namespace::clean;
 
 use overload '""' => \&to_string;
-our $VERSION = '0.004';
+our $VERSION = '0.005';
 
 sub new
 {