| blib/lib/Vroom.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % | 
| statement | 43 | 379 | 11.3 | 
| branch | 0 | 170 | 0.0 | 
| condition | 0 | 15 | 0.0 | 
| subroutine | 15 | 49 | 30.6 | 
| pod | 1 | 31 | 3.2 | 
| total | 59 | 644 | 9.1 | 
| line | stmt | bran | cond | sub | pod | time | code | 
|---|---|---|---|---|---|---|---|
| 1 | 2 | 2 | 41631 | use strict; use warnings; | |||
| 2 | 2 | 4 | |||||
| 2 | 109 | ||||||
| 2 | 12 | ||||||
| 2 | 4 | ||||||
| 2 | 104 | ||||||
| 2 | package Vroom; | ||||||
| 3 | our $VERSION = '0.37'; | ||||||
| 4 | 2 | 2 | 1043 | use Vroom::Mo; | |||
| 2 | 12 | ||||||
| 2 | 12 | ||||||
| 5 | |||||||
| 6 | 2 | 2 | 3043 | use File::HomeDir; | |||
| 2 | 14636 | ||||||
| 2 | 159 | ||||||
| 7 | 2 | 2 | 1798 | use IO::All; | |||
| 2 | 32803 | ||||||
| 2 | 21 | ||||||
| 8 | 2 | 2 | 2074 | use Template::Toolkit::Simple; | |||
| 2 | 147757 | ||||||
| 2 | 120 | ||||||
| 9 | 2 | 2 | 2011 | use Term::Size; | |||
| 2 | 7023 | ||||||
| 2 | 107 | ||||||
| 10 | 2 | 2 | 19 | use YAML::XS; | |||
| 2 | 4 | ||||||
| 2 | 100 | ||||||
| 11 | |||||||
| 12 | 2 | 2 | 11 | use Getopt::Long; | |||
| 2 | 3 | ||||||
| 2 | 20 | ||||||
| 13 | 2 | 2 | 296 | use Cwd; | |||
| 2 | 4 | ||||||
| 2 | 116 | ||||||
| 14 | 2 | 2 | 11 | use Carp; | |||
| 2 | 5 | ||||||
| 2 | 96 | ||||||
| 15 | |||||||
| 16 | 2 | 2 | 33 | use Encode; | |||
| 2 | 5 | ||||||
| 2 | 2451 | ||||||
| 17 | |||||||
| 18 | has input => 'slides.vroom'; | ||||||
| 19 | has notesfile => 'notes.txt'; | ||||||
| 20 | has has_notes => 0; | ||||||
| 21 | has stream => ''; | ||||||
| 22 | has ext => ''; | ||||||
| 23 | has help => 0; | ||||||
| 24 | has clean => 0; | ||||||
| 25 | has compile => 0; | ||||||
| 26 | has sample => 0; | ||||||
| 27 | has run => 0; | ||||||
| 28 | has html => 0; | ||||||
| 29 | has text => 0; | ||||||
| 30 | has ghpublish => 0; | ||||||
| 31 | has start => 0; | ||||||
| 32 | has digits => 0; | ||||||
| 33 | has skip => 0; | ||||||
| 34 | has config => { | ||||||
| 35 | title => 'Untitled Presentation', | ||||||
| 36 | height => 24, | ||||||
| 37 | width => 80, | ||||||
| 38 | list_indent => 10, | ||||||
| 39 | skip => 0, | ||||||
| 40 | vim => 'vim', | ||||||
| 41 | vim_opts => '-u NONE', | ||||||
| 42 | vimrc => '', | ||||||
| 43 | gvimrc => '', | ||||||
| 44 | script => '', | ||||||
| 45 | auto_size => 0, | ||||||
| 46 | }; | ||||||
| 47 | |||||||
| 48 | sub usage { | ||||||
| 49 | 0 | 0 | 0 | return <<'...'; | |||
| 50 |      Usage: vroom  | 
||||||
| 51 | |||||||
| 52 | Commands: | ||||||
| 53 | new - Create a sample 'slides.vroom' file | ||||||
| 54 | vroom - Start slideshow | ||||||
| 55 | compile - Generate slides | ||||||
| 56 | html - Publish slides as HTML | ||||||
| 57 | text - Publish slides as plain text | ||||||
| 58 | clean - Delete generated files | ||||||
| 59 | help - Get help! | ||||||
| 60 | |||||||
| 61 | Options: | ||||||
| 62 | --skip=# - Skip # of slides | ||||||
| 63 | --input=name - Specify an input file name | ||||||
| 64 | |||||||
| 65 | ... | ||||||
| 66 | } | ||||||
| 67 | |||||||
| 68 | sub vroom { | ||||||
| 69 | 0 | 0 | 0 | 1 | my $self = ref($_[0]) ? shift : (shift)->new; | ||
| 70 | |||||||
| 71 | 0 | $self->getOptions; | |||||
| 72 | |||||||
| 73 | 0 | 0 | if ($self->sample) { | ||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 74 | 0 | $self->sampleSlides; | |||||
| 75 | } | ||||||
| 76 | elsif ($self->run) { | ||||||
| 77 | 0 | $self->runSlide; | |||||
| 78 | } | ||||||
| 79 | elsif ($self->clean) { | ||||||
| 80 | 0 | $self->cleanAll; | |||||
| 81 | } | ||||||
| 82 | elsif ($self->compile) { | ||||||
| 83 | 0 | $self->makeSlides; | |||||
| 84 | } | ||||||
| 85 | elsif ($self->start) { | ||||||
| 86 | 0 | $self->makeSlides; | |||||
| 87 | 0 | $self->startUp; | |||||
| 88 | } | ||||||
| 89 | elsif ($self->html) { | ||||||
| 90 | 0 | $self->makeHTML; | |||||
| 91 | } | ||||||
| 92 | elsif ($self->text) { | ||||||
| 93 | 0 | $self->makeText; | |||||
| 94 | } | ||||||
| 95 | elsif ($self->ghpublish) { | ||||||
| 96 | 0 | $self->makePublisher; | |||||
| 97 | } | ||||||
| 98 | elsif ($self->help) { | ||||||
| 99 | 0 | warn $self->usage; | |||||
| 100 | } | ||||||
| 101 | else { | ||||||
| 102 | 0 | warn $self->usage; | |||||
| 103 | } | ||||||
| 104 | } | ||||||
| 105 | |||||||
| 106 | sub getOptions { | ||||||
| 107 | 0 | 0 | 0 | my $self = shift; | |||
| 108 | |||||||
| 109 | 0 | 0 | die <<'...' if cwd eq File::HomeDir->my_home; | ||||
| 110 | |||||||
| 111 | Don't run vroom in your home directory. | ||||||
| 112 | |||||||
| 113 | Create a new directory for your slides and run vroom from there. | ||||||
| 114 | ... | ||||||
| 115 | |||||||
| 116 | 0 | 0 | my $cmd = shift(@ARGV) or die $self->usage; | ||||
| 117 | 0 | 0 | die $self->usage unless $cmd =~ s/ | ||||
| 118 | ^-{0,2}( | ||||||
| 119 | help | | ||||||
| 120 | new | | ||||||
| 121 | vroom | | ||||||
| 122 | compile | | ||||||
| 123 | run | | ||||||
| 124 | html | | ||||||
| 125 | text | | ||||||
| 126 | clean | | ||||||
| 127 | ghpublish | ||||||
| 128 | )$ | ||||||
| 129 | /$1/x; | ||||||
| 130 | 0 | 0 | $cmd = 'start' if $cmd eq 'vroom'; | ||||
| 131 | 0 | 0 | $cmd = 'sample' if $cmd eq 'new'; | ||||
| 132 | 0 | $self->{$cmd} = 1; | |||||
| 133 | |||||||
| 134 | 0 | 0 | GetOptions( | ||||
| 135 | "input=s" => \$self->{input}, | ||||||
| 136 | "skip=i" => \$self->{skip}, | ||||||
| 137 | ) or die $self->usage; | ||||||
| 138 | |||||||
| 139 | 0 | 0 | do { delete $self->{$_} unless defined $self->{$_} } | ||||
| 140 | 0 | for qw(clean compile input vroom); | |||||
| 141 | } | ||||||
| 142 | |||||||
| 143 | sub cleanUp { | ||||||
| 144 | 0 | 0 | 0 | my $self = shift; | |||
| 145 | 0 | unlink(glob "0*"); | |||||
| 146 | 0 | unlink('.help'); | |||||
| 147 | 0 | unlink('.vimrc'); | |||||
| 148 | 0 | unlink('.gvimrc'); | |||||
| 149 | 0 | unlink('run.slide'); | |||||
| 150 | 0 | unlink($self->notesfile); | |||||
| 151 | 0 | io->dir('bin')->rmtree; | |||||
| 152 | 0 | io->dir('done')->rmtree; | |||||
| 153 | } | ||||||
| 154 | |||||||
| 155 | sub cleanAll { | ||||||
| 156 | 0 | 0 | 0 | my $self = shift; | |||
| 157 | 0 | $self->cleanUp; | |||||
| 158 | 0 | io->dir('html')->rmtree; | |||||
| 159 | 0 | io->dir('text')->rmtree; | |||||
| 160 | } | ||||||
| 161 | |||||||
| 162 | sub runSlide { | ||||||
| 163 | 0 | 0 | 0 | my $self = shift; | |||
| 164 | 0 | my $slide = $ARGV[0]; | |||||
| 165 | |||||||
| 166 | 0 | 0 | if ($slide =~ /\.pl$/) { | ||||
| 167 | 0 | exec "clear; $^X $slide"; | |||||
| 168 | } | ||||||
| 169 | |||||||
| 170 | 0 | $self->trim_slide; | |||||
| 171 | |||||||
| 172 | 0 | 0 | if ($slide =~ /\.py$/) { | ||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 173 | 0 | exec "clear; python run.slide"; | |||||
| 174 | } | ||||||
| 175 | elsif ($slide =~ /\.rb$/) { | ||||||
| 176 | 0 | exec "clear; ruby run.slide"; | |||||
| 177 | } | ||||||
| 178 | elsif ($slide =~ /\.php$/) { | ||||||
| 179 | 0 | exec "clear; php run.slide"; | |||||
| 180 | } | ||||||
| 181 | elsif ($slide =~ /\.js$/) { | ||||||
| 182 | 0 | exec "clear; js run.slide"; | |||||
| 183 | } | ||||||
| 184 | elsif ($slide =~ /\.hs$/) { | ||||||
| 185 | 0 | exec "clear; runghc run.slide"; | |||||
| 186 | } | ||||||
| 187 | elsif ($slide =~ /\.yaml$/) { | ||||||
| 188 | 0 | exec "clear; $^X -MYAML::XS -MData::Dumper -e '\$Data::Dumper::Terse = 1; \$Data::Dumper::Indent = 1; print Dumper YAML::XS::LoadFile(shift)' run.slide"; | |||||
| 189 | } | ||||||
| 190 | elsif ($slide =~ /\.sh$/) { | ||||||
| 191 | 0 | exec "clear; $ENV{SHELL} -i run.slide"; | |||||
| 192 | } | ||||||
| 193 | } | ||||||
| 194 | |||||||
| 195 | sub trim_slide { | ||||||
| 196 | 0 | 0 | 0 | my $self = shift; | |||
| 197 | 0 | my $slide = $ARGV[0]; | |||||
| 198 | |||||||
| 199 | 0 | my $text < io($slide); | |||||
| 200 | 0 | $text =~ s/^\s*\n//; | |||||
| 201 | 0 | $text =~ s/\n\s*$/\n/; | |||||
| 202 | 0 | while ($text !~ /^\S/m) { | |||||
| 203 | 0 | $text =~ s/^ //mg; | |||||
| 204 | } | ||||||
| 205 | 0 | $text > io('run.slide'); | |||||
| 206 | } | ||||||
| 207 | |||||||
| 208 | sub makeSlides { | ||||||
| 209 | 0 | 0 | 0 | my $self = shift; | |||
| 210 | 0 | $self->cleanUp; | |||||
| 211 | 0 | $self->getInput; | |||||
| 212 | 0 | $self->buildSlides; | |||||
| 213 | 0 | $self->writeVimrc; | |||||
| 214 | 0 | $self->writeScriptRunner; | |||||
| 215 | 0 | $self->writeHelp; | |||||
| 216 | } | ||||||
| 217 | |||||||
| 218 | sub makeText { | ||||||
| 219 | 0 | 0 | 0 | my $self = shift; | |||
| 220 | 0 | $self->cleanAll; | |||||
| 221 | 0 | $self->makeSlides; | |||||
| 222 | 0 | io('text')->mkdir; | |||||
| 223 | 0 | my @slides = glob('0*'); | |||||
| 224 | 0 | for my $slide (@slides) { | |||||
| 225 | 0 | 0 | next unless $slide =~ /^(\d+)(\.\S+)?$/; | ||||
| 226 | 0 | my $num = $1; | |||||
| 227 | 0 | 0 | my $ext = $2 || ''; | ||||
| 228 | 0 | 0 | my $text = io(-e "${num}z$ext" ? "${num}z$ext" : "$num$ext")->all(); | ||||
| 229 | 0 | io("text/$slide")->print($text); | |||||
| 230 | } | ||||||
| 231 | 0 | eval { | |||||
| 232 | 0 | system("cp .vimrc text"); | |||||
| 233 | }; | ||||||
| 234 | 0 | $self->cleanUp; | |||||
| 235 | } | ||||||
| 236 | |||||||
| 237 | sub makeHTML { | ||||||
| 238 | 0 | 0 | 0 | my $self = shift; | |||
| 239 | 0 | $self->cleanAll; | |||||
| 240 | 0 | $self->makeSlides; | |||||
| 241 | 0 | io('html')->mkdir; | |||||
| 242 | 0 | my @slides = glob('0*'); | |||||
| 243 | 0 | my @notes = $self->parse_notesfile; | |||||
| 244 | 0 | for (my $i = 0; $i < @slides; $i++) { | |||||
| 245 | 0 | my $slide = $slides[$i]; | |||||
| 246 | 0 | 0 | my $prev = ($i > 0) ? $slides[$i - 1] : 'index'; | ||||
| 247 | 0 | 0 | my $next = ($i + 1 < @slides) ? $slides[$i + 1] : ''; | ||||
| 248 | 0 | my $text = io($slide)->all; | |||||
| 249 | 0 | $text = Template::Toolkit::Simple->new()->render( | |||||
| 250 | $self->slideTemplate, | ||||||
| 251 | { | ||||||
| 252 | title => $notes[$i]->{'title'}, | ||||||
| 253 | prev => $prev, | ||||||
| 254 | next => $next, | ||||||
| 255 | content => decode_utf8($text), | ||||||
| 256 | notes => $self->htmlize_note($notes[$i]->{'text'}), | ||||||
| 257 | } | ||||||
| 258 | ); | ||||||
| 259 | 0 | io("html/$slide.html")->print($text); | |||||
| 260 | } | ||||||
| 261 | |||||||
| 262 | 0 | my $index = []; | |||||
| 263 | 0 | for (my $i = 0; $i < @slides; $i++) { | |||||
| 264 | 0 | my $slide = $slides[$i]; | |||||
| 265 | 0 | 0 | next if $slide =~ /^\d+[a-z]/; | ||||
| 266 | 0 | my $title = io($slide)->all; | |||||
| 267 | 0 | $title =~ s/.*?((?-s:\S.*)).*/$1/s; | |||||
| 268 | 0 | push @$index, [$slide, decode_utf8($title)]; | |||||
| 269 | } | ||||||
| 270 | |||||||
| 271 | 0 | io("html/index.html")->print( | |||||
| 272 | Template::Toolkit::Simple->new()->render( | ||||||
| 273 | $self->indexTemplate, | ||||||
| 274 | { | ||||||
| 275 | config => $self->config, | ||||||
| 276 | index => $index, | ||||||
| 277 | |||||||
| 278 | } | ||||||
| 279 | ) | ||||||
| 280 | ); | ||||||
| 281 | 0 | $self->cleanUp; | |||||
| 282 | } | ||||||
| 283 | |||||||
| 284 | sub indexTemplate { | ||||||
| 285 | \ <<'...' | ||||||
| 286 | |||||||
| 287 | |||||||
| 288 |   | 
||||||
| 289 | |||||||
| 290 | |||||||
| 302 | |||||||
| 310 | |||||||
| 311 | |||||||
| 312 |  Use SPACEBAR to peruse the slides or click one to start... | 
||||||
| 313 |  [% config.title | html %] | 
||||||
| 314 |   | 
||||||
| 315 | [% FOR entry = index -%] | ||||||
| 316 | [% slide = entry.shift() -%] | ||||||
| 317 | [% title = entry.shift() -%] | ||||||
| 318 |   | 
||||||
| 319 | [% END -%] | ||||||
| 320 | |||||||
| 321 | |||||||
| 322 | href="http://ingydotnet.github.com/vroom-pm">Vroom. Use <SPACE> key to go | ||||||
| 323 | forward and <BACKSPACE> to go backwards. | ||||||
| 324 | |||||||
| 325 | |||||||
| 326 | |||||||
| 327 | ... | ||||||
| 328 | 0 | 0 | 0 | } | |||
| 329 | |||||||
| 330 | sub slideTemplate { | ||||||
| 331 | \ <<'...' | ||||||
| 332 | |||||||
| 333 | |||||||
| 334 |   | 
||||||
| 335 | |||||||
| 336 | |||||||
| 360 | |||||||
| 361 | |||||||
| 362 |   | 
||||||
| 363 |   | 
||||||
| 364 | [%- content | html -%] | ||||||
| 365 | |||||||
| 366 | |||||||
| 367 |   | 
||||||
| 368 |   | 
||||||
| 369 |   [% notes %]  | 
||||||
| 370 | |||||||
| 371 | |||||||
| 372 | |||||||
| 373 | ... | ||||||
| 374 | 0 | 0 | 0 | } | |||
| 375 | |||||||
| 376 | sub getInput { | ||||||
| 377 | 0 | 0 | 0 | my $self = shift; | |||
| 378 | 0 | 0 | my @stream = io($self->input)->slurp | ||||
| 379 | or croak "No input provided. Make a file called 'slides.vroom'"; | ||||||
| 380 | 0 | 0 | my $stream = join '', map { | ||||
| 381 | 0 | /^----\s+include\s+(\S+)/ | |||||
| 382 | ? scalar(io($1)->all) | ||||||
| 383 | : $_ | ||||||
| 384 | } @stream; | ||||||
| 385 | 0 | $self->stream($stream); | |||||
| 386 | } | ||||||
| 387 | |||||||
| 388 | my $TRANSITION = qr/^\+/m; | ||||||
| 389 | my $SLIDE_MARKER = qr/^={4}\n/m; | ||||||
| 390 | my $TITLE_MARKER = qr/^%\s*(.*?)\n/m; | ||||||
| 391 | |||||||
| 392 | sub buildSlides { | ||||||
| 393 | 0 | 0 | 0 | my $self = shift; | |||
| 394 | 0 | my @split = split /^(----\ *.*)\n/m, $self->stream; | |||||
| 395 | 0 | shift @split; | |||||
| 396 | 0 | @split = grep length, @split; | |||||
| 397 | 0 | 0 | push @split, '----' if $split[0] =~ /\n/; | ||||
| 398 | 0 | my (@raw_configs, @raw_slides); | |||||
| 399 | 0 | while (@split) { | |||||
| 400 | 0 | my ($config, $slide) = splice(@split, 0, 2); | |||||
| 401 | 0 | $config =~ s/^----\s*(.*?)\s*$/$1/; | |||||
| 402 | 0 | push @raw_configs, $config; | |||||
| 403 | 0 | push @raw_slides, $slide; | |||||
| 404 | 0 | 0 | $self->has_notes(1) if $slide =~ $SLIDE_MARKER; | ||||
| 405 | } | ||||||
| 406 | 0 | $self->{digits} = int(log(@raw_slides)/log(10)) + 2; | |||||
| 407 | |||||||
| 408 | 0 | my $number = 0; | |||||
| 409 | |||||||
| 410 | 0 | 0 | '' > io($self->notesfile) if $self->has_notes; # start with a blank file so we can append | ||||
| 411 | 0 | for my $raw_slide (@raw_slides) { | |||||
| 412 | 0 | my $config = $self->parseSlideConfig(shift @raw_configs); | |||||
| 413 | |||||||
| 414 | 0 | 0 | next if $config->{skip}; | ||||
| 415 | |||||||
| 416 | # could move the increment of $number up here, but then we'd count config slides | ||||||
| 417 | # and we don't really want to do that | ||||||
| 418 | # so just use $number + 1 for now, and we'll increment below | ||||||
| 419 | 0 | my ($title, $notes) = $self->extract_notes($raw_slide, $number + 1); | |||||
| 420 | |||||||
| 421 | 0 | 0 | $raw_slide = $self->applyOptions($raw_slide, $config) | ||||
| 422 | or next; | ||||||
| 423 | |||||||
| 424 | 0 | $number++; | |||||
| 425 | |||||||
| 426 | 0 | 0 | 0 | if ($self->config->{skip} or $self->skip) { | |||
| 427 | 0 | 0 | $self->config->{skip}-- if $self->config->{skip}; | ||||
| 428 | 0 | 0 | $self->{skip}-- if $self->{skip}; | ||||
| 429 | 0 | next; | |||||
| 430 | } | ||||||
| 431 | |||||||
| 432 | 0 | 0 | $self->print_notes($title, $number, $notes) if $self->has_notes; | ||||
| 433 | |||||||
| 434 | 0 | $raw_slide = $self->padVertical($raw_slide); | |||||
| 435 | |||||||
| 436 | 0 | my @slides; | |||||
| 437 | my @scripts; | ||||||
| 438 | 0 | my $slide = ''; | |||||
| 439 | 0 | for my $part (split /$TRANSITION/, $raw_slide) { | |||||
| 440 | 0 | 0 | $slide = '' if $config->{replace}; | ||||
| 441 | 0 | my $script = ''; | |||||
| 442 | 0 | 0 | if ($self->config->{script}) { | ||||
| 443 | 0 | ($part, $script) = $self->parseScript($part); | |||||
| 444 | } | ||||||
| 445 | 0 | $slide .= $part; | |||||
| 446 | 0 | 0 | $slide = $self->padVertical($slide) | ||||
| 447 | if $config->{replace}; | ||||||
| 448 | 0 | push @slides, $slide; | |||||
| 449 | 0 | push @scripts, $script; | |||||
| 450 | } | ||||||
| 451 | |||||||
| 452 | 0 | my $base_name = $self->formatNumber($number); | |||||
| 453 | |||||||
| 454 | 0 | my $suffix = 'a'; | |||||
| 455 | 0 | for (my $i = 1; $i <= @slides; $i++) { | |||||
| 456 | 0 | my $slide = $self->padFullScreen($slides[$i - 1]); | |||||
| 457 | 0 | chomp $slide; | |||||
| 458 | 0 | $slide .= "\n"; | |||||
| 459 | 0 | 0 | if ($slide =~ s/^\ *!(.*\n)//m) { | ||||
| 460 | 0 | $slide .= $1; | |||||
| 461 | } | ||||||
| 462 | # this option can't be applied ahead of time | ||||||
| 463 | 0 | 0 | if ($config->{undent}) { | ||||
| 464 | 0 | my $undent = $config->{undent}; | |||||
| 465 | 0 | $slide =~ s/^.{$undent}//gm; | |||||
| 466 | } | ||||||
| 467 | 0 | $slide =~ s{^\ *==\ +(.*?)\ *$} | |||||
| 468 | 0 | {' ' x (($self->config->{width} - length($1)) / 2) . $1}gem; | |||||
| 469 | 0 | my $suf = $suffix++; | |||||
| 470 | 0 | 0 | $suf = $suf eq 'a' | ||||
| 0 | |||||||
| 471 | ? '' | ||||||
| 472 | : $i == @slides | ||||||
| 473 | ? 'z' | ||||||
| 474 | : $suf; | ||||||
| 475 | 0 | my $file_name = "$base_name$suf" . $self->ext; | |||||
| 476 | 0 | io($file_name)->print($slide); | |||||
| 477 | 0 | 0 | if (my $script = shift @scripts) { | ||||
| 478 | 0 | io("bin/$file_name")->assert->print($script); | |||||
| 479 | } | ||||||
| 480 | } | ||||||
| 481 | } | ||||||
| 482 | } | ||||||
| 483 | |||||||
| 484 |  my $NEXT_SLIDE = ' | 
||||||
| 485 | |||||||
| 486 | sub extract_notes { | ||||||
| 487 | 0 | 0 | 0 | my $self = shift; | |||
| 488 | # have to deal with the slide argument in $_[0] directly so we can modify it | ||||||
| 489 | 0 | my $number = $_[1]; | |||||
| 490 | |||||||
| 491 | 0 | 0 | my $title = $_[0] =~ s/$TITLE_MARKER// ? $1 : "Slide $number"; | ||||
| 492 | 0 | 0 | my $notes = $_[0] =~ s/$SLIDE_MARKER(.*)\s*\Z//s ? $1 : ''; | ||||
| 493 | |||||||
| 494 | # verify that the number of transitions in the notes matches the number of transitions in the slide | ||||||
| 495 | # if not, do something about it | ||||||
| 496 | # (note: using a secret operator here; see http://www.catonmat.net/blog/secret-perl-operators/#goatse ) | ||||||
| 497 | 0 | my $num_slide_transitions =()= $_[0] =~ /$TRANSITION/g; | |||||
| 498 | 0 | my $num_notes_transitions =()= $notes =~ /$TRANSITION/g; | |||||
| 499 | 0 | 0 | if ($num_notes_transitions < $num_slide_transitions) | ||||
| 0 | |||||||
| 500 | { | ||||||
| 501 | # add more transitions | ||||||
| 502 | 0 | $notes .= "\n+" x ($num_slide_transitions - $num_notes_transitions); | |||||
| 503 | } | ||||||
| 504 | elsif ($num_notes_transitions > $num_slide_transitions) | ||||||
| 505 | { | ||||||
| 506 | # warn, and then remove transitions | ||||||
| 507 | # we'll reverse the string so we can remove transitions from back to front | ||||||
| 508 | 0 | warn("too many transitions for slide $title"); | |||||
| 509 | 0 | $notes = reverse $notes; | |||||
| 510 | 0 | $notes =~ s/\+\n/\n/ for 1..($num_notes_transitions - $num_slide_transitions); | |||||
| 511 | 0 | $notes = reverse $notes; | |||||
| 512 | } | ||||||
| 513 | |||||||
| 514 | 0 | $notes =~ s/$TRANSITION/$NEXT_SLIDE\n/g; | |||||
| 515 | |||||||
| 516 | 0 | return ($title, $notes); | |||||
| 517 | } | ||||||
| 518 | |||||||
| 519 | sub print_notes { | ||||||
| 520 | 0 | 0 | 0 | my $self = shift; | |||
| 521 | 0 | my ($title, $number, $notes) = @_; | |||||
| 522 | |||||||
| 523 | 0 | 0 | "\n" . ($number == 1 ? ' ' x length($NEXT_SLIDE) : $NEXT_SLIDE) . " -- $title --\n\n$notes\n" >> io($self->notesfile); | ||||
| 524 | } | ||||||
| 525 | |||||||
| 526 | sub parse_notesfile | ||||||
| 527 | { | ||||||
| 528 | 0 | 0 | 0 | my $self = shift; | |||
| 529 | |||||||
| 530 | 0 | 0 | return () unless -r $self->notesfile; | ||||
| 531 | 0 | my $notes = io($self->notesfile)->slurp; | |||||
| 532 | |||||||
| 533 | # first slide doesn't have a marker, so we'll add one, for consistency | ||||||
| 534 | 0 | $notes = $NEXT_SLIDE . $notes; | |||||
| 535 | |||||||
| 536 | 0 | my @notes; | |||||
| 537 | 0 | my @stream = split(/\Q$NEXT_SLIDE\E(?:\s+-- (.*?) --)?\s*/, $notes); | |||||
| 538 | # skipping 0 because, since we're starting with what we're splitting on, the first field will | ||||||
| 539 | # always be empty | ||||||
| 540 | 0 | for (1..$#stream) | |||||
| 541 | { | ||||||
| 542 | 0 | 0 | if ($_ % 2) | ||||
| 543 | { | ||||||
| 544 | 0 | my $title = $stream[$_]; | |||||
| 545 | 0 | 0 | $title = $notes[-1]->{'title'} unless defined $title; | ||||
| 546 | 0 | push @notes, { title => $title }; | |||||
| 547 | } | ||||||
| 548 | else | ||||||
| 549 | { | ||||||
| 550 | 0 | my $text = $stream[$_]; | |||||
| 551 | 0 | $text =~ s/\s+\Z//; | |||||
| 552 | 0 | $notes[-1]->{'text'} = $stream[$_]; | |||||
| 553 | } | ||||||
| 554 | } | ||||||
| 555 | |||||||
| 556 | 0 | return @notes; | |||||
| 557 | } | ||||||
| 558 | |||||||
| 559 | 2 | 2 | 5340 | my %inline_tags; BEGIN { %inline_tags = ( BQ => 'code', IT => 'i', BO => 'b', ); } | |||
| 560 | 0 | 0 | 0 | sub inline_element { my $t = $_[1]; $t =~ s/^.//; $t =~ s/.$//; return "<$inline_tags{$_[0]}>$t$inline_tags{$_[0]}>" } | |||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 561 | sub htmlize_note | ||||||
| 562 | { | ||||||
| 563 | 2 | 2 | 2530 | use Text::Balanced qw< extract_multiple extract_delimited >; | |||
| 2 | 60635 | ||||||
| 2 | 4029 | ||||||
| 564 | |||||||
| 565 | 0 | 0 | 0 | my $self = shift; | |||
| 566 | 0 | my ($note) = @_; | |||||
| 567 | 0 | 0 | $note = '' unless defined $note; | ||||
| 568 | |||||||
| 569 | 0 |      $note =~ s{((^\s*\*\s+.+?\n)+)}{"
  | 
|||||
| 0 | |||||||
| 0 | |||||||
| 0 | |||||||
| 570 | |||||||
| 571 | 0 | my @bits; | |||||
| 572 | 0 | 0 | $note = join('', map { ref $_ ? scalar((push @bits, inline_element(ref $_, $$_)), "{X$#bits}") : $_ } | ||||
| 573 | extract_multiple($note, | ||||||
| 574 | [ | ||||||
| 575 | 0 | 0 | { BQ => sub { extract_delimited($_[0], q{`}, '', q{`}) } }, | ||||
| 576 | 0 | 0 | { IT => sub { extract_delimited($_[0], q{_}, '', q{_}) } }, | ||||
| 577 | 0 | 0 | { BO => sub { extract_delimited($_[0], q{*}, '', q{*}) } }, | ||||
| 578 | 0 | qr/[^`_*]+/, | |||||
| 579 | ]) | ||||||
| 580 | ); | ||||||
| 581 | 0 | $note =~ s{--}{—}g; | |||||
| 582 | 0 | $note =~ s{ \.\.\.}{ ...}g; | |||||
| 583 | 0 |      $note =~ s{\n+}{ }g;  | 
|||||
| 584 | 0 | $note =~ s/{X(\d+)}/$bits[$1]/g; | |||||
| 585 | |||||||
| 586 | 0 | return $note; | |||||
| 587 | } | ||||||
| 588 | |||||||
| 589 | sub parseScript { | ||||||
| 590 | 0 | 0 | 0 | my $self = shift; | |||
| 591 | 0 | my $text = shift; | |||||
| 592 | 0 | chomp $text; | |||||
| 593 | 0 | $text .= "\n"; | |||||
| 594 | 0 | my $script = ''; | |||||
| 595 | 0 | my $delim = $self->config->{script}; | |||||
| 596 | 0 | while ($text =~ s/^[\ \t]*\Q$delim\E(.*\n)//m) { | |||||
| 597 | 0 | $script .= $1; | |||||
| 598 | } | ||||||
| 599 | 0 | return ($text, $script); | |||||
| 600 | } | ||||||
| 601 | |||||||
| 602 | sub formatNumber { | ||||||
| 603 | 0 | 0 | 0 | my $self = shift; | |||
| 604 | 0 | my $number = shift; | |||||
| 605 | 0 | my $digits = $self->digits; | |||||
| 606 | 0 | return sprintf "%0${digits}d", $number; | |||||
| 607 | } | ||||||
| 608 | |||||||
| 609 | my $types = { | ||||||
| 610 | # add pl6 and py3 | ||||||
| 611 | perl => 'pl', pl => 'pl', pm => 'pm', | ||||||
| 612 | ruby => 'rb', rb => 'rb', | ||||||
| 613 | python => 'py', py => 'py', | ||||||
| 614 | haskell => 'hs', hs => 'hs', | ||||||
| 615 | javascript => 'js', js => 'js', | ||||||
| 616 | actionscript => 'as', as => 'as', | ||||||
| 617 | shell => 'sh', sh => 'sh', | ||||||
| 618 | php => 'php', | ||||||
| 619 | java => 'java', | ||||||
| 620 | yaml => 'yaml', | ||||||
| 621 | xml => 'xml', | ||||||
| 622 | json => 'json', | ||||||
| 623 | html => 'html', | ||||||
| 624 | make => 'make', | ||||||
| 625 | diff => 'diff', | ||||||
| 626 | conf => 'conf', | ||||||
| 627 | }; | ||||||
| 628 | sub parseSlideConfig { | ||||||
| 629 | 0 | 0 | 0 | my $self = shift; | |||
| 630 | 0 | my $string = shift; | |||||
| 631 | 0 | my $config = {}; | |||||
| 632 | 0 | my $type_list = join '|', keys %$types; | |||||
| 633 | 0 | for my $option (split /\s*,\s*/, $string) { | |||||
| 634 | 0 | 0 | $config->{$option} = 1 | ||||
| 635 | if $option =~ /^cd/; | ||||||
| 636 | 0 | 0 | $config->{$1} = 1 | ||||
| 637 | if $option =~ /^(config|skip|center|replace|$type_list)$/; | ||||||
| 638 | 0 | 0 | $config->{$1} = 1 | ||||
| 639 | if $option =~ /^(\.\w+)$/; | ||||||
| 640 | 0 | 0 | $config->{indent} = $1 | ||||
| 641 | if $option =~ /i(\d+)/; | ||||||
| 642 | 0 | 0 | $config->{undent} = $1 | ||||
| 643 | if $option =~ /i-(\d+)/; | ||||||
| 644 | } | ||||||
| 645 | 0 | return $config; | |||||
| 646 | } | ||||||
| 647 | |||||||
| 648 | sub applyOptions { | ||||||
| 649 | 0 | 0 | 0 | my $self = shift; | |||
| 650 | 0 | my ($slide, $config) = @_; | |||||
| 651 | |||||||
| 652 | 0 | $config = { | |||||
| 653 | 0 | %{$self->config}, | |||||
| 654 | %$config, | ||||||
| 655 | }; | ||||||
| 656 | |||||||
| 657 | 0 | 0 | if ($config->{config}) { | ||||
| 658 | 0 | $config = { | |||||
| 659 | 0 | %{$self->config}, | |||||
| 660 | 0 | %{(YAML::XS::Load($slide))}, | |||||
| 661 | }; | ||||||
| 662 | |||||||
| 663 | 0 | 0 | if ($config->{auto_size}) { | ||||
| 664 | 0 | my ($columns, $rows) = Term::Size::chars *STDOUT{IO}; | |||||
| 665 | |||||||
| 666 | 0 | $config->{width} = $columns; | |||||
| 667 | 0 | $config->{height} = $rows; | |||||
| 668 | } | ||||||
| 669 | |||||||
| 670 | 0 | $self->config($config); | |||||
| 671 | 0 | return ''; | |||||
| 672 | } | ||||||
| 673 | |||||||
| 674 | 0 | 0 | $slide ||= ''; | ||||
| 675 | 0 | 0 | if ($config->{center}) { | ||||
| 0 | |||||||
| 0 | |||||||
| 676 | 0 | $slide =~ s{^(\+?)\ *(.*?)\ *$} | |||||
| 677 | 0 | {$1 . ' ' x (($self->config->{width} - length($2)) / 2) . $2}gem; | |||||
| 678 | 0 | $slide =~ s{^\s*$}{}gm; | |||||
| 679 | } | ||||||
| 680 | elsif (defined $config->{indent}) { | ||||||
| 681 | 0 | my $indent = $config->{indent}; | |||||
| 682 | 0 | $slide =~ s{^(\+?)}{$1 . ' ' x $indent}gem; | |||||
| 0 | |||||||
| 683 | } | ||||||
| 684 | elsif ($slide =~ /^\+?\*/m) { | ||||||
| 685 | 0 | my $indent = $config->{list_indent}; | |||||
| 686 | 0 | $slide =~ s{^(\+?)}{$1 . ' ' x $indent}gem; | |||||
| 0 | |||||||
| 687 | } | ||||||
| 688 | |||||||
| 689 | 0 | my $ext = ''; | |||||
| 690 | 0 | for my $key (keys %$config) { | |||||
| 691 | 0 | 0 | if (my $e = $types->{$key}) { | ||||
| 0 | |||||||
| 0 | |||||||
| 692 | 0 | $ext = ".$e"; | |||||
| 693 | 0 | last; | |||||
| 694 | } | ||||||
| 695 | elsif ($key =~ s/^cd//) { | ||||||
| 696 | 0 | 0 | if (my $e = $types->{$key}) { | ||||
| 697 | 0 | $ext = ".cd.$e"; | |||||
| 698 | 0 | last; | |||||
| 699 | } | ||||||
| 700 | } | ||||||
| 701 | elsif ($key =~ s/^\.(\w+)//) { | ||||||
| 702 | 0 | $ext = ".$1"; | |||||
| 703 | 0 | last; | |||||
| 704 | } | ||||||
| 705 | } | ||||||
| 706 | 0 | $self->ext($ext); | |||||
| 707 | |||||||
| 708 | 0 | return $slide; | |||||
| 709 | } | ||||||
| 710 | |||||||
| 711 | sub padVertical { | ||||||
| 712 | 0 | 0 | 0 | my $self = shift; | |||
| 713 | 0 | my $slide = shift; | |||||
| 714 | 0 | $slide =~ s/\A\s*\n//; | |||||
| 715 | 0 | $slide =~ s/\n\s*\z//; | |||||
| 716 | 0 | $slide =~ s/ +$//mg; | |||||
| 717 | 0 | my @lines = split /\n/, $slide; | |||||
| 718 | 0 | my $lines = @lines; | |||||
| 719 | 0 | my $before = int(($self->config->{height} - $lines) / 2) - 1; | |||||
| 720 | 0 | return "\n" x $before . $slide; | |||||
| 721 | } | ||||||
| 722 | |||||||
| 723 | sub padFullScreen { | ||||||
| 724 | 0 | 0 | 0 | my $self = shift; | |||
| 725 | 0 | my $slide = shift; | |||||
| 726 | 0 | chomp $slide; | |||||
| 727 | 0 | my @lines = split /\n/, $slide; | |||||
| 728 | 0 | my $lines = @lines; | |||||
| 729 | 0 | my $after = $self->config->{height} - $lines + 1; | |||||
| 730 | 0 | return $slide . "\n" x $after; | |||||
| 731 | } | ||||||
| 732 | |||||||
| 733 | sub writeVimrc { | ||||||
| 734 | 0 | 0 | 0 | my $self = shift; | |||
| 735 | |||||||
| 736 | 0 | my $home_vimrc = File::HomeDir->my_home . "/.vroom/vimrc"; | |||||
| 737 | 0 | 0 | my $home_vimrc_content = -e $home_vimrc ? io($home_vimrc)->all : ''; | ||||
| 738 | |||||||
| 739 | 0 | 0 | my $next_cmd = $self->config->{script} | ||||
| 740 |          ? ':n | 
||||||
| 741 |          : ':n | 
||||||
| 742 | 0 | 0 | my $script_functions = $self->config->{script} ? <<'...' : ''; | ||||
| 743 | function RunIf() | ||||||
| 744 | let script = "bin/" . expand("%") | ||||||
| 745 | let done = "done/" . expand("%") | ||||||
| 746 | if filereadable(done) | ||||||
| 747 | return | ||||||
| 748 | endif | ||||||
| 749 | if filereadable(script) | ||||||
| 750 | call system("sh " . script) | ||||||
| 751 | call system("touch " . done) | ||||||
| 752 | endif | ||||||
| 753 | return | ||||||
| 754 | endfunction | ||||||
| 755 | |||||||
| 756 | function RunNow() | ||||||
| 757 | let done = "done/" . expand("%") | ||||||
| 758 | call system("rm -f " . done) | ||||||
| 759 | call RunIf() | ||||||
| 760 | endfunction | ||||||
| 761 | ... | ||||||
| 762 | |||||||
| 763 | 0 | 0 | 0 | die <<'...' | |||
| 764 | The .vimrc in your current directory does not look like vroom created it. | ||||||
| 765 | |||||||
| 766 | If you are sure it can be overwritten, please delete it yourself this one | ||||||
| 767 | time, and rerun vroom. You should not get this message again. | ||||||
| 768 | |||||||
| 769 | ... | ||||||
| 770 | if -e '.vimrc' and io('.vimrc')->getline !~ /Vroom-\d\.\d\d/; | ||||||
| 771 | |||||||
| 772 | 0 | my $title = "%-20f " . $self->config->{title}; | |||||
| 773 | 0 | $title =~ s/\s/\\ /g; | |||||
| 774 | 2 | 2 | 28 | no strict 'refs'; | |||
| 2 | 5 | ||||||
| 2 | 1414 | ||||||
| 775 | 0 | io(".vimrc")->print(<<"..."); | |||||
| 776 | 0 | " This .vimrc file was created by Vroom-${"VERSION"} | |||||
| 0 | |||||||
| 777 | set nocompatible | ||||||
| 778 | syntax on | ||||||
| 779 | $script_functions | ||||||
| 780 |  map  | 
||||||
| 781 |  map  | 
||||||
| 782 |  map R :!vroom -run % | 
||||||
| 783 |  map RR :!vroom -run % | 
||||||
| 784 |  map AA :call RunNow() | 
||||||
| 785 |  map VV :!vroom -vroom | 
||||||
| 786 |  map QQ :q! | 
||||||
| 787 |  map OO :!open  | 
||||||
| 788 |  map EE :e  | 
||||||
| 789 |  map !! G:!open  | 
||||||
| 790 |  map ?? :e .help | 
||||||
| 791 | set laststatus=2 | ||||||
| 792 | set statusline=$title | ||||||
| 793 | |||||||
| 794 | " Overrides from $home_vimrc | ||||||
| 795 | $home_vimrc_content | ||||||
| 796 | |||||||
| 797 | " Values from slides.vroom config section. (under 'vimrc') | ||||||
| 798 | ${\ $self->config->{vimrc}} | ||||||
| 799 | ... | ||||||
| 800 | |||||||
| 801 | 0 | 0 | if ($self->config->{vim} =~ /\bgvim\b/) { | ||||
| 802 | 0 | my $home_gvimrc = File::HomeDir->my_home . "/.vroom/gvimrc"; | |||||
| 803 | 0 | 0 | my $home_gvimrc_content = -e $home_gvimrc ? io($home_gvimrc)->all : ''; | ||||
| 804 | |||||||
| 805 | 0 | io(".gvimrc")->print(<<"..."); | |||||
| 806 | " Values from slides.vroom config section. (under 'gvimrc') | ||||||
| 807 | 0 | ${\ $self->config->{gvimrc}} | |||||
| 808 | |||||||
| 809 | " Overrides from $home_gvimrc | ||||||
| 810 | $home_gvimrc_content | ||||||
| 811 | ... | ||||||
| 812 | } | ||||||
| 813 | } | ||||||
| 814 | |||||||
| 815 | sub writeScriptRunner { | ||||||
| 816 | 0 | 0 | 0 | my $self = shift; | |||
| 817 | 0 | 0 | return unless $self->config->{script}; | ||||
| 818 | 0 | mkdir 'done'; | |||||
| 819 | } | ||||||
| 820 | |||||||
| 821 | sub writeHelp { | ||||||
| 822 | 0 | 0 | 0 | my $self = shift; | |||
| 823 | 0 | io('.help')->print(<<'...'); | |||||
| 824 | |||||||
| 825 |       | 
||||||
| 826 |       | 
||||||
| 827 | |||||||
| 828 | ?? Help | ||||||
| 829 | QQ Quit Vroom | ||||||
| 830 | |||||||
| 831 | RR Run slide as a program | ||||||
| 832 | VV vroom vroom | ||||||
| 833 | EE Edit file under cursor | ||||||
| 834 | OO Open file under cursor (Mac OS X) | ||||||
| 835 | |||||||
| 836 | |||||||
| 837 | (Press SPACE to leave Help screen and continue) | ||||||
| 838 | |||||||
| 839 | ... | ||||||
| 840 | } | ||||||
| 841 | |||||||
| 842 | sub startUp { | ||||||
| 843 | 0 | 0 | 0 | my $self = shift; | |||
| 844 | 0 | my $vim = $self->config->{vim}; | |||||
| 845 | 0 | 0 | my $vim_opts = $self->config->{vim_opts} || ''; | ||||
| 846 | 0 | exec "$vim $vim_opts '+source .vimrc' 0*"; | |||||
| 847 | } | ||||||
| 848 | |||||||
| 849 | sub sampleSlides { | ||||||
| 850 | 0 | 0 | 0 | my $self = shift; | |||
| 851 | 0 | my $file = $self->input; | |||||
| 852 | 0 | 0 | die <<"..." if -e $file; | ||||
| 853 | '$file' already exists. | ||||||
| 854 | |||||||
| 855 | If you really want to generate a new template slides file, | ||||||
| 856 | please delete or move this one. | ||||||
| 857 | ... | ||||||
| 858 | 0 | io($file)->print(<<'...'); | |||||
| 859 | # This is a sample Vroom input file. It should help you get started. | ||||||
| 860 | # | ||||||
| 861 | # Edit this file with your content. Then run `vroom vroom` to start | ||||||
| 862 | # the show! | ||||||
| 863 | # | ||||||
| 864 | # See `perldoc Vroom` for complete details. | ||||||
| 865 | # | ||||||
| 866 | ---- config | ||||||
| 867 | # Basic config options. | ||||||
| 868 | title: Vroom! | ||||||
| 869 | indent: 5 | ||||||
| 870 | auto_size: 1 | ||||||
| 871 | # height: 18 | ||||||
| 872 | # width: 69 | ||||||
| 873 | vim_opts: '-u NONE' | ||||||
| 874 | skip: 0 | ||||||
| 875 | |||||||
| 876 | # The following options are for Gvim usage. | ||||||
| 877 | # vim: gvim | ||||||
| 878 | # gvimrc: | | ||||||
| 879 | # set fuopt=maxhorz,maxvert | ||||||
| 880 | # set guioptions=egmLtT | ||||||
| 881 | # set guifont=Bitstream_Vera_Sans_Mono:h18 | ||||||
| 882 | # set guicursor=a:blinkon0-ver25-Cursor | ||||||
| 883 | # colorscheme default | ||||||
| 884 | |||||||
| 885 | ---- center | ||||||
| 886 | Vroom! | ||||||
| 887 | |||||||
| 888 | by Ingy döt Net | ||||||
| 889 | |||||||
| 890 | (hint: press the spacebar) | ||||||
| 891 | |||||||
| 892 | ---- | ||||||
| 893 | == Slideshows in Vim | ||||||
| 894 | |||||||
| 895 | * Hate using PowerPoint or HTML Slides for Talks? | ||||||
| 896 | +* Use Vroom! | ||||||
| 897 | |||||||
| 898 | +* You can write you slides in Vim... | ||||||
| 899 | * ...and present them in Vim! | ||||||
| 900 | |||||||
| 901 | ---- | ||||||
| 902 | == Getting Started | ||||||
| 903 | |||||||
| 904 | * Write a file called 'slides.vroom'. | ||||||
| 905 | * Do this in a new directory. | ||||||
| 906 | * Run 'vroom vroom'. | ||||||
| 907 | * Voilà! | ||||||
| 908 | |||||||
| 909 | ---- | ||||||
| 910 | == Navigation | ||||||
| 911 | |||||||
| 912 |  * Hit  | 
||||||
| 913 |  * Hit  | 
||||||
| 914 | * Hit 'Q' to quit. | ||||||
| 915 | |||||||
| 916 | ---- perl,i4 | ||||||
| 917 | # This is some Perl code. | ||||||
| 918 | # Notice the syntax highlighting. | ||||||
| 919 |  # Run it with the  | 
||||||
| 920 | for my $word (qw(Vroom totally rocks!)) { | ||||||
| 921 | print "$word\n"; | ||||||
| 922 | } | ||||||
| 923 | |||||||
| 924 | ---- | ||||||
| 925 | == Get Vroom! | ||||||
| 926 | |||||||
| 927 | * http://search.cpan.org/dist/Vroom/ | ||||||
| 928 | * http://github.com/ingydotnet/vroom-pm/ | ||||||
| 929 | |||||||
| 930 | ---- | ||||||
| 931 | == Vroom as HTML | ||||||
| 932 | |||||||
| 933 | * http://ingydotnet.github.com/vroom-pm/ | ||||||
| 934 | |||||||
| 935 | ---- | ||||||
| 936 | == The End | ||||||
| 937 | ... | ||||||
| 938 | 0 | print "'$file' created.\n"; | |||||
| 939 | } | ||||||
| 940 | |||||||
| 941 | sub makePublisher { | ||||||
| 942 | 0 | 0 | 0 | my $self = shift; | |||
| 943 | 0 | my $input = $self->input; | |||||
| 944 | 0 | 0 | die "Error: This doesn't look like a Vroom directory.\n" | ||||
| 945 | unless -f $input; | ||||||
| 946 | 0 | 0 | die "Error: This doesn't look like a git repository.\n" | ||||
| 947 | unless -d '.git'; | ||||||
| 948 | 0 | 0 | 0 | die "Error: No writeable /tmp directory on this system.\n" | |||
| 949 | unless -d '/tmp' and -w '/tmp'; | ||||||
| 950 | 0 | 0 | die "Error: There is no git branch called 'gh-pages'.\n" . | ||||
| 951 | "Perhaps you should run `git branch gh-pages` first.\n" | ||||||
| 952 | unless `git branch` =~ /\bgh-pages\b/; | ||||||
| 953 | 0 | io('ghpublish')->print(<<'...'); | |||||
| 954 | #!/bin/sh | ||||||
| 955 | |||||||
| 956 | # This script is experimental. Please understand it before you run it on | ||||||
| 957 | # your system. Just because it works for Ingy, doesn't mean it will work | ||||||
| 958 | # for you. | ||||||
| 959 | |||||||
| 960 | if [ -e "/tmp/html" ]; then | ||||||
| 961 | echo "Error: /tmp/html already exists. Perhaps remove it." | ||||||
| 962 | exit 13 | ||||||
| 963 | fi | ||||||
| 964 | |||||||
| 965 | # Create HTML slides. | ||||||
| 966 | vroom html || exit 1 | ||||||
| 967 | # Move the html directory to /tmp | ||||||
| 968 | mv html /tmp || exit 1 | ||||||
| 969 | # Stash any local stuff that isn't committed. | ||||||
| 970 | git stash || exit 1 | ||||||
| 971 | # Switch to your gh-pages branch. (That you already created. Right?) | ||||||
| 972 | git checkout gh-pages || exit 1 | ||||||
| 973 | # Remove all the html files from the gh-pages branch. | ||||||
| 974 | rm -f *.html || exit 1 | ||||||
| 975 | # Move the HTML slides in here. | ||||||
| 976 | mv /tmp/html/* . || exit 1 | ||||||
| 977 | # Remove the html directory from /tmp | ||||||
| 978 | rmdir /tmp/html || exit 1 | ||||||
| 979 | # Add any new files to git. | ||||||
| 980 | git add 0* index.html || exit 1 | ||||||
| 981 | # Commit your changes. | ||||||
| 982 | git commit -am 'Publish my slides' || exit 1 | ||||||
| 983 | # Push them to GitHub. | ||||||
| 984 | git push origin gh-pages || exit 1 | ||||||
| 985 | # Switch back to the master branch. | ||||||
| 986 | git checkout master || exit 1 | ||||||
| 987 | # Get your uncommitted changes back. | ||||||
| 988 | git stash pop || exit 1 | ||||||
| 989 | |||||||
| 990 | # Voilà! (hopefully) | ||||||
| 991 | ... | ||||||
| 992 | |||||||
| 993 | 0 | chmod 0755, 'ghpublish'; | |||||
| 994 | |||||||
| 995 | 0 | print <<'...'; | |||||
| 996 | Created the shell script called 'ghpublish'. | ||||||
| 997 | |||||||
| 998 | This script is somewhat experimental, so please read the code to make sure | ||||||
| 999 | it makes sense on your system. | ||||||
| 1000 | |||||||
| 1001 | If it makes sense to you, run it. (at your own risk :) | ||||||
| 1002 | ... | ||||||
| 1003 | } | ||||||
| 1004 | |||||||
| 1005 | 1; |