Spork-0.21/0000755000175000017500000000000011574443054011237 5ustar ingyingySpork-0.21/META.yml0000644000175000017500000000110111574443023012475 0ustar ingyingy--- abstract: 'Slide Presentations (Only Really Kwiki)' author: - 'Ingy döt Net ' build_requires: ExtUtils::MakeMaker: 6.42 configure_requires: ExtUtils::MakeMaker: 6.42 distribution_type: module generated_by: 'Module::Install version 1.01' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 module_name: Spork name: Spork no_index: directory: - inc - t requires: Kwiki: 0.38 Kwiki::Cache: 0.11 Spoon: 0.22 perl: 5.6.1 resources: license: http://dev.perl.org/licenses/ version: 0.21 Spork-0.21/t/0000755000175000017500000000000011574443054011502 5ustar ingyingySpork-0.21/t/new.t0000644000175000017500000000072310224220307012443 0ustar ingyingyuse Cwd qw(abs_path); use lib abs_path('t'), abs_path('lib'); use strict; use warnings; use diagnostics; use Test::More tests => 3; use Spork; use File::Path; my $spork_dir = 't/spork'; File::Path::rmtree($spork_dir); $SIG{__WARN__} = sub { }; ok(mkdir($spork_dir)); chdir($spork_dir) or die; Spork->new->load_hub->command->process('-new'); ok(-f 'Spork.slides'); $ENV{HOME} = undef; Spork->new->load_hub->command->process('-make'); ok(-f 'slides/index.html'); Spork-0.21/t/formatter1.t0000644000175000017500000000247611574440770013766 0ustar ingyingyuse lib 'lib'; use strict; use Test::More 'no_plan'; use Spork; my $hub = Spork->new->debug->load_hub; my @tests = split /^%%%\n/m, join '', ; shift @tests; for my $test (@tests) { my ($wiki, $html) = split /^<><><>\n/m, $test; my $got_html = $hub->formatter->text_to_html($wiki); is($got_html, $html); } __END__ %%% This is {{not *bold* and {image: foo} }} <><><>

This is not *bold* and {image: foo}

%%% = Level One Header === Level Three Header ===== Level Five Header ======= Level Seven Header <><><>

Level One Header

Level Three Header

Level Five Header
======= Level Seven Header %%% == Simple Header <><><>

Simple Header

%%% == Another Simple Header <><><>

Another Simple Header

%%% This is *bold* <><><>

This is bold

%%% == A *Header* <><><>

A Header

%%% More *bold* <><><>

More bold

%%% Use *==* for h2s. <><><>

Use == for h2s.

%%% This is *bold stuff* man <><><>

This is bold stuff man

%%% Paragraph one. <><><>

Paragraph one.

%%% Paragraph one. Paragraph two. <><><>

Paragraph one.

Paragraph two.

%%% This is *bold* This is not <><><>

This is bold

This is not

Spork-0.21/inc/0000755000175000017500000000000011574443054012010 5ustar ingyingySpork-0.21/inc/Module/0000755000175000017500000000000011574443054013235 5ustar ingyingySpork-0.21/inc/Module/Install.pm0000644000175000017500000003013511574443023015177 0ustar ingyingy#line 1 package Module::Install; # For any maintainers: # The load order for Module::Install is a bit magic. # It goes something like this... # # IF ( host has Module::Install installed, creating author mode ) { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install # 3. The installed version of inc::Module::Install loads # 4. inc::Module::Install calls "require Module::Install" # 5. The ./inc/ version of Module::Install loads # } ELSE { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install # 3. The ./inc/ version of Module::Install loads # } use 5.005; use strict 'vars'; use Cwd (); use File::Find (); use File::Path (); use vars qw{$VERSION $MAIN}; BEGIN { # All Module::Install core packages now require synchronised versions. # This will be used to ensure we don't accidentally load old or # different versions of modules. # This is not enforced yet, but will be some time in the next few # releases once we can make sure it won't clash with custom # Module::Install extensions. $VERSION = '1.01'; # Storage for the pseudo-singleton $MAIN = undef; *inc::Module::Install::VERSION = *VERSION; @inc::Module::Install::ISA = __PACKAGE__; } sub import { my $class = shift; my $self = $class->new(@_); my $who = $self->_caller; #------------------------------------------------------------- # all of the following checks should be included in import(), # to allow "eval 'require Module::Install; 1' to test # installation of Module::Install. (RT #51267) #------------------------------------------------------------- # Whether or not inc::Module::Install is actually loaded, the # $INC{inc/Module/Install.pm} is what will still get set as long as # the caller loaded module this in the documented manner. # If not set, the caller may NOT have loaded the bundled version, and thus # they may not have a MI version that works with the Makefile.PL. This would # result in false errors or unexpected behaviour. And we don't want that. my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; unless ( $INC{$file} ) { die <<"END_DIE" } Please invoke ${\__PACKAGE__} with: use inc::${\__PACKAGE__}; not: use ${\__PACKAGE__}; END_DIE # This reportedly fixes a rare Win32 UTC file time issue, but # as this is a non-cross-platform XS module not in the core, # we shouldn't really depend on it. See RT #24194 for detail. # (Also, this module only supports Perl 5.6 and above). eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; # If the script that is loading Module::Install is from the future, # then make will detect this and cause it to re-run over and over # again. This is bad. Rather than taking action to touch it (which # is unreliable on some platforms and requires write permissions) # for now we should catch this and refuse to run. if ( -f $0 ) { my $s = (stat($0))[9]; # If the modification time is only slightly in the future, # sleep briefly to remove the problem. my $a = $s - time; if ( $a > 0 and $a < 5 ) { sleep 5 } # Too far in the future, throw an error. my $t = time; if ( $s > $t ) { die <<"END_DIE" } Your installer $0 has a modification time in the future ($s > $t). This is known to create infinite loops in make. Please correct this, then run $0 again. END_DIE } # Build.PL was formerly supported, but no longer is due to excessive # difficulty in implementing every single feature twice. if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } Module::Install no longer supports Build.PL. It was impossible to maintain duel backends, and has been deprecated. Please remove all Build.PL files and only use the Makefile.PL installer. END_DIE #------------------------------------------------------------- # To save some more typing in Module::Install installers, every... # use inc::Module::Install # ...also acts as an implicit use strict. $^H |= strict::bits(qw(refs subs vars)); #------------------------------------------------------------- unless ( -f $self->{file} ) { foreach my $key (keys %INC) { delete $INC{$key} if $key =~ /Module\/Install/; } local $^W; require "$self->{path}/$self->{dispatch}.pm"; File::Path::mkpath("$self->{prefix}/$self->{author}"); $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); $self->{admin}->init; @_ = ($class, _self => $self); goto &{"$self->{name}::import"}; } local $^W; *{"${who}::AUTOLOAD"} = $self->autoload; $self->preload; # Unregister loader and worker packages so subdirs can use them again delete $INC{'inc/Module/Install.pm'}; delete $INC{'Module/Install.pm'}; # Save to the singleton $MAIN = $self; return 1; } sub autoload { my $self = shift; my $who = $self->_caller; my $cwd = Cwd::cwd(); my $sym = "${who}::AUTOLOAD"; $sym->{$cwd} = sub { my $pwd = Cwd::cwd(); if ( my $code = $sym->{$pwd} ) { # Delegate back to parent dirs goto &$code unless $cwd eq $pwd; } unless ($$sym =~ s/([^:]+)$//) { # XXX: it looks like we can't retrieve the missing function # via $$sym (usually $main::AUTOLOAD) in this case. # I'm still wondering if we should slurp Makefile.PL to # get some context or not ... my ($package, $file, $line) = caller; die <<"EOT"; Unknown function is found at $file line $line. Execution of $file aborted due to runtime errors. If you're a contributor to a project, you may need to install some Module::Install extensions from CPAN (or other repository). If you're a user of a module, please contact the author. EOT } my $method = $1; if ( uc($method) eq $method ) { # Do nothing return; } elsif ( $method =~ /^_/ and $self->can($method) ) { # Dispatch to the root M:I class return $self->$method(@_); } # Dispatch to the appropriate plugin unshift @_, ( $self, $1 ); goto &{$self->can('call')}; }; } sub preload { my $self = shift; unless ( $self->{extensions} ) { $self->load_extensions( "$self->{prefix}/$self->{path}", $self ); } my @exts = @{$self->{extensions}}; unless ( @exts ) { @exts = $self->{admin}->load_all_extensions; } my %seen; foreach my $obj ( @exts ) { while (my ($method, $glob) = each %{ref($obj) . '::'}) { next unless $obj->can($method); next if $method =~ /^_/; next if $method eq uc($method); $seen{$method}++; } } my $who = $self->_caller; foreach my $name ( sort keys %seen ) { local $^W; *{"${who}::$name"} = sub { ${"${who}::AUTOLOAD"} = "${who}::$name"; goto &{"${who}::AUTOLOAD"}; }; } } sub new { my ($class, %args) = @_; delete $INC{'FindBin.pm'}; { # to suppress the redefine warning local $SIG{__WARN__} = sub {}; require FindBin; } # ignore the prefix on extension modules built from top level. my $base_path = Cwd::abs_path($FindBin::Bin); unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) { delete $args{prefix}; } return $args{_self} if $args{_self}; $args{dispatch} ||= 'Admin'; $args{prefix} ||= 'inc'; $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); $args{bundle} ||= 'inc/BUNDLES'; $args{base} ||= $base_path; $class =~ s/^\Q$args{prefix}\E:://; $args{name} ||= $class; $args{version} ||= $class->VERSION; unless ( $args{path} ) { $args{path} = $args{name}; $args{path} =~ s!::!/!g; } $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; $args{wrote} = 0; bless( \%args, $class ); } sub call { my ($self, $method) = @_; my $obj = $self->load($method) or return; splice(@_, 0, 2, $obj); goto &{$obj->can($method)}; } sub load { my ($self, $method) = @_; $self->load_extensions( "$self->{prefix}/$self->{path}", $self ) unless $self->{extensions}; foreach my $obj (@{$self->{extensions}}) { return $obj if $obj->can($method); } my $admin = $self->{admin} or die <<"END_DIE"; The '$method' method does not exist in the '$self->{prefix}' path! Please remove the '$self->{prefix}' directory and run $0 again to load it. END_DIE my $obj = $admin->load($method, 1); push @{$self->{extensions}}, $obj; $obj; } sub load_extensions { my ($self, $path, $top) = @_; my $should_reload = 0; unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { unshift @INC, $self->{prefix}; $should_reload = 1; } foreach my $rv ( $self->find_extensions($path) ) { my ($file, $pkg) = @{$rv}; next if $self->{pathnames}{$pkg}; local $@; my $new = eval { local $^W; require $file; $pkg->can('new') }; unless ( $new ) { warn $@ if $@; next; } $self->{pathnames}{$pkg} = $should_reload ? delete $INC{$file} : $INC{$file}; push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); } $self->{extensions} ||= []; } sub find_extensions { my ($self, $path) = @_; my @found; File::Find::find( sub { my $file = $File::Find::name; return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; my $subpath = $1; return if lc($subpath) eq lc($self->{dispatch}); $file = "$self->{path}/$subpath.pm"; my $pkg = "$self->{name}::$subpath"; $pkg =~ s!/!::!g; # If we have a mixed-case package name, assume case has been preserved # correctly. Otherwise, root through the file to locate the case-preserved # version of the package name. if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { my $content = Module::Install::_read($subpath . '.pm'); my $in_pod = 0; foreach ( split //, $content ) { $in_pod = 1 if /^=\w/; $in_pod = 0 if /^=cut/; next if ($in_pod || /^=cut/); # skip pod text next if /^\s*#/; # and comments if ( m/^\s*package\s+($pkg)\s*;/i ) { $pkg = $1; last; } } } push @found, [ $file, $pkg ]; }, $path ) if -d $path; @found; } ##################################################################### # Common Utility Functions sub _caller { my $depth = 0; my $call = caller($depth); while ( $call eq __PACKAGE__ ) { $depth++; $call = caller($depth); } return $call; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _read { local *FH; open( FH, '<', $_[0] ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_NEW sub _read { local *FH; open( FH, "< $_[0]" ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_OLD sub _readperl { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; return $string; } sub _readpod { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; return $string if $_[0] =~ /\.pod\z/; $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; $string =~ s/^\n+//s; return $string; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _write { local *FH; open( FH, '>', $_[0] ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_NEW sub _write { local *FH; open( FH, "> $_[0]" ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_OLD # _version is for processing module versions (eg, 1.03_05) not # Perl versions (eg, 5.8.1). sub _version ($) { my $s = shift || 0; my $d =()= $s =~ /(\.)/g; if ( $d >= 2 ) { # Normalise multipart versions $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; } $s =~ s/^(\d+)\.?//; my $l = $1 || 0; my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g; $l = $l . '.' . join '', @v if @v; return $l + 0; } sub _cmp ($$) { _version($_[0]) <=> _version($_[1]); } # Cloned from Params::Util::_CLASS sub _CLASS ($) { ( defined $_[0] and ! ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s ) ? $_[0] : undef; } 1; # Copyright 2008 - 2011 Adam Kennedy. Spork-0.21/inc/Module/Install/0000755000175000017500000000000011574443054014643 5ustar ingyingySpork-0.21/inc/Module/Install/Fetch.pm0000644000175000017500000000462711574443023016237 0ustar ingyingy#line 1 package Module::Install::Fetch; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub get_file { my ($self, %args) = @_; my ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { $args{url} = $args{ftp_url} or (warn("LWP support unavailable!\n"), return); ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; } $|++; print "Fetching '$file' from $host... "; unless (eval { require Socket; Socket::inet_aton($host) }) { warn "'$host' resolve failed!\n"; return; } return unless $scheme eq 'ftp' or $scheme eq 'http'; require Cwd; my $dir = Cwd::getcwd(); chdir $args{local_dir} or return if exists $args{local_dir}; if (eval { require LWP::Simple; 1 }) { LWP::Simple::mirror($args{url}, $file); } elsif (eval { require Net::FTP; 1 }) { eval { # use Net::FTP to get past firewall my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); $ftp->login("anonymous", 'anonymous@example.com'); $ftp->cwd($path); $ftp->binary; $ftp->get($file) or (warn("$!\n"), return); $ftp->quit; } } elsif (my $ftp = $self->can_run('ftp')) { eval { # no Net::FTP, fallback to ftp.exe require FileHandle; my $fh = FileHandle->new; local $SIG{CHLD} = 'IGNORE'; unless ($fh->open("|$ftp -n")) { warn "Couldn't open ftp: $!\n"; chdir $dir; return; } my @dialog = split(/\n/, <<"END_FTP"); open $host user anonymous anonymous\@example.com cd $path binary get $file $file quit END_FTP foreach (@dialog) { $fh->print("$_\n") } $fh->close; } } else { warn "No working 'ftp' program available!\n"; chdir $dir; return; } unless (-f $file) { warn "Fetching failed: $@\n"; chdir $dir; return; } return if exists $args{size} and -s $file != $args{size}; system($args{run}) if exists $args{run}; unlink($file) if $args{remove}; print(((!exists $args{check_for} or -e $args{check_for}) ? "done!" : "failed! ($!)"), "\n"); chdir $dir; return !$?; } 1; Spork-0.21/inc/Module/Install/Win32.pm0000644000175000017500000000340311574443023016077 0ustar ingyingy#line 1 package Module::Install::Win32; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # determine if the user needs nmake, and download it if needed sub check_nmake { my $self = shift; $self->load('can_run'); $self->load('get_file'); require Config; return unless ( $^O eq 'MSWin32' and $Config::Config{make} and $Config::Config{make} =~ /^nmake\b/i and ! $self->can_run('nmake') ); print "The required 'nmake' executable not found, fetching it...\n"; require File::Basename; my $rv = $self->get_file( url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', local_dir => File::Basename::dirname($^X), size => 51928, run => 'Nmake15.exe /o > nul', check_for => 'Nmake.exe', remove => 1, ); die <<'END_MESSAGE' unless $rv; ------------------------------------------------------------------------------- Since you are using Microsoft Windows, you will need the 'nmake' utility before installation. It's available at: http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe or ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe Please download the file manually, save it to a directory in %PATH% (e.g. C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to that directory, and run "Nmake15.exe" from there; that will create the 'nmake.exe' file needed by this module. You may then resume the installation process described in README. ------------------------------------------------------------------------------- END_MESSAGE } 1; Spork-0.21/inc/Module/Install/ReadmeFromPod.pm0000644000175000017500000000162411574443023017664 0ustar ingyingy#line 1 package Module::Install::ReadmeFromPod; use 5.006; use strict; use warnings; use base qw(Module::Install::Base); use vars qw($VERSION); $VERSION = '0.12'; sub readme_from { my $self = shift; return unless $self->is_admin; my $file = shift || $self->_all_from or die "Can't determine file to make readme_from"; my $clean = shift; print "Writing README from $file\n"; require Pod::Text; my $parser = Pod::Text->new(); open README, '> README' or die "$!\n"; $parser->output_fh( *README ); $parser->parse_file( $file ); if ($clean) { $self->clean_files('README'); } return 1; } sub _all_from { my $self = shift; return unless $self->admin->{extensions}; my ($metadata) = grep { ref($_) eq 'Module::Install::Metadata'; } @{$self->admin->{extensions}}; return unless $metadata; return $metadata->{values}{all_from} || ''; } 'Readme!'; __END__ #line 112 Spork-0.21/inc/Module/Install/WriteAll.pm0000644000175000017500000000237611574443023016730 0ustar ingyingy#line 1 package Module::Install::WriteAll; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = qw{Module::Install::Base}; $ISCORE = 1; } sub WriteAll { my $self = shift; my %args = ( meta => 1, sign => 0, inline => 0, check_nmake => 1, @_, ); $self->sign(1) if $args{sign}; $self->admin->WriteAll(%args) if $self->is_admin; $self->check_nmake if $args{check_nmake}; unless ( $self->makemaker_args->{PL_FILES} ) { # XXX: This still may be a bit over-defensive... unless ($self->makemaker(6.25)) { $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; } } # Until ExtUtils::MakeMaker support MYMETA.yml, make sure # we clean it up properly ourself. $self->realclean_files('MYMETA.yml'); if ( $args{inline} ) { $self->Inline->write; } else { $self->Makefile->write; } # The Makefile write process adds a couple of dependencies, # so write the META.yml files after the Makefile. if ( $args{meta} ) { $self->Meta->write; } # Experimental support for MYMETA if ( $ENV{X_MYMETA} ) { if ( $ENV{X_MYMETA} eq 'JSON' ) { $self->Meta->write_mymeta_json; } else { $self->Meta->write_mymeta_yaml; } } return 1; } 1; Spork-0.21/inc/Module/Install/Can.pm0000644000175000017500000000333311574443023015700 0ustar ingyingy#line 1 package Module::Install::Can; use strict; use Config (); use File::Spec (); use ExtUtils::MakeMaker (); use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # check if we can load some module ### Upgrade this to not have to load the module if possible sub can_use { my ($self, $mod, $ver) = @_; $mod =~ s{::|\\}{/}g; $mod .= '.pm' unless $mod =~ /\.pm$/i; my $pkg = $mod; $pkg =~ s{/}{::}g; $pkg =~ s{\.pm$}{}i; local $@; eval { require $mod; $pkg->VERSION($ver || 0); 1 }; } # check if we can run some command sub can_run { my ($self, $cmd) = @_; my $_cmd = $cmd; return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { next if $dir eq ''; my $abs = File::Spec->catfile($dir, $_[1]); return $abs if (-x $abs or $abs = MM->maybe_command($abs)); } return; } # can we locate a (the) C compiler sub can_cc { my $self = shift; my @chunks = split(/ /, $Config::Config{cc}) or return; # $Config{cc} may contain args; try to find out the program part while (@chunks) { return $self->can_run("@chunks") || (pop(@chunks), next); } return; } # Fix Cygwin bug on maybe_command(); if ( $^O eq 'cygwin' ) { require ExtUtils::MM_Cygwin; require ExtUtils::MM_Win32; if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { *ExtUtils::MM_Cygwin::maybe_command = sub { my ($self, $file) = @_; if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { ExtUtils::MM_Win32->maybe_command($file); } else { ExtUtils::MM_Unix->maybe_command($file); } } } } 1; __END__ #line 156 Spork-0.21/inc/Module/Install/VersionCheck.pm0000644000175000017500000000334111574443023017561 0ustar ingyingy#line 1 ## # name: Module::Install::VersionCheck # abstract: Show Author the Current Versions # author: Ingy döt Net # license: perl # copyright: 2010, 2011 package Module::Install::VersionCheck; use 5.008003; use strict; use warnings; use Module::Install::Base; use base 'Module::Install::Base'; our $VERSION = '0.14'; our $AUTHOR_ONLY = 1; my $DEFAULT = '0.00'; sub version_check { my $self = shift; return unless $self->is_admin; my $module_version = $self->_get_module_version(); my $changes_version = $self->_get_changes_version(); my $git_tag_version = $self->_get_git_tag_version(); $self->_report( $module_version, $changes_version, $git_tag_version, ); } sub _get_module_version { my $self = shift; return $DEFAULT unless $self->admin->{extensions}; my ($metadata) = grep { ref($_) eq 'Module::Install::Metadata'; } @{$self->admin->{extensions}}; return $DEFAULT unless $metadata; return $metadata->{values}{version} || $DEFAULT; } sub _get_changes_version { my $self = shift; return $DEFAULT unless -e 'Changes'; open IN, 'Changes' or die "Can't open 'Changes' for input: $!"; my $text = do {local $/; }; $text =~ /\b(\d\.\d\d)\b/ or return $DEFAULT; return $1; } sub _get_git_tag_version { my $self = shift; return $DEFAULT unless -e '.git'; require Capture::Tiny; my $text = Capture::Tiny::capture_merged(sub { system('git tag') }); my $version = $DEFAULT; for (split "\n", $text) { if (/\b(\d\.\d\d)\b/ and $1 > $version) { $version = $1; } } return $version; } sub _report { my $self = shift; print "version_check @_\n"; } 1; Spork-0.21/inc/Module/Install/Metadata.pm0000644000175000017500000004312311574443023016720 0ustar ingyingy#line 1 package Module::Install::Metadata; use strict 'vars'; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } my @boolean_keys = qw{ sign }; my @scalar_keys = qw{ name module_name abstract version distribution_type tests installdirs }; my @tuple_keys = qw{ configure_requires build_requires requires recommends bundles resources }; my @resource_keys = qw{ homepage bugtracker repository }; my @array_keys = qw{ keywords author }; *authors = \&author; sub Meta { shift } sub Meta_BooleanKeys { @boolean_keys } sub Meta_ScalarKeys { @scalar_keys } sub Meta_TupleKeys { @tuple_keys } sub Meta_ResourceKeys { @resource_keys } sub Meta_ArrayKeys { @array_keys } foreach my $key ( @boolean_keys ) { *$key = sub { my $self = shift; if ( defined wantarray and not @_ ) { return $self->{values}->{$key}; } $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); return $self; }; } foreach my $key ( @scalar_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} = shift; return $self; }; } foreach my $key ( @array_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} ||= []; push @{$self->{values}->{$key}}, @_; return $self; }; } foreach my $key ( @resource_keys ) { *$key = sub { my $self = shift; unless ( @_ ) { return () unless $self->{values}->{resources}; return map { $_->[1] } grep { $_->[0] eq $key } @{ $self->{values}->{resources} }; } return $self->{values}->{resources}->{$key} unless @_; my $uri = shift or die( "Did not provide a value to $key()" ); $self->resources( $key => $uri ); return 1; }; } foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { *$key = sub { my $self = shift; return $self->{values}->{$key} unless @_; my @added; while ( @_ ) { my $module = shift or last; my $version = shift || 0; push @added, [ $module, $version ]; } push @{ $self->{values}->{$key} }, @added; return map {@$_} @added; }; } # Resource handling my %lc_resource = map { $_ => 1 } qw{ homepage license bugtracker repository }; sub resources { my $self = shift; while ( @_ ) { my $name = shift or last; my $value = shift or next; if ( $name eq lc $name and ! $lc_resource{$name} ) { die("Unsupported reserved lowercase resource '$name'"); } $self->{values}->{resources} ||= []; push @{ $self->{values}->{resources} }, [ $name, $value ]; } $self->{values}->{resources}; } # Aliases for build_requires that will have alternative # meanings in some future version of META.yml. sub test_requires { shift->build_requires(@_) } sub install_requires { shift->build_requires(@_) } # Aliases for installdirs options sub install_as_core { $_[0]->installdirs('perl') } sub install_as_cpan { $_[0]->installdirs('site') } sub install_as_site { $_[0]->installdirs('site') } sub install_as_vendor { $_[0]->installdirs('vendor') } sub dynamic_config { my $self = shift; unless ( @_ ) { warn "You MUST provide an explicit true/false value to dynamic_config\n"; return $self; } $self->{values}->{dynamic_config} = $_[0] ? 1 : 0; return 1; } sub perl_version { my $self = shift; return $self->{values}->{perl_version} unless @_; my $version = shift or die( "Did not provide a value to perl_version()" ); # Normalize the version $version = $self->_perl_version($version); # We don't support the reall old versions unless ( $version >= 5.005 ) { die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; } $self->{values}->{perl_version} = $version; } sub all_from { my ( $self, $file ) = @_; unless ( defined($file) ) { my $name = $self->name or die( "all_from called with no args without setting name() first" ); $file = join('/', 'lib', split(/-/, $name)) . '.pm'; $file =~ s{.*/}{} unless -e $file; unless ( -e $file ) { die("all_from cannot find $file from $name"); } } unless ( -f $file ) { die("The path '$file' does not exist, or is not a file"); } $self->{values}{all_from} = $file; # Some methods pull from POD instead of code. # If there is a matching .pod, use that instead my $pod = $file; $pod =~ s/\.pm$/.pod/i; $pod = $file unless -e $pod; # Pull the different values $self->name_from($file) unless $self->name; $self->version_from($file) unless $self->version; $self->perl_version_from($file) unless $self->perl_version; $self->author_from($pod) unless @{$self->author || []}; $self->license_from($pod) unless $self->license; $self->abstract_from($pod) unless $self->abstract; return 1; } sub provides { my $self = shift; my $provides = ( $self->{values}->{provides} ||= {} ); %$provides = (%$provides, @_) if @_; return $provides; } sub auto_provides { my $self = shift; return $self unless $self->is_admin; unless (-e 'MANIFEST') { warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; return $self; } # Avoid spurious warnings as we are not checking manifest here. local $SIG{__WARN__} = sub {1}; require ExtUtils::Manifest; local *ExtUtils::Manifest::manicheck = sub { return }; require Module::Build; my $build = Module::Build->new( dist_name => $self->name, dist_version => $self->version, license => $self->license, ); $self->provides( %{ $build->find_dist_packages || {} } ); } sub feature { my $self = shift; my $name = shift; my $features = ( $self->{values}->{features} ||= [] ); my $mods; if ( @_ == 1 and ref( $_[0] ) ) { # The user used ->feature like ->features by passing in the second # argument as a reference. Accomodate for that. $mods = $_[0]; } else { $mods = \@_; } my $count = 0; push @$features, ( $name => [ map { ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ } @$mods ] ); return @$features; } sub features { my $self = shift; while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { $self->feature( $name, @$mods ); } return $self->{values}->{features} ? @{ $self->{values}->{features} } : (); } sub no_index { my $self = shift; my $type = shift; push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; return $self->{values}->{no_index}; } sub read { my $self = shift; $self->include_deps( 'YAML::Tiny', 0 ); require YAML::Tiny; my $data = YAML::Tiny::LoadFile('META.yml'); # Call methods explicitly in case user has already set some values. while ( my ( $key, $value ) = each %$data ) { next unless $self->can($key); if ( ref $value eq 'HASH' ) { while ( my ( $module, $version ) = each %$value ) { $self->can($key)->($self, $module => $version ); } } else { $self->can($key)->($self, $value); } } return $self; } sub write { my $self = shift; return $self unless $self->is_admin; $self->admin->write_meta; return $self; } sub version_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->version( ExtUtils::MM_Unix->parse_version($file) ); # for version integrity check $self->makemaker_args( VERSION_FROM => $file ); } sub abstract_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->abstract( bless( { DISTNAME => $self->name }, 'ExtUtils::MM_Unix' )->parse_abstract($file) ); } # Add both distribution and module name sub name_from { my ($self, $file) = @_; if ( Module::Install::_read($file) =~ m/ ^ \s* package \s* ([\w:]+) \s* ; /ixms ) { my ($name, $module_name) = ($1, $1); $name =~ s{::}{-}g; $self->name($name); unless ( $self->module_name ) { $self->module_name($module_name); } } else { die("Cannot determine name from $file\n"); } } sub _extract_perl_version { if ( $_[0] =~ m/ ^\s* (?:use|require) \s* v? ([\d_\.]+) \s* ; /ixms ) { my $perl_version = $1; $perl_version =~ s{_}{}g; return $perl_version; } else { return; } } sub perl_version_from { my $self = shift; my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); if ($perl_version) { $self->perl_version($perl_version); } else { warn "Cannot determine perl version info from $_[0]\n"; return; } } sub author_from { my $self = shift; my $content = Module::Install::_read($_[0]); if ($content =~ m/ =head \d \s+ (?:authors?)\b \s* ([^\n]*) | =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* ([^\n]*) /ixms) { my $author = $1 || $2; # XXX: ugly but should work anyway... if (eval "require Pod::Escapes; 1") { # Pod::Escapes has a mapping table. # It's in core of perl >= 5.9.3, and should be installed # as one of the Pod::Simple's prereqs, which is a prereq # of Pod::Text 3.x (see also below). $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $Pod::Escapes::Name2character_number{$1} ? chr($Pod::Escapes::Name2character_number{$1}) : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { # Pod::Text < 3.0 has yet another mapping table, # though the table name of 2.x and 1.x are different. # (1.x is in core of Perl < 5.6, 2.x is in core of # Perl < 5.9.3) my $mapping = ($Pod::Text::VERSION < 2) ? \%Pod::Text::HTML_Escapes : \%Pod::Text::ESCAPES; $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $mapping->{$1} ? $mapping->{$1} : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } else { $author =~ s{E}{<}g; $author =~ s{E}{>}g; } $self->author($author); } else { warn "Cannot determine author info from $_[0]\n"; } } #Stolen from M::B my %license_urls = ( perl => 'http://dev.perl.org/licenses/', apache => 'http://apache.org/licenses/LICENSE-2.0', apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1', artistic => 'http://opensource.org/licenses/artistic-license.php', artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', lgpl => 'http://opensource.org/licenses/lgpl-license.php', lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', bsd => 'http://opensource.org/licenses/bsd-license.php', gpl => 'http://opensource.org/licenses/gpl-license.php', gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', mit => 'http://opensource.org/licenses/mit-license.php', mozilla => 'http://opensource.org/licenses/mozilla1.1.php', open_source => undef, unrestricted => undef, restrictive => undef, unknown => undef, ); sub license { my $self = shift; return $self->{values}->{license} unless @_; my $license = shift or die( 'Did not provide a value to license()' ); $license = __extract_license($license) || lc $license; $self->{values}->{license} = $license; # Automatically fill in license URLs if ( $license_urls{$license} ) { $self->resources( license => $license_urls{$license} ); } return 1; } sub _extract_license { my $pod = shift; my $matched; return __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?) (=head \d.*|=cut.*|)\z /xms ) || __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?) (=head \d.*|=cut.*|)\z /xms ); } sub __extract_license { my $license_text = shift or return; my @phrases = ( '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1, '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1, 'Artistic and GPL' => 'perl', 1, 'GNU general public license' => 'gpl', 1, 'GNU public license' => 'gpl', 1, 'GNU lesser general public license' => 'lgpl', 1, 'GNU lesser public license' => 'lgpl', 1, 'GNU library general public license' => 'lgpl', 1, 'GNU library public license' => 'lgpl', 1, 'GNU Free Documentation license' => 'unrestricted', 1, 'GNU Affero General Public License' => 'open_source', 1, '(?:Free)?BSD license' => 'bsd', 1, 'Artistic license 2\.0' => 'artistic_2', 1, 'Artistic license' => 'artistic', 1, 'Apache (?:Software )?license' => 'apache', 1, 'GPL' => 'gpl', 1, 'LGPL' => 'lgpl', 1, 'BSD' => 'bsd', 1, 'Artistic' => 'artistic', 1, 'MIT' => 'mit', 1, 'Mozilla Public License' => 'mozilla', 1, 'Q Public License' => 'open_source', 1, 'OpenSSL License' => 'unrestricted', 1, 'SSLeay License' => 'unrestricted', 1, 'zlib License' => 'open_source', 1, 'proprietary' => 'proprietary', 0, ); while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { $pattern =~ s#\s+#\\s+#gs; if ( $license_text =~ /\b$pattern\b/i ) { return $license; } } return ''; } sub license_from { my $self = shift; if (my $license=_extract_license(Module::Install::_read($_[0]))) { $self->license($license); } else { warn "Cannot determine license info from $_[0]\n"; return 'unknown'; } } sub _extract_bugtracker { my @links = $_[0] =~ m#L<( https?\Q://rt.cpan.org/\E[^>]+| https?\Q://github.com/\E[\w_]+/[\w_]+/issues| https?\Q://code.google.com/p/\E[\w_\-]+/issues/list )>#gx; my %links; @links{@links}=(); @links=keys %links; return @links; } sub bugtracker_from { my $self = shift; my $content = Module::Install::_read($_[0]); my @links = _extract_bugtracker($content); unless ( @links ) { warn "Cannot determine bugtracker info from $_[0]\n"; return 0; } if ( @links > 1 ) { warn "Found more than one bugtracker link in $_[0]\n"; return 0; } # Set the bugtracker bugtracker( $links[0] ); return 1; } sub requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->requires( $module => $version ); } } sub test_requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->test_requires( $module => $version ); } } # Convert triple-part versions (eg, 5.6.1 or 5.8.9) to # numbers (eg, 5.006001 or 5.008009). # Also, convert double-part versions (eg, 5.8) sub _perl_version { my $v = $_[-1]; $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; $v =~ s/(\.\d\d\d)000$/$1/; $v =~ s/_.+$//; if ( ref($v) ) { # Numify $v = $v + 0; } return $v; } sub add_metadata { my $self = shift; my %hash = @_; for my $key (keys %hash) { warn "add_metadata: $key is not prefixed with 'x_'.\n" . "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/; $self->{values}->{$key} = $hash{$key}; } } ###################################################################### # MYMETA Support sub WriteMyMeta { die "WriteMyMeta has been deprecated"; } sub write_mymeta_yaml { my $self = shift; # We need YAML::Tiny to write the MYMETA.yml file unless ( eval { require YAML::Tiny; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.yml\n"; YAML::Tiny::DumpFile('MYMETA.yml', $meta); } sub write_mymeta_json { my $self = shift; # We need JSON to write the MYMETA.json file unless ( eval { require JSON; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.json\n"; Module::Install::_write( 'MYMETA.json', JSON->new->pretty(1)->canonical->encode($meta), ); } sub _write_mymeta_data { my $self = shift; # If there's no existing META.yml there is nothing we can do return undef unless -f 'META.yml'; # We need Parse::CPAN::Meta to load the file unless ( eval { require Parse::CPAN::Meta; 1; } ) { return undef; } # Merge the perl version into the dependencies my $val = $self->Meta->{values}; my $perl = delete $val->{perl_version}; if ( $perl ) { $val->{requires} ||= []; my $requires = $val->{requires}; # Canonize to three-dot version after Perl 5.6 if ( $perl >= 5.006 ) { $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e } unshift @$requires, [ perl => $perl ]; } # Load the advisory META.yml file my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); my $meta = $yaml[0]; # Overwrite the non-configure dependency hashs delete $meta->{requires}; delete $meta->{build_requires}; delete $meta->{recommends}; if ( exists $val->{requires} ) { $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; } if ( exists $val->{build_requires} ) { $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; } return $meta; } 1; Spork-0.21/inc/Module/Install/AckXXX.pm0000644000175000017500000000151511574443023016305 0ustar ingyingy#line 1 ## # name: Module::Install::AckXXX # abstract: Warn Author About XXX.pm # author: Ingy döt Net # license: perl # copyright: 2010, 2011 package Module::Install::AckXXX; use 5.008003; use strict; use warnings; my $requires = " use App::Ack 1.94 (); use Capture::Tiny 0.10 (); "; use base 'Module::Install::Base'; our $VERSION = '0.16'; our $AUTHOR_ONLY = 1; sub ack_xxx { my $self = shift; return unless $self->is_admin; require Capture::Tiny; sub ack { system "ack -G '\\.(pm|t|PL)\$' '^\\s*use XXX\\b'"; } my $output = Capture::Tiny::capture_merged(\&ack); $self->_report($output) if $output; } sub _report { my $self = shift; my $output = shift; chomp ($output); print <<"..."; *** AUTHOR WARNING *** *** Found usage of XXX.pm in this code: $output ... } 1; Spork-0.21/inc/Module/Install/Scripts.pm0000644000175000017500000000101111574443023016615 0ustar ingyingy#line 1 package Module::Install::Scripts; use strict 'vars'; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub install_script { my $self = shift; my $args = $self->makemaker_args; my $exe = $args->{EXE_FILES} ||= []; foreach ( @_ ) { if ( -f $_ ) { push @$exe, $_; } elsif ( -d 'script' and -f "script/$_" ) { push @$exe, "script/$_"; } else { die("Cannot find script '$_'"); } } } 1; Spork-0.21/inc/Module/Install/Makefile.pm0000644000175000017500000002703211574443023016716 0ustar ingyingy#line 1 package Module::Install::Makefile; use strict 'vars'; use ExtUtils::MakeMaker (); use Module::Install::Base (); use Fcntl qw/:flock :seek/; use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.01'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub Makefile { $_[0] } my %seen = (); sub prompt { shift; # Infinite loop protection my @c = caller(); if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; } # In automated testing or non-interactive session, always use defaults if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { local $ENV{PERL_MM_USE_DEFAULT} = 1; goto &ExtUtils::MakeMaker::prompt; } else { goto &ExtUtils::MakeMaker::prompt; } } # Store a cleaned up version of the MakeMaker version, # since we need to behave differently in a variety of # ways based on the MM version. my $makemaker = eval $ExtUtils::MakeMaker::VERSION; # If we are passed a param, do a "newer than" comparison. # Otherwise, just return the MakeMaker version. sub makemaker { ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 } # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified # as we only need to know here whether the attribute is an array # or a hash or something else (which may or may not be appendable). my %makemaker_argtype = ( C => 'ARRAY', CONFIG => 'ARRAY', # CONFIGURE => 'CODE', # ignore DIR => 'ARRAY', DL_FUNCS => 'HASH', DL_VARS => 'ARRAY', EXCLUDE_EXT => 'ARRAY', EXE_FILES => 'ARRAY', FUNCLIST => 'ARRAY', H => 'ARRAY', IMPORTS => 'HASH', INCLUDE_EXT => 'ARRAY', LIBS => 'ARRAY', # ignore '' MAN1PODS => 'HASH', MAN3PODS => 'HASH', META_ADD => 'HASH', META_MERGE => 'HASH', PL_FILES => 'HASH', PM => 'HASH', PMLIBDIRS => 'ARRAY', PMLIBPARENTDIRS => 'ARRAY', PREREQ_PM => 'HASH', CONFIGURE_REQUIRES => 'HASH', SKIP => 'ARRAY', TYPEMAPS => 'ARRAY', XS => 'HASH', # VERSION => ['version',''], # ignore # _KEEP_AFTER_FLUSH => '', clean => 'HASH', depend => 'HASH', dist => 'HASH', dynamic_lib=> 'HASH', linkext => 'HASH', macro => 'HASH', postamble => 'HASH', realclean => 'HASH', test => 'HASH', tool_autosplit => 'HASH', # special cases where you can use makemaker_append CCFLAGS => 'APPENDABLE', DEFINE => 'APPENDABLE', INC => 'APPENDABLE', LDDLFLAGS => 'APPENDABLE', LDFROM => 'APPENDABLE', ); sub makemaker_args { my ($self, %new_args) = @_; my $args = ( $self->{makemaker_args} ||= {} ); foreach my $key (keys %new_args) { if ($makemaker_argtype{$key}) { if ($makemaker_argtype{$key} eq 'ARRAY') { $args->{$key} = [] unless defined $args->{$key}; unless (ref $args->{$key} eq 'ARRAY') { $args->{$key} = [$args->{$key}] } push @{$args->{$key}}, ref $new_args{$key} eq 'ARRAY' ? @{$new_args{$key}} : $new_args{$key}; } elsif ($makemaker_argtype{$key} eq 'HASH') { $args->{$key} = {} unless defined $args->{$key}; foreach my $skey (keys %{ $new_args{$key} }) { $args->{$key}{$skey} = $new_args{$key}{$skey}; } } elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { $self->makemaker_append($key => $new_args{$key}); } } else { if (defined $args->{$key}) { warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; } $args->{$key} = $new_args{$key}; } } return $args; } # For mm args that take multiple space-seperated args, # append an argument to the current list. sub makemaker_append { my $self = shift; my $name = shift; my $args = $self->makemaker_args; $args->{$name} = defined $args->{$name} ? join( ' ', $args->{$name}, @_ ) : join( ' ', @_ ); } sub build_subdirs { my $self = shift; my $subdirs = $self->makemaker_args->{DIR} ||= []; for my $subdir (@_) { push @$subdirs, $subdir; } } sub clean_files { my $self = shift; my $clean = $self->makemaker_args->{clean} ||= {}; %$clean = ( %$clean, FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), ); } sub realclean_files { my $self = shift; my $realclean = $self->makemaker_args->{realclean} ||= {}; %$realclean = ( %$realclean, FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), ); } sub libs { my $self = shift; my $libs = ref $_[0] ? shift : [ shift ]; $self->makemaker_args( LIBS => $libs ); } sub inc { my $self = shift; $self->makemaker_args( INC => shift ); } sub _wanted_t { } sub tests_recursive { my $self = shift; my $dir = shift || 't'; unless ( -d $dir ) { die "tests_recursive dir '$dir' does not exist"; } my %tests = map { $_ => 1 } split / /, ($self->tests || ''); require File::Find; File::Find::find( sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 }, $dir ); $self->tests( join ' ', sort keys %tests ); } sub write { my $self = shift; die "&Makefile->write() takes no arguments\n" if @_; # Check the current Perl version my $perl_version = $self->perl_version; if ( $perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; } # Make sure we have a new enough MakeMaker require ExtUtils::MakeMaker; if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { # MakeMaker can complain about module versions that include # an underscore, even though its own version may contain one! # Hence the funny regexp to get rid of it. See RT #35800 # for details. my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/; $self->build_requires( 'ExtUtils::MakeMaker' => $v ); $self->configure_requires( 'ExtUtils::MakeMaker' => $v ); } else { # Allow legacy-compatibility with 5.005 by depending on the # most recent EU:MM that supported 5.005. $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 ); $self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 ); } # Generate the MakeMaker params my $args = $self->makemaker_args; $args->{DISTNAME} = $self->name; $args->{NAME} = $self->module_name || $self->name; $args->{NAME} =~ s/-/::/g; $args->{VERSION} = $self->version or die <<'EOT'; ERROR: Can't determine distribution version. Please specify it explicitly via 'version' in Makefile.PL, or set a valid $VERSION in a module, and provide its file path via 'version_from' (or 'all_from' if you prefer) in Makefile.PL. EOT $DB::single = 1; if ( $self->tests ) { my @tests = split ' ', $self->tests; my %seen; $args->{test} = { TESTS => (join ' ', grep {!$seen{$_}++} @tests), }; } elsif ( $Module::Install::ExtraTests::use_extratests ) { # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness. # So, just ignore our xt tests here. } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { $args->{test} = { TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), }; } if ( $] >= 5.005 ) { $args->{ABSTRACT} = $self->abstract; $args->{AUTHOR} = join ', ', @{$self->author || []}; } if ( $self->makemaker(6.10) ) { $args->{NO_META} = 1; #$args->{NO_MYMETA} = 1; } if ( $self->makemaker(6.17) and $self->sign ) { $args->{SIGN} = 1; } unless ( $self->is_admin ) { delete $args->{SIGN}; } if ( $self->makemaker(6.31) and $self->license ) { $args->{LICENSE} = $self->license; } my $prereq = ($args->{PREREQ_PM} ||= {}); %$prereq = ( %$prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->requires) ); # Remove any reference to perl, PREREQ_PM doesn't support it delete $args->{PREREQ_PM}->{perl}; # Merge both kinds of requires into BUILD_REQUIRES my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); %$build_prereq = ( %$build_prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->configure_requires, $self->build_requires) ); # Remove any reference to perl, BUILD_REQUIRES doesn't support it delete $args->{BUILD_REQUIRES}->{perl}; # Delete bundled dists from prereq_pm, add it to Makefile DIR my $subdirs = ($args->{DIR} || []); if ($self->bundles) { my %processed; foreach my $bundle (@{ $self->bundles }) { my ($mod_name, $dist_dir) = @$bundle; delete $prereq->{$mod_name}; $dist_dir = File::Basename::basename($dist_dir); # dir for building this module if (not exists $processed{$dist_dir}) { if (-d $dist_dir) { # List as sub-directory to be processed by make push @$subdirs, $dist_dir; } # Else do nothing: the module is already present on the system $processed{$dist_dir} = undef; } } } unless ( $self->makemaker('6.55_03') ) { %$prereq = (%$prereq,%$build_prereq); delete $args->{BUILD_REQUIRES}; } if ( my $perl_version = $self->perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; if ( $self->makemaker(6.48) ) { $args->{MIN_PERL_VERSION} = $perl_version; } } if ($self->installdirs) { warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; $args->{INSTALLDIRS} = $self->installdirs; } my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) } keys %$args; my $user_preop = delete $args{dist}->{PREOP}; if ( my $preop = $self->admin->preop($user_preop) ) { foreach my $key ( keys %$preop ) { $args{dist}->{$key} = $preop->{$key}; } } my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); } sub fix_up_makefile { my $self = shift; my $makefile_name = shift; my $top_class = ref($self->_top) || ''; my $top_version = $self->_top->VERSION || ''; my $preamble = $self->preamble ? "# Preamble by $top_class $top_version\n" . $self->preamble : ''; my $postamble = "# Postamble by $top_class $top_version\n" . ($self->postamble || ''); local *MAKEFILE; open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; eval { flock MAKEFILE, LOCK_EX }; my $makefile = do { local $/; }; $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; # Module::Install will never be used to build the Core Perl # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; # XXX - This is currently unused; not sure if it breaks other MM-users # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; seek MAKEFILE, 0, SEEK_SET; truncate MAKEFILE, 0; print MAKEFILE "$preamble$makefile$postamble" or die $!; close MAKEFILE or die $!; 1; } sub preamble { my ($self, $text) = @_; $self->{preamble} = $text . $self->{preamble} if defined $text; $self->{preamble}; } sub postamble { my ($self, $text) = @_; $self->{postamble} ||= $self->admin->postamble; $self->{postamble} .= $text if defined $text; $self->{postamble} } 1; __END__ #line 541 Spork-0.21/inc/Module/Install/ManifestSkip.pm0000644000175000017500000000155711574443023017602 0ustar ingyingy#line 1 ## # name: Module::Install::ManifestSkip # abstract: Generate a MANIFEST.SKIP file # author: Ingy döt Net # license: perl # copyright: 2010, 2011 # see: # - Module::Manifest::Skip package Module::Install::ManifestSkip; use 5.008003; use strict; use warnings; use base 'Module::Install::Base'; my $requires = " use Module::Manifest::Skip 0.10 (); "; our $VERSION = '0.19'; our $AUTHOR_ONLY = 1; my $skip_file = "MANIFEST.SKIP"; sub manifest_skip { my $self = shift; return unless $self->is_admin; eval $requires; die $@ if $@; print "Writing $skip_file\n"; open OUT, '>', $skip_file or die "Can't open $skip_file for output: $!";; print OUT Module::Manifest::Skip->new->text; close OUT; $self->clean_files('MANIFEST'); $self->clean_files($skip_file) if grep /^clean$/, @_; } 1; Spork-0.21/inc/Module/Install/Base.pm0000644000175000017500000000214711574443023016053 0ustar ingyingy#line 1 package Module::Install::Base; use strict 'vars'; use vars qw{$VERSION}; BEGIN { $VERSION = '1.01'; } # Suspend handler for "redefined" warnings BEGIN { my $w = $SIG{__WARN__}; $SIG{__WARN__} = sub { $w }; } #line 42 sub new { my $class = shift; unless ( defined &{"${class}::call"} ) { *{"${class}::call"} = sub { shift->_top->call(@_) }; } unless ( defined &{"${class}::load"} ) { *{"${class}::load"} = sub { shift->_top->load(@_) }; } bless { @_ }, $class; } #line 61 sub AUTOLOAD { local $@; my $func = eval { shift->_top->autoload } or return; goto &$func; } #line 75 sub _top { $_[0]->{_top}; } #line 90 sub admin { $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new; } #line 106 sub is_admin { ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin'); } sub DESTROY {} package Module::Install::Base::FakeAdmin; use vars qw{$VERSION}; BEGIN { $VERSION = $Module::Install::Base::VERSION; } my $fake; sub new { $fake ||= bless(\@_, $_[0]); } sub AUTOLOAD {} sub DESTROY {} # Restore warning handler BEGIN { $SIG{__WARN__} = $SIG{__WARN__}->(); } 1; #line 159 Spork-0.21/Changes0000644000175000017500000000533211574441421012531 0ustar ingyingy--- version: 0.21 date: Sat Jun 11 02:15:10 EST 2011 changes: - Add Kwiki::Cache to prereqs - rt-15037 --- version: 0.20 date: Mon Apr 4 07:38:17 PDT 2005 changes: - remove use_class - the plugin base class - add hooks_class into config so we have hooks - Kwid Formatter for Spork - Some convienent methods... - now handles 'spork -compress' as 'kwiki -compress' - unbreak global config (~/.sporkrc/config.yaml) - now handles 'spork -compress' as 'kwiki -compress' - Also pass down sub_num. So plugins can distinguish wheather it's the first of sub-slides or not. - work-around of 'cannot call unhook on a undef ref' error. - somehow Spoon::Hooked objects are destroyed before Spoon::Hub, which doesn't make much sense. - make plugins file - plugins file works - Make installer better - add plugin.pm - Make tests pass when we have .sporkrc --- version: 0.19 date: Sun Jan 23 16:40:16 PST 2005 changes: - Make Spork up to date with latest Spoon stuff. --- version: 0.18 date: Mon Jun 21 09:20:53 PDT 2004 changes: - Integrate Kwiki Formatter now that Kwiki is released --- version: 0.17 date: Tue Jun 1 14:06:46 PDT 2004 changes: - Accomodate Spoon::Formatter changes - Option to turn off mouse controls --- version: 0.16 date: Thu May 20 13:23:33 PDT 2004 changes: - Upgraded Formatter to latest Kwiki style - Include WAFL --- version: 0.15 date: Fri May 7 02:19:20 PDT 2004 changes: - Added =cut to Spork::Config - Integrated my Kwiki --- version: 0.14 date: Wed Mar 31 23:02:59 CST 2004 changes: - 0.13 was the unlucky release. Had a couple bugs. --- version: 0.14 date: Wed Mar 31 23:02:59 CST 2004 changes: - 0.13 was the unlucky release. Had a couple bugs. --- version: 0.13 date: Wed Mar 31 11:39:28 CST 2004 changes: - Documentation for 'spork' was borked - Refactored loose ends - Added messages for spork commands --- version: 0.12 date: Wed Mar 31 00:07:36 CST 2004 changes: - Add a config, anywhere a slide could be. - Support ~/.sporkrc/config.yaml - Expand templates on |spork -make| unless template directory exists - Change to image<...> - Add auto_scrolldown - Javascript controls - Accesskey controls - Make control_links an option - Make title be a link to start - Add download_method: wget (lwp, curl) - Spoon::Config->add_config($hash_ref) - Upgrade documentation - Upgrade sample slideshow - Remove '#' from start and index slide - Change 'template' to 'template/tt2' - i18n-ize - Add character_encoding ---- == Crazy Ideas * Generate a Wiki when slides are made ** Auto signin for audience ** Take audience questions through the wiki --- version: 0.11 date: Tue Mar 23 00:23:46 PST 2004 changes: - Fixed typo reported by clkao --- version: 0.10 date: Sun Mar 21 16:36:17 PST 2004 changes: - Initial release. Spork-0.21/MANIFEST0000644000175000017500000000131211574443032012361 0ustar ingyingybin/rebuild bin/spork Changes inc/Module/Install.pm inc/Module/Install/AckXXX.pm inc/Module/Install/Base.pm inc/Module/Install/Can.pm inc/Module/Install/Fetch.pm inc/Module/Install/Makefile.pm inc/Module/Install/ManifestSkip.pm inc/Module/Install/Metadata.pm inc/Module/Install/ReadmeFromPod.pm inc/Module/Install/Scripts.pm inc/Module/Install/VersionCheck.pm inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm lib/Spork.pm lib/Spork/Command.pm lib/Spork/Config.pm lib/Spork/Formatter.pm lib/Spork/Formatter/Autringy.pm lib/Spork/Hub.pm lib/Spork/Plugin.pm lib/Spork/Registry.pm lib/Spork/Slides.pm lib/Spork/Template/TT2.pm Makefile.PL MANIFEST This list of files META.yml README t/formatter1.t t/new.t Spork-0.21/bin/0000755000175000017500000000000011574443054012007 5ustar ingyingySpork-0.21/bin/rebuild0000755000175000017500000000061111574440652013362 0ustar ingyingy#!/usr/bin/env perl use lib 'lib'; use Spork; die "Must be run from the Spork directory\n" unless -f "rebuild"; my $spork_dir = shift or die "No spork directory specified\n"; die "Invalid spork directory '$spork_dir'\n" unless -d $spork_dir; $spork_dir =~ s/\/+$//; my $hub = Spork->new->load_hub; $hub->template->compress_files($spork_dir); $hub->slides->compress_files($spork_dir); Spork-0.21/bin/spork0000755000175000017500000000133411574440652013075 0ustar ingyingy#!/usr/bin/perl -w use strict; use warnings; use Spork; our $VERSION = '0.19'; use lib 'lib'; Spork->new->load_hub->command->process(@ARGV); __END__ =head1 NAME spork - The Spork Command Line Utility =head1 USAGE > mkdir my-slideshow > cd my-slideshow > spork -new > spork -make > spork -start =head1 DESCRIPTION Spork is a Perl module for creating standalone HTML slideshows from Kwiki markup. =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2004. Brian Ingerson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut # vim: set ft=perl: Spork-0.21/README0000644000175000017500000001207011574443023012113 0ustar ingyingyNAME Spork - Slide Presentations (Only Really Kwiki) SYNOPSIS mkdir my-slideshow cd my-slideshow spork -new vim Spork.slides vim config.yaml spork -make spork -start DESCRIPTION Spork lets you create HTML slideshow presentations easily. It comes with a sample slideshow. All you need is a text editor, a browser and a topic. Spork allows you create an entire slideshow by editing a single file called "Spork.slides" (by default). Each slide is created using a minimal markup language similar to the syntax used in Kwiki wikis. MARKUP SYNTAX Spork markup is like Kwiki markup. Slides Slides are separated by lines consisting entirely of four or more dashes. Each slide consists of text and markup. This section describes each of the markup units. Any slide can be made to be multipart by putting a '+' at the beginning of a line where you want to break it. Each subpart will be cumulative to that point. Headings A heading is a line starting with 1-6 equals signs followed by a space followed by the heading text. The number of equals signs corresponds to the level of the heading. === A Level Three Heading Paragraphs Paragraphs are just paragraphs. They end with a blank line. This is my paragraph of something that I wanted to show you. This paragraph is now ending. Preformatted Text Preformatted text, like program source code for instance, is indicated by indenting it. My code: sub greet { print "Hello there\n"; } Pretty Print You can markup a section of your source code with various colors and highlights. In this example we make the word "greet" display green and the word "Hello" display red and underline the quoted string. .pretty. sub greet { # GGGGG print "Hello there\n"; # _______________ # RRRRR } .pretty. Coming soon. Unordered List Use asterisks to mark bullet points. The number of asterisks indicates the nesting level. * Point One ** Point One A ** Point One B * Point Two * Point Three Ordered List Same as unordered lists except use zeroes to mark bullet points. Ordered and unordered lists can be intermingled. 0 Point One ** Point One A ** Point One B 0 Point Two 0 Point Three Bold Text Sourround one or more words with asterisks to make the text bold. This is *bold text* example. Italic Text Sourround one or more words with slashes to make the text italicized. This is /italic text/ example. Underlined Text Sourround one or more words with underscores to make the text underlined. This is _underlined text_ example. Teletyped Text Sourround one or more words with pipes to make the text appear in a fixed width font. This is |fixed width font| example. Images Each slide can display an image. {image: http://www.example.com/images/xyz123.png} This will download a copy of the image if it hasn't been downloaded yet. That way you can view your slides offline. If more than one image is encoded in a slide, Spork takes the last one. This is useful for a multipart slide where you want the image to change. Just put this image tag in the correct subpart. Files You can create a link to a local file. When clicked the file should appear in a new browser window. {file: mydir/myfile.txt} The "file_base" configuration setting will be prepended to relative paths. CONFIGURATION Spork slideshows can be configured in three different ways. The first way is with the local "config.yaml" created by "spork -new". The second way is through a global configuration file called "~/.sporkrc/config.yaml". Any settings in the local file will override settings in the global file. The third way is to put YAML sections directly in your slides file. You can put a YAML section anywhere in the file that a slide would go, and you can have more than one section. In fact, you could change the configuration for each slide by putting a YAML section before each slide. Any settings in these sections will override the setting that came from anywhere else. See Spork::Config for more information. CUSTOMIZATION You can easily extend and customize Spork by writing subclasses and putting them in the configuration or by fiddling with the template files. This version uses Template Toolkit templates by default. SEE ALSO Kwiki, Spoon AUTHOR Ingy döt Net COPYRIGHT Copyright (c) 2011. Ingy döt Net. All rights reserved. Copyright (c) 2004, 2005. Brian Ingerson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html Spork-0.21/lib/0000755000175000017500000000000011574443054012005 5ustar ingyingySpork-0.21/lib/Spork/0000755000175000017500000000000011574443054013103 5ustar ingyingySpork-0.21/lib/Spork/Slides.pm0000644000175000017500000001625710220702053014657 0ustar ingyingypackage Spork::Slides; use Spork -Base; use mixin 'Spoon::Installer'; require CGI; const class_id => 'slides'; field image_url => ''; field slide_heading => ''; field slide_index => []; field 'first_slide'; field top_config => {}; field config => -init => '$self->hub->config'; sub make_slides { my @slides = $self->split_slides($self->config->slides_file); $self->first_slide($slides[0]); $self->config->add_config($slides[0]->{config}); $self->top_config({$self->config->all}); $self->make_start; for (my $i = 0; $i < @slides; $i++) { my $slide = $slides[$i]; $self->config->add_config($slide->{config}); my $content = $slides[$i]{slide_content}; $slide->{first_slide} = $slides[0]->{slide_name}; $slide->{prev_slide} = $i ? $self->make_link($slides[$i - 1]{slide_name}) : 'start.html'; $slide->{next_slide} = $slides[$i + 1] ? $self->make_link($slides[$i + 1]{slide_name}) : ''; $self->slide_heading(''); $self->image_url(''); my $parsed = $self->hub->formatter->text_to_parsed($content); my $html = $parsed->to_html; $slide->{slide_heading} = $self->slide_heading; $slide->{image_html} = $self->get_image_html; my $output = $self->hub->template->process('slide.html', %$slide, hub => $self->hub, index_slide => 'index.html', slide_content => $html, spork_version => "Spork v$Spork::VERSION", ); my $file_name = $self->config->slides_directory . '/' . $slide->{slide_name}; $output > io($file_name)->assert; push @{$self->slide_index}, $slide if $slide->{slide_name} =~ /^slide\d+a?\.html$/; } $self->make_index; } sub make_link { my $link = shift; return $link unless $self->config->auto_scrolldown; return $link if $link =~ /^slide\d+a?\.html$/; return "$link#end"; } sub make_index { my $output = $self->hub->template->process('index.html', %{$self->top_config}, slides => $self->slide_index, spork_version => "Spork v$Spork::VERSION", next_slide => 'start.html', ); my $file_name = $self->config->slides_directory . '/index.html'; $output > io($file_name)->assert; } sub make_start { my $output = $self->hub->template->process('start.html', spork_version => "Spork v$Spork::VERSION", index_slide => 'index.html', next_slide => $self->first_slide->{slide_name}, ); $output > io($self->start_name)->assert; } sub start_name { $self->config->slides_directory . '/start.html'; } sub split_slides { my $slides_file = shift; my @slide_info; my @slides = grep $_, split /^-{4,}\s*\n/m, io($slides_file)->slurp; my $slide_num = 1; my $config = {}; for my $slide (@slides) { if ($slide =~ /\A(^(---|\w+\s*:.*|-\s+.*|#.*)\n)+\z/m) { $config = $self->hub->config->parse_yaml($slide); next; } my @sub_slides = $self->sub_slides($slide); my $sub_num = @sub_slides > 1 ? 'a' : ''; while (@sub_slides) { my $sub_slide = shift @sub_slides; my $slide_info = { slide_num => $slide_num, slide_content => $sub_slide, slide_name => "slide$slide_num$sub_num.html", last => @sub_slides ? 0 : 1, config => $config, sub_num => $sub_num }; $config = {}; push @slide_info, $slide_info; $sub_num++; } $slide_num++; } return @slide_info; } sub sub_slides { my $raw_slide = shift; my (@slides, $slide); for (split /^\+/m, $raw_slide) { push @slides, $slide .= $_; } return @slides; } sub get_image_html { my $image_url = $self->image_url or return ''; my $image_width; ($image_url, $image_width) = split /\s+/, $image_url; $image_width ||= $self->config->image_width; my $image_file = $image_url; $image_file =~ s/.*\///; my $images_directory = $self->config->slides_directory . '/images'; io->dir($images_directory)->assert->open; my $image_html = qq{}; return $image_html if -f "$images_directory/$image_file"; require Cwd; my $home = Cwd::cwd(); chdir($images_directory) or die; my $method = $self->config->download_method . '_download'; warn "- Downloading $image_url\n"; $self->$method($image_url, $image_file); chdir($home) or die; return -f "$images_directory/$image_file" ? $image_html : ''; } sub wget_download { my ($image_url, $image_file) = @_; system "wget $image_url 2> /dev/null"; } sub curl_download { my ($image_url, $image_file) = @_; system "curl -o $image_file $image_url 2> /dev/null"; } sub lwp_download { my ($image_url, $image_file) = @_; system "lwp-download $image_url > /dev/null"; } __DATA__ =head1 NAME Spork::Slides - Slide Presentations (Only Really Kwiki) =head1 SYNOPSIS =head1 DESCRIPTION =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2004, 2005. Brian Ingerson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut __Spork.slides__ ---- presentation_topic: Spork presentation_title: Spork - The Kwiki Way To Do Slideshows presentation_place: Portland, Oregon presentation_date: March 25nd, 2004 ---- == What is Spork? * Spork Stands for: +** Slide Presentation (Only Really Kwiki) +* Spork is an HTML Slideshow Generator ** All slides are in one simple file ** Run |spork -make| to make the slides +* Spork is a CPAN Module +* Spork is Based on Spoon ---- == Using Spork Spork makes setting up a slide presentation very easy. Just follow these easy steps: * mkdir myslides * cd myslides * spork -new * vim config.yaml Spork.slides * spork -make * spork -start ---- show_controls: 0 ---- == Moving About * To Advance Slide: ** Click /Next/ or Click Mouse or ** Hit /Enter/ or /ctl-n/ or /spacebar/ * To Move Backwards: ** Click /Previous/ or ** Hit /Delete/ or /ctl-p/ * Other Movements ** Starting Slide - /ctl-s/ ** Index Slide - /ctl-i/ * Notice The Control Links Have Disappeared ---- == Creating Slides Slides are all done in *Kwiki* markup language. Simple stuff. * Example Slide: == Sample Slide My point is, it's as easy as: * One +* Two +* Three Putting a plus (+) at the start of a line creates a subslide effect. ---- == Using Images * Hey Look. A picture! {image: http://search.cpan.org/s/img/cpan_banner.png} +* Woah, it changed! {image: http://cpan.org/misc/jpg/cpan.jpg} +* Images are cached locally ---- == Linking to Files * Often Times You Want to Show a File * {file: ./Spork.slides This} is the Slide Show Text! * Just Write a Line Like This * {file: ./Spork.slides This} is the Slide Show Text! * {file: ./Spork.slides This} is the Slide Show Text! * For Relative Paths, Set This in the |config.yaml| file_base: /Users/ingy/dev/cpan/Spork ---- banner_bgcolor: lightblue ---- == That's All * The END Spork-0.21/lib/Spork/Formatter.pm0000644000175000017500000000446310220576152015404 0ustar ingyingypackage Spork::Formatter; use Kwiki::Formatter -Base; sub formatter_classes { ( (map { s/^Heading$/Spork::Formatter::Heading/; $_ } super), 'Spork::Formatter::Inline', ); } const all_phrases => [qw(wafl_phrase asis strong em u tt tt2 hyper)]; sub wafl_classes { qw( Spork::Formatter::Image Spork::Formatter::File) } ################################################################################ package Spork::Formatter::Inline; use base 'Spoon::Formatter::Unit'; use Kwiki ':char_classes'; const formatter_id => 'tt2'; const pattern_start => qr/(^|(?<=[^$ALPHANUM]))\|/; const pattern_end => qr/\|(?=[^$ALPHANUM]|\z)/; const html_start => ""; const html_end => ""; ################################################################################ package Spork::Formatter::Heading; use base 'Kwiki::Formatter::Heading'; sub to_html { my $text = join '', map { ref $_ ? $_->to_html : $_ } @{$self->units}; my $level = $self->level; $self->hub->slides->slide_heading($text) unless $self->hub->slides->slide_heading; return "$text\n"; } ################################################################################ package Spork::Formatter::File; use base 'Spoon::Formatter::WaflPhrase'; const wafl_id => 'file'; sub html { require Cwd; my ($file, $link_text) = split /\s+/, $self->arguments, 2; $link_text ||= $file; $file = $self->hub->config->file_base . "/$file" unless $file =~ /^\.{0,1}\//; $file = Cwd::abs_path($file); qq{' . $link_text . ''; } ################################################################################ package Spork::Formatter::Image; use base 'Spoon::Formatter::WaflPhrase'; const wafl_id => 'image'; sub to_html { $self->hub->slides->image_url($self->arguments); return ''; } __END__ =head1 NAME Spork::Formatter - Slide Presentations (Only Really Kwiki) =head1 SYNOPSIS =head1 DESCRIPTION =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2004, 2005. Brian Ingerson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Spork-0.21/lib/Spork/Config.pm0000644000175000017500000001334010220756715014645 0ustar ingyingypackage Spork::Config; use Kwiki::Config -Base; use mixin 'Spoon::Installer'; const class_id => 'config'; sub default_configs { my @configs; push @configs, "config.yaml" if -f "config.yaml"; push @configs, "$ENV{HOME}/.sporkrc/config.yaml" if defined $ENV{HOME} and -f "$ENV{HOME}/.sporkrc/config.yaml"; return @configs; } sub default_config { my $config = super; $config->{slides_file} = 'Spork.slides'; $config->{template_directory} = 'template/tt2'; $config->{template_path} = [ 'template/tt2' ]; return $config; } sub default_classes { ( config_class => 'Spork::Config', registry_class => 'Spork::Registry', hub_class => 'Spork::Hub', formatter_class => 'Spork::Formatter', template_class => 'Spork::Template::TT2', command_class => 'Spork::Command', slides_class => 'Spork::Slides', hooks_class => 'Spoon::Hooks', # For Kwiki Plugins: cgi_class => 'Kwiki::CGI', pages_class => 'Kwiki::Pages', preferences_class => 'Kwiki::Preferences', css_class => 'Kwiki::CSS', javascript_class => 'Kwiki::Javascript', cache_class => 'Kwiki::Cache', kwiki_command_class => 'Kwiki::Command', ) } __DATA__ =head1 NAME Spork::Config - Spork Configuration Class =head1 SETTINGS This is a list of all the current configuration options in alphabetical order: =over 4 =item * author_email The presentation author's email address. =item * author_name The presentation author's full name. =item * author_webpage The presentation author's webpage. =item * auto_scrolldown When a multipart slide is too long for the display, force it to scroll all the way down when you link to it. =item * banner_bgcolor Background color for the banner boxes at the top and bottom of each slide. =item * character_encoding I18N character encoding. You probably want 'utf-8'. =item * copyright_string A copyright message to be displayed on each slide. =item * download_method Which program to use when downloading images. Possible values are: wget - default curl lwp =item * file_base A path to prepend to any relative file path provided to the C< >> directive. =item * file_base A path to prepend to any relative file path provided to the C< >> directive. =item * formatter_class Perl module to be used for slides formatting. You probably won't change this unless you are up to the task of writing your own custom formatter. =item * image_width This is the default width that all images in your slideshow will be scaled to. =item * link_index Text for link to index page. =item * link_next Text for link to next page. =item * link_previous Text for link to previous page. =item * logo_image A small image to put at the bottom of each slide. You can leave this value empty if you don't have a logo. =item * mouse_controls If this is turned off, clicking on the page will not advance the screen. This is useful if you like to use the mouse to hilight things on the page. =item * show_controls If this is turned off, the control links (previous, index, next) will not display. =item * slides_directory The directory where all your slides will be written to when you do C. =item * slides_file The name of the file that you write all of your slides in. =item * start_command The command that gets executed when you type C. =item * template_class The Perl module that is used for template processing. This module also contains the default templates that are used. Possible values are: Spork::Template::TT2 (Template Toolkit - default) Spork::Template::Mason (HTML::Mason - by Dave Rolsky) Spork::Template::Simple (Simplistic version with no dependencies) =item * template_directory The directory where spork writes all its templates during C. Templates will only be written if this directory does not exist. So to force templates to be upgraded, delete this directory. This directory should be listed in C. =item * template_path A list of template directories to be used by the template processing class. =back =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2004, 2005. Brian Ingerson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut __config.yaml__ ################################################################################ # Spork Configuration File. # # Please read this file over and set the values to your own. # # If you want global settings for all your slideshows, copy this file to # ~/.sporkrc/config.yaml. Any settings in this local file will override # the global value of that setting. # # See C for details on settings. ################################################################################ author_name: Brian Ingerson author_email: ingy@cpan.org author_webpage: http://search.cpan.org/~ingy/ copyright_string: Copyright © 2005 Brian Ingerson banner_bgcolor: hotpink show_controls: 1 mouse_controls: 0 image_width: 350 auto_scrolldown: 1 logo_image: logo.png file_base: /Users/ingy/dev/cpan/Spork/ slides_file: Spork.slides template_directory: template/tt2 template_path: - ./template/tt2 slides_directory: slides download_method: wget character_encoding: utf-8 link_previous: < < Previous link_next: Next >> link_index: Index start_command: open slides/start.html # Change core classes here: # formatter_class: Spork::Formatter::Kwid # Set plugin classes here: # plugin_classes: # - Spork::S5 # - Spork::S5Theme # - Spork::S5ThemeFlower # - Spork::S5ThemeBlackday # - Kwiki::PerlBlocks __plugins__ Spork-0.21/lib/Spork/Formatter/0000755000175000017500000000000011574443054015046 5ustar ingyingySpork-0.21/lib/Spork/Formatter/Autringy.pm0000644000175000017500000000221310207375637017207 0ustar ingyingypackage Spork::Formatter::Autringy; use Spork::Formatter -Base; sub formatter_classes { map { s/^Ulist$/Spork::Formatter::Autringy::Ulist/; s/^Item$/Spork::Formatter::Autringy::Item/; $_; } super; } ################################################################################ package Spork::Formatter::Autringy::Ulist; use base 'Kwiki::Formatter::Ulist'; const bullet => '[\*\-]+\ +'; ################################################################################ package Spork::Formatter::Autringy::Item; use base 'Kwiki::Formatter::Item'; const formatter_id => 'li'; const bullet => '[\*\-]+\ +'; field which => ''; sub html_start { return super unless $self->hub->config->flipflop; $self->which =~ /-/ ? '
  • ' : '
  • '; } sub html_end { $self->hub->config->flipflop ? "
  • \n" : super; } sub match { my $bullet = $self->bullet; $self->which($1) if $self->text =~ /^($bullet)(.*)\n/m; return unless $self->text =~ /^$bullet(.*)\n/m; $self->set_match; return 1; } Spork-0.21/lib/Spork/Plugin.pm0000644000175000017500000000105210220702053014655 0ustar ingyingypackage Spork::Plugin; use Spoon::Plugin -Base; our $VERSION = '0.01'; stub 'class_id'; field config => {}, -init => '$self->hub->config'; field template => {}, -init => '$self->hub->template'; field formatter => {},-init => '$self->hub->formatter'; __END__ =head1 NAME Spork::Plugin - Spork plugin base class =head1 COPYRIGHT Copyright 2005 by Kang-min Liu . This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See =cut Spork-0.21/lib/Spork/Template/0000755000175000017500000000000011574443054014656 5ustar ingyingySpork-0.21/lib/Spork/Template/TT2.pm0000644000175000017500000001157610207375637015642 0ustar ingyingypackage Spork::Template::TT2; use Spoon::Template::TT2 -Base; use mixin 'Spoon::Installer'; sub plugins { {} } sub extract_to { $self->hub->config->template_directory; } sub path { $self->hub->config->template_path || [ $self->hub->config->template_directory ]; } __DATA__ __top.html__ [% slide_heading %] [% FOR css_file = hub.css.files -%] [% END -%]
    [% presentation_topic %] [% presentation_title %] [% slide_num ? "#$slide_num" : ' ' %]
    __bottom.html__
    __index.html__ [% INCLUDE top.html %]
      [% FOR slide = slides -%]
    1. [% slide.slide_heading %]
    2. [% END -%]
    [% INCLUDE bottom.html %] __start.html__ [% INCLUDE top.html %]

    [% presentation_title %]

    [% author_name %]

    [% author_email %]

    [% presentation_place %]

    [% presentation_date %]

    [% INCLUDE bottom.html %] __slide.html__ [% INCLUDE top.html %]
    [% image_html %] [% slide_content -%] [%- UNLESS last -%] continued... [% END %]
    [% INCLUDE bottom.html %] __slide.css__ /* BEGIN index.css */ hr { color: #202040; height: 0px; border-top: 0px; border-bottom: 3px #202040 ridge; border-left: 0px; border-right: 0px; } a:link { color: #123422; text-decoration: none; } a:visited { color: #123333; text-decoration: none; } a:hover { text-decoration: underline; } p { font-size: 24pt; margin: 6pt; } div p { font-size: 18pt; margin-top: 12pt; margin-bottom: 12pt; margin-left: 6pt; margin-right: 6pt; } small { font-size: 9pt; font-style: italic; } #topbar { background: [% banner_bgcolor %]; color: blue; position:absolute; right: 5px; left: 5px; top: 5px; height: 50px; } #bottombar { background: [% banner_bgcolor %]; color: blue; position: fixed; right: 5px; left: 5px; bottom: 5px; height: 50px; z-index: 0; } .top_spacer { height: 0px; margin: 0px 0px 0px 0px; padding: 1px 0px 0px 0px; } .spacer { bottom: 5px; height: 50px; } #content { background:#fff; margin-left: 20px; margin-right:20px; margin-top: 80px; } #logo { position: fixed; right: 40px; bottom: 51px; width: 130px; height: 150px; z-index:3; background-image: url([% images_directory %]/[% logo_image %]); background-repeat: no-repeat; } /* END index.css */ __controls.js__ // BEGIN controls.js function nextSlide() { window.location = '[% next_slide %]'; } function prevSlide() { window.location = '[% prev_slide %]'; } function indexSlide() { window.location = 'index.html'; } function startSlide() { window.location = 'start.html'; } function closeSlide() { window.close(); } function handleKey(e) { var key; if (e == null) { // IE key = event.keyCode } else { // Mozilla if (e.altKey || e.ctrlKey) { return true } key = e.which } switch(key) { case 8: prevSlide(); break case 13: nextSlide(); break case 32: nextSlide(); break case 81: closeSlide(); break case 105: indexSlide(); break case 110: nextSlide(); break case 112: prevSlide(); break case 115: startSlide(); break default: //xxx(e.which) } } document.onkeypress = handleKey [% IF mouse_controls -%] document.onclick = nextSlide [% END -%] // END controls.js Spork-0.21/lib/Spork/Hub.pm0000644000175000017500000000005210207375637014157 0ustar ingyingypackage Spork::Hub; use Spoon::Hub -Base; Spork-0.21/lib/Spork/Command.pm0000644000175000017500000000534610220721112015004 0ustar ingyingypackage Spork::Command; use Spork -Base; sub boolean_arguments { qw( -new -make -start -compress) } sub process { $self->call_handler(@_); $self->hub->remove_hooks; } sub call_handler { my ($args,@others) = $self->parse_arguments(@_); return $self->new_spork if $args->{-new}; return $self->make_spork if $args->{-make}; return $self->start_spork if $args->{-start}; return $self->handle_compress(@others) if $args->{-compress}; return $self->usage; } sub handle_compress { eval q{use mixin 'Spoon::Installer'}; $self->compress_lib(@_); } sub new_spork { my @files = io('.')->all; die "Can't make new spork in a non-empty directory\n" if @files; warn "Extracting sample slideshow: Spork.slides...\n"; $self->hub->slides->extract_files; warn "Extracting sample configuration file: config.yaml...\n"; $self->hub->config->extract_files; warn "Done. Now edit these files and run 'spork -make'.\n\n" } sub make_spork { $self->assert_registry; unless (-e $self->hub->template->extract_to) { warn "Extracting template files...\n"; $self->hub->template->extract_files; } { use Cwd; my $home = cwd; chdir io->dir($self->hub->config->slides_directory)->assert->open->name; my $kwiki_command = $self->hub->kwiki_command; for my $class (@{$self->hub->config->plugin_classes}) { eval "use $class; 1" or die $@; my $class_id = $class->new->class_id; $self->hub->config->add_config({"${class_id}_class" => $class}); $kwiki_command->install($class_id); } chdir $home; } warn "Creating slides...\n"; $self->hub->slides->make_slides; warn "Slideshow created! Now run try running 'spork -start'.\n\n"; } sub start_spork { my $command = $self->hub->config->start_command or die "No start_command in configuration"; warn $command, "\n"; exec $command; } sub usage { warn <hub->registry->load; } __END__ =head1 NAME Spork::Command - Slide Presentations (Only Really Kwiki) =head1 SYNOPSIS =head1 DESCRIPTION =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2004, 2005. Brian Ingerson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Spork-0.21/lib/Spork/Registry.pm0000644000175000017500000000006410207375637015254 0ustar ingyingypackage Spork::Registry; use Spoon::Registry -Base; Spork-0.21/lib/Spork.pm0000644000175000017500000001201011574440736013437 0ustar ingyingypackage Spork; use 5.006001; use strict; use warnings; use Spoon 0.22 -Base; our $VERSION = '0.21'; use Kwiki 0.38 (); use Kwiki::Cache 0.11 (); const config_class => 'Spork::Config'; __END__ =head1 NAME Spork - Slide Presentations (Only Really Kwiki) =head1 SYNOPSIS mkdir my-slideshow cd my-slideshow spork -new vim Spork.slides vim config.yaml spork -make spork -start =head1 DESCRIPTION Spork lets you create HTML slideshow presentations easily. It comes with a sample slideshow. All you need is a text editor, a browser and a topic. Spork allows you create an entire slideshow by editing a single file called C (by default). Each slide is created using a minimal markup language similar to the syntax used in Kwiki wikis. =head1 MARKUP SYNTAX Spork markup is like Kwiki markup. =head2 Slides Slides are separated by lines consisting entirely of four or more dashes. Each slide consists of text and markup. This section describes each of the markup units. Any slide can be made to be multipart by putting a '+' at the beginning of a line where you want to break it. Each subpart will be cumulative to that point. =head2 Headings A heading is a line starting with 1-6 equals signs followed by a space followed by the heading text. The number of equals signs corresponds to the level of the heading. === A Level Three Heading =head2 Paragraphs Paragraphs are just paragraphs. They end with a blank line. This is my paragraph of something that I wanted to show you. This paragraph is now ending. =head2 Preformatted Text Preformatted text, like program source code for instance, is indicated by indenting it. My code: sub greet { print "Hello there\n"; } =head2 Pretty Print You can markup a section of your source code with various colors and highlights. In this example we make the word "greet" display green and the word "Hello" display red and underline the quoted string. .pretty. sub greet { # GGGGG print "Hello there\n"; # _______________ # RRRRR } .pretty. Coming soon. =head2 Unordered List Use asterisks to mark bullet points. The number of asterisks indicates the nesting level. * Point One ** Point One A ** Point One B * Point Two * Point Three =head2 Ordered List Same as unordered lists except use zeroes to mark bullet points. Ordered and unordered lists can be intermingled. 0 Point One ** Point One A ** Point One B 0 Point Two 0 Point Three =head2 Bold Text Sourround one or more words with asterisks to make the text bold. This is *bold text* example. =head2 Italic Text Sourround one or more words with slashes to make the text italicized. This is /italic text/ example. =head2 Underlined Text Sourround one or more words with underscores to make the text underlined. This is _underlined text_ example. =head2 Teletyped Text Sourround one or more words with pipes to make the text appear in a fixed width font. This is |fixed width font| example. =head2 Images Each slide can display an image. {image: http://www.example.com/images/xyz123.png} This will download a copy of the image if it hasn't been downloaded yet. That way you can view your slides offline. If more than one image is encoded in a slide, Spork takes the last one. This is useful for a multipart slide where you want the image to change. Just put this image tag in the correct subpart. =head2 Files You can create a link to a local file. When clicked the file should appear in a new browser window. {file: mydir/myfile.txt} The C configuration setting will be prepended to relative paths. =head1 CONFIGURATION Spork slideshows can be configured in three different ways. The first way is with the local C created by C. The second way is through a global configuration file called C<~/.sporkrc/config.yaml>. Any settings in the local file will override settings in the global file. The third way is to put YAML sections directly in your slides file. You can put a YAML section anywhere in the file that a slide would go, and you can have more than one section. In fact, you could change the configuration for each slide by putting a YAML section before each slide. Any settings in these sections will override the setting that came from anywhere else. See L for more information. =head1 CUSTOMIZATION You can easily extend and customize Spork by writing subclasses and putting them in the configuration or by fiddling with the template files. This version uses Template Toolkit templates by default. =head1 SEE ALSO L, L =head1 AUTHOR Ingy döt Net =head1 COPYRIGHT Copyright (c) 2011. Ingy döt Net. All rights reserved. Copyright (c) 2004, 2005. Brian Ingerson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Spork-0.21/Makefile.PL0000644000175000017500000000032211574442723013210 0ustar ingyingyuse inc::Module::Install; all_from 'lib/Spork.pm'; requires_from 'lib/Spork.pm'; ack_xxx; readme_from; version_check; manifest_skip 'clean'; install_script 'bin/spork'; clean_files 't/spork'; WriteAll;