Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at CFUNITED 2010 (Landsdown, VA) with:

Generating ePub Electronic Books With ColdFusion

By Ben Nadel on
Tags: ColdFusion

Last week, I purchased an ePub book from Borders Books online. It turned out, however, that I had to use Adobe Digital Editions to read it with the given DRM. Having purchased the book with the intent to import it into iBooks, I was necessarily peeved at what I took to be an egregiously underhanded approach to e-commerce (shame on you, Borders). This lead me to start looking up information about ePub books to see if I could somehow strip the DRM and import it into iBooks. In my search I happen to come across a site that mentioned that ePub books were nothing more than a compressed compilation of XHTML pages. When I read this, I immediately thought to myself, "I can build XHTML pages in ColdFusion - maybe I can build ePub books in ColdFusion." And so, after a few hours, here's the product of my first round of effort.


 
 
 

 
 
 
 
 

First, I want to just given a huge shout-out to JediSaber.com; the underlying assets of this ePub project are based on the information and sample ePub book that I found in their ePub tutorial.

ColdFusion has a long history of making document generation a pain-free endeavor. I wanted to extend that mindset as much as possible; as such, I tried to model my ColdFusion ePub custom tags on the existing CFDocument tags (for ColdFusion PDF generation). Right now, there are only three custom tags available: Book, Section, and StyleSheet. Book, like CFDocument, is the parent custom tag that is used to define the book container and meta properties (Title, Author, Publisher, etc.). Section, like CFDocumentSection, is used to define individual, navigable areas of the book. StyleSheet allows the user to provide their own, optional CSS styling for the embedded XHTML content.

As with the CFDocument tag, I wanted to make embedding images in an ePub book a no-brainer activity. As such, the ColdFusion ePub custom tags allow image paths to be relative to the calling context. That is, images that are relatively-pathed to the CFML invoking the ePub custom tags will be imported into the ePub book automatically. This functionality is due entirely to the brilliant work of Elliott Sprehn, who showed me how to get the template path of the calling context.

That said, let's take a look at an example page. Here, I am compiling a ePub book with a list of movies. Notice that each movie is defined in its own epub:Section tag, which will make it part of the native table of contents.

  • <!---
  • Import the ePub name-space for creating our ePub format digital
  • book in ColdFusion. This is essentially a collection of XHTML
  • files and configuration data. This project will abstract this
  • level of detail.
  • --->
  • <cfimport prefix="epub" taglib="../../library/epub/" />
  •  
  •  
  • <!---
  • We are going to use ColdFusion custom tags to define the
  • elements of the book. These are just an abstraction layer above
  • the underlying component layer.
  •  
  • NOTE: We are supplying a tempDirectory value for "scratch"
  • space. If we excluded it, the ePub library would be using the
  • getTempDirectory() value instead.
  • --->
  • <epub:book
  • title="Movies Worth Watching"
  • author="Ben Nadel"
  • publisher="Kinky Solutions"
  • filename="#expandPath( './movies.epub' )#"
  • overwrite="true"
  • tempdirectory="#expandPath( './temp/' )#"
  • convertimagestopng="true">
  •  
  •  
  • <!--- This is an (optional) stylesheet override. --->
  • <epub:stylesheet>
  •  
  • body {
  • font-family: "helvetic nueue" ;
  • }
  •  
  • body.titlePage h1,
  • body.titlePage h2 {
  • text-align: center ;
  • }
  •  
  • p {
  • margin: 0px 0px 0px 0px ;
  • text-indent: 0.3in ;
  • }
  •  
  • p.moviePoster {
  • margin: 0px 0px 20px 0px ;
  • text-align: center ;
  • }
  •  
  • p.moviePoster img {
  • border: 10px solid #CCCCCC ;
  • }
  •  
  • </epub:stylesheet>
  •  
  •  
  • <epub:section class="titlePage">
  •  
  • <h1>
  • Movies Worth Watching
  • </h1>
  •  
  • <h2>
  • by Ben Nadel
  • </h2>
  •  
  • </epub:section>
  •  
  •  
  • <epub:section>
  •  
  • <h1>
  • Preface
  • </h1>
  •  
  • <p>
  • I've always loved movies. For as long as I can remember,
  • movie watching has been a hugely rewarding part of my
  • life. I find that almost all movies have something in
  • them that is rewarding, from slap-stick comedies, to
  • coming of age dramas, to documentaries.
  • </p>
  •  
  • <p>
  • In this book, I'd like to sift through them all and
  • present you with the cream of the crop - the movies
  • are defintely worth watching.
  • </p>
  •  
  • </epub:section>
  •  
  •  
  • <epub:section>
  •  
  • <h1>
  • Terminator 2
  • </h1>
  •  
  • <p class="moviePoster">
  • <img
  • src="./images/terminator_2.jpg"
  • width="213"
  • height="300"
  • />
  • </p>
  •  
  • <p>
  • This has to be one of the best movies of all time. It is
  • one of the few sequels that has surpased the original by
  • leaps and bounds. While T1 was a great movie, T2 is just
  • in a different league.
  • </p>
  •  
  • </epub:section>
  •  
  •  
  • <epub:section>
  •  
  • <h1>
  • When Harry Met Sally
  • </h1>
  •  
  • <p class="moviePoster">
  • <img
  • src="images/when_harry_met_sally.jpg"
  • width="203"
  • height="300"
  • />
  • </p>
  •  
  • <p>
  • Perhaps one of the greatest romantic comedies ever made,
  • this movie.....
  • </p>
  •  
  • </epub:section>
  •  
  •  
  • </epub:book>
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <h1>
  • Your ePub Book Has Been Generated!
  • </h1>
  •  
  • <p>
  • Your ePub file awaits: <a href="./movies.epub">movies.epub</a>.
  • </p>

The epub:Book tag allows the programmer to provide meta-data about the book. But, it also allows the programmer to provide some addition directives. By default, the ColdFusion ePub project will try to use the getTempDirectory() location as its scratch disk (for intermediary ePub assets). You can choose to override this, however, as I have done with the tempDirectory attribute.

Additionally, you can tell the ColdFusion ePub project to convert the images to PNG format on the fly. According the ePub tutorial that I read, PNG images are the only ones officially supported in the ePub Standard. While some ePub readers may support additional file types, a reader like Adobe Digital Editions (which I used for testing) only supports PNG images.

The content of each epub:Section tag must be valid XHTML. That is, it must be able to be parsed into XML. This is necessary because the user-provided content is merged into an XHTML template. Furthermore, the title of each section (or chapter) is automatically extracted from the first "h1" element node using an xmlSearch() XPath query.

That said, running the above code generates the following ePub book (movies.epub).


 
 
 

 
 Movies Worth Watching - An ePub book generated by ColdFusion and Ben Nadel. 
 
 
 

Since this is my first effort at creating ePub books in ColdFusion, I am not completely satisfied with how the ColdFusion custom tags have been architected. Furthermore, I know nothing about how to create a nicely formatted table of contents (TOC) that is linkable to sections of the generated ePub book. Hopefully, that kind of functionality will be added with time. As with all things "ColdFusion", however, I just wanted to keep this as easy-to-use as possible.

ColdFusion ePub Project On GitHub

I'm not gonna lie - I want to be one of the cool kids. Can I hang with y'all, can I roll with y'all? As such, I'm going to start putting all of my little side-projects on my GitHub account. This way, if anyone has any ideas that they want to contribute, a centralized repository is supposed to make that kind of stuff relatively simple (says the guy who has no idea how to branch or fork yet).



Reader Comments

Excellent work Ben! This is a great project. I work for a small non-profit publishing company and this kind of stuff is exactly what I'm looking for. Now... Who's up for the challenge of converting PDFs to ePub using ColdFusion?

I thought ePUB was a standard and that all but the KIndle could read books in that format. Am I wrong?

@Josh,

Thanks! As far as PDF to ePub, I have to assume that is doable. I believe I have seen people pull images and text out of PDFs; which, theoretically, could be re-packaged as ePub sections. Though, @Ray has way more PDF experience than I do. To this day, I think I've only ever used CFDocument to create PDFs.

@Anna,

Thanks :)

@Ben,

I am not 100% sure. I did try to open this in Kindle and it definitely said No. I think it is becoming a generally-held standard though, from what I've read. But I can't speak from authority on that.

@Ben [Nadel],

As I recall, before he worked for Adobe, Ben Forta published a PDF-creation custom tag immediately prior to CF offering cfdocument format="pdf". I mean right away Adobe started offering a native CF solution to the same problem.

Add to that the fact that the code between cfdocument and /cfdocument is already supposed to be HTML. That would seem to make ePub support relatively easy to implement. So I wouldn't be at all surprised if cfdocument started supporting format="epub" as early as 9.0.2.

Adobe doesn't like it when customers create new features faster than they do! :-)

@WebManWalking,

You make a good point. CFDocument is already html-oriented. It probably wouldn't be too much work to add type="epub" to the mix. The question might simply be one of demand - is there a demand for creating on-the-fly ePub books? I would assume that Adobe apps like InDesign can already do things like this natively.

Time shall tell. Mostly, I just wanted to see if it was possible; and, as always, ColdFusion made it relatively simple.

@Ben,

I can foresee format="epub" being used exactly like format="pdf", in exactly the same sorts of situations.

At my site, we typically generate PDF for reports and documentation. You want the document to be relatively static, as it represents what things were at a particular point in time. And yet the document itself has to be generated, based on stuff that changes over time. But since PDF can already be imported and read on an iPad, you're right, the demand for ePub might be small.

The more I think about it, the main benefit of ePub over PDF would be to authors: generating something they could offer for sale in electronic bookstores. (PDF is too tacky for that market.)

Maybe YOU could use the ePub custom tags to put together a CF/jQuery book for iBookstore. You'd probably want to create a publishing house name and logo, to make it look professional. Then offer it for sale via Apple. I think they take a 30% cut. Not bad.

@WebManWalking,

I haven't read too many PDFs on my iPad. One of the things that I love love love love about reading ePub books on the iPad is the ability to highlight and leave notes. If that wasn't available on a PDF for some reason (I've not checked this), that would be a big reason for me to want things delivered as ePub format.

@Ben,
There are 3rd party PDF readers for the iPad that allow annotations and highlighting if you are looking for it.

I'm really looking forward to working with ePub 3.0 someday. ePub 3 is supposed to support HTML5 and embedded JavaScript. I'm not an expert in the matter, but it sure sounds cool to be able to use jQuery in a interactive eBook based on HTML standards.

@Ben,

I typically have reference material in the PDFs Collection section of my iBooks: Unicode charts, API references, etc. So I was able to check this for you.

Highlighting and notes are dependent on being able to select text. In my tests just now, I wasn't able to select text in any of my PDFs. Neither double-tapping nor dragging worked. So no, you can't highlight or add notes unless it's an ePub.

Another difference was text enlargement. In ePub, you get small-letter-A-large-letter-A icon that allows you bump up the font size while keeping the page size the same. The icon appears in the normally-hidden row of controls at top of page. It's absent in PDFs. You can still enlarge/shrink pages, but you have to do so with unpinch/pinch, which changes the whole page's size as well. This puts some enlarged text off-screen, and you have to drag the page around left and right to see everything.

So ePub's definitely the way to author. :-)

So when are you going to put the mobi code on git? ;) You make us all look lazy which describes me to a large degree. I love your experiments like this one.

@Josh,

It will be really interesting to see what people do with embedded JavaScript in books. Honestly, I am not even sure what I *would* try to do with it, should it be available. The only thing that I can think of right now would be to have code samples actually embedded directly in the book. Reading something about JavaScript? Why not a button that says, "Click here to Run"? That would be cool!

@WebManWalking,

Thanks for checking on the PDF stuff. I think the only thing I ever tried to read in PDF on the iPad, now that I am thinking about it, was some sort of Google Best Practices booklet on SEO or something. What I remember was that the pages never sized properly. I had to constantly zoom in and pinch and pan to read the PDF. Since ePub is just XHTML under the hood, it definitely has some serious advantages.

@Roger,

I just did a quick Google search and it looks like the concepts behind Mobi and ePub are actually very similar. They both appear to be built on the idea of underlying XHTML pages. I'll see what I can do ;)

Calibre is actually what I use to convert ePub books to .mobi for reading on the Kindle. It does a pretty good job of conversion and has a lot of options available.

No, the Kindle does not currently open ePub books directly. There have been rumors going around for quite some time that it will eventually do so, particularly with the upcoming release of ePub version 3, but with the existence of Calibre and other third-party tools, there's no immediate need for it.

I finally brought in my July issue of Linux Journal to share information from it. There is a large article (pages 54-57) on using Sigil (http://code.google.com/p/sigil/) to create EPub books. It gives detail on the HTML and CSS to do things like drop caps and pull quotes. In addition, there are some resources:

EBook Layout: http://www.members.shaw.ca/nathanieldesign/book_layout

EPub Zen Garden: http://epubzengarden.com/contribute

EBook Programs, Plugins, Conversions: http://wiki.mobileread.com/wiki/E-book_conversion

Hope these help you or someone getting your code to add even more features (and I might do a Git clone just to see if there's something I can contribute).

Keep up the great blogging, Ben!

Thanks a lot for sharing this info. I downloaded u'r code. But when I ran, it throws an error that,

"An exception occurred when performing a file operation copy on files /cfusion/wwwroot/CFIDE/epub/library/epub/template/META-INF/container.xml and /cfusion/wwwroot/CFIDE/epub/examples/movies/temp//BFD8E992-BCC9-9FA0-043632E2CB727793///cfusion/wwwroot/CFIDE/epub/library/epub/template/META-INF/container.xml.


Since it's a copying, I hardcoded the related code as destination="#local.scratchDirectory#/container.xml"

It results in another error that

C:/ColdFusionZeus/cfusion/wwwroot/CFIDE/epub/examples/movies/temp/C0372C8A-DA30-0728-A142A3F4E2E6385F/OEBPS/images/terminator_2_61FCB77303FFA291BE5CF57E584F22B6.png (The system cannot find the path specified)

Any suggestions. Thanks in advance.

Sunil

@David L, @David D,

The Calibre stuff looks pretty cool. Actually, if I couldn't get the ColdFusion custom tags to work, that was gonna be the next thing that I tried. I've just been a bit side-tracked (hard for me to stay concentrated on any one thing too long).

@Tony,

I love the ida of the ePub Zen Garden! What an awesome resource. I'll have to check that out. CSS is hard; and I'm sure that CSS for a new device contraint (ePub) is always harder when it comes to working out the kinks. Having a repo of some tried and true styles is definitely awesome. Thanks!

@Sunil,

Do the JPGs (being referenced in the XHTML) exist on your local system? It looks like it might be having trouble finding them?

I enjoy your site and it lifts my spirits. I was wondering if you could advise me on my best options on a project. At my website, there's a .pdf that represents the first chapter of James Joyce's Ulysses--marked up. And there's a lot and they are long.

.pdf does have the layout I like, but I'd sure like to get this into .epub so that I could try to program in notes. Is this possible or am I dreaming?

Ben Logan

@Josh,

Simple, install Calibre ebook manager, and use cfExec to call caliber routines (which it exposes as a service) giving the PDF to input and the name, *output format* (with the default being epub,), and directory for the output and voila, Simple Matter Of Programming(tm)!