cray
Version:
Epub parser
136 lines (102 loc) • 3.17 kB
JavaScript
/**
* @author: Akshay Kr Singh.
* @date: 20/11/15.
* @github: https://github.com/akshayKrSingh
*/
var util = require('util');
var xml2js = require('xml2js');
var _ = require('lodash');
var EpubErrors = require('./errors');
var Epub = function() {
if (!(this instanceof Epub)) {
return new Epub();
}
};
Epub.prototype.generateContainerInfo = function(xml) {
var self = this;
var opfRegEx = xml.match(/<rootfile.*full\-path=["|'](.*?)["|']/),
opfPath = root = opfRegEx ? opfRegEx[1] : -1, opsRoot = '';
if (root === -1) {return self.error = EpubErrors['EPUB#container'].format;}
if (root.match(/\//)) { // not at top level
opsRoot = root.replace(/\/([^\/]+)\.opf/i, '');
if (!opsRoot.match(/\/$/)) { // does not end in slash, but we want it to
opsRoot += '/';
}
if (opsRoot.match(/^\//)) {
opsRoot = opsRoot.replace(/^\//, '');
}
} else { // at top level
opsRoot = '';
}
self.opfRoot = opsRoot;
self.opfPath = opfPath;
};
Epub.prototype.generateOpfInfo = function(xml) {
var epub = this;
epub.error = null;
function parseMeta(metadata) {
var metaProp = {
arr: ['language', 'title', 'date', 'creator', 'contributor', 'publisher', 'rights'],
prefix: 'dc:'
};
_.each(metaProp.arr, function(meta) {
if (meta === 'contributor') {
var contributors = metadata[metaProp.prefix + meta] ? metadata[metaProp.prefix + meta] : '';
return epub.metadata[meta] = (_.isArray(contributors)) ? contributors : [contributors];
}
if (metadata[metaProp.prefix + meta]) {
epub.metadata[meta] = (_.isObject(metadata[metaProp.prefix + meta][0])) ?
metadata[metaProp.prefix + meta][0]._ : metadata[metaProp.prefix + meta][0];
} else {
epub.metadata[meta] = "";
}
});
}
function parseManifest(manifest) {
var items = [];
_.each(manifest, function(item) {
var temp = item.$;
if (temp.properties) {
if (temp.properties === 'nav') {
return epub.nav = temp;
}
if (temp.properties === 'cover-image') {
return epub.cover = {
imagePath: temp.href
}
}
return '';
}
items.push(temp);
});
epub.manifest = items;
}
function parseSpine(spine) {
var spines = [], invalid = false;
_.each(spine, function(item) {
var manifest = _.find(epub.manifest, {id: item.$.idref});
//TODO validate spine entries authentically
if (manifest) {spines.push(manifest);}
});
epub.spines = spines;
}
function parseOpf(fileString) {
xml2js.parseString(fileString, function (err, opfJson) {
if (err) {
return epub.error = EpubErrors['EPUB#opf'].format;
}
var temp = {
metadata: opfJson.package.metadata[0],
manifest: opfJson.package.manifest[0],
spine: opfJson.package.spine[0]
};
epub.metadata = {};
parseMeta(temp.metadata);
parseManifest(temp.manifest.item);
parseSpine(temp.spine.itemref);
epub.isValid = true;
});
}
parseOpf(xml);
};
module.exports = Epub;