From 99c9e486cfb5efc708e7325d11c222a63aac3490 Mon Sep 17 00:00:00 2001 From: Eliot Kimber Date: Sun, 14 Jan 2024 16:16:30 -0600 Subject: [PATCH 1/4] WIP: Starting on external hyperlink work --- .../xml2docx/generator/DocxGenerator.java | 13 +++++-------- .../docx/Manual-and-Styled-Lists.docx | Bin 22335 -> 23426 bytes version.properties | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java b/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java index 2f3f2d6..9131102 100644 --- a/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java +++ b/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java @@ -43,6 +43,7 @@ import org.apache.poi.xwpf.usermodel.XWPFHeader; import org.apache.poi.xwpf.usermodel.XWPFHeaderFooter; import org.apache.poi.xwpf.usermodel.XWPFHyperlinkRun; +import org.apache.poi.xwpf.usermodel.XWPFHyperlink; import org.apache.poi.xwpf.usermodel.XWPFNum; import org.apache.poi.xwpf.usermodel.XWPFNumbering; import org.apache.poi.xwpf.usermodel.XWPFParagraph; @@ -2244,23 +2245,19 @@ private void makeHyperlink(XWPFParagraph para, XmlCursor cursor) throws DocxGene // while everything else is a URI to an external resource. CTHyperlink hyperlink = para.getCTP().addNewHyperlink(); - + XWPFHyperlinkRun hyperlinkRun = makeHyperlinkRun(hyperlink, cursor, para); // Set the appropriate target: if (href.startsWith("#")) { // Just a fragment ID, must be to a bookmark String bookmarkName = href.substring(1); hyperlink.setAnchor(bookmarkName); + cursor.push(); + } else { - // Create a relationship that targets the href and use the - // relationship's ID on the hyperlink - // It's not yet clear from the POI API how to create a new relationship for - // use by an external hyperlink. - // throw new NotImplementedException("Links to external resources not yet implemented."); + } - cursor.push(); - XWPFHyperlinkRun hyperlinkRun = makeHyperlinkRun(hyperlink, cursor, para); cursor.pop(); para.addRun(hyperlinkRun); diff --git a/src/test/resources/docx/Manual-and-Styled-Lists.docx b/src/test/resources/docx/Manual-and-Styled-Lists.docx index 174601f96c4e7ee79e3a28c3ebea7f321dd23a59..84e2693889d14561126f504847f47ab2e3073566 100644 GIT binary patch delta 18037 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 WSs-gl=;X#gvB{d@0&HKxKr#S;kt{X< delta 16915 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 Juljf7{{S?OyGj56 diff --git a/version.properties b/version.properties index 2e8b9a7..1bf5794 100644 --- a/version.properties +++ b/version.properties @@ -1 +1 @@ -version=1.1.3 +version=1.2.0 From 50d2f12813b2297c73f066d322291fb767946ee6 Mon Sep 17 00:00:00 2001 From: Eliot Kimber Date: Mon, 15 Jan 2024 09:39:06 -0600 Subject: [PATCH 2/4] WIP: Handle external hyperlinks --- .../xml2docx/generator/DocxGenerator.java | 22 ++++++++++--------- .../xml2docx/TestDocxGenerator.java | 2 +- .../simplewp/simplewpml-issue-65.swpx | 4 +++- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java b/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java index 9131102..1453ace 100644 --- a/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java +++ b/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java @@ -43,10 +43,10 @@ import org.apache.poi.xwpf.usermodel.XWPFHeader; import org.apache.poi.xwpf.usermodel.XWPFHeaderFooter; import org.apache.poi.xwpf.usermodel.XWPFHyperlinkRun; -import org.apache.poi.xwpf.usermodel.XWPFHyperlink; import org.apache.poi.xwpf.usermodel.XWPFNum; import org.apache.poi.xwpf.usermodel.XWPFNumbering; import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRelation; import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFStyle; import org.apache.poi.xwpf.usermodel.XWPFStyles; @@ -1757,7 +1757,7 @@ private void makeFootnote(XWPFParagraph para, XmlObject xml) throws DocxGenerati } } - noteCursor.dispose(); + noteCursor.close(); } @@ -2244,23 +2244,25 @@ private void makeHyperlink(XWPFParagraph para, XmlCursor cursor) throws DocxGene // Convention in simple WP XML is fragment identifiers are to bookmark IDs, // while everything else is a URI to an external resource. - CTHyperlink hyperlink = para.getCTP().addNewHyperlink(); - XWPFHyperlinkRun hyperlinkRun = makeHyperlinkRun(hyperlink, cursor, para); - // Set the appropriate target: + // If the hyperlink is to a bookmark (just a fragment ID) then we we create a hyperlink with + // an anchor, otherwise we create an external hyperlink to a URI. + CTHyperlink hyperlink = para.getCTP().addNewHyperlink(); + XWPFHyperlinkRun hyperlinkRun = makeHyperlinkRun(hyperlink, cursor, para); if (href.startsWith("#")) { // Just a fragment ID, must be to a bookmark String bookmarkName = href.substring(1); hyperlink.setAnchor(bookmarkName); - cursor.push(); - } else { - + // Create an external hyperlink. This creates the necessary relationship. + // Not using the createHyperlinkRun() of paragraph because it doesn't handle the + // runs within the . The + String rId = para.getDocument().getPackagePart().addExternalRelationship(href, XWPFRelation.HYPERLINK.getRelation()).getId(); + hyperlinkRun.setHyperlinkId(rId); } - - cursor.pop(); para.addRun(hyperlinkRun); + } /** diff --git a/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java b/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java index c21a579..288d813 100644 --- a/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java +++ b/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java @@ -259,7 +259,7 @@ public void testHyperlinkHandling() throws Exception { assertEquals("First run in para before the hyperlink", ((XWPFRun)run).getText(0)); run = runIterator.next(); // Should be the hyperlink assertTrue("Expected a XWPFHyperlinkRun", run instanceof XWPFHyperlinkRun); - assertTrue("Expected fun following the hyperlink", runIterator.hasNext()); + assertTrue("Expected run following the hyperlink", runIterator.hasNext()); run = runIterator.next(); // Should be the hyperlink assertEquals("Run after the hyperlink.", ((XWPFRun)run).getText(0)); } diff --git a/src/test/resources/simplewp/simplewpml-issue-65.swpx b/src/test/resources/simplewp/simplewpml-issue-65.swpx index 8f11ee5..20e1cf2 100644 --- a/src/test/resources/simplewp/simplewpml-issue-65.swpx +++ b/src/test/resources/simplewp/simplewpml-issue-65.swpx @@ -64,5 +64,7 @@ 1996; 24: 1-11.

- +

External hyperlink: Wordinator + After hyperlink para with external hyperlink

+ From b076352ed696fefdd3f59ef7df138098b6a6dd4c Mon Sep 17 00:00:00 2001 From: Eliot Kimber Date: Mon, 15 Jan 2024 09:48:45 -0600 Subject: [PATCH 3/4] #136: External links work, hyperlink test passes --- .../xml2docx/generator/DocxGenerator.java | 16 ++++++++++------ .../resources/simplewp/simplewpml-issue-65.swpx | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java b/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java index 1453ace..eeb0ed4 100644 --- a/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java +++ b/src/main/java/org/wordinator/xml2docx/generator/DocxGenerator.java @@ -2248,21 +2248,25 @@ private void makeHyperlink(XWPFParagraph para, XmlCursor cursor) throws DocxGene // an anchor, otherwise we create an external hyperlink to a URI. CTHyperlink hyperlink = para.getCTP().addNewHyperlink(); - XWPFHyperlinkRun hyperlinkRun = makeHyperlinkRun(hyperlink, cursor, para); + + // Set the appropriate target: + if (href.startsWith("#")) { - // Just a fragment ID, must be to a bookmark + // Just a fragment ID, must be to a bookmark, set @anchor attribute. String bookmarkName = href.substring(1); hyperlink.setAnchor(bookmarkName); } else { // Create an external hyperlink. This creates the necessary relationship. // Not using the createHyperlinkRun() of paragraph because it doesn't handle the - // runs within the . The + // runs within the as we need. Set the @rId attribute. String rId = para.getDocument().getPackagePart().addExternalRelationship(href, XWPFRelation.HYPERLINK.getRelation()).getId(); - hyperlinkRun.setHyperlinkId(rId); + hyperlink.setId(rId); } - para.addRun(hyperlinkRun); - + cursor.push(); + XWPFHyperlinkRun hyperlinkRun = makeHyperlinkRun(hyperlink, cursor, para); + cursor.pop(); + para.addRun(hyperlinkRun); } /** diff --git a/src/test/resources/simplewp/simplewpml-issue-65.swpx b/src/test/resources/simplewp/simplewpml-issue-65.swpx index 20e1cf2..2ef6fc7 100644 --- a/src/test/resources/simplewp/simplewpml-issue-65.swpx +++ b/src/test/resources/simplewp/simplewpml-issue-65.swpx @@ -65,6 +65,6 @@

External hyperlink: Wordinator - After hyperlink para with external hyperlink

+
After hyperlink para with external hyperlink

From 72550190b9eea67b3c4bc20c960c5d02abca5457 Mon Sep 17 00:00:00 2001 From: Eliot Kimber Date: Mon, 15 Jan 2024 09:57:19 -0600 Subject: [PATCH 4/4] Fixes #136: Test for external link rId passes --- .../xml2docx/TestDocxGenerator.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java b/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java index 288d813..930bd3c 100644 --- a/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java +++ b/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java @@ -251,7 +251,7 @@ public void testHyperlinkHandling() throws Exception { XWPFParagraph p = iterator.next(); assertNotNull("Expected a paragraph", p); assertEquals("Issue 65: Data following hyperlink is dropped", p.getText()); - // Normal footnote with generated ref + // Hyperlink to a bookmark (internal link): p = iterator.next(); Iterator runIterator = p.getIRuns().iterator(); assertTrue("Expected runs", runIterator.hasNext()); @@ -260,8 +260,25 @@ public void testHyperlinkHandling() throws Exception { run = runIterator.next(); // Should be the hyperlink assertTrue("Expected a XWPFHyperlinkRun", run instanceof XWPFHyperlinkRun); assertTrue("Expected run following the hyperlink", runIterator.hasNext()); - run = runIterator.next(); // Should be the hyperlink + run = runIterator.next(); assertEquals("Run after the hyperlink.", ((XWPFRun)run).getText(0)); + // Now look for external link: + p = iterator.next(); + assertNotNull("Expected another paragraph after internal hyperlink", p); + p = iterator.next(); + assertNotNull("Expected another paragraph after internal hyperlink", p); + p = iterator.next(); // Should be paragraph with hyperlink + assertNotNull("Expected another paragraph after internal hyperlink", p); + runIterator = p.getIRuns().iterator(); + assertTrue("Expected runs", runIterator.hasNext()); + run = runIterator.next(); + assertTrue("First run in para before the hyperlink", ((XWPFRun)run).getText(0).startsWith("External hyperlink:")); + run = runIterator.next(); // Should be the hyperlink + assertTrue("Expected a XWPFHyperlinkRun", run instanceof XWPFHyperlinkRun); + XWPFHyperlinkRun linkRun = (XWPFHyperlinkRun)run; + String rId = linkRun.getHyperlinkId(); + assertNotNull("Expected and rId", rId); + } @Test