Page 1 of 1

suroundInFragment method

Posted: Tue May 16, 2023 8:44 pm
by np18
Hi,
I have the following TEI XML structure (simplified)

Code: Select all

<list>
  <item><label someAtr="somevalue" someOtherAtr="othervalue" >some <g>m</g>ixed content</label></item>
  <item><label someAtr="somevalue" someOtherAtr="othervalue">some <g>m<unclear>ixed content</unclear></label></item>
  ...
</list>
I want to surround the mixed content (Roman numerals mixed with some other symbols and elements) with a <num> element:

Code: Select all

<list>
  <item><label someAtr="somevalue" someOtherAtr="othervalue" ><num>some <g>m</g>ixed content</num></label></item>
  <item><label someAtr="somevalue" someOtherAtr="othervalue"><num>some <g>m<unclear>ixed content</unclear></num></label></item>
  ...
</list>
This needs to be done programmatically from an authorOperation, as the value of the numeral and other stuff is computed and inserted.

I try to insert <num> by using

Code: Select all

authorAccess.getDocumentController().surroundInFragment("<num></num>", labelNode.getStartOffset(), labelNode.getEndOffset());
Which surrounds the <label> element with an <num> element. To do it the other way around, I tried to compute the (changing) length of the <label> start tag and add the value to the labelNode.getStartOffset(). Then the fixed length of the closing tag </label> = 8 is subtracted from the EndOffset.

This is the line I use for the insertion:

Code: Select all

authorAccess.getDocumentController().surroundInFragment("<num></num>", labelNode.getStartOffset() + startTagLength, labelNode.getEndOffset() - 8);
This is how I compute the starting tag length somewhere earlier in the code (in a for loop looping through a nodelist found by xpath):

Code: Select all

  	AuthorElement labelElement = (AuthorElement) labelNode;
	    	
    	// Get length of the element's name, add 2 for angle brackets.
    	int startTagLength = labelElement.getName().length() + 2; // +2 for '<' and '>'
	    	
    	// Iterate over all attributes and add their lengths
    	int attrCount = labelElement.getAttributesCount();
    	for (int i = 0; i < attrCount; i++) {
    	    // Get attribute name, add 1 for equals sign, get value, add 2 for quotes, add 1 for leading space.
    	    String attrName = labelElement.getAttributeAtIndex(i);
    	    String attrValue = labelElement.getAttribute(attrName).getValue();
    	    startTagLength += attrName.length() + attrValue.length() + 1 + 2 + 1;
    	}
If I use this operation in Oxygen, it only works if I leave the elements offset untouched, producing <num><label></label></num>. The moment I add and subtract the computed offset, the action does something (because oxygen freezes for a second), but produces no outcome or error message whatsoever.

Questions:
- Is there a more elegant way to do this using oxygenxml API?
- Why does my code have no effect?

Any help would be greatly appreciated (as always!)

Best,
Michael

Re: suroundInFragment method

Posted: Wed May 17, 2023 8:53 am
by alex_jitianu
Hello,

There are a couple aspects to consider:
1. In the model, each start tag and end tag has just one special marker character.
2. An AuthorNode start offset points to the start marker and the end offset points to the end marker, as depicted in the link above
3. surroundInFragment() endOffset is inclusive, so that offset also gets surrounded.

To surround the contents of the label element, this should do:

Code: Select all

authorAccess.getDocumentController().surroundInFragment("<num></num>", labelNode.getStartOffset() + 1, labelNode.getEndOffset() - 1);
Please note that the above code will be in trouble for an empty label element (labelNode.getStartOffset() + 1 = labelNode.getEndOffset()) in which case you should just insert at labelNode.getStartOffset() + 1

Best regards,
Alex

Re: suroundInFragment method

Posted: Wed May 17, 2023 10:14 am
by np18
Dear Alex,
thanks, that works! I misunderstood the image, but now it makes perfect sense. The empty element is no problem because in this case, nothing will be inserted.
Thanks for the help and explanation!