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