6ad65071a911e84818ac23c14e1b884daf92e265
1 #!/usr/bin/perl
3 # This is a script to render a plain text outline file into SVG.
4 #
5 # Copyright (C) 2006 Bryce Harrington. Available for use under the GPL.
7 use strict;
8 use Getopt::Long;
9 use Pod::Usage;
10 use SVG::Parser;
11 use vars qw($VERSION);
12 $VERSION = '1.00';
14 our $opt_version = 0;
15 our $opt_help = 0;
16 our $opt_man = 0;
17 our $opt_debug = 1;
18 our $opt_master = "template.svg";
19 our $opt_width = 300;
20 our $opt_height = 200;
21 our $opt_x_margin = 100;
22 our $opt_y_margin = 150;
23 our $opt_font = 'Arial';
24 our $opt_font_family = 'Arial';
25 our $opt_font_size = 24;
27 Getopt::Long::Configure ("bundling", "no_ignore_case");
28 GetOptions(
29 "version|V", # Prints the version and exits
30 "help|h", # Prints a brief help message
31 "man", # Prints a manual page (detailed help)
32 "debug|D=i", # Prints debug messages
33 "master|m=s", # Master template to use
34 "width|w=i", # Page width
35 "height|h=i", # Page height
36 "x-margin|x=i", # Horizontal offset
37 "y-margin|y=i", # Vertical offset
38 "font=s", # Default font name
39 "font-family=s", # Default font family
40 "font-size=s", # Default font size
41 );
43 my $i = 0;
44 my $page = 0;
45 my $filename;
46 my $svg;
48 sub start_page {
49 my $title = shift;
50 end_page();
52 $filename = sprintf("%02d_$title.svg", $page);
53 $filename =~ s/\s+/_/g;
54 $filename =~ s#/#-#g;
55 $filename =~ s#[^\w\:\.\,\+\-]+#_#g;
57 $svg = SVG::Parser->new()->parsefile($opt_master);
58 $svg->comment('Generated by outline2svg');
59 $page++;
60 $i = 0;
61 }
63 sub end_page {
64 if (defined($svg) && defined($filename)) {
65 open(FILE, ">$filename")
66 or die "Could not open '$filename' for writing: $!\n";
67 my $contents = $svg->xmlify();
68 # Work-around bug in SVG::Parser
69 $contents =~ s/�//g;
70 print "$filename\n" if $opt_debug>0;
71 print FILE $contents;
72 close(FILE) || print "Error closing $filename: $!\n";
74 undef $svg;
75 undef $filename;
76 }
77 }
80 my $font = $opt_font;
81 my $font_family = $opt_font_family;
82 my $font_size = $opt_font_size;
83 my $line_spacing = $font_size * 1.5;
85 while (my $line = <>) {
86 chomp($line);
87 $line =~ s/\s+$//; # Trim trailing space
88 my $x = 10;
89 my $style = { 'font' => $font,
90 'font-family' => $font_family,
91 'font-size' => $font_size
92 };
94 # Convert tabs into spaces, otherwise we get errors about invalid char
95 $line =~ s/\t/ /g;
97 # If we've encountered a page marker, increment the page number
98 if ($line =~ /^\* (.*)$/) {
99 my $title = $1;
100 start_page($title);
102 if ($title !~ /^(title|overview)$/i ) {
103 $style->{'font-size'} *= 1.5;
104 $svg->text(id => "title_$i",
105 x => $opt_x_margin,
106 y => $opt_y_margin,
107 'xml:space' => 'preserve',
108 style => $style,
109 )
110 ->cdata($title);
111 }
112 $i++;
114 } elsif (defined($svg)) {
115 my $y = $line_spacing*(1+$i);
117 my $num_leading_spaces = 0;
118 if ($line =~ /^(\s+)/) {
119 $num_leading_spaces = length($1);
121 }
123 if ($num_leading_spaces > 0 &&
124 length($line) > $num_leading_spaces &&
125 length($line) + $num_leading_spaces > 70 &&
126 length($line) + $num_leading_spaces <76 ) {
127 # Looks like user is trying to center this text
128 $line =~ s/^\s+//;
129 $style->{'align'} = 'centered';
130 $style->{'anchor'} = 'middle';
131 $x = $opt_width / 2;
133 } else {
134 while ($line && $line =~ /^\s/) {
135 $line =~ s/^\s//; # Just delete one space at a time
136 $x += 5;
137 }
139 # Create bullets if needed
140 if ($line =~ /^-\s+/) {
141 $line =~ s/^-\s+//;
142 $x += 10;
143 $svg->circle(cx=>$opt_x_margin + $x - ($font_size/2),
144 cy=>$opt_y_margin + $y - ($font_size/3),
145 r=>($font_size/6.0));
146 }
147 }
149 # Convert markup into appropriate SVG-isms
150 $svg->text(id => "text_line_$i",
151 x => $opt_x_margin + $x,
152 y => $opt_y_margin + $y,
153 'xml:space' => 'preserve',
154 style => $style,
155 )
156 ->cdata($line);
157 $i++;
158 }
159 }
160 end_page();
162 #print $svg->xmlify();