EFM - Epub for Monocle in Javascript

1,284 views
Skip to first unread message

Robert Schroll

unread,
Jan 21, 2013, 2:14:26 AM1/21/13
to monoc...@googlegroups.com
Hi all,

More for my own amusement than anything else, I've spent some time
trying to build a pure-Javascript epub reader based on Monocle. It's
basically working now, so I split out the Javascript part into what I'm
calling EFM, Epub for Monocle. It's available on Github
(https://github.com/rschroll/efm), and you can see a reader in action
(http://rschroll.github.com/efm).

Maybe this will be useful for someone out there. I'm not planning on
spending a lot of time developing this further, but I will take a look
at any pull requests or patches I get.

As I note in the README, the biggest problem I had was dealing with
auxiliary files, like images and stylesheets. Monocle ensures that the
main HTML files are requested through the book data object, but
references to other content are left unchanged. Thus, the browser
requests them from the same place as the container HTML file, where
these files aren't.

I didn't see a way around this within Monocle (if there is, please point
it out!), so I ended up rewriting URLs in the content files to be data
URLs encoding the contents of the auxiliary files. This is enough for
the Epub files that I've tested, but if one auxiliary file refers to
another (a stylesheet linking to a font or image, say), that second file
will be MIA. Any clever ideas on how to get around this would be
appreciated.

Let me know what you think,
Robert

Joseph Pearson

unread,
Jan 22, 2013, 1:29:30 AM1/22/13
to monoc...@googlegroups.com
Very nice! Pretty fast too. I've idly mentioned the possibility of this fully client-side approach for a few years, but this is the first time I've seen it implemented as a library, so kudos.

You're right about the problem with non-component files (or 'resources') in the package — the URLs in the EPUB assume that they are being served over something that functions like a web server, relative to the iframe's URL. Since EPUB makes that assumption, Monocle does too. Which means you have to do pretty much what you suggest: parse all the content for file references and replace them with data-uris or the like. I know Aron Woost did this to achieve offline caching with his Monocle implementation (whereas Booki.sh and OverDrive Read use the applicationCache to get offline support, which isn't helpful to you). You could ping @aronwoost on GitHub for some ideas here.

(There is a much more outlandish idea, leveraging HTML5 features like WebSockets to create a client-side webserver — this would be fun, and I'm sure I've seen a project like that, but I've no idea whether it would work end-to-end.)


Thanks for sharing!

— J





--





--
Joseph Pearson | software inventor | inventivelabs.com.au | +61394163198

Luis Oliveira

unread,
Jan 22, 2013, 8:19:21 AM1/22/13
to monoc...@googlegroups.com

First,  I would like to congrat Robert for EFM. Nice job!

 

Regarding the Robert question about non-component files (which URLs should be rewritten), I am involved in a project that use Monocle and recently we implemented a similar task with success (saving locally the book resources and loading them when book is opened). With binary files, it’s easy (just use data URLs). However, we found some issues when embedding SVG files. IMO, it’s the main issue in this process. Regarding auxiliary files that refers another files (e.g. a CSS that has references to images or fonts), we implemented a script that “resolves” all these references in order to CSS work “stand alone” (again, using data URLs). And it works…

 

Regarding Joseph idea of using Websockets to create a client side server, it’s interesting but the main issue is that Websockets are not supported in Android browsers - http://caniuse.com/#feat=websockets


Luis

--
 
 

rsch...@gmail.com

unread,
Jan 22, 2013, 9:49:31 PM1/22/13
to monoc...@googlegroups.com
On Tuesday, January 22, 2013 10:19:21 AM UTC-3, lmvco wrote:

First,  I would like to congrat Robert for EFM. Nice job!

Thanks!

 Regarding the Robert question about non-component files (which URLs should be rewritten), I am involved in a project that use Monocle and recently we implemented a similar task with success (saving locally the book resources and loading them when book is opened). With binary files, it’s easy (just use data URLs). However, we found some issues when embedding SVG files. IMO, it’s the main issue in this process.

I tested one epub with embedded SVG files, and it seemed to work for me.  But I didn't check this out very closely.

Regarding auxiliary files that refers another files (e.g. a CSS that has references to images or fonts), we implemented a script that “resolves” all these references in order to CSS work “stand alone” (again, using data URLs). And it works…

Cool.  Do you have an algorithm to work out the dependencies of these auxiliary files so they can be encoded in the correct order?  Or do you just do the images and fonts first, and assume that that SVG files only reference those and the CSS files only reference images, fonts, and SVG files?  (I'm sure the latter would be enough 99.9% of the time.)

 On 22 January 2013 06:29, Joseph Pearson <jos...@inventivelabs.com.au> wrote:

Very nice! Pretty fast too. I've idly mentioned the possibility of this fully client-side approach for a few years, but this is the first time I've seen it implemented as a library, so kudos.
Thanks for the kind works, and for the link.  I hope it turns out to be useful for people.

Robert

Luis Oliveira

unread,
Jan 27, 2013, 11:12:43 AM1/27/13
to monoc...@googlegroups.com
On 23 January 2013 02:49, <rsch...@gmail.com> wrote:
On Tuesday, January 22, 2013 10:19:21 AM UTC-3, lmvco wrote:

First,  I would like to congrat Robert for EFM. Nice job!

Thanks!

 Regarding the Robert question about non-component files (which URLs should be rewritten), I am involved in a project that use Monocle and recently we implemented a similar task with success (saving locally the book resources and loading them when book is opened). With binary files, it’s easy (just use data URLs). However, we found some issues when embedding SVG files. IMO, it’s the main issue in this process.

I tested one epub with embedded SVG files, and it seemed to work for me.  But I didn't check this out very closely.

Regarding auxiliary files that refers another files (e.g. a CSS that has references to images or fonts), we implemented a script that “resolves” all these references in order to CSS work “stand alone” (again, using data URLs). And it works…

Cool.  Do you have an algorithm to work out the dependencies of these auxiliary files so they can be encoded in the correct order?  Or do you just do the images and fonts first, and assume that that SVG files only reference those and the CSS files only reference images, fonts, and SVG files?  (I'm sure the latter would be enough 99.9% of the time.)

No, I didn't create an algorithm to deal with dependencies. Currently, I just replace images and fonts (needs to improve and cover other scenarios).

 

 On 22 January 2013 06:29, Joseph Pearson <jos...@inventivelabs.com.au> wrote:

Very nice! Pretty fast too. I've idly mentioned the possibility of this fully client-side approach for a few years, but this is the first time I've seen it implemented as a library, so kudos.
Thanks for the kind works, and for the link.  I hope it turns out to be useful for people.

Robert

--
 
 

sangari

unread,
Mar 6, 2013, 2:54:06 AM3/6/13
to monoc...@googlegroups.com
hai,

  Thanks for your code.but it is not working in ipad webview can u help me.

Martijn Joosse

unread,
Mar 26, 2013, 6:01:31 AM3/26/13
to monoc...@googlegroups.com
Hi, thanks for your script. 

How do I get this working with ePub-files I already have on my webserver, instead of uploading them?

Martijn


Op maandag 21 januari 2013 08:14:26 UTC+1 schreef Robert Schroll het volgende:

Robert Schroll

unread,
Mar 26, 2013, 11:33:13 AM3/26/13
to monoc...@googlegroups.com
On Tue, Mar 26, 2013 at 6:01 AM, Martijn Joosse <jmjo...@gmail.com>
wrote:
> How do I get this working with ePub-files I already have on my
> webserver, instead of uploading them?
>

Well, the first question to ask is, why would you want to use EFM if
your epubs are already on the webserver?  You could have your
webserver convert the epub files to book data objects and serve those
directly to Monocle.  This way, you won't be restricted by client
capabilities.  If you're planning on serving those files often, you
could do the conversion once on your desktop and put the book data
objects on the webserver as javascript files.  Now the client running
Monocle can get the book data object it wants without waiting for any
conversion to take place.

But if you want to use EFM, you probably could.  The first argument to
the Epub object doesn't actually need to be a File object; it can be a
Blob object.  Here are two StackOverflow questions about converting
remote resources to Blobs:
http://stackoverflow.com/questions/6165266/downloading-mp3-files-using-html5-blobs-in-a-chrome-extension/11518906#11518906
http://stackoverflow.com/questions/11519469/downloading-files-using-html5-blobs-in-a-chrome-extension
Note that BlobBuilder was recently deprecated, so you may want to
translate these solutions:
http://updates.html5rocks.com/2012/06/Don-t-Build-Blobs-Construct-Them

I haven't tried any of these, but it looks rather straightforward, if
this is what you want to do.  But I'm pretty sure it isn't.

Robert



Jayavelu V

unread,
Oct 30, 2013, 2:08:04 AM10/30/13
to monoc...@googlegroups.com
Hi Team ,

I needed help how to integrate monocle js in android please explain this !!!!!

DeeperShopping Christian Books

unread,
Dec 30, 2013, 10:21:27 PM12/30/13
to monoc...@googlegroups.com
I just wanted to say thanks to everyone for Monocle and EFM. I've implemented an ebook reader on our webstore using monocle and im pleased with the results. You can preview our monocle implementation on this product page:


Thanks,

Bill
DeeperShopping Christian Books...

Ori Idan

unread,
Dec 31, 2013, 2:14:51 AM12/31/13
to monocle-js
Hi Bill,

Looks good what you have done, however when I open the book for preview, I see only the top part. Part of the window is hidden with no option to move the window.

-- 
Ori Idan
CEO

DeeperShopping Christian Books

unread,
Dec 31, 2013, 5:26:55 PM12/31/13
to monoc...@googlegroups.com
Thanks Ori

I guess i need to change the window css to support smaller screens. I'll do some testing and see what can be done with a responsive design for the window.

Regards,

Bill.

rajesh kumar

unread,
Apr 24, 2014, 9:46:20 AM4/24/14
to monoc...@googlegroups.com
Hi Robert,

I am using your efm liabrary for parsing epub books. You take the contents of the  book as an event which comes from here " <input type="file" id="file" accept="application/epub+zip" onchange="fileSelected(event)" />". And then you do  var files = event.target.files; and pass the file to new Epub(files[0], createReader);.

My problem is that I have the file in my file system but I want the user to do that from C# code not from html. So can you tell me that what should I pass as parameter to the 
fileSelected function so that its the same which comes from html. I mean whats the format of the parameter. is it a dictionary, a list or a stream or ?

Can you please help me. I am stuck in a deadlock.

Thanks,
Rajesh

Robert Schroll

unread,
Apr 24, 2014, 10:20:20 AM4/24/14
to monoc...@googlegroups.com
On Thu, Apr 24, 2014 at 9:46 AM, rajesh kumar
<rajesh.l...@gmail.com> wrote:
> My problem is that I have the file in my file system but I want the
> user to do that from C# code not from html. So can you tell me that
> what should I pass as parameter to the
> fileSelected function so that its the same which comes from html. I
> mean whats the format of the parameter. is it a dictionary, a list or
> a stream or ?

In that example, the fileSelected function takes a change event, but
that's not terribly important. The important think is the first
argument to the Epub constructor, which here is an HTML5 file object
[1]. But EFM, or more precisely, zip.js, is only using the Blob
interface [2], so you can get away with just passing a Blob with the
file contents [3]. I have no idea how to do either of these from C#.

But before you try to do one of those, ask yourself why you'd want to
use EFM if you already have a C# part. Why not just parse the epub in
C#? It's got to be faster and safer than doing it in Javascript.

Robert

[1] http://www.w3.org/TR/FileAPI/#dfn-file
[2] http://www.w3.org/TR/FileAPI/#dfn-Blob
[3] See, e.g.,
https://github.com/rschroll/efm#working-with-remote-epub-files

rajesh kumar

unread,
Apr 25, 2014, 4:55:47 AM4/25/14
to monoc...@googlegroups.com
I tried this.

 $(document).ready(function () {

            var xhr = new XMLHttpRequest();
            var src = "The Aesop for Children.epub";
            xhr.open('GET', src, true);
            xhr.responseType = "blob";
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200)
                    new Epub(xhr.response, createReader);
            }
            xhr.send();
        });

But my epub files are on my D drive. Its not on a web server. So how to make that as a blob object??

Thanks,
Rajesh

Robert Schroll

unread,
Apr 25, 2014, 11:14:56 AM4/25/14
to monoc...@googlegroups.com
On Fri, Apr 25, 2014 at 4:55 AM, rajesh kumar
<rajesh.l...@gmail.com> wrote:
> I tried this.
>
> $(document).ready(function () {
>
> var xhr = new XMLHttpRequest();
> var src = "The Aesop for Children.epub";
> xhr.open('GET', src, true);
> xhr.responseType = "blob";
> xhr.onreadystatechange = function () {
> if (xhr.readyState == 4 && xhr.status == 200)
> new Epub(xhr.response, createReader);
> }
> xhr.send();
> });
>
> But my epub files are on my D drive. Its not on a web server. So how
> to make that as a blob object??

Depending on your browser environment, you may be able to open a
XMLHttpRequest for a file:// URL. But then again, you may not.

The better solution, it seems to me, would be to launch a local web
server and hit that with your XMLHttpRequest. If you're going to do
that, though, why not parse the epub in the server and pass the book
data object to your browser?

Robert



Patrick Sturge

unread,
May 8, 2015, 11:11:09 AM5/8/15
to monoc...@googlegroups.com
Does EFM support bookmark and/or annotations? If it does how does it work?

Instead of loading the epub file is there a way to load the file from a SQL table?

Thanks

Patrick

Robert Schroll

unread,
May 8, 2015, 11:37:42 AM5/8/15
to monoc...@googlegroups.com
On Fri, May 8, 2015 at 11:11 AM, Patrick Sturge <trini...@gmail.com>
wrote:
> Does EFM support bookmark and/or annotations? If it does how does it
> work?

No. I'm unfamiliar with the standards for dealing with these in epub
files. Presuming that they are recorded in a particular file within
the zip container, indicated in the OPF file. If so, you should be
able to add additional parse steps within the parseOPF function.

> Instead of loading the epub file is there a way to load the file from
> a SQL table?

EFM only needs a HTML5 Blob object. If you can get your database to
output such an object, or create such an object from its output, you
should be all set.

I have to wonder how an epub file got into a database inside a webpage.
You must have put it there, so why not store a book data object
instead of the epub file and avoid EFM completely?

Robert

Patrick Ellis Sturge

unread,
May 8, 2015, 9:40:07 PM5/8/15
to monoc...@googlegroups.com
Robert,
What about my question on bookmark and annotations?

Patrick Ellis Sturge
The Ventura Group
5126 Ralston St, Ventura CA 93003
Office: (805) 665-5061
Cell: (805) 279-8981
> --
> You received this message because you are subscribed to a topic in the Google Groups "Monocle" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/monocle-js/qOmTrOTS4Nc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to monocle-js+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Robert Schroll

unread,
May 12, 2015, 6:43:08 PM5/12/15
to monoc...@googlegroups.com
On Fri, May 8, 2015 at 9:40 PM, Patrick Ellis Sturge
<trini...@gmail.com> wrote:
> Robert,
> What about my question on bookmark and annotations?

This one?

On Fri, May 8, 2015 at 11:37 AM, Robert Schroll <rsch...@gmail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages