#! /usr/bin/perl # # Pocket Sheet data (as saved by PVlink) to Gnumeric XML converter # Version 0.2 (2003/03/25) # Copyright (c) 2003 by Marcin Woli\'nski # http://www.mimuw.edu.pl/~wolinski/pv # # Usage: Call it with a name of PVlink-saved file. Gnumeric data # is written to STDOUT. # # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # use strict; use MIME::Base64; use vars qw($shname $dispc $dispr $curc $curr $freeze $fzc1 $fzc2 $fzr1 $fzr2 $protect $linedisp $auto $cellcount $xcount $ycount $date $width @cells $cellsdata $xlinesdata $ylinesdata $maxcol $maxrow); $maxcol=$maxrow=0; $cellsdata=$xlinesdata=$ylinesdata=''; while (<>) { die "That doesn't look like PVlink data file" unless m/^([0-9A-F]+) [^ ]+ (.+)\n/; my ($fcode, $fdata) = ($1, decode_base64($2)); if ($fcode eq '100100') { die "Wrong length of header (${\(length($fdata))}bytes)" unless 118 == length($fdata); ($shname,$dispc,$dispr,$curc,$curr,$freeze,$fzc1,$fzc2,$fzr1,$fzr2, $protect,$linedisp,$auto, $cellcount,$xcount,$ycount,$date,$width) = unpack 'Z33 S4 C S4 CCC S3 a7 a52', $fdata; print STDERR "Converting '$shname'..."; } elsif ($fcode =~ /^10020[01]$/) { $xlinesdata .= $fdata; } elsif ($fcode =~ /^10021[01]$/) { $ylinesdata .= $fdata; } elsif ($fcode =~ /^10030[01]$/) { $cellsdata .= $fdata; } else { die "That doesn't look like Pocket Sheet data" } } # Now all decoded cell data is gathered in $cellsdata: for (my $i=0; $i < $cellcount; $i++) { die "Short cell data" if length($cellsdata) < 16; my @celldata = unpack 'S2 CC Z3 CCCCC S', $cellsdata; # print join ' ', @celldata; print "\n"; die "Short read in cell data" if length($cellsdata) < 16+$celldata[10]; my $celltext = substr $cellsdata, 16, $celldata[10]; substr($cellsdata, 0, 16+$celldata[10]) = ''; $maxcol = $celldata[0] if $maxcol < $celldata[0]; $maxrow = $celldata[1] if $maxrow < $celldata[1]; # push @cells, [@celldata, $celltext]; $cells[$celldata[0]][$celldata[1]] = [@celldata, $celltext]; } # Gnumeric header: print <<"EOS"; application gnumeric $shname $maxcol $maxrow 1.000000 EOS # Dump cells: foreach my $col (@cells) { next unless defined($col); foreach my $cell (@$col) { next unless defined($cell); print << "EOS"; $cell->[11] EOS } } # Gnumeric footer: print <<"EOS"; EOS print STDERR " done.\n";