You can add a new Document Type Association or edit the properties of an existing one from the +Preferences+Document Type Association option pane. All the changes can be made into the Document type edit dialog.
The <oXygen/> Author toolbars and menus can be changed to provide a productive editing experience for the content authors. You can create a set of actions that are specific to a document type.
In the example with the sdf
framework, you created the
stylesheet and the validation schema. Now let's add some actions for inserting a
section
and a table
. To add a new action, follow the
procedure:
Open the Options Dialog, and select the Document Types Association option pane.
In the lower part of the Document Type Association dialog, click on the Author tab, then select the Actions label.
To add a new action click on the
button.This paragraph describes how you can define the action for adding a section. We
assume the icon files Section16.gif
for the menu item and Section20.gif
for the toolbar, are already available. Although we
could use the same icon size for both menu and toolbar, usually the icons from the
toolbars are larger than the ones placed in the menus. These files should be placed in
the frameworks/sdf
directory.
An unique identifier for the action. You can use insert_section.
The name of the action. It is displayed as a tooltip when the action is placed in the toolbar, or as the menu item name. Use Insert section.
On Windows, the menu items can be accessed using (ALT + letter) combination, when the menu is visible. The letter is visually represented by underlining the first letter from the menu item name having the same value. Since the name is Insert section, you can use as a menu access key the letter s.
You can add a short description for the action. In our case Adds a section element will suffice.
The path to the file that contains the toolbar image for the action. A good
practice is to store the image files inside the framework directory. This way we
can use the editor variable${frameworks}
to make the image file relative to the
framework location. Insert ${frameworks}/sdf/Section20.gif
If the images are bundled in a jar archive together with some Java operations implementation for instance, it might be convenient for you to refer the images not by the file name, but by their relative path location in the class-path.
If the image file Section20.gif
is located in the
directory images
inside the jar archive, you can refer to
it by using /images/Section20.gif. The jar
file must be added into the Classpath list.
The path to the file that contains the menu image. Insert ${frameworks}/sdf/Section16.gif
A shortcut key combination for triggering the action. To define it, click in the text field and press the desired key combination. You can choose Ctrl+Shift+s.
The shortcut is enabled only by adding the action to the main menu of the Author mode which contains all the actions that the author will have in a menu for the current document type.
At this time the action has no functionality added to it. Next you must define how this action operates. An action can have multiple operation modes, each of them activated by the evaluation of an XPath version 2.0 expression.
The XPath expression of an operation mode is evaluated relative to the current element. The current element is the one where the caret is positioned. In fact there is hierarchy of elements containing the caret position, but you are considering only the closest one. A simple expression like:
title
is a relative one and checks if the current element has a "title" child element. To check that the current element is a section you can use the expression:
local-name()='section'
<oXygen/> Author determines the operation to be executed by iterating through the defined operation modes. The first operation whose XPath expression "matched" the current document context gets executed, while the others are being ignored. Make sure you order correctly your operations by placing the ones with more specific XPath selectors before the ones having more generic selectors.
For instance the expression
person[@name='Cris' and @age='24']
is more specific than
person[@name='Cris']
The action mode using the first expression must be placed before the one using the second expression in the action modes list.
You decide that you can add sections only if the current element is either a
book
, article
, or another section
.
Set the value to:
local-name()='section' or local-name()='book' or local-name()='article'
A set of built-in operations is available. A complete list is found in the Author Default Operations section. To this set you can add your own Java operation implementations. In our case, you will use the InsertFragmentOperation built-in operation, that inserts an XML fragment at the caret position.
Configure the arguments by setting the following values:
<section xmlns= "http://www.oxygenxml.com/sample/documentation"> <title/> </section>
Leave it empty. This means the location will be the element at the caret position.
Select "Inside".
You will create an action that inserts into the document a table with three rows and three columns. The first row is the table header. Similarly to the insert section action, you will use the InsertFragmentOperation.
The icon files are Table16.gif
for the menu item and Table20.gif
for the toolbar and are already available. These
files must be placed in the frameworks/sdf
directory.
The action properties:
You can use insert_table.
Insert Insert table.
Enter the t letter.
You can use Adds a section element.
Use ${frameworks}/sdf/Table20.gif
Insert ${frameworks}/sdf/Table16.gif
You can choose Ctrl+Shift+t.
Now let's set up the operation the action uses.
Set it to the value
true()
true() is equivalent with leaving this field empty.
You will use InsertFragmentOperation built-in operations that inserts an XML fragment at the caret position.
Configure its arguments by setting the values:
<table xmlns= "http://www.oxygenxml.com/sample/documentation"> <header><td/><td/><td/></header> <tr><td/><td/><td/></tr> <tr><td/><td/><td/></tr> </table>
In our example we will always add tables at the end of the section that contains the caret position. Use:
ancestor::section/*[last()]
Select "After".
Now that you have defined the two actions you can add them to the toolbar. You can configure additional toolbars on which to add your custom actions.
The first thing to check is that the toolbar Author custom actions should be displayed when switching to the Author mode: Right click in the application window upper part, in the area that contains the toolbar buttons and check Author custom actions in the displayed menu if it is unchecked.
Open the Document Type edit dialog for the SDF framework and select on the Author tab. Next click on the Toolbar label.
The panel is divided in two sections: the left side contains a list of actions, while the right one contains an action tree, displaying the list of actions added in the toolbar. The special entry called Separator allows you to visually separate the actions in the toolbar.
Select the Insert section action in the left and the Toolbar label in the right, then press the button.
Now select the Insert table action in the left and the Insert section in the right. Press the button.
When opening a Simple Documentation Framework test document in Author mode, the toolbar below will be displayed at the top of the editor.
If you have many custom toolbar actions or want to group actions according to their category you can add additional toolbars with custom names and split the actions to better suit your purpose.
Defined actions can be grouped into customized menus in the <oXygen/> menu bar. For this open the Document Type dialog for the SDF framework and click on the Author tab. Next click on the Menu label.
In the left side you have the list of actions and some special entries:
Creates a submenu. You can nest an unlimited number of menus.
Creates a separator into a menu. In this way you can logically separate the menu entries.
In the right side you have the menu tree, having the Menu entry as root. To change its name click on this label to select it, then press the button. Enter SD Framework as name, and D as menu access key.
Select the Submenu label in the left an the SD Framework label in the right, then press the button. Change the submenu name to Table, using the button.
Select the Insert section action in the left and the Table label in the right, then press the button.
Now select the Insert table action in the left and the Table in the right. Press the button.
When opening a Simple Documentation Framework test document in Author mode, the menu you created is displayed in the editor menu bar, between the Debugger and the Document menus. In the menu you find the submenu and the two actions:
The shortcut of an action defined for the current document type is enabled only if the action is added to the main menu. Otherwise the author can run the action only from the toolbar.
The contextual menu is shown when you right click (on Mac OS X it is used the combination ctrl and mouse click) in the Author editing area. In fact you are configuring the bottom part of the menu, since the top part is reserved for a list of generic actions like Copy, Paste, Undo, etc..
Open the Document Type dialog for the SDF framework and click on the Author tab. Next click on the Contextual Menu label.
Follow the same steps as explained above in the Configuring the Main Menu, except changing the menu name - the contextual menu has no name.
To test it, open the test file, and click to open the contextual menu. In the lower part there is shown the
sub-menu and the action:Below are listed all the operations and their arguments.
Inserts an XML fragment at the current cursor position. The selection - if there is one, remains unchanged. The fragment will be inserted in the current context of the cursor position. That means that if the current XML document uses some namespace declarations then the inserted fragment must use the same declarations. The inserted fragment will not be copied and pasted to the cursor position, but the namespace declarations of the fragment will be adapted if needed to the existing namespace declarations of the XML document. Examples of namespace adjusting when the fragment is inserted and the descriptions of the arguments are described here.
Similar to InsertFragmentOperation, except it removes the selected content before inserting the fragment.
Inserts a text. It removes the selected content before inserting the text section.
The text section to insert.
Surrounds the selected content by a fragment. Since the fragment can have multiple nodes, the surrounded content will be always placed in the first leaf element. If there is no selection, the operation will simply insert the fragment at the caret position. The arguments are described here.
The surround with text operation takes two arguments, two text values that will be inserted before and after the selected content. If there is no selected content, the two sections will be inserted at the caret position. The arguments of the operation are:
The text that will be placed before the selection.
The test that will be placed after the selection.
The value for this argument is a text. This is parsed by the <oXygen/> Author as it was already in the document at the caret position. You can use entities references declared in the document and it is namespace aware. The fragment may have multiple roots.
You can use even namespace prefixes that are not declared in the inserted fragment, if they are declared in the document where the insertion is done. For clarity, you should always to prefix and declare namespaces in the inserted fragment!
If there are namespace declarations in the fragment that are identical to the in the document insertion context, the namespace declaration attributes are removed from the fragment elements.
Example 8.2. Prefixes that are not bound explicitly
For instance, the fragment:
<x:item id="dty2"/> &ent; <x:item id="dty3"/>
Can be correctly inserted in the document: ('|' marks the insertion point):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE x:root [
<!ENTITY ent "entity">
]>
<x:root xmlns:x="nsp">
|
</x:root>
Result:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE x:root [
<!ENTITY ent "entity">
]>
<x:root xmlns:x="nsp">
<x:item id="dty2"/>
&ent;
<x:item id="dty3"/>
</x:root>
Example 8.3. Default namespaces
If there is a default namespace declared in the document and the document fragment does not declare a namespace, the elements from the fragment are considered to be in no namespace.
For instance the fragment:
<item id="dty2"/> <item id="dty3"/>
Inserted in the document:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="nsp">
|
</root>
Gives the result document:
<?xml version="1.0" encoding="UTF-8"?> <root xmlns="nsp"> <item xmlns="" id="dty2"/> <item xmlns="" id="dty3"/> </root>
An XPath expression that is relative to the current node. It selects the reference node for the fragment insertion.
One of the three constants: "Inside", "After", or "Before" , showing where the insertion is made relative to the reference node selected by the insertLocation. "Inside" has the meaning of the first child of the reference node.
The XML fragment that will surround the selection.
Example 8.4. Surrounding with a fragment
Let's consider the fragment:
<F> <A></A> <B> <C></C> </B> </F>
And the document:
<doc> <X></X> <Y></Y> <Z></Z> <doc>
Considering the selected content that is to be surrounded is the
sequence of elements X
and Y
, then the
result is:
<doc> <F> <A> <X></X> <Y></Y> </A> <B> <C></C> </B> </F> <Z></Z> <doc>
Because the element A
was the first leaf in the
fragment, it received the selected content. The fragment was then inserted
in the place of the selection.