You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2018/10/11 17:44:40 UTC
[tika] 03/03: TIKA-2735 -- allow user to avoid extracting "master"
sections and notes sections from ppt[xm]?
This is an automated email from the ASF dual-hosted git repository.
tallison pushed a commit to branch branch_1x
in repository https://gitbox.apache.org/repos/asf/tika.git
commit 307a8bd592d6e25419bbad19aac47cc7de201c4d
Author: TALLISON <ta...@apache.org>
AuthorDate: Thu Oct 4 13:32:37 2018 -0400
TIKA-2735 -- allow user to avoid extracting "master" sections and notes sections from ppt[xm]?
---
.../tika/parser/microsoft/HSLFExtractor.java | 268 ++++++++++++---------
.../tika/parser/microsoft/OfficeParserConfig.java | 42 +++-
.../ooxml/SXSLFPowerPointExtractorDecorator.java | 71 +++---
.../ooxml/XSLFPowerPointExtractorDecorator.java | 50 ++--
.../parser/microsoft/PowerPointParserTest.java | 48 ++++
.../parser/microsoft/ooxml/OOXMLParserTest.java | 43 ++++
.../parser/microsoft/ooxml/SXSLFExtractorTest.java | 35 +++
7 files changed, 384 insertions(+), 173 deletions(-)
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java
index 5095709..356c47e 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java
@@ -16,12 +16,6 @@
*/
package org.apache.tika.parser.microsoft;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
import org.apache.poi.common.usermodel.Hyperlink;
import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
import org.apache.poi.hslf.model.HeadersFooters;
@@ -40,16 +34,17 @@ import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTable;
import org.apache.poi.hslf.usermodel.HSLFTableCell;
-import org.apache.poi.hslf.usermodel.HSLFTextBox;
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
import org.apache.poi.hslf.usermodel.HSLFTextRun;
import org.apache.poi.hslf.usermodel.HSLFTextShape;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.sl.usermodel.Comment;
+import org.apache.poi.sl.usermodel.ShapeContainer;
import org.apache.poi.sl.usermodel.SimpleShape;
-import org.apache.tika.exception.TikaException;
+import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.tika.exception.EncryptedDocumentException;
+import org.apache.tika.exception.TikaException;
import org.apache.tika.extractor.EmbeddedDocumentUtil;
import org.apache.tika.io.CloseShieldInputStream;
import org.apache.tika.io.IOExceptionWithCause;
@@ -61,6 +56,11 @@ import org.apache.tika.sax.XHTMLContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
public class HSLFExtractor extends AbstractPOIFSExtractor {
public HSLFExtractor(ParseContext context, Metadata metadata) {
@@ -92,143 +92,169 @@ public class HSLFExtractor extends AbstractPOIFSExtractor {
/* Iterate over slides and extract text */
for (HSLFSlide slide : _slides) {
xhtml.startElement("div", "class", "slide");
+ HeadersFooters slideHeaderFooters =
+ (officeParserConfig.getIncludeHeadersAndFooters()) ?
+ slide.getHeadersFooters() : null;
- // Slide header, if present
- HeadersFooters hf = slide.getHeadersFooters();
- if (hf != null && hf.isHeaderVisible() && hf.getHeaderText() != null) {
- xhtml.startElement("p", "class", "slide-header");
+ HeadersFooters notesHeadersFooters =
+ (officeParserConfig.getIncludeHeadersAndFooters()) ?
+ ss.getNotesHeadersFooters() : null;
- xhtml.characters(hf.getHeaderText());
+ if (officeParserConfig.getIncludeHeadersAndFooters()) {
+ // Slide header, if present
+ if (slideHeaderFooters != null && slideHeaderFooters.isHeaderVisible() && slideHeaderFooters.getHeaderText() != null) {
+ xhtml.startElement("p", "class", "slide-header");
- xhtml.endElement("p");
+ xhtml.characters(slideHeaderFooters.getHeaderText());
+
+ xhtml.endElement("p");
+ }
}
// Slide master, if present
- extractMaster(xhtml, slide.getMasterSheet());
-
- // Slide text
- {
- xhtml.startElement("div", "class", "slide-content");
-
- textRunsToText(xhtml, slide.getTextParagraphs());
-
- xhtml.endElement("div");
+ if (officeParserConfig.getIncludeSlideMasterContent()) {
+ extractMaster(xhtml, slide.getMasterSheet());
}
+ // Slide text
+ xhtml.startElement("div", "class", "slide-content");
+ textRunsToText(xhtml, slide.getTextParagraphs());
// Table text
- for (HSLFShape shape : slide.getShapes()) {
- if (shape instanceof HSLFTable) {
- extractTableText(xhtml, (HSLFTable) shape);
+ List<HSLFShape> shapes = getShapes(slide);
+ if (shapes != null) {
+ for (HSLFShape shape : shapes) {
+ if (shape instanceof HSLFTable) {
+ extractTableText(xhtml, (HSLFTable) shape);
+ }
}
}
+ extractGroupText(xhtml, slide, 0);
+ //end slide content
+ xhtml.endElement("div");
- extractGroupText(xhtml, slide.getShapes(), 0);
-
- // Slide footer, if present
- if (hf != null && hf.isFooterVisible() && hf.getFooterText() != null) {
- xhtml.startElement("p", "class", "slide-footer");
-
- xhtml.characters(hf.getFooterText());
-
- xhtml.endElement("p");
- }
-
- // Comments, if present
- StringBuilder authorStringBuilder = new StringBuilder();
- for (Comment comment : slide.getComments()) {
- authorStringBuilder.setLength(0);
- xhtml.startElement("p", "class", "slide-comment");
-
- if (comment.getAuthor() != null) {
- authorStringBuilder.append(comment.getAuthor());
+ if (officeParserConfig.getIncludeHeadersAndFooters()) {
+ // Slide footer, if present
+ if (slideHeaderFooters != null && slideHeaderFooters.isFooterVisible() && slideHeaderFooters.getFooterText() != null) {
+ xhtml.startElement("p", "class", "slide-footer");
+ xhtml.characters(slideHeaderFooters.getFooterText());
+ xhtml.endElement("p");
}
- if (comment.getAuthorInitials() != null) {
- if (authorStringBuilder.length() > 0) {
- authorStringBuilder.append(" ");
- }
- authorStringBuilder.append("("+comment.getAuthorInitials()+")");
- }
- if (authorStringBuilder.length() > 0) {
- if (comment.getText() != null) {
- authorStringBuilder.append(" - ");
- }
- xhtml.startElement("b");
- xhtml.characters(authorStringBuilder.toString());
- xhtml.endElement("b");
- }
- if (comment.getText() != null) {
- xhtml.characters(comment.getText());
- }
- xhtml.endElement("p");
}
+ handleComments(slide, xhtml);
+ handleNotes(slide, notesHeadersFooters, xhtml);
// Now any embedded resources
handleSlideEmbeddedResources(slide, xhtml);
-
- // Find the Notes for this slide and extract inline
- HSLFNotes notes = slide.getNotes();
- if (notes != null) {
- xhtml.startElement("div", "class", "slide-notes");
-
- textRunsToText(xhtml, notes.getTextParagraphs());
-
- xhtml.endElement("div");
- }
-
-
// Slide complete
xhtml.endElement("div");
}
+ handleSlideEmbeddedPictures(ss, xhtml);
+ if (officeParserConfig.getExtractMacros()) {
+ extractMacros(ss, xhtml);
+ }
// All slides done
xhtml.endElement("div");
+ }
+
+ private void handleComments(HSLFSlide slide, XHTMLContentHandler xhtml) throws SAXException {
+ if (slide.getComments() == null || slide.getComments().size() == 0) {
+ return;
+ }
+ xhtml.startElement("div", "class", "slide-comments");
- /* notes */
- xhtml.startElement("div", "class", "slide-notes");
- HashSet<Integer> seenNotes = new HashSet<>();
- HeadersFooters hf = ss.getNotesHeadersFooters();
+ // Comments, if present
+ StringBuilder authorStringBuilder = new StringBuilder();
+ for (Comment comment : slide.getComments()) {
+ authorStringBuilder.setLength(0);
+ xhtml.startElement("p", "class", "slide-comment");
- for (HSLFSlide slide : _slides) {
- HSLFNotes notes = slide.getNotes();
- if (notes == null) {
- continue;
+ if (comment.getAuthor() != null) {
+ authorStringBuilder.append(comment.getAuthor());
}
- Integer id = notes._getSheetNumber();
- if (seenNotes.contains(id)) {
- continue;
+ if (comment.getAuthorInitials() != null) {
+ if (authorStringBuilder.length() > 0) {
+ authorStringBuilder.append(" ");
+ }
+ authorStringBuilder.append("(" + comment.getAuthorInitials() + ")");
}
- seenNotes.add(id);
-
- // Repeat the Notes header, if set
- if (hf != null && hf.isHeaderVisible() && hf.getHeaderText() != null) {
- xhtml.startElement("p", "class", "slide-note-header");
- xhtml.characters(hf.getHeaderText());
- xhtml.endElement("p");
+ if (authorStringBuilder.length() > 0) {
+ if (comment.getText() != null) {
+ authorStringBuilder.append(" - ");
+ }
+ xhtml.startElement("b");
+ xhtml.characters(authorStringBuilder.toString());
+ xhtml.endElement("b");
}
+ if (comment.getText() != null) {
+ xhtml.characters(comment.getText());
+ }
+ xhtml.endElement("p");
+ }
+ //end comments
+ xhtml.endElement("div");
+ }
+
+ private void handleNotes(HSLFSlide slide,
+ HeadersFooters notesHeaderFooters, XHTMLContentHandler xhtml) throws SAXException, TikaException, IOException {
- // Notes text
- textRunsToText(xhtml, notes.getTextParagraphs());
+ if (!officeParserConfig.getIncludeSlideNotes()) {
+ return;
+ }
+ // Find the Notes for this slide and extract inline
+ HSLFNotes notes = slide.getNotes();
+ if (notes == null) {
+ return;
+ }
- // Repeat the notes footer, if set
- if (hf != null && hf.isFooterVisible() && hf.getFooterText() != null) {
- xhtml.startElement("p", "class", "slide-note-footer");
- xhtml.characters(hf.getFooterText());
- xhtml.endElement("p");
+ xhtml.startElement("div", "class", "notes");
+
+ // Repeat the Notes header, if set
+ if (officeParserConfig.getIncludeHeadersAndFooters() &&
+ notesHeaderFooters != null &&
+ notesHeaderFooters.isHeaderVisible() &&
+ notesHeaderFooters.getHeaderText() != null) {
+ xhtml.startElement("p", "class", "slide-note-header");
+ xhtml.characters(notesHeaderFooters.getHeaderText());
+ xhtml.endElement("p");
+ }
+ xhtml.startElement("div", "class", "notes-content");
+ // Notes text
+ textRunsToText(xhtml, notes.getTextParagraphs());
+
+ List<HSLFShape> shapes = getShapes(notes);
+ if (shapes != null && shapes.size() > 0) {
+ // Table text
+ for (HSLFShape shape : shapes) {
+ if (shape instanceof HSLFTable) {
+ extractTableText(xhtml, (HSLFTable) shape);
+ }
}
}
+ extractGroupText(xhtml, notes, 0);
+ //notes content
+ xhtml.endElement("div");
- handleSlideEmbeddedPictures(ss, xhtml);
- if (officeParserConfig.getExtractMacros()) {
- extractMacros(ss, xhtml);
+ // Repeat the Notes footer, if set
+ if (officeParserConfig.getIncludeHeadersAndFooters() &&
+ notesHeaderFooters != null &&
+ notesHeaderFooters.isFooterVisible() &&
+ notesHeaderFooters.getFooterText() != null) {
+ xhtml.startElement("p", "class", "slide-note-footer");
+ xhtml.characters(notesHeaderFooters.getFooterText());
+ xhtml.endElement("p");
}
+ // Now any embedded resources
+ handleSlideEmbeddedResources(notes, xhtml);
+ //end notes
xhtml.endElement("div");
}
//Extract any text that's within an HSLFTextShape that's a descendant of
//an HSLFGroupShape.
- private void extractGroupText(XHTMLContentHandler xhtml, List<HSLFShape> shapes, int depth) throws SAXException {
-
+ private void extractGroupText(XHTMLContentHandler xhtml, ShapeContainer shapeContainer, int depth) throws SAXException {
+ List<HSLFShape> shapes = getShapes(shapeContainer);
if (shapes == null) {
return;
}
@@ -239,11 +265,13 @@ public class HSLFExtractor extends AbstractPOIFSExtractor {
//However, cells are considered grouped within the table, so ignore them.
//I don't believe that cells can be inside a text box or other
//grouped text containing object, so always ignore them.
+ //I also don't believe that a table can be grouped with a table.
+ //If these beliefs are wrong...must fix!
List<List<HSLFTextParagraph>> paragraphList = new ArrayList<>();
for (HSLFShape shape : shapes) {
if (shape instanceof HSLFGroupShape) {
//work recursively, HSLFGroupShape can contain HSLFGroupShape
- extractGroupText(xhtml, ((HSLFGroupShape)shape).getShapes(), depth+1);
+ extractGroupText(xhtml, ((HSLFGroupShape)shape), depth+1);
} else if (shape instanceof HSLFTextShape
&& ! (shape instanceof HSLFTableCell) && depth > 0) {
paragraphList.add(((HSLFTextShape)shape).getTextParagraphs());
@@ -289,7 +317,7 @@ public class HSLFExtractor extends AbstractPOIFSExtractor {
if (master == null) {
return;
}
- List<HSLFShape> shapes = master.getShapes();
+ List<HSLFShape> shapes = getShapes(master);
if (shapes == null || shapes.isEmpty()) {
return;
}
@@ -441,19 +469,14 @@ public class HSLFExtractor extends AbstractPOIFSExtractor {
}
}
- private void handleSlideEmbeddedResources(HSLFSlide slide, XHTMLContentHandler xhtml)
+ private void handleSlideEmbeddedResources(ShapeContainer shapeContainer, XHTMLContentHandler xhtml)
throws TikaException, SAXException, IOException {
- List<HSLFShape> shapes;
- try {
- shapes = slide.getShapes();
- } catch (NullPointerException e) {
- // Sometimes HSLF hits problems
- // Please open POI bugs for any you come across!
- EmbeddedDocumentUtil.recordEmbeddedStreamException(e, parentMetadata);
+ List<HSLFShape> shapes = getShapes(shapeContainer);
+ if (shapes == null) {
return;
}
-
for (HSLFShape shape : shapes) {
+ //handle ActiveXShape, movie shape?
if (shape instanceof HSLFObjectShape) {
HSLFObjectShape oleShape = (HSLFObjectShape) shape;
HSLFObjectData data = null;
@@ -520,4 +543,17 @@ public class HSLFExtractor extends AbstractPOIFSExtractor {
}
}
}
+
+ //Can return null!
+ private List<HSLFShape> getShapes(ShapeContainer shapeContainer) {
+ try {
+ return shapeContainer.getShapes();
+ } catch (NullPointerException e) {
+ // Sometimes HSLF hits problems
+ // Please open POI bugs for any you come across!
+ EmbeddedDocumentUtil.recordEmbeddedStreamException(e, parentMetadata);
+ return null;
+ }
+ }
+
}
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/OfficeParserConfig.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/OfficeParserConfig.java
index 5d34b2e..d2bc790 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/OfficeParserConfig.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/OfficeParserConfig.java
@@ -17,8 +17,6 @@
package org.apache.tika.parser.microsoft;
-import org.apache.tika.config.Field;
-
import java.io.Serializable;
public class OfficeParserConfig implements Serializable {
@@ -30,6 +28,8 @@ public class OfficeParserConfig implements Serializable {
private boolean includeShapeBasedContent = true;
private boolean includeHeadersAndFooters = true;
private boolean includeMissingRows = false;
+ private boolean includeSlideNotes = true;
+ private boolean includeSlideMasterContent = true;
private boolean concatenatePhoneticRuns = true;
private boolean useSAXDocxExtractor = false;
@@ -206,6 +206,44 @@ public class OfficeParserConfig implements Serializable {
public boolean getIncludeMissingRows() {
return includeMissingRows;
}
+
+ public boolean getIncludeSlideNotes() {
+ return includeSlideNotes;
+ }
+
+ /**
+ * Whether or not to process slide notes content. If set
+ * to <code>false</code>, the parser will skip the text content
+ * and all embedded objects from the slide notes in ppt and ppt[xm].
+ * The default is <code>true</code>.
+ *
+ * @param includeSlideNotes whether or not to process slide notes
+ * @since 1.19.1
+ */
+ public void setIncludeSlideNotes(boolean includeSlideNotes) {
+ this.includeSlideNotes = includeSlideNotes;
+ }
+
+ /**
+ * @since 1.19.1
+ * @return whether or not to process content in slide masters
+ */
+ public boolean getIncludeSlideMasterContent() {
+ return includeSlideMasterContent;
+ }
+
+ /**
+ * Whether or not to include contents from any of the three
+ * types of masters -- slide, notes, handout -- in a .ppt or ppt[xm] file.
+ * If set to <code>false</code>, the parser will not extract
+ * text or embedded objects from any of the masters.
+ *
+ * @since 1.19.1
+ * @param includeSlideMasterContent
+ */
+ public void setIncludeSlideMasterContent(boolean includeSlideMasterContent) {
+ this.includeSlideMasterContent = includeSlideMasterContent;
+ }
}
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java
index 10ff76e..ac6e278 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/SXSLFPowerPointExtractorDecorator.java
@@ -122,20 +122,22 @@ public class SXSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
}
}
- handleGeneralTextContainingPart(XSLFRelation.SLIDE_MASTER.getRelation(),
- "slide-master",
- mainDocument,
- metadata,
- new PlaceHolderSkipper(new OOXMLWordAndPowerPointTextHandler(
- new OOXMLTikaBodyPartHandler(xhtml), new HashMap<String, String>())));
-
- handleGeneralTextContainingPart(HANDOUT_MASTER,
- "slide-handout-master",
- mainDocument,
- metadata,
- new OOXMLWordAndPowerPointTextHandler(
- new OOXMLTikaBodyPartHandler(xhtml), new HashMap<String, String>())
- );
+ if (config.getIncludeSlideMasterContent()) {
+ handleGeneralTextContainingPart(XSLFRelation.SLIDE_MASTER.getRelation(),
+ "slide-master",
+ mainDocument,
+ metadata,
+ new PlaceHolderSkipper(new OOXMLWordAndPowerPointTextHandler(
+ new OOXMLTikaBodyPartHandler(xhtml), new HashMap<String, String>())));
+
+ handleGeneralTextContainingPart(HANDOUT_MASTER,
+ "slide-handout-master",
+ mainDocument,
+ metadata,
+ new OOXMLWordAndPowerPointTextHandler(
+ new OOXMLTikaBodyPartHandler(xhtml), new HashMap<String, String>())
+ );
+ }
}
private void loadCommentAuthors() {
@@ -195,26 +197,29 @@ public class SXSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
xhtml.endElement("div");
+ if (config.getIncludeSlideMasterContent()) {
+ handleGeneralTextContainingPart(XSLFRelation.SLIDE_LAYOUT.getRelation(),
+ "slide-master-content", slidePart,
+ metadata,
+ new PlaceHolderSkipper(new OOXMLWordAndPowerPointTextHandler(
+ new OOXMLTikaBodyPartHandler(xhtml), linkedRelationships))
+ );
+ }
+ if (config.getIncludeSlideNotes()) {
+ handleGeneralTextContainingPart(XSLFRelation.NOTES.getRelation(),
+ "slide-notes", slidePart,
+ metadata,
+ new OOXMLWordAndPowerPointTextHandler(
+ new OOXMLTikaBodyPartHandler(xhtml), linkedRelationships));
+ if (config.getIncludeSlideMasterContent()) {
+ handleGeneralTextContainingPart(XSLFRelation.NOTES_MASTER.getRelation(),
+ "slide-notes-master", slidePart,
+ metadata,
+ new OOXMLWordAndPowerPointTextHandler(
+ new OOXMLTikaBodyPartHandler(xhtml), linkedRelationships));
- handleGeneralTextContainingPart(XSLFRelation.SLIDE_LAYOUT.getRelation(),
- "slide-master-content", slidePart,
- metadata,
- new PlaceHolderSkipper(new OOXMLWordAndPowerPointTextHandler(
- new OOXMLTikaBodyPartHandler(xhtml), linkedRelationships))
- );
-
- handleGeneralTextContainingPart(XSLFRelation.NOTES.getRelation(),
- "slide-notes", slidePart,
- metadata,
- new OOXMLWordAndPowerPointTextHandler(
- new OOXMLTikaBodyPartHandler(xhtml), linkedRelationships));
-
- handleGeneralTextContainingPart(XSLFRelation.NOTES_MASTER.getRelation(),
- "slide-notes-master", slidePart,
- metadata,
- new OOXMLWordAndPowerPointTextHandler(
- new OOXMLTikaBodyPartHandler(xhtml), linkedRelationships));
-
+ }
+ }
handleGeneralTextContainingPart(XSLFRelation.COMMENTS.getRelation(),
null, slidePart,
metadata,
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSLFPowerPointExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSLFPowerPointExtractorDecorator.java
index 3d929ba..c63fcb3 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSLFPowerPointExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSLFPowerPointExtractorDecorator.java
@@ -110,29 +110,32 @@ public class XSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
extractContent(slide.getShapes(), false, xhtml, slideDesc);
xhtml.endElement("div");
- // slide layout which is the master sheet for this slide
- xhtml.startElement("div", "class", "slide-master-content");
- XSLFSlideLayout slideLayout = slide.getMasterSheet();
- extractContent(slideLayout.getShapes(), true, xhtml, null);
- xhtml.endElement("div");
-
- // slide master which is the master sheet for all text layouts
- XSLFSheet slideMaster = slideLayout.getMasterSheet();
- extractContent(slideMaster.getShapes(), true, xhtml, null);
-
- // notes (if present)
- XSLFNotes slideNotes = slide.getNotes();
- if (slideNotes != null) {
- xhtml.startElement("div", "class", "slide-notes");
-
- extractContent(slideNotes.getShapes(), false, xhtml, slideDesc);
+ if (config.getIncludeSlideMasterContent()) {
+ // slide layout which is the master sheet for this slide
+ xhtml.startElement("div", "class", "slide-master-content");
+ XSLFSlideLayout slideLayout = slide.getMasterSheet();
+ extractContent(slideLayout.getShapes(), true, xhtml, null);
+ xhtml.endElement("div");
- // master sheet for this notes
- XSLFNotesMaster notesMaster = slideNotes.getMasterSheet();
- if (notesMaster != null) {
- extractContent(notesMaster.getShapes(), true, xhtml, null);
+ // slide master which is the master sheet for all text layouts
+ XSLFSheet slideMaster = slideLayout.getMasterSheet();
+ extractContent(slideMaster.getShapes(), true, xhtml, null);
+ }
+ if (config.getIncludeSlideNotes()) {
+ // notes (if present)
+ XSLFNotes slideNotes = slide.getNotes();
+ if (slideNotes != null) {
+ xhtml.startElement("div", "class", "slide-notes");
+
+ extractContent(slideNotes.getShapes(), false, xhtml, slideDesc);
+
+ // master sheet for this notes
+ XSLFNotesMaster notesMaster = slideNotes.getMasterSheet();
+ if (notesMaster != null) {
+ extractContent(notesMaster.getShapes(), true, xhtml, null);
+ }
+ xhtml.endElement("div");
}
- xhtml.endElement("div");
}
// comments (if present)
@@ -193,6 +196,7 @@ public class XSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
private void extractContent(List<? extends XSLFShape> shapes, boolean skipPlaceholders, XHTMLContentHandler xhtml, String slideDesc)
throws SAXException {
for (XSLFShape sh : shapes) {
+
if (sh instanceof XSLFTextShape) {
XSLFTextShape txt = (XSLFTextShape) sh;
Placeholder ph = txt.getTextType();
@@ -202,7 +206,9 @@ public class XSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
boolean inHyperlink = false;
for (XSLFTextParagraph p : txt.getTextParagraphs()) {
xhtml.startElement("p");
-
+ if (! config.getIncludeHeadersAndFooters() && p.isHeaderOrFooter()) {
+ continue;
+ }
for (XSLFTextRun run : p.getTextRuns()) {
//TODO: add check for targetmode=external into POI
//then check to confirm that the urls are actually
diff --git a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/PowerPointParserTest.java b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/PowerPointParserTest.java
index dbba939..658c0d5 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/PowerPointParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/PowerPointParserTest.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.util.List;
import java.util.Locale;
+import org.apache.ctakes.typesystem.type.syntax.O;
import org.apache.tika.TikaTest;
import org.apache.tika.exception.EncryptedDocumentException;
import org.apache.tika.metadata.Metadata;
@@ -122,6 +123,23 @@ public class PowerPointParserTest extends TikaTest {
}
@Test
+ @Ignore("not sure why this isn't working")
+ public void testSkipHeaderFooter() throws Exception {
+ //now test turning off header/footer
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeHeadersAndFooters(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ String xml = getXML("testPPT_various.ppt", context).xml;
+ //"This is the header text" should show up as a notes header
+ //however, it is currently being extracted while we process notes
+ //as just a regular HSLFTextParagraph with a value of "false"
+ //for p.isHeaderOrFooter().
+ assertNotContained("This is the header text", xml);
+
+ }
+
+ @Test
public void testMasterFooter() throws Exception {
ContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
@@ -141,6 +159,18 @@ public class PowerPointParserTest extends TikaTest {
assertEquals(-1, content.indexOf("*"));
}
+ @Test
+ @Ignore("not working")
+ public void testTurningOffMasterFooter() throws Exception {
+ //now test turning off master content
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ assertNotContained("Master footer",
+ getXML("testPPT_masterFooter.ppt", context).xml);
+ }
+
/**
* TIKA-712 Master Slide Text from PPT and PPTX files
* should be extracted too
@@ -163,6 +193,15 @@ public class PowerPointParserTest extends TikaTest {
//TIKA-1171, POI-62591
assertEquals(-1, content.indexOf("*"));
+
+ //now test turning off master content
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ content = getXML("testPPT_masterText.ppt", context).xml;
+ assertNotContained("Text that I added", content);
+
}
@Test
@@ -182,6 +221,15 @@ public class PowerPointParserTest extends TikaTest {
assertEquals(-1, content.indexOf("Click to edit Master"));
//TIKA-1171, POI-62591
assertEquals(-1, content.indexOf("*"));
+
+ //now test turning off master content
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ content = getXML("testPPT_masterText2.ppt", context).xml;
+ assertNotContained("Text that I added", content);
+
}
/**
diff --git a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java
index a2eb625..ce8ea28 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java
@@ -770,6 +770,18 @@ public class OOXMLParserTest extends TikaTest {
}
@Test
+ public void testSkipHeaderFooter() throws Exception {
+ //now test turning off header/footer
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeHeadersAndFooters(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ String xml = getXML("testPPT_various.pptx", context).xml;
+ assertNotContained("This is the header text", xml);
+
+ }
+
+ @Test
public void testCommentPPTX() throws Exception {
XMLResult r = getXML("testPPT_comment.pptx");
assertContains("<p class=\"slide-comment\"><b>Allison, Timothy B. (ATB)", r.xml);
@@ -789,6 +801,21 @@ public class OOXMLParserTest extends TikaTest {
assertContains("Master footer is here", content);
}
+ @Test
+ @Ignore("can't tell why this isn't working")
+ public void testTurningOffMasterContent() throws Exception {
+ //now test turning off master content
+
+ //the underlying xml has "Master footer" in
+ //the actual slide's xml, not just in the master slide.
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ String xml = getXML("testPPT_masterFooter.pptx", context).xml;
+ assertNotContained("Master footer", xml);
+ }
+
/**
* TIKA-712 Master Slide Text from PPT and PPTX files
* should be extracted too
@@ -805,6 +832,14 @@ public class OOXMLParserTest extends TikaTest {
String content = handler.toString();
assertContains("Text that I added to the master slide", content);
+
+ //now test turning off master content
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ content = getXML("testPPT_masterText.pptx", context).xml;
+ assertNotContained("Text that I added", content);
}
@Test
@@ -819,6 +854,14 @@ public class OOXMLParserTest extends TikaTest {
String content = handler.toString();
assertContains("Text that I added to the master slide", content);
+
+ //now test turning off master content
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ content = getXML("testPPT_masterText2.pptx", context).xml;
+ assertNotContained("Text that I added", content);
}
@Test
diff --git a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/SXSLFExtractorTest.java b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/SXSLFExtractorTest.java
index cb935c5..651e5f5 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/SXSLFExtractorTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/ooxml/SXSLFExtractorTest.java
@@ -369,6 +369,21 @@ public class SXSLFExtractorTest extends TikaTest {
getXML("testPPT_masterFooter.pptx", parseContext).xml);
}
+ @Test
+ @Ignore("can't tell why this isn't working")
+ public void testTurningOffMasterContent() throws Exception {
+ //now test turning off master content
+
+ //the underlying xml has "Master footer" in
+ //the actual slide's xml, not just in the master slide.
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ config.setUseSAXPptxExtractor(true);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+ String xml = getXML("testPPT_masterFooter.pptx", context).xml;
+ assertNotContained("Master footer", xml);
+ }
/**
* TIKA-712 Master Slide Text from PPT and PPTX files
* should be extracted too
@@ -377,12 +392,32 @@ public class SXSLFExtractorTest extends TikaTest {
public void testMasterText() throws Exception {
assertContains("Text that I added to the master slide",
getXML("testPPT_masterText.pptx", parseContext).xml);
+
+ //now test turning off master content
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ config.setUseSAXPptxExtractor(true);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+
+ assertNotContained("Text that I added",
+ getXML("testPPT_masterText.pptx", context).xml);
}
@Test
public void testMasterText2() throws Exception {
assertContains("Text that I added to the master slide",
getXML("testPPT_masterText2.pptx", parseContext).xml);
+
+ //now test turning off master content
+ OfficeParserConfig config = new OfficeParserConfig();
+ config.setIncludeSlideMasterContent(false);
+ config.setUseSAXPptxExtractor(true);
+ ParseContext context = new ParseContext();
+ context.set(OfficeParserConfig.class, config);
+
+ assertNotContained("Text that I added",
+ getXML("testPPT_masterText2.pptx", context).xml);
}
@Test