int start = Integer.parseInt(insertion.getAttributeValue("xtspanstart"));
int end = Integer.parseInt(insertion.getAttributeValue("xtspanend"));
boolean inParent = false;
while(!inParent) {
currentParent = newParent;
Elements children = currentParent.getChildElements();
for(int i=0;i<children.size();i++) {
Element child = children.get(i);
int elemStart = Integer.parseInt(child.getAttributeValue("xtspanstart"));
int elemEnd = Integer.parseInt(child.getAttributeValue("xtspanend"));
if(elemEnd < start) continue;
if(elemStart <= start && elemEnd >= end) {
newParent = child;
break;
}
}
if(newParent == currentParent) inParent = true;
}
/* OK, we now have our parent element */
/* Now find the nodes enclosed by the new element */
Node firstInnerNode = null;
Node lastInnerNode = null;
int parentStart = Integer.parseInt(currentParent.getAttributeValue("xtspanstart"));
int parentEnd = Integer.parseInt(currentParent.getAttributeValue("xtspanend"));
Elements children = currentParent.getChildElements();
/* Parent node contains only text, maybe? */
if(children.size() == 0) {
int startOffset = start - parentStart;
int endOffset = end - parentStart;
if(start == parentStart && end == parentEnd) {
firstInnerNode = currentParent.getChild(0);
lastInnerNode = currentParent.getChild(0);
} else if(start == parentStart) {
firstInnerNode = currentParent.getChild(0);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(0, endOffset));
Text textNode = new Text(txt.substring(endOffset));
currentParent.appendChild(textNode);
} else if(end == parentEnd) {
firstInnerNode = currentParent.getChild(0);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(startOffset));
Text textNode = new Text(txt.substring(0, startOffset));
currentParent.insertChild(textNode, 0);
} else {
firstInnerNode = currentParent.getChild(0);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(startOffset, endOffset));
Text textNode = new Text(txt.substring(0, startOffset));
currentParent.insertChild(textNode, 0);
textNode = new Text(txt.substring(endOffset));
currentParent.appendChild(textNode);
}
} else {
/* Parent node contains other Elements */
int charPos = parentStart;
/* Look through the slots in front of the element */
for(int i=0;i<children.size();i++) {
Element child = children.get(i);
/* elemStart is also where the Text _ends_ */
int elemStart = Integer.parseInt(child.getAttributeValue("xtspanstart"));
/* We'll need this later on, for the charPos at the next point of the loop */
int elemEnd = Integer.parseInt(child.getAttributeValue("xtspanend"));
if(charPos <= start && start <= elemStart && charPos <= end && end <= elemStart) {
/* The putative tag starts and ends here. */
int startOffset = start - charPos;
int endOffset = end - charPos;
if(start == charPos && end == elemStart) {
/* Tag swallows the Text whole */
firstInnerNode = XOMTools.getPreviousSibling(child);
lastInnerNode = XOMTools.getPreviousSibling(child);
} else if(start == charPos) {
/* Tag starts at the start of the Text */
firstInnerNode = XOMTools.getPreviousSibling(child);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(0, endOffset));
Text textNode = new Text(txt.substring(endOffset));
XOMTools.insertAfter(firstInnerNode, textNode);
} else if(end == elemStart) {
/* Tag starts at the start of the Text */
firstInnerNode = XOMTools.getPreviousSibling(child);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(startOffset));
Text textNode = new Text(txt.substring(0, startOffset));
XOMTools.insertBefore(firstInnerNode, textNode);
} else {
/* Tag is within the Text */
firstInnerNode = XOMTools.getPreviousSibling(child);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(startOffset, endOffset));
Text textNode = new Text(txt.substring(0, startOffset));
XOMTools.insertBefore(firstInnerNode, textNode);
textNode = new Text(txt.substring(endOffset));
XOMTools.insertAfter(firstInnerNode, textNode);
}
} else if(charPos <= start && start <= elemStart) {
/* The start's in there somewhere */
if(charPos == elemStart) {
/* A zero-length gap - convenient */
firstInnerNode = child;
} else if(start == elemStart) {
/* the insertion starts at the same place as the inner element. */
firstInnerNode = child;
} else if(start == charPos) {
/* the insertion starts at the same place as the previous element /
* the parent element. There's a Text node inbetween that needs
* eating.
*/
firstInnerNode = XOMTools.getPreviousSibling(child);
if(!(firstInnerNode instanceof Text)) throw new Exception("Ptc24 is a fool!");
} else {
/* Text surgery required */
Text textNode = (Text)(XOMTools.getPreviousSibling(child));
int offset = start - charPos;
String txt = textNode.getValue();
textNode.setValue(txt.substring(0, offset));
firstInnerNode = new Text(txt.substring(offset));
XOMTools.insertAfter(textNode, firstInnerNode);
}
} else if(charPos <= end && end <= elemStart) {
/* The end's in there somewhere */
if(charPos == elemStart) {
/* A zero-length gap - convenient */
lastInnerNode = child;
} else if(end == charPos) {
/* the insertion ends at the end of the last inner (previous) element. */
lastInnerNode = children.get(i-1);
} else if(end == elemStart) {
/* the insertion ends at the same place as the start of
* this element. There's a Text node inbetween that needs
* eating.
*/
lastInnerNode = XOMTools.getPreviousSibling(child);
if(!(lastInnerNode instanceof Text)) throw new Exception("Ptc24 is a fool!");
} else {
/* Text surgery required */
lastInnerNode = (XOMTools.getPreviousSibling(child));
int offset = end - charPos;
String txt = lastInnerNode.getValue();
((Text)lastInnerNode).setValue(txt.substring(0, offset));
Text textNode = new Text(txt.substring(offset));
XOMTools.insertAfter(lastInnerNode, textNode);
}
}
if(firstInnerNode != null && lastInnerNode != null) break;
charPos = elemEnd;
}
if(firstInnerNode == null) {
int startOffset = start - charPos;
int endOffset = end - charPos;
if(start == charPos && end == parentEnd) {
firstInnerNode = currentParent.getChild(currentParent.getChildCount()-1);
lastInnerNode = currentParent.getChild(currentParent.getChildCount()-1);
} else if(start == charPos) {
firstInnerNode = currentParent.getChild(currentParent.getChildCount()-1);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(0, endOffset));
Text textNode = new Text(txt.substring(endOffset));
currentParent.appendChild(textNode);
} else if(end == parentEnd) {
firstInnerNode = currentParent.getChild(currentParent.getChildCount()-1);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(startOffset));
Text textNode = new Text(txt.substring(0, startOffset));
XOMTools.insertBefore(firstInnerNode, textNode);
} else {
firstInnerNode = currentParent.getChild(currentParent.getChildCount()-1);
lastInnerNode = firstInnerNode;
String txt = ((Text)firstInnerNode).getValue();
((Text)firstInnerNode).setValue(txt.substring(startOffset, endOffset));
Text textNode = new Text(txt.substring(0, startOffset));
XOMTools.insertBefore(firstInnerNode, textNode);
textNode = new Text(txt.substring(endOffset));
currentParent.appendChild(textNode);
}
}
if(lastInnerNode == null) {
Element lastChild = children.get(children.size()-1);
charPos = Integer.parseInt(lastChild.getAttributeValue("xtspanend"));
if(charPos == parentEnd) {
/* A zero-length gap - convenient */
lastInnerNode = lastChild;
} else if(end == charPos) {