package nota.oxygen.common.list; import java.util.ArrayList; import java.util.List; import nota.oxygen.common.BaseAuthorOperation; import nota.oxygen.common.Utils; import org.w3c.dom.Element; import ro.sync.ecss.extensions.api.ArgumentDescriptor; import ro.sync.ecss.extensions.api.ArgumentsMap; import ro.sync.ecss.extensions.api.AuthorConstants; import ro.sync.ecss.extensions.api.AuthorDocumentController; import ro.sync.ecss.extensions.api.AuthorOperationException; import ro.sync.ecss.extensions.api.node.AuthorElement; import ro.sync.ecss.extensions.api.node.AuthorNode; /** * Marks-up the selected items as list items * @author Ole Holst Andersen (oha@nota.nu) */ public class MarkupListItemsOperation extends BaseAuthorOperation { @Override protected void doOperation() throws AuthorOperationException { try { AuthorDocumentController docCtrl = getAuthorAccess().getDocumentController(); int startSel = getSelectionStart(); int endSel = getSelectionEnd(); AuthorElement firstAthElem = (AuthorElement)docCtrl.getNodeAtOffset(startSel+1); AuthorElement lastAthElem = (AuthorElement)docCtrl.getNodeAtOffset(endSel-1); if (firstAthElem.getParent()!=lastAthElem.getParent()) { String msg = "Selected nodes are not siblings:\n"; msg += "first element: "+firstAthElem.getLocalName()+"[@id='"+firstAthElem.getAttribute("id")+"']\n"; msg += "last element: "+lastAthElem.getLocalName()+"[@id='"+lastAthElem.getAttribute("id")+"']\n"; showMessage(msg); return; } startSel = firstAthElem.getStartOffset(); endSel = lastAthElem.getEndOffset(); docCtrl.surroundInFragment(listFragment, startSel, endSel); startSel = firstAthElem.getStartOffset(); endSel = lastAthElem.getEndOffset(); AuthorElement list = (AuthorElement)docCtrl.getNodeAtOffset(startSel); int childIndex = 0; while (childIndex<list.getContentNodes().size()) { AuthorNode nod = list.getContentNodes().get(childIndex); startSel = list.getStartOffset(); endSel = list.getEndOffset(); if (!(nod instanceof AuthorElement)) { throw new AuthorOperationException("Cannot apply markup to mixed content"); } AuthorElement elem = (AuthorElement)nod; if (!elementsToSubstitute.contains(elem.getLocalName())) { String msg = "One of the elements in the selection is not applicable for markup: " +elem.getLocalName()+"[@id='"+elem.getAttribute("id").getValue()+"']\n" +"Applicable elements are:"; for (String e : elementsToSubstitute) msg += "\n"+e; throw new AuthorOperationException(msg); } docCtrl.surroundInFragment(itemFragment, elem.getStartOffset(), elem.getEndOffset()); if (!keepSubstitutes) { //remove the original element that was surrounded with the item element, //keeping its children as children of the item element AuthorElement item = (AuthorElement)elem.getParent(); Element itemElem = Utils.deserializeElement(serialize(item)); if (itemElem.getFirstChild() instanceof Element) { Element e = (Element)itemElem.getFirstChild(); while (e.hasChildNodes()) { itemElem.insertBefore(e.removeChild(e.getFirstChild()), e); } itemElem.removeChild(e); } docCtrl.insertXMLFragment(Utils.serialize(itemElem), item, AuthorConstants.POSITION_BEFORE); docCtrl.deleteNode(item); } childIndex++; } } catch (AuthorOperationException e) { throw e; } catch (Exception e) { throw new AuthorOperationException( "Unexpected "+e.getClass().getName()+"occured: "+e.getMessage(), e); } } @Override protected void parseArguments(ArgumentsMap args) throws IllegalArgumentException { listFragment = (String)args.getArgumentValue(ARG_LIST_FRAGMENT); itemFragment = (String)args.getArgumentValue(ARG_ITEM_FRAGMENT); String elems = (String)args.getArgumentValue(ARG_ELEMENTS_TO_SUBSTITUTE); elementsToSubstitute = new ArrayList<String>(); for (String e : elems.split(" ")) elementsToSubstitute.add(e); keepSubstitutes = YES_NO[0].equals(args.getArgumentValue(ARG_KEEP_SUBSTITUTES)); } private static String ARG_LIST_FRAGMENT = "list fragment"; private static String ARG_ITEM_FRAGMENT = "item fragment"; private static String ARG_ELEMENTS_TO_SUBSTITUTE = "elements to substitute"; private static String ARG_KEEP_SUBSTITUTES = "keep substitutes"; private static String[] YES_NO = new String[] {"yes", "no"}; private String listFragment; private String itemFragment; private List<String> elementsToSubstitute; private boolean keepSubstitutes; @Override public ArgumentDescriptor[] getArguments() { return new ArgumentDescriptor[] { new ArgumentDescriptor(ARG_LIST_FRAGMENT, ArgumentDescriptor.TYPE_FRAGMENT, "list xml fragment"), new ArgumentDescriptor(ARG_ITEM_FRAGMENT, ArgumentDescriptor.TYPE_FRAGMENT, "item xml fragment"), new ArgumentDescriptor(ARG_ELEMENTS_TO_SUBSTITUTE, ArgumentDescriptor.TYPE_STRING, "local names of elements to substitute with item - space separated"), new ArgumentDescriptor(ARG_KEEP_SUBSTITUTES, ArgumentDescriptor.TYPE_CONSTANT_LIST, "local names of elements to substitute with item - space separated", YES_NO, YES_NO[1]) }; } @Override public String getDescription() { return "Markup list items"; } }