Commit af740c82 authored by Jos van den Oever's avatar Jos van den Oever

Replace bookmark/bookmark-end with bookmark-begin/bookmark-end.

A common problem in ODF files is that <text:bookmark/> is used instead of
<text:bookmark-end/>. This issue is fixed with this patch.
parent 3501cf6a
......@@ -554,12 +554,13 @@ public class OdfNormalizer {
n.normalize();
sortAutomaticStyles(doc);
fixBookmarkStart(doc, xml);
fixReferenceMarkOrder(doc, xml);
NamespaceCleaner.clean(doc);
}
static private final String markArray[] = { "bookmark-end",
"reference-mark-end", "reference-mark-start", "bookmark" };
"reference-mark-end", "reference-mark-start", "bookmark-start" };
static private final List<String> markList = Arrays.asList(markArray);
static private final HashSet<String> marks = new HashSet<String>();
static {
......@@ -574,11 +575,48 @@ public class OdfNormalizer {
&& marks.contains(n.getLocalName());
}
static private void fixBookmarkStart(Document document, XML xml) {
// replace each text:bookmark that has a corresponding text:bookmark-end
// by text:bookmark-start
XPathResult<Element> elements = XPath.elementIterator(document,
"//text:bookmark-end");
Set<String> ends = new HashSet<String>();
for (Element e : elements) {
ends.add(e.getAttributeNS(NC.text, "name"));
}
elements = XPath.elementIterator(document, "//text:bookmark");
List<Element> bookmarks = new LinkedList<Element>();
for (Element e : elements) {
final String name = e.getAttributeNS(NC.text, "name");
if (ends.contains(name)) {
bookmarks.add(e);
}
}
for (Element e : bookmarks) {
changeQName(e, NC.text, "text:bookmark-start");
}
}
static private void changeQName(Element e, String uri, String qname) {
final Element e2 = e.getOwnerDocument().createElementNS(uri, qname);
Node n = e.getFirstChild();
while (n != null) {
e2.appendChild(n);
n = e.getFirstChild();
}
final NamedNodeMap as = e.getAttributes();
final int l = as.getLength();
for (int i = 0; i < l; ++i) {
e2.setAttributeNode((Attr) as.item(i).cloneNode(false));
}
e.getParentNode().replaceChild(e2, e);
}
static private void fixReferenceMarkOrder(Document document, XML xml) {
XPathResult<Element> elements = XPath
.elementIterator(
document,
"//text:reference-mark-start|//text:reference-mark-end|//text:bookmark|//text:bookmark-end");
"//text:reference-mark-start|//text:reference-mark-end|//text:bookmark-start|//text:bookmark-end");
List<Node> list = new LinkedList<Node>();
List<Node> done = new LinkedList<Node>();
for (Element e : elements) {
......
......@@ -3,7 +3,7 @@
<office:body>
<office:text>
<text:h text:outline-level="3" text:style-name="Heading_20_3">
<text:reference-mark-start text:name="DDE_LINK17"/><text:reference-mark-start text:name="attribute-table:protected_element-table:covered-table-cell"/><text:reference-mark-start text:name="line-2411"/><text:reference-mark-start text:name="line-2511"/><text:reference-mark-start text:name="line-261"/><text:reference-mark-start text:name="line-271"/><text:bookmark text:name="__RefHeading__1418582_253892949"/>
<text:reference-mark-start text:name="DDE_LINK17"/><text:reference-mark-start text:name="attribute-table:protected_element-table:covered-table-cell"/><text:reference-mark-start text:name="line-2411"/><text:reference-mark-start text:name="line-2511"/><text:reference-mark-start text:name="line-261"/><text:reference-mark-start text:name="line-271"/><text:bookmark-start text:name="__RefHeading__1418582_253892949"/>
table:covered-table-cell<text:bookmark-end text:name="__RefHeading__1418582_253892949"/><text:reference-mark-end text:name="DDE_LINK17"/><text:reference-mark-end text:name="attribute-table:protected_element-table:covered-table-cell"/><text:reference-mark-end text:name="line-2411"/><text:reference-mark-end text:name="line-2511"/><text:reference-mark-end text:name="line-261"/><text:reference-mark-end text:name="line-271"/>
</text:h>
</office:text>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment