summaryrefslogtreecommitdiffstats
path: root/share/extensions/outline2svg.pl
blob: 1c1daf0c34f303300d272f58816449d5f510014a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/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 <presentation.outline> [ --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/&#x00;//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();