API for customizing olinik insertion

Oxygen general issues.
dcramer
Posts: 161
Joined: Sat Aug 28, 2010 1:23 am

API for customizing olinik insertion

Post by dcramer »

Hi there,
At some point, I would like to customize oXygen's olink dialog so that if you are inserting an olink where the targetptr ends in a certain string (i.e. ".glossary"), clicking OK inserts a glossterm with the value of the targetptr stored in some attribute.

This would allow us to use the olink insertion dialog as a way to insert glossary terms from a master glossary in addition to regular olinks.

Would this be possible using existing APIs or should I look for other ways to do this?

Thanks,
David
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Re: API for customizing olinik insertion

Post by Radu »

Hi David,

All custom Author operations are written using the Author Java API.
What you need to do in order to make such customizations is to start looking over the Author SDK kit and the included PDF file:
http://www.oxygenxml.com/developer.html ... horing_SDK

The main idea is that in the Oxygen Installation directory in the "framworks/docbook" directory there are two *.framwork XML configuration files (which get saved when you edit the frameworks from the Oxygen Preferences->Document Types Association option page) and a docbook.jar which contains compiled Java code for the operations defined for both the Docbook 4 and Docbook 5 frameworks.

The Author SDK comes along with sources for the Docbook customizations so what you could do would be to modify and recompile those sources back to the jar file.

Then you would share the whole "docbook" framework directory with the other users.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
dcramer
Posts: 161
Joined: Sat Aug 28, 2010 1:23 am

Re: API for customizing olinik insertion

Post by dcramer »

Ok, I've taken a look at ro.sync.ecss.extensions.docbook.olink.InsertOLinkOperation and it seems that there's not much going on in that class. Most of the logic must be in ro.sync.ecss.docbook.DocbookAccess, but that's in oxygen.jar.

The modification I need to make for our situation is that if the targetdoc is a certain value ("Glossary"), then instead of inserting an <olink> the tool should insert something like <glossterm linkend="whatever.glossary">Whatever</glossterm> (where the text of the glossentry/glossterm is Whatever and the xml:id is whatever.glossary). To do that, I think I need to reimplement DocbookAccess.insertOLink, but I still need insertOLink to do most of the stuff it does now (but handle the special case when the targetdoc is "Glossary". I'm learning Java as I go on this, but I think I need the source for DocbookAccess to do this (i.e. I can't just extend it).

Thanks,
David
Radu
Posts: 9049
Joined: Fri Jul 09, 2004 5:18 pm

Re: API for customizing olinik insertion

Post by Radu »

Hi,

Most of the code in the extension implementations for Docbook, DITA, etc is exposed but sometimes some operations need some more complex GUI functionality like the quick search in the Insert OLink dialog.

You have two possiblities:
1) Call the DocbookAccess.chooseOLink(AuthorAccess authorAccess) static method which shows the dialog and returns the chosen values in an information object. Then process the information and insert your own XML fragment (make sure that the inserted XML fragment is explicitly set in the Docbook 5 namespace, see the code below).

2) There is another workaround which you can use to obtain the desired result.
In the doOperation method you can let Oxygen to insert the olink element and then retrieve the information you need from it, remove it and insert your custom XML fragment.
You can find bellow a sample code that does this:

Code: Select all

/**
* @see ro.sync.ecss.extensions.api.AuthorOperation#doOperation(ro.sync.ecss.extensions.api.AuthorAccess, ro.sync.ecss.extensions.api.ArgumentsMap)
*/
public void doOperation(AuthorAccess authorAccess, ArgumentsMap args)
throws IllegalArgumentException, AuthorOperationException {
authorAccess.getDocumentController().beginCompoundEdit();
try {
Object namespaceObj = args.getArgumentValue(NAMESPACE_ARGUMENT);
// Show the OLInk dialog
DocbookAccess.insertOLink(authorAccess, (String) namespaceObj);

try {
int caretOffset = authorAccess.getEditorAccess().getCaretOffset();
AuthorNode possibleOlinkAtCaret = authorAccess.getDocumentController().getNodeAtOffset(caretOffset);
if(possibleOlinkAtCaret.getType() == AuthorNode.NODE_TYPE_ELEMENT) {
AuthorElement olinkAtCaret = (AuthorElement) possibleOlinkAtCaret;
if("olink".equals(olinkAtCaret.getLocalName())) {

//The caret is inside an link.
String targetDoc = olinkAtCaret.getAttribute("targetdoc").getValue();
String targetPtr = olinkAtCaret.getAttribute("targetptr").getValue();

//Here you can decide whether to replace or not the element

//And if you want to replace:

//Now remove the olink element completely
boolean deleted = authorAccess.getDocumentController().deleteNode(olinkAtCaret);

if(deleted) {
//And insert your own element
//<glossterm linkend="whatever.glossary">Whatever</glossterm>
authorAccess.getDocumentController().insertXMLFragmentSchemaAware(
"<glossterm xmlns='http://docbook.org/ns/docbook' linkend=\"" + targetDoc + "." + targetPtr + "\"></glossterm>",
authorAccess.getEditorAccess().getCaretOffset());
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
} finally {
authorAccess.getDocumentController().endCompoundEdit();
}
}
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
dcramer
Posts: 161
Joined: Sat Aug 28, 2010 1:23 am

Re: API for customizing olinik insertion

Post by dcramer »

Hi Radu,
I picked method 2 and it works beautifully.

Thanks!
David
Post Reply