Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

Parsing iCal Data
by Robert Pratte | Pages: 1, 2, 3, 4

The specification describes additional complexity in terms of sub-objects/structures, alternate shapes (the default is an oval), ranking, and more. One additional item worth noting is that Dot recognizes comments in C- and Java-style formats (// and /*). To help troubleshoot problems (and for good coding practice), I suggest that your parser insert comments into the Dot input file.

Consider how you might create a Dot file from the data parsed earlier. If you pass to the function that handles the writing of the Dot file the reference to the filehandle of your Dot input file (the output of your conversion) along with the reference to your parsed data structure, then you might generate your Dot file along these lines:

##------------------------------
  ## Name our Dot graph 
  ##------------------------------
  if ( $raw->{'CALNAME'} ) {
      print { $$file } 'digraph "'. $raw->{'CALNAME'} ."\" {\n\n";
   } elsif ( $$raw{'CALID'} ) {
      print { $$file } 'digraph "'. $raw->{'CALID'} ."\" {\n\n";
   } else {
      print { $$file } "digraph unnamed {\n\n";
   }


   ##-----------------------------------------
   ## Some optional rendering info
   ##-----------------------------------------
   print { $$file } '   size     = "10,7";'. "\n".
                    '   compound = true;'  . "\n".
                    '   ratio    = fill;'  . "\n".
                    '   rankdir  = LR;'    . "\n\n";


   ##-----------------------------------------
   ## Generate our Dot data
   ##   we will wrap most data in double-quotes 
   ##   since most Dot interpreters don't like spaces, 
   ##   something allowed in iCal data
   ##-----------------------------------------
   foreach $key ( keys %$raw ) {
      if ( ref( $raw->{$key} ) eq 'HASH' ) {
         my $block = $raw->{$key};

           ##------------------------------
           ## graphViz doesn't like - in names
           ##------------------------------
         $block->{'UID'} =~ s/-/_/g;

           ##------------------------------
           ## produce list of all unique tasks
           ##------------------------------
         push( @{ $tasks->{$block->{'SUMMARY'}} }, '"'. $block->{'UID'} .'"' );

           ##------------------------------
           ## build record
           ##------------------------------
         my $eventBlock = '"'. $block->{'UID'} .
                          '" [ shape = record, label = "'. $block->{'SUMMARY'} .
                           ' | <START> Start | <END> End ';

         if ( $block->{'DESCRIPTION'} ) {
            $eventBlock .= ' | '. $block->{'DESCRIPTION'};
         }
         $eventBlock .= '"];';

         print { $$file } '   '. $eventBlock ."\n\n";


            ##------------------------------
            ## build relations based upon time
            ##------------------------------
         push( @timeLine,    '"'. $block->{'START'} .'"' );
         print { $$file } '   "'. $block->{'UID'} .'":START  
		    -> "'. $block->{'START'} ."\"\;\n\n";

         if ( $$block{'END'} ) {
            push( @timeLine,    '"'. $block->{'END'} .'"' );
            print { $$file } '   "'. $block->{'UID'} .'":END    
			   -> "'. $block->{'END'} ."\"\;\n\n";
         }

         print { $$file } "\n\n";

}

      ##------------------------------
      ## tie non-unique tasks
      ##------------------------------
    print { $$file } '   // Create tasks relationships'. "\n\n";
    foreach ( keys %$tasks ) {
       if ( @{ $tasks->{$_} } > 1 ) {
          print { $$file } '   '. join( ' -> ', @{ $tasks->{$_} } ) ."\;\n\n";
       }
    }
    print { $$file } "\n\n";


      ##------------------------------
      ## Render our timeline
      ##------------------------------
    print { $$file } '   // Create timeline relationships'. "\n\n";
    print { $$file } '   '. join( ' -> ', sort( @timeLine )) ."\;\n\n";


      ##------------------------------
      ## Close off dot file
      ##------------------------------
    print { $$file } "}\n";

Pages: 1, 2, 3, 4

Next Pagearrow