aboutsummaryrefslogtreecommitdiff
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
parenta02b92d7b7d95ab2e8f9e2dfb8a7661b61306674 (diff)
Replace zipfile with unzip
-rw-r--r--lib/document-to-html.js4
-rw-r--r--lib/document-xml-reader.js4
-rw-r--r--lib/docx-reader.js115
-rw-r--r--package.json2
-rw-r--r--tests/document-to-html.tests.js4
-rw-r--r--tests/testing.js17
6 files changed, 107 insertions, 39 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")
diff --git a/package.json b/package.json
index 3b815f2..cb9a44b 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,7 @@
"sax": "~0.5.2",
"underscore": "~1.4.4",
"lop": "~0.2.6",
- "zipfile": "~0.3.4",
+ "unzip": "~0.1.7",
"optimist": "~0.3.5",
"connect": "~2.7.3",
"dustjs-linkedin": "~1.2.1",
diff --git a/tests/document-to-html.tests.js b/tests/document-to-html.tests.js
index 04ac143..5ed2224 100644
--- a/tests/document-to-html.tests.js
+++ b/tests/document-to-html.tests.js
@@ -158,8 +158,8 @@ describe('DocumentConverter', function() {
test('images are written with data URIs', function() {
var imageBuffer = new Buffer("Not an image at all!");
var image = new documents.Image(
- function() {
- return q.when(imageBuffer);
+ function(encoding) {
+ return q.when(imageBuffer.toString(encoding));
}
);
var converter = new DocumentConverter();
diff --git a/tests/testing.js b/tests/testing.js
index af8ec94..6fef626 100644
--- a/tests/testing.js
+++ b/tests/testing.js
@@ -1,6 +1,7 @@
var path = require("path");
var fs = require("fs");
var q = require("q");
+var _ = require("underscore");
exports.test = test;
exports.testData = testData;
@@ -22,8 +23,20 @@ function testData(testDataPath) {
}
function createFakeDocxFile(files) {
- function read(path) {
- return q.when(files[path]);
+ function read(path, encoding) {
+ return q.when(files[path], function(buffer) {
+ if (_.isString(buffer)) {
+ buffer = new Buffer(buffer);
+ }
+
+ if (!Buffer.isBuffer(buffer)) {
+ return q.reject(new Error("file was not a buffer"));
+ } else if (encoding) {
+ return q.when(buffer.toString(encoding));
+ } else {
+ return q.when(buffer);
+ }
+ });
}
function exists(path) {