How to set up your own Bookreader

Now that the Digital Walters BookReaders are all updated and online, I wanted to make a post documenting how you too can create BookReaders along the same lines.

The original BookReader source is available from the Internet Archive. That was the staring point. Doug Emery and I worked together to modify that code to pull most of the information needed by the BookReader out of a TEI Manuscript Description – although the same process could potentially be followed to read from some other XML file containing the appropriate information. I did have to write an XSLT to create the BookReader files themselves (one for each manuscript). Of course it would also be possible to create one BookReader file for all manuscripts to share! But I wanted the BookReaders to be able to be grabbed and used separately, rather than being dependent on server-side scripting in order to use.

You will need:

The .zip file from Internet Archive contains a License, a readme text file, and three folders: BookReader, BookReaderDemo, and BookReaderIA. The modified BookReader.js file available here replaces the BookReaderJSSimple.js file contained in the BookReaderDemo folder. The rest of the files in the folder should be unchanged. The BookReader folder is required for the system to work. We don’t use the BookReaderIA folder.

To run the sample modified BookReader.js file:

  • Replace the BookReaderJSSimple.js file in the BookReaderDemo folder with the .js file from the link above
  • Place the TEI document in the BookReaderDemo folder
  • Open the index.html document in the BookReaderDemo folder

It really is that easy. If you want to take the files I have on this site and host them yourself, please do! The relevant URLs are all formatted as above.

Now, you may want to use these files as a basis to build BookReaders for your own collection. If you have TEI Manuscript Description files you should be able to do it. The file will need to have (or you will need to be able to generate somehow):

  • Title of the book or manuscript
    • TEI/teiHeader/fileDesc/titleStmt/title[@type=’common’]
  • a URL to the official webpage of the manuscript (if there is one)
    • We generated this by supplying the base URL ( and then filling in the rest of the URL from the TEI (‘.concat(siglum,’/data/’,idno,’/’) – where siglum and idno were pulled from different areas of the file
  • The number of leaves / pages
    • We generated this by counting <surface> tags – but because some of the images were duplicates (one with flap closed, one with flap open) and also included fore-edge, tail, spine, and head images, we had to do a bit of work to keep those from being counted.
    • var surfaces = $(file).find(“surface:[n!=’Fore-edge’][n!=’Tail’][n!=’Spine’][n!=’Head’]”).
      not(“[n*=’flap closed’]”);;
      var leafCount = $(surfaces).size();
  • An indication of whether the manuscript / book is to be read left to right or right to left (we generated this by searching for the language code and specifying which languages are l-r)
    • var rtlLangs = [ ‘ara’, ‘heb’, ‘jpr’, ‘jrb’, ‘per’, ‘tuk’, ‘syc’, ‘syr’, ‘sam’, ‘arc’, ‘ota’ ]
      // get the lang from the TEI
      var lang = $(file).find(‘textLang’).attr(‘mainLang’);
      // set pageProgression if lang is in rtlLangs
      if (jQuery.inArray(lang, rtlLangs) > -1) {
      br.pageProgression = ‘rl’;
  • URLs of the location of the page / leaf files
    • These were generated using the file names that were provided in the TEI document (@url on the third <graphic> tag, which was the resolution file we wanted for the page turning)
    • var path = $(file).find(‘surface’).eq(index).find(‘graphic’).eq(2).attr(‘url’);
      var graphicurl = url + path;
      return graphicurl;
  • The height and width of page/leaf files
    • I tried many different ways to get these. In the first version of the Digital Walters BookReaders I hard-coded the height and width into the .js file (this is what is done in the demo version available from Internet Archive). Unfortunately the image files in Digital Walters are different sizes – although always 1800px on the long edge, the short edge will vary page by page, and the long edge is not always the vertical side. Eventually, the Digital Walters team very kindly generated new TEI files for me to use, with the height and width hard-coded. Ideally there would be some way to automatically generate height and width from the files themselves but if there is some way to do that, I don’t know it!
    • br.getPageWidth = function(index) {
      var widthpx =
      if (widthpx) {
      var width = parseInt(widthpx.replace(“px”,””));
      return width;
      } else {
      return 1200;
    • And again for height

One last thing: because I wanted to generate many files at the same time, one per manuscript, I set up an XSLT that I could use to create those files based on information from the TEI documents. That XSLT is available here: Aside from the body of the .js there are just a few transformations, and they are (I think) sufficiently documented.

I hope this is useful. I certainly learned a lot working on this project. Thanks to Doug Emery for all his technical help, to Will Noel for his moral support and interest in the project (and for putting me in touch with Doug!). And finally, thanks to the Trustees of the Walters Art Museum for making all of this great data available under Open Access licenses so people like me can do fun and cool things with it!

Leave a Reply

Your email address will not be published.