#!/usr/bin/perl # This is a script to render a plain text outline file into SVG. # # Copyright (C) 2006 Bryce Harrington. Available for use under the GPL. # # Usage: outline2svg.pl [ --master=template.svg ] # use strict; use Getopt::Long; use Pod::Usage; use SVG::Parser; use vars qw($VERSION); $VERSION = '1.00'; our $opt_version = 0; our $opt_help = 0; our $opt_man = 0; our $opt_debug = 1; our $opt_master = "template.svg"; our $opt_width = 300; our $opt_height = 200; our $opt_x_margin = 100; our $opt_y_margin = 150; our $opt_font = 'Arial'; our $opt_font_family = 'Arial'; our $opt_font_size = 24; Getopt::Long::Configure ("bundling", "no_ignore_case"); GetOptions( "version|V", # Prints the version and exits "help|h", # Prints a brief help message "man", # Prints a manual page (detailed help) "debug|D=i", # Prints debug messages "master|m=s", # Master template to use "width|w=i", # Page width "height|h=i", # Page height "x-margin|x=i", # Horizontal offset "y-margin|y=i", # Vertical offset "font=s", # Default font name "font-family=s", # Default font family "font-size=s", # Default font size ); my $i = 0; my $page = 0; my $filename; my $svg; sub start_page { my $title = shift; end_page(); $filename = sprintf("%02d_$title.svg", $page); $filename =~ s/\s+/_/g; $filename =~ s#/#-#g; $filename =~ s#[^\w\:\.\,\+\-]+#_#g; $svg = SVG::Parser->new()->parsefile($opt_master); $svg->comment('Generated by outline2svg'); $page++; $i = 0; } sub end_page { if (defined($svg) && defined($filename)) { open(FILE, ">$filename") or die "Could not open '$filename' for writing: $!\n"; my $contents = $svg->xmlify(); # Work-around bug in SVG::Parser $contents =~ s/�//g; print "$filename\n" if $opt_debug>0; print FILE $contents; close(FILE) || print "Error closing $filename: $!\n"; undef $svg; undef $filename; } } my $font = $opt_font; my $font_family = $opt_font_family; my $font_size = $opt_font_size; my $line_spacing = $font_size * 1.5; while (my $line = <>) { chomp($line); $line =~ s/\s+$//; # Trim trailing space my $x = 10; my $style = { 'font' => $font, 'font-family' => $font_family, 'font-size' => $font_size }; # Convert tabs into spaces, otherwise we get errors about invalid char $line =~ s/\t/ /g; # If we've encountered a page marker, increment the page number if ($line =~ /^\* (.*)$/) { my $title = $1; start_page($title); if ($title !~ /^(title|overview)$/i ) { $style->{'font-size'} *= 1.5; $svg->text(id => "title_$i", x => $opt_x_margin, y => $opt_y_margin, 'xml:space' => 'preserve', style => $style, ) ->cdata($title); } $i++; } elsif (defined($svg)) { my $y = $line_spacing*(1+$i); my $num_leading_spaces = 0; if ($line =~ /^(\s+)/) { $num_leading_spaces = length($1); } if ($num_leading_spaces > 0 && length($line) > $num_leading_spaces && length($line) + $num_leading_spaces > 70 && length($line) + $num_leading_spaces <76 ) { # Looks like user is trying to center this text $line =~ s/^\s+//; $style->{'align'} = 'centered'; $style->{'anchor'} = 'middle'; $x = $opt_width / 2; } else { while ($line && $line =~ /^\s/) { $line =~ s/^\s//; # Just delete one space at a time $x += 5; } # Create bullets if needed if ($line =~ /^-\s+/) { $line =~ s/^-\s+//; $x += 10; $svg->circle(cx=>$opt_x_margin + $x - ($font_size/2), cy=>$opt_y_margin + $y - ($font_size/3), r=>($font_size/6.0)); } } # Convert markup into appropriate SVG-isms $svg->text(id => "text_line_$i", x => $opt_x_margin + $x, y => $opt_y_margin + $y, 'xml:space' => 'preserve', style => $style, ) ->cdata($line); $i++; } } end_page(); #print $svg->xmlify();