You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kpresenter/kprconverter.pl

175 lines
5.0 KiB

#!/usr/bin/perl -w
# converts a KPresenter document from the old format to the new one (v2)
# due to the new text object
use Time::Local;
open(INPUT, "<$ARGV[0]") || die "Cannot open $ARGV[0]";
open(OUTPUT, ">$ARGV[1]") || die "Cannot create $ARGV[1]";
$objType="";
$insideParag=0;
$insideObj=0;
$insidePixmaps=0; # are we inside the <PIXMAPS> tags?
$currentText="";
$currentTextType=0;
while (<INPUT>)
{
study; # This speeds up the whole RE stuff because Perl creates some hash for the string
if (/<DOC/)
{
# store the url because this is a prart of the "path" for the images
$url=$1 if(m/url=\"(.*?)\"/);
s/>$/ syntaxVersion=\"2\">/;
}
elsif (/<PIXMAPS>/)
{
$insidePixmaps=1;
}
elsif (/<\/PIXMAPS>/)
{
$insidePixmaps=0;
}
elsif (/<TEXTOBJ/)
{
# Save object type of the TEXTOBJ tag
$objType=$1 if (m/objType=(\"[0-9]+\")/);
s/gap=/margin=/;
}
elsif (/<PARAGRAPH/)
{
$insideParag=1;
s/<PARAGRAPH /<P /;
# In the old format we had horzAlign="[0|1|2]" 0=left, 1=center, 2=right
# In the new one it's align="..." and uses the Qt::AlignmentFlags enums.
# Qt::AlignLeft=1, AlignRight=2, AlignHCenter=4
$alignment=$1 if(/horzAlign=(\"[0-2]+\")/);
$alignment =~ tr/01/14/;
s/horzAlign=\"[0-2]+\"/align=$alignment/;
s/>$/ type=$objType>/;
}
elsif (/<\/PARAGRAPH>/)
{
$insideParag=0;
s/<\/PARAGRAPH/<\/P/;
# Flush last text tag
$_ = $currentText . "</TEXT>\n" . $_ if ($currentText);
$currentText="";
}
elsif (/<LINE/ || /<\/LINE/)
{
$_ = "" if ($insideParag); # ignore
}
elsif (/<OBJ>/)
{
$insideObj=1;
$_ = ""; # ignore
}
elsif (/<\/OBJ>/)
{
$insideObj=0;
$_ = ""; # ignore
}
elsif ($insideObj)
{
$toprint="";
if (m/<TYPE value="([0-9]+)"/)
{
$currentTextType=$1;
if ($currentTextType) # 1 -> this is a white space
{
# If we have a previous text element, we keep it (merging)
# Otherwise this white space is the first one in the object -> cheat
$currentTextType=0 if (!$currentText);
}
if (!$currentTextType) # 0 -> normal text
{
# If we have a previous text element, write it out
$toprint = $currentText . "</TEXT>\n" if ($currentText);
# Start a new text element
$currentText = " <TEXT ";
}
}
elsif (/<FONT/ && !$currentTextType) # normal text
{
s/\s*<FONT //;
s/\/>//;
chomp;
# Append all attributes
$currentText .= $_; # the same as $currentText = $currentText . $_, but faster
}
elsif (/<COLOR/ && !$currentTextType) # normal text
{
$red=$1 if (m/red=\"([0-9]+)\"/);
$green=$1 if (m/green=\"([0-9]+)\"/);
$blue=$1 if (m/blue=\"([0-9]+)\"/);
# Convert color to HTML representation
$currentText .= sprintf(" color=\"#%02x%02x%02x\"", $red, $green, $blue );
}
elsif (m/<TEXT>(.*)<\/TEXT>/)
{
if (!$currentTextType) # normal text
{
# Close opening tag and append the text - but don t do more yet
@entities=split( "(&[a-z]+;)", $1);
$text="";
foreach ( @entities )
{
if (!/&lt;/ && !/&gt;/ )
{
# Replace & by &amp; but only if not in an entity
s/\&/\&amp;/g;
}
$text .= $_;
}
$currentText .= ">" . $text;
}
else
{
# White space. Simply appending, closing the text tag.
$toprint = $currentText . $1 . "</TEXT>\n";
$currentText = ""; # reset
}
}
$_=$toprint;
}
elsif ($insidePixmaps)
{
if(/\s+name=\"/)
{
# Aha - this file is not version 2 but was created as "proper" tgz storage... medieval times :)
print "Found a name attribute, no need to create one.\n";
}
elsif (/<KEY(.*)\/>/)
{
# Okay - plain old kpresenter magic...
$key=$1;
study($key); # should be faster ;)
# Note: The .*? is needed because it would be too greedy otherwise
$filename=$1 if($key =~ /filename=\"(.*?)\"/);
# Get the values - really straightforward
$year=$1 if($key =~ /year=\"(\d+)\"/);
$month=$1 if($key =~ /month=\"(\d+)\"/);
$day=$1 if($key =~ /day=\"(\d+)\"/);
$hour=$1 if($key =~ /hour=\"(\d+)\"/);
$minute=$1 if($key =~ /minute=\"(\d+)\"/);
$second=$1 if($key =~ /second=\"(\d+)\"/);
# In Perl the month is <0...11>!!!
$timestamp=timegm($second, $minute, $hour, $day, $month-1, $year);
# Unfortunately we even have to mess with that string...
$timestring=scalar gmtime($timestamp);
# There are still some spaces too much when day<10
$timestring =~ s/ / /;
# Okay. Now let's cat the whole caboodle...
$nameattrib=$url . $filename . "_" . $timestring;
# ...and put it in place.
s/\/>/ name=\"$nameattrib\" \/>/;
}
}
print OUTPUT $_;
}
close(INPUT);
close(OUTPUT);