aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2013-04-09 21:36:35 +0100
committerMichael Williamson <mike@zwobble.org>2013-04-09 21:36:35 +0100
commitf854e23429c23451a968dfe4691fba5eb21ea21e (patch)
tree4061308df30c8cae988d51b4d53686c4248db508 /lib
parenta02b92d7b7d95ab2e8f9e2dfb8a7661b61306674 (diff)
Replace zipfile with unzip
Diffstat (limited to 'lib')
-rw-r--r--lib/document-to-html.js4
-rw-r--r--lib/document-xml-reader.js4
-rw-r--r--lib/docx-reader.js115
3 files changed, 89 insertions, 34 deletions
diff --git a/lib/document-to-html.js b/lib/document-to-html.js
index fe3b566..64672ee 100644
--- a/lib/document-to-html.js
+++ b/lib/document-to-html.js
@@ -97,9 +97,9 @@ function DocumentConverter(options) {
});
},
"image": function(element, html, callback) {
- element.read().then(function(imageBuffer) {
+ element.read("base64").then(function(imageBuffer) {
// TODO: set alt attribute to wp:inline/wp:docPr/@descr
- var src = "data:image/png;base64," + imageBuffer.toString("base64");
+ var src = "data:image/png;base64," + imageBuffer;
var attributes = {src: src};
if (element.altText) {
attributes.alt = element.altText;
diff --git a/lib/document-xml-reader.js b/lib/document-xml-reader.js
index ea15204..04eec21 100644
--- a/lib/document-xml-reader.js
+++ b/lib/document-xml-reader.js
@@ -116,9 +116,7 @@ function DocumentXmlReader(relationships, docxFile) {
.first("a:blip")
.attributes["r:embed"];
var imagePath = relationships[relationshipId].target;
- var readImage = function() {
- return docxFile.read(path.join("word", imagePath));
- };
+ var readImage = docxFile.read.bind(docxFile, path.join("word", imagePath));
var altText = element.first("wp:docPr").attributes.descr;
var image = documents.Image(readImage, altText)
diff --git a/lib/docx-reader.js b/lib/docx-reader.js
index ecaa10c..9cb912f 100644
--- a/lib/docx-reader.js
+++ b/lib/docx-reader.js
@@ -2,8 +2,9 @@ exports.read = read;
var q = require("q");
var _ = require("underscore");
-var ZipFile = require("zipfile").ZipFile;
+var unzip = require("unzip");
var path = require("path");
+var fs = require("fs");
var xmlreader = require("./xmlreader");
var documents = require("./documents");
@@ -13,39 +14,95 @@ var Result = require("./results").Result;
function read(docxFile) {
if (_.isString(docxFile)) {
- var zipFile = new ZipFile(docxFile);
- var exists = function(path) {
- return zipFile.names.indexOf(path) !== -1;
- }
- docxFile = {
- read: function(path, encoding) {
- if (exists(path)) {
- return q.ninvoke(zipFile, "readFile", path)
- .then(function(value) {
- if (encoding) {
- return value.toString(encoding);
- } else {
- return value;
- }
- });
- } else {
- return q.reject(new Error("No file in zip: " + path));
- }
- },
- exists: exists
- };
+ var zipPath = docxFile;
+ docxFile = openZip(zipPath);
}
+ return q.when(docxFile, function(docxFile) {
- return q.all([
- readXmlFile(docxFile, "word/_rels/document.xml.rels"),
- readXmlFile(docxFile, "word/document.xml")
- ]).spread(function(relationshipsXml, documentXml) {
- var relationships = relationshipsXml ? readRelationships(relationshipsXml) : {};
- var reader = new DocumentXmlReader(relationships, docxFile);
- return reader.convertXmlToDocument(documentXml);
+ return q.all([
+ readXmlFile(docxFile, "word/_rels/document.xml.rels"),
+ readXmlFile(docxFile, "word/document.xml")
+ ]).spread(function(relationshipsXml, documentXml) {
+ var relationships = relationshipsXml ? readRelationships(relationshipsXml) : {};
+ var reader = new DocumentXmlReader(relationships, docxFile);
+ return reader.convertXmlToDocument(documentXml);
+ });
});
}
+function openZip(zipPath) {
+ var deferred = q.defer();
+ var names = [];
+
+ fs.createReadStream(zipPath)
+ .pipe(unzip.Parse())
+ .on("entry", function(entry) {
+ names.push(entry.path);
+ entry.autodrain();
+ })
+ .on("close", function() {
+ deferred.resolve(zipFile);
+ })
+ .on("error", function(err) {
+ deferred.reject(err);
+ });
+
+ var exists = function(path) {
+ return names.indexOf(path) !== -1;
+ }
+ var zipFile = {
+ read: function(path, encoding) {
+ if (!exists(path)) {
+ return q.reject(new Error("No file in zip: " + path));
+ }
+ var readDeferred = q.defer();
+
+ var readStream = fs.createReadStream(zipPath)
+ .pipe(unzip.Parse())
+ .on("entry", function(entry) {
+ if (entry.path === path) {
+ readEntry(entry);
+ } else {
+ entry.autodrain();
+ }
+ })
+ .on("error", readDeferred.reject.bind(readDeferred));
+
+ function readEntry(entry) {
+ entry.setEncoding(encoding);
+
+ var fragments = [];
+
+ entry
+ .on("data", function(data) {
+ fragments.push(data);
+ })
+ .on("end", function() {
+ readDeferred.resolve(fragments.join(""));
+ })
+ .on("error", readDeferred.reject.bind(readDeferred))
+ }
+
+ return readDeferred.promise;
+
+ if (exists(path)) {
+ return q.ninvoke(zipFile, "readFile", path)
+ .then(function(value) {
+ if (encoding) {
+ return value.toString(encoding);
+ } else {
+ return value;
+ }
+ });
+ } else {
+ return q.reject(new Error("No file in zip: " + path));
+ }
+ },
+ exists: exists
+ };
+ return deferred.promise;
+}
+
function readXmlFile(docxFile, path) {
if (docxFile.exists(path)) {
return docxFile.read(path, "utf-8")