Skip to content

Commit

Permalink
Handle internal hyperlinks created with complex fields
Browse files Browse the repository at this point in the history
  • Loading branch information
mwilliamson committed Aug 1, 2021
1 parent 2a3c8d6 commit 67142b6
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.4.19

* Handle internal hyperlinks created with complex fields.

# 1.4.18

* When extracting raw text, convert tab elements to tab characters.
Expand Down
29 changes: 17 additions & 12 deletions lib/docx/body-reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,28 +139,33 @@ function BodyReader(options) {
} else if (type === "end") {
complexFieldStack.pop();
} else if (type === "separate") {
var href = parseHyperlinkFieldCode(currentInstrText.join(''));
var complexField = href === null ? unknownComplexField : {type: "hyperlink", href: href};
var hyperlinkOptions = parseHyperlinkFieldCode(currentInstrText.join(''));
var complexField = hyperlinkOptions === null ? unknownComplexField : {type: "hyperlink", options: hyperlinkOptions};
complexFieldStack.pop();
complexFieldStack.push(complexField);
}
return emptyResult();
}

function currentHyperlinkHref() {
function currentHyperlinkOptions() {
var topHyperlink = _.last(complexFieldStack.filter(function(complexField) {
return complexField.type === "hyperlink";
}));
return topHyperlink ? topHyperlink.href : null;
return topHyperlink ? topHyperlink.options : null;
}

function parseHyperlinkFieldCode(code) {
var result = /\s*HYPERLINK "(.*)"/.exec(code);
if (result) {
return result[1];
} else {
return null;
var externalLinkResult = /\s*HYPERLINK "(.*)"/.exec(code);
if (externalLinkResult) {
return {href: externalLinkResult[1]};
}

var internalLinkResult = /\s*HYPERLINK\s+\\l\s+"(.*)"/.exec(code);
if (internalLinkResult) {
return {anchor: internalLinkResult[1]};
}

return null;
}

function readInstrText(element) {
Expand Down Expand Up @@ -236,9 +241,9 @@ function BodyReader(options) {
var properties = _.find(children, isRunProperties);
children = children.filter(negate(isRunProperties));

var hyperlinkHref = currentHyperlinkHref();
if (hyperlinkHref !== null) {
children = [new documents.Hyperlink(children, {href: hyperlinkHref})];
var hyperlinkOptions = currentHyperlinkOptions();
if (hyperlinkOptions !== null) {
children = [new documents.Hyperlink(children, hyperlinkOptions)];
}

return new documents.Run(children, properties);
Expand Down
35 changes: 33 additions & 2 deletions test/docx/body-reader.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ test("complex fields", (function() {
function isHyperlinkedRun(hyperlinkProperties) {
return isRun({
children: contains(
isHyperlink(_.extend({href: uri}, hyperlinkProperties))
isHyperlink(hyperlinkProperties)
)
});
}
Expand All @@ -257,7 +257,7 @@ test("complex fields", (function() {
assert.deepEqual(instrText, []);
},

"runs in a complex field for hyperlinks are read as hyperlinks": function() {
"runs in a complex field for hyperlink without switch are read as external hyperlinks": function() {
var hyperlinkRunXml = runOfText("this is a hyperlink");
var paragraphXml = new XmlElement("w:p", {}, [
beginXml,
Expand All @@ -272,6 +272,33 @@ test("complex fields", (function() {
isEmptyRun,
isEmptyHyperlinkedRun,
isHyperlinkedRun({
href: uri,
children: contains(
isText("this is a hyperlink")
)
}),
isEmptyRun
));
},

"runs in a complex field for hyperlink with l switch are read as internal hyperlinks": function() {
var hyperlinkRunXml = runOfText("this is a hyperlink");
var paragraphXml = new XmlElement("w:p", {}, [
beginXml,
new XmlElement("w:instrText", {}, [
xml.text(' HYPERLINK \\l "InternalLink"')
]),
separateXml,
hyperlinkRunXml,
endXml
]);
var paragraph = readXmlElementValue(paragraphXml);

assertThat(paragraph.children, contains(
isEmptyRun,
isEmptyHyperlinkedRun,
isHyperlinkedRun({
anchor: "InternalLink",
children: contains(
isText("this is a hyperlink")
)
Expand Down Expand Up @@ -324,6 +351,7 @@ test("complex fields", (function() {
isEmptyRun,
isEmptyHyperlinkedRun,
isHyperlinkedRun({
href: uri,
children: contains(
isText("this is a hyperlink")
)
Expand Down Expand Up @@ -356,6 +384,7 @@ test("complex fields", (function() {
isEmptyHyperlinkedRun,
isEmptyHyperlinkedRun,
isHyperlinkedRun({
href: uri,
children: contains(
isText("this is a hyperlink")
)
Expand Down Expand Up @@ -387,6 +416,7 @@ test("complex fields", (function() {
isEmptyHyperlinkedRun,
isEmptyHyperlinkedRun,
isHyperlinkedRun({
href: uri,
children: contains(
isText("John Doe")
)
Expand Down Expand Up @@ -415,6 +445,7 @@ test("complex fields", (function() {
isEmptyHyperlinkedRun,
isEmptyHyperlinkedRun,
isHyperlinkedRun({
href: uri,
children: contains(
isText("this is a hyperlink")
)
Expand Down

0 comments on commit 67142b6

Please sign in to comment.