[Keith Vetter] 2014-03-14 : I've been working with eBooks for over a decade now, so I thought I'd share a simple command line tool I use to create an epub from a single text or xhtml file. You need to specify the epub's title, author and content, which can be either an xhtml file or raw text (which will get converted into xhtml). You can also specify a cover image. If the xhtml source has images, you can include them also. The command line usage is: epubCreator "Pride and Prejudice" "Jane Austen" p_and_p.xhtml cover.jpg img1.jpg img2.jpg An http://www.idpf.org/epub/30/spec/epub30-publications.html%|%epub file%|% is essentially a zip file with some metadata files and one or more xhtml files with the book's content. ====== ##+########################################################################## # # epubCreator.tsh -- command line tool to create an epub version 3.0 # file from a single text or xhmtml file, an optional cover image and # a list of 0 or more images # by Keith Vetter 2014-03-14 # # usage: epubCreator Title Author BookContent ?CoverImage? OtherImages... # package require uuid package require fileutil array set EXT {"" "" .png image/png .gif image/gif .jpg image/jpeg .jpeg image/jpeg .svg image/svg+xml} ################################################################ proc Init {rawname title author cover images} { global E set guid [::uuid::uuid generate] set E(rawname) $rawname set E(basename) [file tail [file rootname $E(rawname)]] set E(dirname) [file normalize [file dirname $E(rawname)]] set E(output,tempdir) [file join [::fileutil::tempdir] "epub_$guid"] set E(output,final) [file join $E(dirname) "$E(basename).epub"] set E(epub) EPUB set E(epub,tempdir) [file join $E(output,tempdir) $E(epub)] set E(html,name) "$E(basename).xhtml" set E(html,tempname) [file join $E(epub,tempdir) "$E(html,name)"] set E(opf,name) [file join $E(epub) package.opf] set E(opf,tempname) [file join $E(output,tempdir) $E(opf,name)] set E(mimetype) mimetype set E(mimetype,tempname) [file join $E(output,tempdir) $E(mimetype)] set E(meta-inf) META-INF set E(meta-inf,tempdir) [file join $E(output,tempdir) $E(meta-inf)] set E(meta-inf,tempname) [file join $E(meta-inf,tempdir) container.xml] set E(nav,name) nav.xhtml set E(nav,tempname) [file join $E(epub,tempdir) $E(nav,name)] set E(cover,source) $cover set E(cover,name) [file tail $cover] set E(cover,format) $::EXT([file extension $cover]) set E(images) $images set E(date) [clock format [clock seconds] -gmt 1 -format "%Y-%m-%dT%TZ"] file mkdir $E(output,tempdir) file mkdir $E(meta-inf,tempdir) file mkdir $E(epub,tempdir) set E(guid) "ebook:$guid" set E(title) $title set E(author) $author } proc MakeEpubFiles {} { global E WriteAllData $E(html,tempname) [TextToHtml] WriteAllData $E(mimetype,tempname) "application/epub+zip" WriteAllData $E(meta-inf,tempname) [subst $::CONTAINER_XML] WriteAllData $E(opf,tempname) [MakeOPF] WriteAllData $E(nav,tempname) [subst $::NAV_XHTML] } proc TextToHtml {} { global E set fin [open $E(rawname) r] set data [read $fin] ; list close $fin if {[string first " > \x22 " ' '} $data] ; list regsub -all -line {^$} $data {
} data
set data "[subst $::HTML_TEMPLATE]" ; list
}
return $data
}
proc MakeOPF {} {
global E
set opf [subst $::CONTENT_OPF]
if {$E(cover,source) eq ""} {
regsub -all -line {^.*id_cover.*$} $opf "" opf
} else {
file copy $E(cover,source) $E(epub,tempdir)
}
;# Copy any additional images
set image_items ""
for {set i 0} {$i < [llength $E(images)]} {incr i} {
set iname [lindex $E(images) $i]
file copy $iname $E(epub,tempdir)
set tailname [file tail $iname]
set media $::EXT([file extension $iname])
set id "id_image_$i"
set line "
$data