Lack of setter modification methods on AuthorNode

Oxygen general issues.
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Lack of setter modification methods on AuthorNode

Post by xsaero00 »

I am trying to process pasted text. I want to look for certain pattern and change that into elements.
If pasted text is " hello [1;2]" i want to change that into " hello <xref linkend="id.1"/><xref linkend="id.2"/>"
I am using ClipboardFragmentProcessor but I ran into a wall. There appears to be no methods that would allow me changind text AuthorNodes from fragmentInformation.getFragment().getContentNodes(). There are absolutely no setter methods on AuthorNode and I cant find a way to create new AuthorNodes. I am actually not sure where the text in ClipboardFragmentInformation is stored.

Thanks for you help in advance.
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Re: Lack of setter modification methods on AuthorNode

Post by xsaero00 »

The forum topic should be "Lack of setter or modification methods on AuthorNode"
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Re:

Post by xsaero00 »

The process method of ClipboardFragmentProcessor does not fire when pasting from another text editor like Microsoft Word or Notepad. It seems to only fire when copying/pasting from Oxygen Editor. Is this normal?
Radu
Posts: 9018
Joined: Fri Jul 09, 2004 5:18 pm

Re: Luch of setter modification methods on AuthorNode

Post by Radu »

Hi Mike,

I'll post one message for each question:
The process method of ClipboardFragmentProcessor does not fire when pasting from another text editor like Microsoft Word or Notepad. It seems to only fire when copying/pasting from Oxygen Editor. Is this normal?
The ClipboardFragmentProcessor can only be used to pre-process fragments which come from the Author page (or another Author page) by means of copy/paste or drag and drop.

But:

In the ExtensionsBundle implementation you can overwrite this method:

Code: Select all

ro.sync.ecss.extensions.api.ExtensionsBundle#createExternalObjectInsertionHandler()
and overwrite this method from the AuthorExternalObjectInsertionHandler:

Code: Select all

ro.sync.ecss.extensions.api.AuthorExternalObjectInsertionHandler.insertXHTMLFragment(AuthorAccess, Reader)
This callback will allow you access to the XHTML flavor from the clipboard when pasting for example fragments from MS Office and you will be able to process the XHTML and insert the desired XML fragment in the document.

As an alternative the SDK comes with the Java sources for the:

Code: Select all

ro.sync.ecss.extensions.dita.DITAExternalObjectInsertionHandler
which overwrites this method:

Code: Select all

ro.sync.ecss.extensions.api.AuthorExternalObjectInsertionHandler#getImporterStylesheetFileName(ro.sync.ecss.extensions.api.AuthorAccess)
from the base class, allowing it to specify an XSLT stylesheet which will be applied on the XHTML fragment and then the base class will take care to insert the result XML in the document.

The "xhtml2dita.xsl" stylesheet resides in the OXYGEN_INSTALL_DIR/frameworks/dita/resources directory and in order to be found the DITA document type edit dialog specifies in the Classpath tab an additional path: ${frameworks}/dita/resources/

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Radu
Posts: 9018
Joined: Fri Jul 09, 2004 5:18 pm

Re: Lack of setter modification methods on AuthorNode

Post by Radu »

Hi Mike,
If pasted text is " hello [1;2]" i want to change that into " hello <xref linkend="id.1"/><xref linkend="id.2"/>"
The architecture of the AuthorDocumentFragment can be described better by the image located here:

http://www.oxygenxml.com/InstData/Edito ... gment.html

Basically the AuthorNode's usually correspond to XML Elements (they are instances of AuthorElement.

The method which allows you to manipulate the text is this one:

Code: Select all

ro.sync.ecss.extensions.api.node.AuthorDocumentFragment.getContent()
The ro.sync.ecss.extensions.api.Content interface allows you access to the text characters and you can modify them but you have to be careful not to delete any special control characters (which have the integer value of '0').

What you are trying to do will also imply adding two more nodes to the fragment content nodes corresponding to the 2 xrefs which you are trying to add.
This is quite impossible to accomplish with the current API.
The simplest way would have been to be able from the API to set another fragment back to the ClipboardFragmentInformation like:

Code: Select all

  /**
* @see ro.sync.ecss.extensions.api.content.ClipboardFragmentProcessor#process(ro.sync.ecss.extensions.api.content.ClipboardFragmentInformation)
*/
public void process(ClipboardFragmentInformation fragmentInformation) {
AuthorDocumentFragment frag = fragmentInformation.getFragment();
try {
String xmlContent = authorAccess.getDocumentController().serializeFragmentToXML(frag);
xmlContent.replace("[1;2]", "<xref linkend=\"id.1\"/><xref linkend=\"id.2\"/>");

//Re-create a new fragment from the XML
AuthorDocumentFragment newFragment = authorAccess.getDocumentController().createNewDocumentFragmentInContext(xmlContent, authorAccess.getEditorAccess().getCaretOffset());
//UNFORTUNATELY THIS METHOD DOES NOT EXIST
fragmentInformation.setFragment(newFragment);
} catch (BadLocationException e) {
e.printStackTrace();
} catch (AuthorOperationException e) {
e.printStackTrace();
}
}
but unfortunately we do not yet have a method to set another fragment in the fragment information object. We'll try to add this method in the upcoming Oxygen 13 (in a couple of weeks).

Maybe as a workaround you could instead overwrite this method in the ExtensionsBundle:

Code: Select all

ro.sync.ecss.extensions.api.ExtensionsBundle#getAuthorSchemaAwareEditingHandler()
and return an extension of :

Code: Select all

ro.sync.ecss.extensions.api.AuthorSchemaAwareEditingHandlerAdapter
which overwrites this method:

Code: Select all

ro.sync.ecss.extensions.api.AuthorSchemaAwareEditingHandlerAdapter.handlePasteFragment(int, AuthorDocumentFragment[], int, AuthorAccess)
The final code would be like this:

Code: Select all

  /**
* @see ro.sync.ecss.extensions.api.AuthorSchemaAwareEditingHandlerAdapter#handlePasteFragment(int, ro.sync.ecss.extensions.api.node.AuthorDocumentFragment[], int, ro.sync.ecss.extensions.api.AuthorAccess)
*/
@Override
public boolean handlePasteFragment(int offset, AuthorDocumentFragment[] fragmentsToInsert,
int actionId, AuthorAccess authorAccess) throws InvalidEditException {
try {
for (int i = 0; i < fragmentsToInsert.length; i++) {
String xmlContent = authorAccess.getDocumentController().serializeFragmentToXML(fragmentsToInsert[i]);
if(xmlContent.contains("[1;2]")) {
xmlContent = xmlContent.replace("[1;2]", "<xref linkend=\"id.1\"/><xref linkend=\"id.2\"/>");

//Re-create a new fragment from the XML
AuthorDocumentFragment newFragment = authorAccess.getDocumentController().createNewDocumentFragmentInContext(xmlContent, authorAccess.getEditorAccess().getCaretOffset());
//And set the new fragment in the array.
fragmentsToInsert[i] = newFragment;
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
//We are just modifying fragments here, so tell that the insertion should be done in the default implementation.
return false;
}
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
xsaero00
Posts: 58
Joined: Sat Aug 01, 2009 12:57 am

Re:

Post by xsaero00 »

Thanks. I was able to do the substitution. For text pasted from Word I modified xhtml2db5.xsl stylesheet and for plain text I used ro.sync.ecss.extensions.api.AuthorSchemaAwareEditingHandlerAdapter#handlePasteFragment

Thanks for all the help.
Post Reply