EPublisher-Target-Plugin-EPub
view release on metacpan or search on metacpan
lib/EPublisher/Target/Plugin/EPub.pm view on Meta::CPAN
close $xhtml_fh;
close $in_fh;
$epub->copy_xhtml( $xhtml_filename, "text/$counter.xhtml", linear => 'no' );
# cleaning up...
unlink $xhtml_filename;
unlink $in_file_temp;
$self->add_to_table_of_contents( $counter, $parser->{to_index} );
# add images
my @images = $parser->images_to_import();
for my $image ( @images ) {
my $path = $image->{path};
my $name = $image->{name};
my $image_id = $epub->copy_image( $path, "images/$name" );
$epub->add_meta_item( "image$image_counter", $image_id );
}
$counter++;
}
# Add Pod headings to table of contents.
$self->set_table_of_contents( $epub, $self->table_of_contents );
# clean up...
unlink $css_filename if !$self->user_css;
# Generate the ePub eBook.
my $success = $epub->pack_zip( $out_filename );
if ( !$success ) {
$self->publisher->debug( "402: can't create epub" );
return '';
}
# delete tmp dir created by EBook::EPUB
my $epub_tmp = $epub->tmpdir;
remove_tree $epub_tmp if $epub_tmp and -d $epub_tmp;
return $out_filename;
}
sub add_to_table_of_contents {
my ($self,$page, $arrayref) = @_;
push @{ $self->{__toc} }, +{ page => $page, headings => $arrayref };
return 1;
}
sub table_of_contents {
my ($self) = @_;
return $self->{__toc};
}
sub _html_header {
return
qq{<?xml version="1.0" encoding="UTF-8"?>\n}
. qq{<!DOCTYPE html\n}
. qq{ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n}
. qq{ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n}
. qq{\n}
. qq{<html xmlns="http://www.w3.org/1999/xhtml">\n}
. qq{<head>\n}
. qq{<title></title>\n}
. qq{<meta http-equiv="Content-Type" }
. qq{content="text/html; charset=iso-8859-1"/>\n}
. qq{<link rel="stylesheet" href="../styles/style.css" }
. qq{type="text/css"/>\n}
. qq{</head>\n}
. qq{\n}
. qq{<body>\n};
}
sub set_table_of_contents {
my ($self,$epub,$pod_headings) = @_;
my $play_order = 1;
my $max_heading_level = $self->_config->{max_heading_level} || 2;
my @navpoints = ($epub) x ($max_heading_level + 1);
for my $content_part ( @{$pod_headings} ) {
my $headings = $content_part->{headings};
my $page = $content_part->{page};
for my $heading ( @{$headings} ) {
my $heading_level = $heading->[0];
my $section = $heading->[1];
my $label = $heading->[2];
my $content = "text/$page.xhtml";
# Only deal with head1 and head2 headings.
next if $heading_level > $max_heading_level;
# Add the pod section to the NCX data, Except for the root heading.
$content .= '#' . $section;# if $play_order > 1;
my %options = (
content => $content,
id => 'navPoint-' . $play_order,
play_order => $play_order,
label => $label,
);
$play_order++;
# Add the navpoints at the correct nested level.
my $navpoint_obj = $navpoints[ $heading_level - 1 ];
$navpoint_obj = $navpoint_obj->add_navpoint( %options );
$navpoints[ $heading_level ] = $navpoint_obj;
}
}
}
sub get_css_file {
my ($self,$css_filename) = @_;
my $css_fh;
# If the user supplied the css filename check if it exists.
if ( $css_filename ) {
if ( -e $css_filename ) {
$self->user_css(1);
return $css_filename;
}
else {
warn "CSS file $css_filename not found.\n";
}
}
# If the css file doesn't exist or wasted supplied create a default.
( $css_fh, $css_filename ) = tempfile();
print $css_fh "h1 { font-size: 110%; }\n";
print $css_fh "h2, h3, h4 { font-size: 100%; }\n";
print $css_fh ".code { font-family: Courier; }\n";
close $css_fh;
return $css_filename;
}
sub user_css {
my ($self,$value) = @_;
return $self->{__user_css} if @_ != 2;
$self->{__user_css} = $value;
}
sub add_cover {
my ($self,$epub,$cover_filename) = @_;
# Check if the cover image exists.
if ( !-e $cover_filename ) {
warn "Cover image $cover_filename not found.\n";
return undef;
}
my $cover_basename = basename $cover_filename;
# Add cover metadata for iBooks.
my $cover_id = $epub->copy_image( $cover_filename, "images/$cover_basename" );
$epub->add_meta_item( 'cover', $cover_id );
# Add an additional cover page for other eBook readers.
my $cover_xhtml =
qq[<?xml version="1.0" encoding="UTF-8"?>\n]
. qq[<!DOCTYPE html\n]
. qq[ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n]
. qq[ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n]
. qq[<html xmlns="http://www.w3.org/1999/xhtml">\n]
. qq[<head>\n]
. qq[<title></title>\n]
. qq[<meta http-equiv="Content-Type" ]
. qq[content="text/html; charset=iso-8859-1"/>\n]
. qq[<style type="text/css"> img { max-width: 100%; }</style>\n]
. qq[</head>\n]
. qq[<body>\n]
. qq[ <p><img alt="" src="../images/$cover_basename" /></p>\n]
. qq[</body>\n]
. qq[</html>\n\n];
# Crete a temp file for the cover xhtml.
my ( $tmp_fh, $tmp_filename ) = tempfile();
print $tmp_fh $cover_xhtml;
close $tmp_fh;
# Add the cover page to the ePub doc.
$epub->copy_xhtml( $tmp_filename, 'text/cover.xhtml', linear => 'no' );
# Add the cover to the OPF guide.
my $guide_options = {
type => 'cover',
href => 'text/cover.xhtml',
title => 'Cover',
};
$epub->guide->add_reference( $guide_options );
# Cleanup the temp file.
unlink $cover_xhtml;
return $cover_id;
}
## -------------------------------------------------------------------------- ##
## Change behavour of Pod::Simple::XHTML
## -------------------------------------------------------------------------- ##
{
no warnings 'redefine';
sub Pod::Simple::XHTML::idify {
my ($self, $t, $not_unique) = @_;
for ($t) {
s/<[^>]+>//g; # Strip HTML.
s/&[^;]+;//g; # Strip entities.
s/^([^a-zA-Z]+)$/pod$1/; # Prepend "pod" if no valid chars.
s/^[^a-zA-Z]+//; # First char must be a letter.
s/[^-a-zA-Z0-9_]+/-/g; # All other chars must be valid.
}
return $t if $not_unique;
my $i = '';
$i++ while $self->{ids}{"$t$i"}++;
return "$t$i";
}
sub Pod::Simple::XHTML::start_Verbatim {}
lib/EPublisher/Target/Plugin/EPub.pm view on Meta::CPAN
return @{ $self->{images_to_import} || [] };
};
sub Pod::Simple::XHTML::end_image {
my ($self) = @_;
my %regexe = (
path_quoted => qr/"([^"]+)"(?:\s+(.*))?/s, # =image "C:\path with\whitespace.png" alt text
path_plain => qr/([^\s]+)(?:\s+(.*))?/s, # =image C:\path\img.png alt text
);
my $text = $self->{scratch};
my $regex = $text =~ /^\s*"/ ? $regexe{path_quoted} : $regexe{path_plain};
my ($path,$alt) = $text =~ $regex;
$alt = '' if !defined $alt;
return if !$path;
if ( !-e $path ) {
warn "Image $path does not exist!";
return;
}
my $filename = basename $path;
# save complete path in $self->{images_to_import}
push @{$self->{images_to_import}}, { path => $path, name => $filename };
$self->{scratch} = qq~<p><img src="../images/$filename" alt="$alt" /></p>~;
$self->emit;
};
*Pod::Simple::XHTML::start_L = sub {
# The main code is taken from Pod::Simple::XHTML.
my ( $self, $flags ) = @_;
my ( $type, $to, $section ) = @{$flags}{ 'type', 'to', 'section' };
my $url =
$type eq 'url' ? $to
: $type eq 'pod' ? $self->resolve_pod_page_link( $to, $section )
: $type eq 'man' ? $self->resolve_man_page_link( $to, $section )
: undef;
# This is the new/overridden section.
if ( defined $url ) {
$url = $self->encode_entities( $url );
}
# If it's an unknown type, use an attribute-less <a> like HTML.pm.
$self->{'scratch'} .= '<a' . ( $url ? ' href="' . $url . '">' : '>' );
};
*Pod::Simple::XHTML::start_Document = sub {
my ($self) = @_;
my $xhtml_headers =
qq{<?xml version="1.0" encoding="UTF-8"?>\n}
. qq{<!DOCTYPE html\n}
. qq{ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n}
. qq{ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n} . qq{\n}
. qq{<html xmlns="http://www.w3.org/1999/xhtml">\n}
. qq{<head>\n}
. qq{<title></title>\n}
. qq{<meta http-equiv="Content-Type" }
. qq{content="text/html; charset=utf-8"/>\n}
. qq{<link rel="stylesheet" href="../styles/style.css" }
. qq{type="text/css"/>\n}
. qq{</head>\n} . qq{\n}
. qq{<body>\n};
$self->{'scratch'} .= $xhtml_headers;
$self->emit('nowrap');
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
EPublisher::Target::Plugin::EPub - Use EPub as a target for EPublisher
=head1 VERSION
version 0.6
=head1 SYNOPSIS
use EPublisher::Target;
my $EPub = EPublisher::Target->new( { type => 'EPub' } );
$EPub->deploy;
=head1 METHODS
=head2 deploy
creates the output.
$EPub->deploy;
=head1 YAML SPEC
EPubTest:
source:
#...
target:
type: EPub
author: reneeb
output: /path/to/test.epub
title: The Books Title
cover: /path/to/an/image/for/the/cover.jpg
encoding: utf-8
( run in 3.324 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )