You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ss...@apache.org on 2020/01/29 11:28:27 UTC

svn commit: r1873298 - in /xmlgraphics/fop/trunk/fop-core/src: main/java/org/apache/fop/accessibility/ main/java/org/apache/fop/accessibility/fo/ main/java/org/apache/fop/apps/ test/java/org/apache/fop/accessibility/fo/ test/java/org/apache/fop/apps/

Author: ssteiner
Date: Wed Jan 29 11:28:26 2020
New Revision: 1873298

URL: http://svn.apache.org/viewvc?rev=1873298&view=rev
Log:
FOP-2909: Hide empty blocks from structure tree

Added:
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/Event.java   (with props)
Modified:
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/Accessibility.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfBuilder.java
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfParserTestCase.java
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/Accessibility.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/Accessibility.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/Accessibility.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/Accessibility.java Wed Jan 29 11:28:26 2020
@@ -28,6 +28,9 @@ public final class Accessibility {
     /** Constant string for the rendering options key to enable accessibility features. */
     public static final String ACCESSIBILITY = "accessibility";
 
+    /** Constant string for the rendering options key to suppress empty tags from structure tree. */
+    public static final String KEEP_EMPTY_TAGS = "keep-empty-tags";
+
     /**
      * The value to be set on the 'role' property for the element and its descendants to
      * be considered as artifacts.

Added: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/Event.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/Event.java?rev=1873298&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/Event.java (added)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/Event.java Wed Jan 29 11:28:26 2020
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+package org.apache.fop.accessibility.fo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.fop.fo.FOEventHandler;
+
+class Event {
+    private List<Event> children = new ArrayList<Event>();
+    protected FOEventHandler eventHandler;
+    protected Event parent;
+    protected boolean hasContent;
+
+    public Event(FO2StructureTreeConverter structureTreeConverter) {
+        eventHandler = structureTreeConverter.converter;
+    }
+
+    public Event(Event parent) {
+        this.parent = parent;
+    }
+
+    public void run() {
+        if (hasContent()) {
+            for (Event e : children) {
+                e.run();
+            }
+        }
+        children.clear();
+    }
+
+    private boolean hasContent() {
+        for (Event e : children) {
+            if (e.hasContent()) {
+                return true;
+            }
+        }
+        return hasContent;
+    }
+
+    public void add(Event child) {
+        children.add(child);
+    }
+}

Propchange: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/Event.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java Wed Jan 29 11:28:26 2020
@@ -73,7 +73,7 @@ import org.apache.fop.fo.properties.Comm
 public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
 
     /** The top of the {@link converters} stack. */
-    private FOEventHandler converter;
+    protected FOEventHandler converter;
 
     private Stack<FOEventHandler> converters = new Stack<FOEventHandler>();
 
@@ -99,6 +99,42 @@ public class FO2StructureTreeConverter e
 
     }
 
+    private Event root = new Event((Event) null);
+    private Event currentNode = root;
+
+    private void startContent(Event event, boolean hasContent) {
+        if (getUserAgent().isKeepEmptyTags()) {
+            event.run();
+        } else {
+            Event node = new Event(currentNode);
+            event.hasContent = hasContent;
+            node.add(event);
+            currentNode.add(node);
+            currentNode = node;
+        }
+    }
+
+    private void content(Event event, boolean hasContent) {
+        if (getUserAgent().isKeepEmptyTags()) {
+            event.run();
+        } else {
+            currentNode.add(event);
+            event.hasContent = hasContent;
+        }
+    }
+
+    private void endContent(Event event) {
+        if (getUserAgent().isKeepEmptyTags()) {
+            event.run();
+        } else {
+            currentNode.add(event);
+            currentNode = currentNode.parent;
+            if (currentNode == root) {
+                root.run();
+            }
+        }
+    }
+
     /**
      * Creates a new instance.
      *
@@ -149,51 +185,83 @@ public class FO2StructureTreeConverter e
     }
 
     @Override
-    public void startPageNumber(PageNumber pagenum) {
-        converter.startPageNumber(pagenum);
+    public void startPageNumber(final PageNumber pagenum) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startPageNumber(pagenum);
+            }
+        }, true);
         super.startPageNumber(pagenum);
     }
 
     @Override
-    public void endPageNumber(PageNumber pagenum) {
-        converter.endPageNumber(pagenum);
+    public void endPageNumber(final PageNumber pagenum) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endPageNumber(pagenum);
+            }
+        });
         super.endPageNumber(pagenum);
     }
 
     @Override
-    public void startPageNumberCitation(PageNumberCitation pageCite) {
-        converter.startPageNumberCitation(pageCite);
+    public void startPageNumberCitation(final PageNumberCitation pageCite) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startPageNumberCitation(pageCite);
+            }
+        }, true);
         super.startPageNumberCitation(pageCite);
     }
 
     @Override
-    public void endPageNumberCitation(PageNumberCitation pageCite) {
-        converter.endPageNumberCitation(pageCite);
+    public void endPageNumberCitation(final PageNumberCitation pageCite) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endPageNumberCitation(pageCite);
+            }
+        });
         super.endPageNumberCitation(pageCite);
     }
 
     @Override
-    public void startPageNumberCitationLast(PageNumberCitationLast pageLast) {
-        converter.startPageNumberCitationLast(pageLast);
+    public void startPageNumberCitationLast(final PageNumberCitationLast pageLast) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startPageNumberCitationLast(pageLast);
+            }
+        }, true);
         super.startPageNumberCitationLast(pageLast);
     }
 
     @Override
-    public void endPageNumberCitationLast(PageNumberCitationLast pageLast) {
-        converter.endPageNumberCitationLast(pageLast);
+    public void endPageNumberCitationLast(final PageNumberCitationLast pageLast) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endPageNumberCitationLast(pageLast);
+            }
+        });
         super.endPageNumberCitationLast(pageLast);
     }
 
     @Override
-    public void startStatic(StaticContent staticContent) {
+    public void startStatic(final StaticContent staticContent) {
         handleStartArtifact(staticContent);
-        converter.startStatic(staticContent);
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startStatic(staticContent);
+            }
+        }, true);
         super.startStatic(staticContent);
     }
 
     @Override
-    public void endStatic(StaticContent staticContent) {
-        converter.endStatic(staticContent);
+    public void endStatic(final StaticContent staticContent) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endStatic(staticContent);
+            }
+        });
         handleEndArtifact(staticContent);
         super.endStatic(staticContent);
     }
@@ -211,277 +279,457 @@ public class FO2StructureTreeConverter e
     }
 
     @Override
-    public void startBlock(Block bl) {
-        converter.startBlock(bl);
+    public void startBlock(final Block bl) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startBlock(bl);
+            }
+        }, false);
         super.startBlock(bl);
     }
 
     @Override
-    public void endBlock(Block bl) {
-        converter.endBlock(bl);
+    public void endBlock(final Block bl) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endBlock(bl);
+            }
+        });
         super.endBlock(bl);
     }
 
     @Override
-    public void startBlockContainer(BlockContainer blc) {
-        converter.startBlockContainer(blc);
+    public void startBlockContainer(final BlockContainer blc) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startBlockContainer(blc);
+            }
+        }, false);
         super.startBlockContainer(blc);
     }
 
     @Override
-    public void endBlockContainer(BlockContainer blc) {
-        converter.endBlockContainer(blc);
+    public void endBlockContainer(final BlockContainer blc) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endBlockContainer(blc);
+            }
+        });
         super.endBlockContainer(blc);
     }
 
     @Override
-    public void startInline(Inline inl) {
-        converter.startInline(inl);
+    public void startInline(final Inline inl) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startInline(inl);
+            }
+        }, true);
         super.startInline(inl);
     }
 
     @Override
-    public void endInline(Inline inl) {
-        converter.endInline(inl);
+    public void endInline(final Inline inl) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endInline(inl);
+            }
+        });
         super.endInline(inl);
     }
 
     @Override
-    public void startTable(Table tbl) {
-        converter.startTable(tbl);
+    public void startTable(final Table tbl) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startTable(tbl);
+            }
+        }, true);
         super.startTable(tbl);
     }
 
     @Override
-    public void endTable(Table tbl) {
-        converter.endTable(tbl);
+    public void endTable(final Table tbl) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endTable(tbl);
+            }
+        });
         super.endTable(tbl);
     }
 
     @Override
-    public void startColumn(TableColumn tc) {
-        converter.startColumn(tc);
+    public void startColumn(final TableColumn tc) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startColumn(tc);
+            }
+        }, true);
         super.startColumn(tc);
     }
 
     @Override
-    public void endColumn(TableColumn tc) {
-        converter.endColumn(tc);
+    public void endColumn(final TableColumn tc) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endColumn(tc);
+            }
+        });
         super.endColumn(tc);
     }
 
     @Override
-    public void startHeader(TableHeader header) {
-        converter.startHeader(header);
+    public void startHeader(final TableHeader header) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startHeader(header);
+            }
+        }, true);
         super.startHeader(header);
     }
 
     @Override
-    public void endHeader(TableHeader header) {
-        converter.endHeader(header);
+    public void endHeader(final TableHeader header) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endHeader(header);
+            }
+        });
         super.endHeader(header);
     }
 
     @Override
-    public void startFooter(TableFooter footer) {
-        converter.startFooter(footer);
+    public void startFooter(final TableFooter footer) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startFooter(footer);
+            }
+        }, true);
         super.startFooter(footer);
     }
 
     @Override
-    public void endFooter(TableFooter footer) {
-        converter.endFooter(footer);
+    public void endFooter(final TableFooter footer) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endFooter(footer);
+            }
+        });
         super.endFooter(footer);
     }
 
     @Override
-    public void startBody(TableBody body) {
-        converter.startBody(body);
+    public void startBody(final TableBody body) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startBody(body);
+            }
+        }, true);
         super.startBody(body);
     }
 
     @Override
-    public void endBody(TableBody body) {
-        converter.endBody(body);
+    public void endBody(final TableBody body) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endBody(body);
+            }
+        });
         super.endBody(body);
     }
 
     @Override
-    public void startRow(TableRow tr) {
-        converter.startRow(tr);
+    public void startRow(final TableRow tr) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startRow(tr);
+            }
+        }, true);
         super.startRow(tr);
     }
 
     @Override
-    public void endRow(TableRow tr) {
-        converter.endRow(tr);
+    public void endRow(final TableRow tr) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endRow(tr);
+            }
+        });
         super.endRow(tr);
     }
 
     @Override
-    public void startCell(TableCell tc) {
-        converter.startCell(tc);
+    public void startCell(final TableCell tc) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startCell(tc);
+            }
+        }, true);
         super.startCell(tc);
     }
 
     @Override
-    public void endCell(TableCell tc) {
-        converter.endCell(tc);
+    public void endCell(final TableCell tc) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endCell(tc);
+            }
+        });
         super.endCell(tc);
     }
 
     @Override
-    public void startList(ListBlock lb) {
-        converter.startList(lb);
+    public void startList(final ListBlock lb) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startList(lb);
+            }
+        }, true);
         super.startList(lb);
     }
 
     @Override
-    public void endList(ListBlock lb) {
-        converter.endList(lb);
+    public void endList(final ListBlock lb) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endList(lb);
+            }
+        });
         super.endList(lb);
     }
 
     @Override
-    public void startListItem(ListItem li) {
-        converter.startListItem(li);
+    public void startListItem(final ListItem li) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startListItem(li);
+            }
+        }, true);
         super.startListItem(li);
     }
 
     @Override
-    public void endListItem(ListItem li) {
-        converter.endListItem(li);
+    public void endListItem(final ListItem li) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endListItem(li);
+            }
+        });
         super.endListItem(li);
     }
 
     @Override
-    public void startListLabel(ListItemLabel listItemLabel) {
-        converter.startListLabel(listItemLabel);
+    public void startListLabel(final ListItemLabel listItemLabel) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startListLabel(listItemLabel);
+            }
+        }, true);
         super.startListLabel(listItemLabel);
     }
 
     @Override
-    public void endListLabel(ListItemLabel listItemLabel) {
-        converter.endListLabel(listItemLabel);
+    public void endListLabel(final ListItemLabel listItemLabel) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endListLabel(listItemLabel);
+            }
+        });
         super.endListLabel(listItemLabel);
     }
 
     @Override
-    public void startListBody(ListItemBody listItemBody) {
-        converter.startListBody(listItemBody);
+    public void startListBody(final ListItemBody listItemBody) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startListBody(listItemBody);
+            }
+        }, true);
         super.startListBody(listItemBody);
     }
 
     @Override
-    public void endListBody(ListItemBody listItemBody) {
-        converter.endListBody(listItemBody);
+    public void endListBody(final ListItemBody listItemBody) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endListBody(listItemBody);
+            }
+        });
         super.endListBody(listItemBody);
     }
 
     @Override
     public void startMarkup() {
-        converter.startMarkup();
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startMarkup();
+            }
+        }, true);
         super.startMarkup();
     }
 
     @Override
     public void endMarkup() {
-        converter.endMarkup();
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endMarkup();
+            }
+        });
         super.endMarkup();
     }
 
     @Override
-    public void startLink(BasicLink basicLink) {
-        converter.startLink(basicLink);
+    public void startLink(final BasicLink basicLink) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startLink(basicLink);
+            }
+        }, true);
         super.startLink(basicLink);
     }
 
     @Override
-    public void endLink(BasicLink basicLink) {
-        converter.endLink(basicLink);
+    public void endLink(final BasicLink basicLink) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endLink(basicLink);
+            }
+        });
         super.endLink(basicLink);
     }
 
     @Override
-    public void image(ExternalGraphic eg) {
-        converter.image(eg);
+    public void image(final ExternalGraphic eg) {
+        content(new Event(this) {
+            public void run() {
+                eventHandler.image(eg);
+            }
+        }, true);
         super.image(eg);
     }
 
     @Override
     public void pageRef() {
-        converter.pageRef();
+        content(new Event(this) {
+            public void run() {
+                eventHandler.pageRef();
+            }
+        }, true);
         super.pageRef();
     }
 
     @Override
-    public void startInstreamForeignObject(InstreamForeignObject ifo) {
-        converter.startInstreamForeignObject(ifo);
+    public void startInstreamForeignObject(final InstreamForeignObject ifo) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startInstreamForeignObject(ifo);
+            }
+        }, true);
         super.startInstreamForeignObject(ifo);
     }
 
     @Override
-    public void endInstreamForeignObject(InstreamForeignObject ifo) {
-        converter.endInstreamForeignObject(ifo);
+    public void endInstreamForeignObject(final InstreamForeignObject ifo) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endInstreamForeignObject(ifo);
+            }
+        });
         super.endInstreamForeignObject(ifo);
     }
 
     @Override
-    public void startFootnote(Footnote footnote) {
-        converter.startFootnote(footnote);
+    public void startFootnote(final Footnote footnote) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startFootnote(footnote);
+            }
+        }, true);
         super.startFootnote(footnote);
     }
 
     @Override
-    public void endFootnote(Footnote footnote) {
-        converter.endFootnote(footnote);
+    public void endFootnote(final Footnote footnote) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endFootnote(footnote);
+            }
+        });
         super.endFootnote(footnote);
     }
 
     @Override
-    public void startFootnoteBody(FootnoteBody body) {
-        converter.startFootnoteBody(body);
+    public void startFootnoteBody(final FootnoteBody body) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startFootnoteBody(body);
+            }
+        }, true);
         super.startFootnoteBody(body);
     }
 
     @Override
-    public void endFootnoteBody(FootnoteBody body) {
-        converter.endFootnoteBody(body);
+    public void endFootnoteBody(final FootnoteBody body) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endFootnoteBody(body);
+            }
+        });
         super.endFootnoteBody(body);
     }
 
     @Override
-    public void startLeader(Leader l) {
+    public void startLeader(final Leader l) {
         converters.push(converter);
         converter = eventSwallower;
-        converter.startLeader(l);
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startLeader(l);
+            }
+        }, true);
         super.startLeader(l);
     }
 
     @Override
-    public void endLeader(Leader l) {
-        converter.endLeader(l);
+    public void endLeader(final Leader l) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endLeader(l);
+            }
+        });
         converter = converters.pop();
         super.endLeader(l);
     }
 
     @Override
-    public void startWrapper(Wrapper wrapper) {
+    public void startWrapper(final Wrapper wrapper) {
         handleStartArtifact(wrapper);
-        converter.startWrapper(wrapper);
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startWrapper(wrapper);
+            }
+        }, true);
         super.startWrapper(wrapper);
     }
 
     @Override
-    public void endWrapper(Wrapper wrapper) {
-        converter.endWrapper(wrapper);
+    public void endWrapper(final Wrapper wrapper) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endWrapper(wrapper);
+            }
+        });
         handleEndArtifact(wrapper);
         super.endWrapper(wrapper);
     }
 
     @Override
-    public void startRetrieveMarker(RetrieveMarker retrieveMarker) {
-        converter.startRetrieveMarker(retrieveMarker);
+    public void startRetrieveMarker(final RetrieveMarker retrieveMarker) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startRetrieveMarker(retrieveMarker);
+            }
+        }, true);
         saveState(retrieveMarker);
         super.startRetrieveMarker(retrieveMarker);
     }
@@ -491,15 +739,23 @@ public class FO2StructureTreeConverter e
     }
 
     @Override
-    public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
-        converter.endRetrieveMarker(retrieveMarker);
+    public void endRetrieveMarker(final RetrieveMarker retrieveMarker) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endRetrieveMarker(retrieveMarker);
+            }
+        });
         super.endRetrieveMarker(retrieveMarker);
     }
 
     @Override
-    public void restoreState(RetrieveMarker retrieveMarker) {
+    public void restoreState(final RetrieveMarker retrieveMarker) {
         restoreRetrieveMarkerState(retrieveMarker);
-        converter.restoreState(retrieveMarker);
+        content(new Event(this) {
+            public void run() {
+                eventHandler.restoreState(retrieveMarker);
+            }
+        }, true);
         super.restoreState(retrieveMarker);
     }
 
@@ -511,46 +767,74 @@ public class FO2StructureTreeConverter e
     }
 
     @Override
-    public void startRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
-        converter.startRetrieveTableMarker(retrieveTableMarker);
+    public void startRetrieveTableMarker(final RetrieveTableMarker retrieveTableMarker) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startRetrieveTableMarker(retrieveTableMarker);
+            }
+        }, true);
         saveState(retrieveTableMarker);
         super.startRetrieveTableMarker(retrieveTableMarker);
     }
 
     @Override
-    public void endRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
-        converter.endRetrieveTableMarker(retrieveTableMarker);
+    public void endRetrieveTableMarker(final RetrieveTableMarker retrieveTableMarker) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endRetrieveTableMarker(retrieveTableMarker);
+            }
+        });
         super.endRetrieveTableMarker(retrieveTableMarker);
     }
 
     @Override
-    public void restoreState(RetrieveTableMarker retrieveTableMarker) {
+    public void restoreState(final RetrieveTableMarker retrieveTableMarker) {
         restoreRetrieveMarkerState(retrieveTableMarker);
-        converter.restoreState(retrieveTableMarker);
+        currentNode.add(new Event(this) {
+            public void run() {
+                eventHandler.restoreState(retrieveTableMarker);
+            }
+        });
         super.restoreState(retrieveTableMarker);
     }
 
     @Override
-    public void character(Character c) {
-        converter.character(c);
+    public void character(final Character c) {
+        content(new Event(this) {
+            public void run() {
+                eventHandler.character(c);
+            }
+        }, true);
         super.character(c);
     }
 
     @Override
-    public void characters(FOText foText) {
-        converter.characters(foText);
+    public void characters(final FOText foText) {
+        content(new Event(this) {
+            public void run() {
+                eventHandler.characters(foText);
+            }
+        }, foText.length() > 0);
         super.characters(foText);
     }
 
     @Override
-    public void startExternalDocument(ExternalDocument document) {
-        converter.startExternalDocument(document);
+    public void startExternalDocument(final ExternalDocument document) {
+        startContent(new Event(this) {
+            public void run() {
+                eventHandler.startExternalDocument(document);
+            }
+        }, true);
         super.startExternalDocument(document);
     }
 
     @Override
-    public void endExternalDocument(ExternalDocument document) {
-        converter.endExternalDocument(document);
+    public void endExternalDocument(final ExternalDocument document) {
+        endContent(new Event(this) {
+            public void run() {
+                eventHandler.endExternalDocument(document);
+            }
+        });
         super.endExternalDocument(document);
     }
 

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java Wed Jan 29 11:28:26 2020
@@ -149,6 +149,7 @@ public class FOUserAgent {
         this.resourceResolver = resourceResolver;
         setTargetResolution(factory.getTargetResolution());
         setAccessibility(factory.isAccessibilityEnabled());
+        setKeepEmptyTags(factory.isKeepEmptyTags());
         imageSessionContext = new AbstractImageSessionContext(factory.getFallbackResolver()) {
 
             public ImageContext getParentContext() {
@@ -817,4 +818,17 @@ public class FOUserAgent {
     public HyphenationTreeCache getHyphenationTreeCache() {
         return factory.getHyphenationTreeCache();
     }
+
+    public void setKeepEmptyTags(boolean b) {
+        getRendererOptions().put(Accessibility.KEEP_EMPTY_TAGS, b);
+    }
+
+    public boolean isKeepEmptyTags() {
+        Boolean enabled = (Boolean)getRendererOptions().get(Accessibility.KEEP_EMPTY_TAGS);
+        if (enabled != null) {
+            return enabled;
+        } else {
+            return true;
+        }
+    }
 }

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java Wed Jan 29 11:28:26 2020
@@ -38,6 +38,7 @@ import org.apache.xmlgraphics.image.load
 import org.apache.xmlgraphics.image.loader.util.Penalty;
 import org.apache.xmlgraphics.io.ResourceResolver;
 
+import org.apache.fop.accessibility.Accessibility;
 import org.apache.fop.apps.io.InternalResourceResolver;
 import org.apache.fop.apps.io.ResourceResolverFactory;
 import org.apache.fop.configuration.Configuration;
@@ -185,6 +186,8 @@ public class FopConfParser {
         if (cfg.getChild("accessibility", false) != null) {
             try {
                 fopFactoryBuilder.setAccessibility(cfg.getChild("accessibility").getValueAsBoolean());
+                fopFactoryBuilder.setKeepEmptyTags(
+                        cfg.getChild("accessibility").getAttributeAsBoolean(Accessibility.KEEP_EMPTY_TAGS, true));
             } catch (ConfigurationException e) {
                 LogUtil.handleException(log, e, false);
             }

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java Wed Jan 29 11:28:26 2020
@@ -328,6 +328,10 @@ public final class FopFactory implements
         return config.isAccessibilityEnabled();
     }
 
+    boolean isKeepEmptyTags() {
+        return config.isKeepEmptyTags();
+    }
+
     /** @see FopFactoryConfig#getImageManager() */
     public ImageManager getImageManager() {
         return config.getImageManager();

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java Wed Jan 29 11:28:26 2020
@@ -160,6 +160,11 @@ public final class FopFactoryBuilder {
         return this;
     }
 
+    public FopFactoryBuilder setKeepEmptyTags(boolean b) {
+        fopFactoryConfigBuilder.setKeepEmptyTags(b);
+        return this;
+    }
+
     /**
      * Sets the {@link LayoutManagerMaker} so that users can configure how FOP creates
      * {@link org.apache.fop.layoutmgr.LayoutManager}s.
@@ -330,6 +335,8 @@ public final class FopFactoryBuilder {
 
         private boolean accessibility;
 
+        private boolean keepEmptyTags = true;
+
         private LayoutManagerMaker layoutManagerMaker;
 
         private URI baseURI;
@@ -385,6 +392,10 @@ public final class FopFactoryBuilder {
             return accessibility;
         }
 
+        public boolean isKeepEmptyTags() {
+            return keepEmptyTags;
+        }
+
         /** {@inheritDoc} */
         public LayoutManagerMaker getLayoutManagerMakerOverride() {
             return layoutManagerMaker;
@@ -485,6 +496,7 @@ public final class FopFactoryBuilder {
     private interface FopFactoryConfigBuilder {
 
         void setAccessibility(boolean enableAccessibility);
+        void setKeepEmptyTags(boolean b);
 
         void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker);
 
@@ -531,6 +543,9 @@ public final class FopFactoryBuilder {
         public void setAccessibility(boolean enableAccessibility) {
             throwIllegalStateException();
         }
+        public void setKeepEmptyTags(boolean b) {
+            throwIllegalStateException();
+        }
 
         public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
             throwIllegalStateException();
@@ -612,6 +627,10 @@ public final class FopFactoryBuilder {
             config.accessibility = enableAccessibility;
         }
 
+        public void setKeepEmptyTags(boolean b) {
+            config.keepEmptyTags = b;
+        }
+
         public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
             config.layoutManagerMaker = lmMaker;
         }

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java Wed Jan 29 11:28:26 2020
@@ -67,6 +67,7 @@ public interface FopFactoryConfig {
      * @return true if accessibility features have been requested
      */
     boolean isAccessibilityEnabled();
+    boolean isKeepEmptyTags();
 
     /**
      * Returns the overriding LayoutManagerMaker instance, if any.

Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java Wed Jan 29 11:28:26 2020
@@ -19,12 +19,15 @@
 
 package org.apache.fop.accessibility.fo;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.StringWriter;
 
+import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
@@ -33,6 +36,7 @@ import javax.xml.transform.TransformerEx
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
@@ -44,6 +48,7 @@ import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
@@ -132,6 +137,52 @@ public class FO2StructureTreeConverterTe
         assertNull(d.getStructureTreeEventHandler().startNode("table-body", null, null));
     }
 
+    @Test
+    public void testRemoveBlocks() throws Exception {
+        compare("<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">\n"
+                        + "  <fo:layout-master-set>\n"
+                        + "    <fo:simple-page-master master-name=\"simple\">\n"
+                        + "      <fo:region-body />\n"
+                        + "    </fo:simple-page-master>\n"
+                        + "  </fo:layout-master-set>\n"
+                        + "  <fo:page-sequence master-reference=\"simple\">\n"
+                        + "    <fo:flow flow-name=\"xsl-region-body\">\n"
+                        + "    <fo:block/>"
+                        + "    <fo:block><fo:block/></fo:block>\n"
+                        + "    <fo:block>a</fo:block>\n"
+                        + "    </fo:flow>\n"
+                        + "  </fo:page-sequence>\n"
+                        + "</fo:root>\n",
+                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                        + "<structure-tree-sequence>\n"
+                        + "<structure-tree xmlns=\"http://xmlgraphics.apache.org/fop/intermediate\" "
+                        + "xmlns:foi=\"http://xmlgraphics.apache.org/fop/internal\" "
+                        + "xmlns:fox=\"http://xmlgraphics.apache.org/fop/extensions\">\n"
+                        + "<fo:flow xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" flow-name=\"xsl-region-body\">\n"
+                        + "<fo:block>\n"
+                        + "<marked-content/>\n"
+                        + "</fo:block>\n"
+                        + "</fo:flow>\n"
+                        + "</structure-tree>\n"
+                        + "</structure-tree-sequence>\n");
+    }
+
+    private void compare(final String fo, String tree) throws Exception {
+        foLoader = new FOLoader("") {
+            public InputStream getFoInputStream() {
+                return new ByteArrayInputStream(fo.getBytes());
+            }
+        };
+        DOMResult actualStructureTree = buildActualStructureTree();
+        Document doc = (Document) actualStructureTree.getNode();
+        StringWriter sw = new StringWriter();
+        TransformerFactory tf = TransformerFactory.newInstance();
+        Transformer transformer = tf.newTransformer();
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        transformer.transform(new DOMSource(doc), new StreamResult(sw));
+        assertEquals(tree, sw.toString());
+    }
+
     private void testConverter(String foResourceName) throws Exception {
         foLoader = new FOLoader(foResourceName);
         DOMResult expectedStructureTree = loadExpectedStructureTree();
@@ -216,6 +267,7 @@ public class FO2StructureTreeConverterTe
     private static FOUserAgent createFOUserAgent(FODocumentParser documentParser) {
         FOUserAgent userAgent = documentParser.createFOUserAgent();
         userAgent.setAccessibility(true);
+        userAgent.setKeepEmptyTags(false);
         return userAgent;
     }
 

Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfBuilder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfBuilder.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfBuilder.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfBuilder.java Wed Jan 29 11:28:26 2020
@@ -43,6 +43,7 @@ import javax.xml.transform.stream.Stream
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import org.apache.fop.accessibility.Accessibility;
 import org.apache.fop.render.RendererConfigOption;
 
 /**
@@ -137,8 +138,12 @@ public class FopConfBuilder implements F
      * @param setAccessibility true to enable accessibility features
      * @return <b>this</b>
      */
-    public FopConfBuilder setAccessibility(boolean setAccessibility) {
-        return createElement("accessibility", String.valueOf(setAccessibility));
+    public FopConfBuilder setAccessibility(boolean setAccessibility, boolean keepEmptyTags) {
+        Element el = fopConfDOM.createElement(Accessibility.ACCESSIBILITY);
+        el.setAttribute(Accessibility.KEEP_EMPTY_TAGS, String.valueOf(keepEmptyTags));
+        el.appendChild(fopConfDOM.createTextNode(String.valueOf(setAccessibility)));
+        root.appendChild(el);
+        return this;
     }
 
     @Deprecated

Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfParserTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfParserTestCase.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfParserTestCase.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/FopConfParserTestCase.java Wed Jan 29 11:28:26 2020
@@ -89,11 +89,17 @@ public class FopConfParserTestCase {
 
     @Test
     public void testAccessibility() {
-        builder.setAccessibility(false);
+        builder.setAccessibility(false, true);
         assertFalse(buildFactory().isAccessibilityEnabled());
     }
 
     @Test
+    public void testAccessibilityKeepEmptyTags() {
+        builder.setAccessibility(true, false);
+        assertFalse(buildFactory().isKeepEmptyTags());
+    }
+
+    @Test
     public void testSourceResolution() {
         float srcRes = 123.456f;
         builder.setSourceResolution(srcRes);

Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java?rev=1873298&r1=1873297&r2=1873298&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java Wed Jan 29 11:28:26 2020
@@ -52,6 +52,11 @@ public final class MutableConfig impleme
         return delegate.isAccessibilityEnabled();
     }
 
+
+    public boolean isKeepEmptyTags() {
+        return delegate.isKeepEmptyTags();
+    }
+
     public LayoutManagerMaker getLayoutManagerMakerOverride() {
         return delegate.getLayoutManagerMakerOverride();
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org