aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2017-02-19 11:08:06 +0000
committerGitHub <noreply@github.com>2017-02-19 11:08:06 +0000
commit2e0d6e07bb8d9ccbd53270a450bd9ee5145f845b (patch)
tree407ef0c07a0d6d567a16f6cc682915b2ee251289 /lib
parent15f4381cf54901895836551a30f66c0cee974a0c (diff)
parentf89115c9817b4cd4da91c7e3e9882b0eac4ae40d (diff)
Merge pull request #110 from jdlehman/instrText-hyperlinks
Enable hyperlinks that are not defined with w:hyperlink
Diffstat (limited to 'lib')
-rw-r--r--lib/docx/body-reader.js93
-rw-r--r--lib/docx/docx-reader.js4
2 files changed, 77 insertions, 20 deletions
diff --git a/lib/docx/body-reader.js b/lib/docx/body-reader.js
index 529d6f2..a19ecdb 100644
--- a/lib/docx/body-reader.js
+++ b/lib/docx/body-reader.js
@@ -1,4 +1,5 @@
-exports.BodyReader = BodyReader;
+exports.createBodyReader = createBodyReader;
+exports._readNumberingProperties = readNumberingProperties;
var _ = require("underscore");
@@ -7,8 +8,20 @@ var Result = require("../results").Result;
var warning = require("../results").warning;
var uriToZipEntryName = require("./uris").uriToZipEntryName;
+function createBodyReader(options) {
+ return {
+ readXmlElement: function(element) {
+ return new BodyReader(options).readXmlElement(element);
+ },
+ readXmlElements: function(elements) {
+ return new BodyReader(options).readXmlElements(elements);
+ }
+ };
+}
function BodyReader(options) {
+ var complexFields = [];
+ var currentInstrText = [];
var relationships = options.relationships;
var contentTypes = options.contentTypes;
var docxFile = options.docxFile;
@@ -125,7 +138,7 @@ function BodyReader(options) {
styleId: style.styleId,
styleName: style.name,
alignment: element.firstOrEmpty("w:jc").attributes["w:val"],
- numbering: readNumberingProperties(element.firstOrEmpty("w:numPr"))
+ numbering: readNumberingProperties(element.firstOrEmpty("w:numPr"), numbering)
};
});
},
@@ -133,14 +146,37 @@ function BodyReader(options) {
return readXmlElements(element.children)
.map(function(children) {
var properties = _.find(children, isRunProperties);
-
- return new documents.Run(
- children.filter(negate(isRunProperties)),
- properties
- );
+ children = children.filter(negate(isRunProperties));
+
+ var scopedHyperlink = scopedComplexFieldOfType(complexFields, "hyperlink");
+ if (scopedHyperlink !== undefined) {
+ children = [new documents.Hyperlink(children, {href: scopedHyperlink.href})];
+ }
+
+ return new documents.Run(children, properties);
});
},
"w:rPr": readRunProperties,
+ "w:fldChar": function(element) {
+ var type = element.attributes["w:fldCharType"];
+ if (type === "begin") {
+ currentInstrText = [];
+ } else if (type === "end") {
+ complexFields.pop();
+ } else if (type === "separate") {
+ var href = parseHyperlinkFieldCode(currentInstrText.join(''));
+ if (href !== null) {
+ complexFields.push({type: "hyperlink", href: href});
+ } else {
+ complexFields.push(null);
+ }
+ }
+ return emptyResult();
+ },
+ "w:instrText": function(element) {
+ currentInstrText.push(element.text());
+ return emptyResult();
+ },
"w:t": function(element) {
return elementResult(new documents.Text(element.text()));
},
@@ -210,21 +246,12 @@ function BodyReader(options) {
"wp:anchor": readDrawingElement,
"v:imagedata": readImageData
};
+
return {
readXmlElement: readXmlElement,
- readXmlElements: readXmlElements,
- _readNumberingProperties: readNumberingProperties
+ readXmlElements: readXmlElements
};
- function readNumberingProperties(element) {
- var level = element.firstOrEmpty("w:ilvl").attributes["w:val"];
- var numId = element.firstOrEmpty("w:numId").attributes["w:val"];
- if (level === undefined || numId === undefined) {
- return null;
- } else {
- return numbering.findLevel(numId, level);
- }
- }
function readTable(element) {
return readXmlElements(element.children)
@@ -379,6 +406,17 @@ function BodyReader(options) {
type + " style with ID " + styleId + " was referenced but not defined in the document");
}
}
+
+
+function readNumberingProperties(element, numbering) {
+ var level = element.firstOrEmpty("w:ilvl").attributes["w:val"];
+ var numId = element.firstOrEmpty("w:numId").attributes["w:val"];
+ if (level === undefined || numId === undefined) {
+ return null;
+ } else {
+ return numbering.findLevel(numId, level);
+ }
+}
var supportedImageTypes = {
"image/png": true,
@@ -491,3 +529,22 @@ function joinElements(first, second) {
function identity(value) {
return value;
}
+
+function parseHyperlinkFieldCode(code) {
+ var result = /\s*HYPERLINK "(.*)"/.exec(code);
+ if (result) {
+ return result[1];
+ } else {
+ return null;
+ }
+}
+
+function complexFieldsOfType(complexFields, type) {
+ return complexFields.filter(function(complexField) {
+ return complexField.type === type;
+ });
+}
+
+function scopedComplexFieldOfType(complexFields, type) {
+ return _.last(complexFieldsOfType(complexFields, type));
+}
diff --git a/lib/docx/docx-reader.js b/lib/docx/docx-reader.js
index 0c7d57f..5aa95ca 100644
--- a/lib/docx/docx-reader.js
+++ b/lib/docx/docx-reader.js
@@ -7,7 +7,7 @@ var documents = require("../documents");
var Result = require("../results").Result;
var readXmlFromZipFile = require("./office-xml-reader").readXmlFromZipFile;
-var BodyReader = require("./body-reader").BodyReader;
+var createBodyReader = require("./body-reader").createBodyReader;
var DocumentXmlReader = require("./document-xml-reader").DocumentXmlReader;
var relationshipsReader = require("./relationships-reader");
var contentTypesReader = require("./content-types-reader");
@@ -95,7 +95,7 @@ function readXmlFileWithBody(name, options, func) {
});
return readRelationshipsFromZipFile(options.docxFile).then(function(relationships) {
- var bodyReader = new BodyReader({
+ var bodyReader = new createBodyReader({
relationships: relationships,
contentTypes: options.contentTypes,
docxFile: options.docxFile,