AppleScript C Perl Shell Xcode Other

Creating eBooks in ePub format using Perl on Mac OS X from database with images

Post Reply
coding / perl     Views: 2316Prev .. Next
Creating eBooks in ePub format using Perl on Mac OS X from database with imagesPosted: Thursday, September 26, 2013 [02:52:44] - 1
rootPosted by:rootMember Since:
June 16 2010
Posts: 356
Creating open source eBook file is a breeze on Mac using Perl. It resizes images, reads data from database (in my case hash file).
View Code#!/usr/bin/perl
## Required optional for Mac OS X software:
## ImageMagick
## EBook::EPUB
## IF USED BY DAEMON - SET THE ENV PROPERLY
unless($ENV{'SECURITYSESSIONID'}) {
$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local:/usr/local/bin:/opt/local/bin';
}
## MAKE SURE DATA FILE PRESENT
unless(-f "/your_data_file.txt") {exit(0);}
our %maindata;
eval {require "/your_data_file.txt"};
if($@) {print "$@\n";exit(0);} ## EXIT ON ERROR

use strict;
use EBook::EPUB; ## INSTALL EBook::EPUB FROM >cpan by entering: install EBook::EPUB at >cpan prompt

our %infodata;our $infoName;our $Remarks;our %copy;our %imcopy;our $filepub;our $infoNamePr;our $imr;our $dtitle;
our $alllinks;our $noblt;our $newdir;our %sendtoserver;our $dirname;
unless(-d "/temp.dir/temp.epub") {`mkdir -p /temp.dir/temp.epub`;} ## CREATE TEMP FOLDER IF NOT PRESENT
unless(-d "/final.dir/epub") {`mkdir -p /final.dir/epub`;} ## CREATE FINAL FOLDER IF NOT PRESENT
foreach my $l (keys (%maindata)) { ############# FOREACH FILE ########## <<<
my @kim = split(/\//,$l);$filepub=$l;pop(@kim);$newdir = join '/',@kim;@kim=();
unless(-d "/final.dir/epub/$newdir") {`mkdir -p /final.dir/epub/$newdir`;}
`rm -rf /temp.dir/temp.epub/*`; ## REMOVE OLD FILES IN TEMP FOLDER
my $file = $l;
eval {require "/path-to-data-file/$file.txt"};
unless($infoName) {print "No data in \"/path-to-data-file/$file.txt\"\n";exit(0);}
my @mnnm = split(/ /,$infoName);my $templ;my $spr='';my $ppr='';$infoNamePr='';
foreach $ppr (@mnnm) {$infoNamePr .= "$spr$ppr";$templ .= "$spr$ppr";
if(length($templ) > 12) {$templ='';$spr="\n";} else {$spr=' ';}
} ## FOREACH WORD END
## CREATE COVER FOR eBook - EXPERIMENT WITH IT FIRST
`convert -size 480x600 gradient: -sigmoidal-contrast 6,50% -fill white -stroke black -font Helvetica -pointsize 80 -gravity center -annotate 0 'Parts\n\n\n' -font Helvetica -pointsize 40 -gravity center -annotate 0 '\n$infoNamePr' /temp.dir/temp.epub/cover.jpg`;

## CREATE CSS FILE
my $css = "\* {font:1em/18px \"Courier New\", Courier, mono;color:#000; }
body {font:1em/18px \"Courier New\", Courier, mono;color:#000;background-color:#fff;}
ul, ol, li {font:.8em/10px \"Courier New\", Courier, mono;color:#000;font-weight:bold; }
.notes {font:12px/1em \"Courier New\", Courier, mono;}
.mtbl td {background-color:#f9f9f9;padding-right:5px;padding-left:5px;font:11px/.9em \"Courier New\", Courier, mono;}
.hd {background-color:#eeeae9;padding-right:5px;padding-left:5px;font:14px/1.1em \"Courier New\", Courier, mono;font-weight:bold;}
.mlink {color:#1f89e8;font-weight:bold;text-decoration:none;font-family: \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;margin-top:15px;}
.alist {margin-left:15px;font:.9em/12px \"Courier New\", Courier, mono;color:#000;font-weight:bold; }
h1 {font-weight:bold;font:16px/1.2em \"Courier New\", Courier, mono;}
.brk {page-break-after:always;}";
open(CSS,">/temp.dir/temp.epub/style.css");print CSS $css;close(CSS);

foreach my $p (sort keys(%infodata)) { ######
print "Rec: $p\n";
delete $infodata{$p}{'thumb'};
## ADOPTING IMAGES FROM ORIGINALS AND ADDING A WATERMARK (FROM watermark.png FILE)
my $image = $infodata{$p}{'image'}{'imageFile'};
my $w = $infodata{$p}{'image'}{'width'};
my $h = $infodata{$p}{'image'}{'height'};
my @kim = split(/\//,$image);my $imagename = pop(@kim);pop(@kim);$dirname=join '/',@kim;@kim=();
my $imagen = "/temp.dir/temp.epub/$imagename";$image = "/path-to-data-file/$image";#$imagen =~ s#\.\w{3}$#\.png#;
$imr = `anytopnm $image`;($w,$h) = &pnmsize($imr);$imr='';
if($w > 600 || $h > 600) { ## RESIZE IMAGE IF TOO BIG
`convert -density 72 $image -resize 600x600 $imagen`;
`composite -tile /path-to-data-file/watermark.png $imagen $imagen`;
$imr = `anytopnm $imagen`;($w,$h) = &pnmsize($imr);$imr='';
} else {
`convert -density 72 $image $imagen`;
`composite -tile /path-to-data-file/watermark.png $imagen $imagen`;
}
$image=$imagename;$imcopy{$imagen}=$image;
$imagen = $imagename;
delete $infodata{$p}{'image'};
$dtitle=$p;
if($infodata{$p}{'info'}{'data'}) {$infodata{$p}{'info'}{'data'} =~ s/\&//;$infodata{$p}{'info'}{'data'} =~ s/\&/\&\;/g;
$dtitle .= " - $infodata{$p}{'info'}{'data'}";delete $infodata{$p}{'info'}{'data'};delete $infodata{$p}{'info'};}
## CREATE DATA TABLE
my $ttable;
foreach my $n (sort numb keys %{$infodata{$p}}) {
if($n eq 'info') {next;}
$ttable .= "<tr>\n\t<td>\n$n\n</td>\n\t<td>\n$infodata{$p}{$n}{'part number'}\n</td>\n\t<td>\n$infodata{$p}{$n}{'description'}\n</td>\n\t<td>\n$infodata{$p}{$n}{'quantity'}\n</td>\n\t<td>\n$infodata{$p}{$n}{'notes'}\n</td>\n</tr>\n";
} ## FOREACH NUMBER
my $fname = $dtitle;$fname =~ s/^W+//;$fname =~ s/W+$//;$fname =~ s/\W//g;
$dtitle =~ s/\&//;$dtitle =~ s/\&/\&\;/g;$ttable =~ s/\&//;$ttable =~ s/\&/\&\;/g;

$ttable = "<table class=\"mtbl\" summary=\"Parts listing\">
<tr>\n<td class=\"hd\">\n\#\#\n</td>\n\t<td>\nPart \#\n</td>\n\t<td>\nDescription\n</td>\n\t<td>\nQty\n</td>\n\t<td>\nNotes\n</td>\n</tr>
$ttable</table>";
$dtitle =~ s#\"##g;
$alllinks .= "<li>\n\t<a href=\"$fname.xml\">$dtitle</a>\n</li>\n";
open(TXH,">/temp.dir/temp.epub/$fname.html");
print TXH <<EOH;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd";>
<html xmlns="http://www.w3.org/1999/xhtml";>
<head>
<link rel="stylesheet" type="text/css" href="style.css" media="all"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>$dtitle</title>
</head>
<body>
<h1>$dtitle</h1>
<img class="brk" width="$w" height="$h" src="$imagen" alt="$dtitle"></img>
$ttable
<p><a class="mlink" href="http://www.your-site.com/$dirname/">Your Site Link</a></p>
</body>
</html>
EOH
close(TXH);
`tidy -q -asxml /temp.dir/temp.epub/$fname.html >/temp.dir/temp.epub/$fname.xml`; ## CONVERT HTML TO XML FORMAT
$copy{"/temp.dir/temp.epub/$fname.xml"}="$fname.xml";
$ttable='';
} ## FOREACH PART END ######################
$alllinks =~ s/\&//;$alllinks =~ s#\&#\&#g;

if($Remarks) {$Remarks =~ s#\n#<br />\n#g;
open(TXH,">/temp.dir/temp.epub/notes.html");
print TXH <<EOH;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd";>
<html xmlns="http://www.w3.org/1999/xhtml";>
<head>
<link rel="stylesheet" type="text/css" href="style.css" media="all"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>$infoName Notes</title>
</head>
<body>
<h1>$infoName Notes</h1>
<p class="notes">$Remarks</p>
</body>
</html>
EOH
close(TXH);
`tidy -q -asxml /temp.dir/temp.epub/notes.html >/temp.dir/temp.epub/notes.xml`; ## CONVERT HTML TO XML FORMAT
$copy{"/temp.dir/temp.epub/notes.xml"}="notes.xml";
$alllinks = "<li>\n\t<a href=\"notes.xml\">Info Notes</a>\n</li>\n$alllinks";
} ## END REMARKS PRESENT

open(TXH,">/temp.dir/temp.epub/page1.html");
print TXH <<EOH;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd";>
<html xmlns="http://www.w3.org/1999/xhtml";>
<head>
<link rel="stylesheet" type="text/css" href="style.css" media="all"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>$infoName Table of Contents</title>
</head>
<body>
<h1>$infoName Table of Contents</h1>
<ol class="alist">
$alllinks</ol>
</body>
</html>
EOH
close(TXH);
`tidy -q -asxml /temp.dir/temp.epub/page1.html >/temp.dir/temp.epub/page1.xml`; ## CONVERT HTML TO XML FORMAT

## NOW CREATE ACTUAL EPUB FILE
my $epub = EBook::EPUB->new;
$epub->add_title("$infoName");
$epub->add_language('en');
$epub->copy_stylesheet('/temp.dir/temp.epub/style.css', 'style.css'); ## ADD CSS FILE
my $chapter_id = $epub->copy_xhtml('/temp.dir/temp.epub/page1.xml','page1.xhtml'); ## ADD TABLE OF CONTENTS
my $navpoint = $epub->add_navpoint(
label => "Chapter 1",
id => $chapter_id,
content => 'page1.xhtml',
play_order => 1
);
my $mypages;
foreach $mypages (sort keys(%imcopy)) {
$epub->copy_file($mypages,$imcopy{$mypages}, 'image/jpeg'); ## INCLUDE ALL IMAGES
}
foreach $mypages (sort keys(%copy)) { ## INCLUDE ALL PAGES
$epub->copy_xhtml($mypages, $copy{$mypages},
linear => 'no'
);
}
my $cover_id = $epub->copy_image('/temp.dir/temp.epub/cover.jpg', 'cover.jpg'); ## ADD EBOOK COVER
$epub->add_meta_item('cover', $cover_id);
$epub->pack_zip("/final.dir/epub/$filepub.epub");
%copy=();%imcopy=();$alllinks='';
} ############################################ FOREACH FILE END ######## <<<
`rm -rf /temp.dir/temp.epub`; ## REMOVE TEMP FOLDER WHEN DONE

sub numb {$a <=> $b;}

sub pnmsize { ## GET IMAGE SIZE SUB-ROUTINE
my($pnm) = @_;
my ($width,$height);
($width,$height)=$pnm=~m#^P\d+\s+(\d+)\s+(\d+)\s+\d+\s#ois;
return ($width,$height) if ($width && $height);
} ## END SUB PNM SIZE ##

List of files data (hash) file format:
View Code%maindata=(
'path.to.data.file/data.file1' => {
'dataName','My Great Information',
'Records','15'
},
'path.to.data.file/data.file2' => {
'dataName','My Great other Information',
'Records','34'
}

Data file linked from list of files has above:
View Code$infoName='Title for your eBook';
%infodata=(
'My Great Information' => {
'thumb' => {
'height','168',
'thumbFile','path.to.thumbnail1.jpg',
'width','120'
},
'image' => {
'height','800',
'imageFile','path.to.image1.jpg',
'width','572'
},
'1' => {
'description','Description 1',
'part number','Part # 1',
'quantity','8'
},
'2' => {
'description','Description 2',
'part number','Part # 2',
'quantity','5'
'info' => {
'data','additional/optional info'
}
},

'My Great other Information' => {
'thumb' => {
'height','150',
'thumbFile','path.to.thumbnail2.jpg',
'width','120'
},
'image' => {
'height','800',
'imageFile','path.to.image2.jpg',
'width','572'
},
'1' => {
'description','Description 1',
'part number','Part # 1',
'quantity','8'
},
'2' => {
'description','Description 2',
'part number','Part # 2',
'quantity','5'
'info' => {
'data','additional/optional info'
}
}
);

instead of txt hash files it could be any accessible database.There's no place like ~
coding / perlPrev .. Next
 
Post Reply
Home - Coding: AppleScript C Perl Shell Xcode Other
Our Telegram Group