diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/docx/body-reader.js | 93 | ||||
| -rw-r--r-- | lib/docx/docx-reader.js | 4 |
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, |
