Creating eBooks in ePub format using Perl on Mac OS X from database with images
Post ReplyCreating eBooks in ePub format using Perl on Mac OS X from database with imagesPosted: Thursday, September 26, 2013 [02:52:44] - 1
Creating open source eBook file is a breeze on Mac using Perl. It resizes images, reads data from database (in my case hash file). ## 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"; use strict; use EBook::EPUB; ## INSTALL EBook::EPUB FROM >cpan by entering: install EBook::EPUB at >cpan prompt our %infodata; our $alllinks; 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); unless(-d "/final.dir/epub/$newdir") {`mkdir -p /final.dir/epub/$newdir`;} my $file = $l; eval {require "/path-to-data-file/$file.txt"}; unless($infoName) {print "No data in \"/path-to-data-file/$file.txt\"\n"; my @mnnm = split(/ /,$infoName); foreach $ppr (@mnnm) {$infoNamePr .= "$spr$ppr"; if(length($templ) > 12) {$templ=''; } ## 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"); 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 $imagen = "/temp.dir/temp.epub/$imagename"; $imr = `anytopnm $image`; 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`; } else { `convert -density 72 $image $imagen`; `composite -tile /path-to-data-file/watermark.png $imagen $imagen`; } $image=$imagename; $imagen = $imagename; delete $infodata{$p}{'image'}; $dtitle=$p; if($infodata{$p}{'info'}{'data'}) {$infodata{$p}{'info'}{'data'} =~ s/\&//; ## 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; $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/\&//; 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=(); } ############################################ 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) = @_; ($width,$height)=$pnm=~m#^P\d+\s+(\d+)\s+(\d+)\s+\d+\s#ois; } ## END SUB PNM SIZE ## List of files data (hash) file format: 'path.to.data.file/data.file1' => { }, 'path.to.data.file/data.file2' => { } Data file linked from list of files has above: %infodata=( 'My Great Information' => { }, 'My Great other Information' => { } ); instead of txt hash files it could be any accessible database. |