Page 1 of 1

Insert same UUID twice

Posted: Thu May 04, 2017 1:07 pm
by Seb
I want to create an Author Mode action (InsertFragmentOperation) that generates a single UUID and inserts it in two positions.

Doing this

Code: Select all

<addSpan spanTo="#${uuid}"/>${selection}<anchor xml:id="${uuid}"/>
results in two different UUIDs being inserted. Is there a way to insert the same UUID in both places?

Re: Insert same UUID twice

Posted: Thu May 04, 2017 3:50 pm
by sorin_carbunaru
Hello,

You can obtain what you want by using an XSLTOperation instead of InsertFragmentOperation, with the following value for the script argument:

Code: Select all


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vars="java:ro.sync.util.editorvars.EditorVariables"
exclude-result-prefixes="xs vars"
version="2.0">
<xsl:param name="ID" select="vars:expandEditorVariables('${uuid}', '')"/>
<xsl:template match="/">
<addSpan spanTo="#{$ID}"/>${selection}<anchor xml:id="{$ID}"/>
</xsl:template>
</xsl:stylesheet>
This way we first create a parameter with a unique value, and then use that value in 2 different places.

Be careful to set the action argument to At caret position. All the other arguments can use the default values.

Best wishes,
Sorin Carbunaru
oXygen XML

Re: Insert same UUID twice

Posted: Thu May 04, 2017 3:59 pm
by Seb
Thanks. It works.

Is there also way to use "XSLTOperation" as a replacement for "InsertOrReplaceFragmentOperation", so that selected text will not be duplicated?

Re: Insert same UUID twice

Posted: Thu May 04, 2017 5:03 pm
by sorin_carbunaru
No, you cannot use XSLTOperation instead of InsertOrReplaceFragmentOperation. What you can do is use them both, in the proper order. Let me explain.

oXygen has an operation that allows you to execute multiple actions: ExecuteMultipleActionsOperation. What you have to do is to first create 2 actions:
1. An action based on InsertOrReplaceFragmentOperation, that replaces the selection with an empty string (in other words it performs a deletion). Notice that you have to edit the fragment argument, leave it empty and press OK. If you don't do this, the default value is null, and you don't want that. We need an empty string.
2. An action based on XSLTOperation. This will perform the fragment insertion.

After creating these actions, provide their IDs to an action built over ExecuteMultipleActionsOperation, first the ID of action 1 and then of the second. When running this complex action, oXygen will first delete the selection and then insert your XML fragment. This way you will get what you expect.

Re: Insert same UUID twice

Posted: Thu May 04, 2017 5:31 pm
by Seb
Thanks again. But this does not seem to keep the selection which I want to wrap:

Code: Select all

    <xsl:template match="/">
<addSpan spanTo="#{$ID}"/>${selection}<anchor xml:id="{$ID}"/>
</xsl:template>
After the first action has deleted the selection, the second action has no reference of it anymore, does it?

Re: Insert same UUID twice

Posted: Fri May 05, 2017 9:30 am
by sorin_carbunaru
You didn't mention you want to wrap the selection. You first mentioned InsertFragmentOperation, then InsertOrReplaceFragmentOperation, so it's not clear to me what you try to achieve. I thought you want to insert a fragment at the cursor position or replace the selection. Please explain the entire use case, so we can provide you the best solution.

Re: Insert same UUID twice

Posted: Fri May 05, 2017 12:19 pm
by Seb
I have used the editor variable ${selection} in my initial post:

Code: Select all

<addSpan spanTo="#${uuid}"/>${selection}<anchor xml:id="${uuid}"/>
Then you have used ${selection} in your XSLT snippet. From that I thought it would be clear that I want to wrap the selection.

You have provided a substitute for "InsertFragmentOperation" and then I have asked for a substitute for "InsertOrReplaceFragmentOperation".

To make things more clear, here's again the entire use case (note that this is identical to my initial post except that I have just replaced "InsertFragmentOperation" with "InsertOrReplaceFragmentOperation"):

I want to create an Author Mode action (InsertOrReplaceFragmentOperation) that generates a single UUID and inserts it in two positions.

Doing this

Code: Select all

<addSpan spanTo="#${uuid}"/>${selection}<anchor xml:id="${uuid}"/>
results in two different UUIDs being inserted. Is there a way to insert the same UUID in both places?

Re: Insert same UUID twice

Posted: Fri May 05, 2017 3:08 pm
by sorin_carbunaru
Oh, I am so sorry! I have been so concentrated on ${uuid} that I omitted ${selection}, and that's why I couldn't understand some things in your posts. My bad.

Now, getting back to the issue. You cannot get the desired results by using Insert(OrReplace)FragmentOperation. But you can do that with another type of operation, namely JSOperation. The JavaScript code that you need to provide is the following:

Code: Select all


function doOperation() {
var ctrl = authorAccess.getDocumentController();
// Compute ID only once
var uuid = '${uuid}';
var addSpanEl = '<addSpan spanTo="#' + uuid + '"/>';
var anchorEl= '<anchor xml:id="' + uuid + '"/>';

var offset = authorAccess.getCaretOffset();
// The selected text or empty string
var selectedText = authorAccess.getSelectedText();
if (selectedText) {
// Delete selected text to avoid duplicating it
authorAccess.getEditorAccess().deleteSelection();
offset = authorAccess.getEditorAccess().getSelectionStart();

}

var frag = ctrl.createNewDocumentFragmentInContext(addSpanEl + selectedText + anchorEl, offset);
ctrl.insertFragment(offset, frag);
}

Re: Insert same UUID twice

Posted: Fri May 05, 2017 4:15 pm
by Seb
Perfect! This does exactly what I wanted to achieve. Again, thank you very much and no need to be sorry.