--- a
+++ b/bin/nona-svg
@@ -0,0 +1,155 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Panotools::Script;
+use Getopt::Long;
+use Pod::Usage;
+my $help = 0;
+my @image;
+my $output = 'output';
+
+GetOptions ('i=s' => \@image,
+            'o=s' => \$output,
+            'h|help' => \$help);
+
+pod2usage (-verbose => 2) if $help;
+
+my $path_pto = shift || pod2usage;
+die "Can't find $path_pto" unless -e $path_pto;
+
+my $pto = new Panotools::Script;
+$pto->Read ($path_pto);
+
+# input image paths can be overridden on command line
+for my $id (0 .. scalar @ARGV -1)
+{
+    $pto->Image->[$id]->{n} = '"'. $ARGV[$id] .'"';
+}
+
+# do all images unless -i parameter is specified
+unless (scalar @image)
+{
+    @image = (0 .. scalar @{$pto->Image} -1);
+}
+
+$pto->InitTrafo ($path_pto);
+
+for my $id_image (@image)
+{
+
+    open SVG, '<'. $pto->Image->[$id_image]->Path ($pto);
+    my @lines = (<SVG>);
+    close SVG;
+
+    my $xml = join '', @lines;
+    $xml =~ s/(\r|\l|\n)//g;
+    $xml =~ s/[[:space:]]+/ /g;
+    $xml =~ s/> </></g;
+
+    my ($width) = $xml =~ /<svg[^>]*[[:space:]]width="([0-9.]+)"/;
+    my ($height) = $xml =~ /<svg[^>]*[[:space:]]height="([0-9.]+)"/;
+
+    next unless $width;
+    next unless $height;
+
+    my $width_out = $pto->Panorama->{w};
+    my $height_out = $pto->Panorama->{h};
+
+    $xml =~ s/(<svg[^>]*[[:space:]]width=)"[0-9.]+"/$1"$width_out"/;
+    $xml =~ s/(<svg[^>]*[[:space:]]height=)"[0-9.]+"/$1"$height_out"/;
+
+    for my $path ($xml =~ /([[:space:]]d="[-0-9.,CLMQSTZclmqstz[:space:]]*")/g)
+    {
+        my @tokens = $path =~ /([[:space:]]d="|[-0-9.]+[,[:space:]][-0-9.]+|[[:space:]]|[CLMQSTZclmqstz]|")/g;
+
+        my $relative = 0;
+        my ($x_last, $y_last) = (0.0, 0.0);
+        my ($x_curr, $y_curr) = (0.0, 0.0);
+        my @tokens_out;
+
+        for my $token (@tokens)
+        {
+            $relative = 0 if ($token =~ /^([CLMQST])$/);
+            # lower case letters indicate relative coordinates follow
+            $relative = 1 if ($token =~ /^([lm])$/);
+            # these are relative to start of command
+            if ($token =~ /^([cqst])$/)
+            {
+                $relative = 2;
+                ($x_curr, $y_curr) = ($x_last, $y_last);
+            }
+
+            # coordinate pairs can be space or comma separated
+            if ($token =~ /([-0-9.]+)[,[:space:]]([-0-9.]+)/)
+            {
+                my ($x, $y) = ($1, $2);
+                if ($relative == 1)
+                {
+                    $x += $x_last;
+                    $y += $y_last;
+                }
+                if ($relative == 2)
+                {
+                    $x += $x_curr;
+                    $y += $y_curr;
+                }
+                $x_last = $x;
+                $y_last = $y;
+
+                ($x, $y) = $pto->Trafo ($id_image, $x, $y);
+                $token = $x .','. $y;
+            }
+            push @tokens_out, $token;
+        }
+        my $path_new = join '', @tokens_out;
+        # all coordinates are now absolute
+        $path_new =~ tr/clmqst/CLMQST/;
+
+        $xml =~ s/$path/$path_new/;
+    }
+
+    open SVG, '>'. $output . sprintf("%04d", $id_image) .'.svg';
+    print SVG $xml;
+    close SVG;
+}
+
+0;
+
+__END__
+
+=head1 NAME
+
+nona-svg - stitch a vector panorama image 
+
+=head1 SYNOPSIS
+
+ nona-svg [options] -o output project_file (image files)
+
+ Options:
+  -o prefix    Prefix for output
+  -i num       Images to render, can be specified multiple times
+  -h | --help  Outputs help documentation.
+
+=head1 DESCRIPTION
+
+B<nona-svg> is a drop in replacement for nona that works with SVG vector files.
+
+=head1 LICENSE
+
+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.
+
+=head1 SEE ALSO
+
+L<http://hugin.sourceforge.net/>
+
+=head1 AUTHOR
+
+Bruno Postle - August 2012
+
+=cut
+