/* * org.openmicroscopy.shoola.util.ui.omeeditpane.ChemicalSymbolsFormatter * *------------------------------------------------------------------------------ * Copyright (C) 2006-2009 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.ui.omeeditpane; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; /** * Class for replacing 'fake' chemical symbols E.g. ul or 'C with the correct * chemical symbol. * A number of symbols are added when the class is created. More can be * added using {@link #addSymbol(String, String)}. * Simply call the {@link #parseRegex(Document, int)} method to parse the * document at the given point and replace the pre-defined matches. * The editing is done on a separate thread, so that this method can be called * from a Document Listener (won't conflict on concurrent editing). * * @author William Moore      * <a href="mailto:will@lifesci.dundee.ac.uk">will@lifesci.dundee.ac.uk</a> * @version 3.0 * @since 3.0-Beta4 */ public class ChemicalSymbolsEditer { /** The Doc to parse */ Document doc; /** A Map of the symbol patterns, * each with the value with which to replace it.*/ private Map <String, String> symbols; /** The Style of the plain text */ private SimpleAttributeSet plainText; /** The index at which the editing occurs */ private int characterIndex; /** * Punctuation or space must follow a regex pattern * NB: this single character is not replaced. */ public static final String PUNCTUATION = "[!:,.;)+&@#/%?~_| ]"; /** * Creates an instance. */ public ChemicalSymbolsEditer(SimpleAttributeSet plainText) { this.plainText = plainText; symbols = new HashMap<String, String>(); } /** * Add a Regex to the Map parsed for matches. * * @param regex The Regex to find. * @param replacement The replacement value */ public void addSymbol(String regex, String replacement) { // every regex must be followed by punctuation or space symbols.put(regex + PUNCTUATION, replacement); } /** * Parse the document, find the regex matches and edit the text for each. * Editing will only occur for regex matches that contain the index, so * that the document will not be edited in other places. * If you want to apply edits to all the regex matches, use index = -1 * * @param document The document to handle. * @param index Look for regex matches that contain this index. * Use -1 if you want to edit all regex matches in doc. */ public void parseRegex(Document document, int index) { doc = document; characterIndex = index; SwingUtilities.invokeLater(new Runnable() { public void run() { // remove this class as a listener, to avoid recursive edits //doc.removeDocumentListener(ChemicalSymbolsFormatter.this); try { Iterator<String> i = symbols.keySet().iterator(); String text = doc.getText(0, doc.getLength()); List<Position> positionList = new ArrayList<Position>(); String regex; String replacement; while (i.hasNext()) { regex = i.next(); replacement = symbols.get(regex); positionList.clear(); WikiView.findExpressions(text, regex, positionList); // edit the regex int start, end; for (Position p : positionList) { if ((characterIndex > -1) && (! p.contains(characterIndex, characterIndex))) continue; start = p.getStart(); // don't remove the punctuation/space that forms the // last character of the regex. end = p.getEnd()-1; doc.remove(start, end-start); doc.insertString(start, replacement, plainText); } } } catch (BadLocationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); } }