/* * This file is part of NixNote/NeighborNote * Copyright 2009 Randy Baumgarte * * This file may be licensed under the terms of of the * GNU General Public License Version 2 (the ``GPL''). * * Software distributed under the License is distributed * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either * express or implied. See the GPL for the specific language * governing rights and limitations. * * You should have received a copy of the GPL along with this * program. If not, go to http://www.gnu.org/licenses/gpl.html * or write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package cx.fbn.nevernote.xml; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.trolltech.qt.xml.QDomDocument; import com.trolltech.qt.xml.QDomDocumentFragment; import com.trolltech.qt.xml.QDomElement; import com.trolltech.qt.xml.QDomNode; import com.trolltech.qt.xml.QDomNodeList; import com.trolltech.qt.xml.QDomText; public class XMLInsertHilight { private final QDomDocument doc; List<String> terms; List<QDomNode> oldNodes; List<QDomNode> newNodes; public XMLInsertHilight(QDomDocument d, List<String> t) { doc = d; terms = t; oldNodes = new ArrayList<QDomNode>(); newNodes = new ArrayList<QDomNode>(); scanTags(); } public QDomDocument getDoc() { for (int i=0; i<oldNodes.size(); i++) { oldNodes.get(i).parentNode().replaceChild(newNodes.get(i), oldNodes.get(i)); } return doc; } // Start looking through the tree. private void scanTags() { // QDomElement element = doc.firstChildElement(); // parseChildren(element.firstChild()); if (doc.hasChildNodes()) parseNodes(doc.childNodes()); return; } private void parseNodes(QDomNodeList nodes) { for (int i=0; i<nodes.size(); i++) { QDomNode node = nodes.at(i); if (node.hasChildNodes()) { parseNodes(node.childNodes()); } scanWords(node); } } // Parse through individual nodes public void parseChildren(QDomNode node) { for(; !node.isNull(); node = node.nextSibling()) { if (node.hasChildNodes()) { QDomNodeList l = node.childNodes(); for (int i=0; i<l.size(); i++) parseChildren(l.at(i)); } if (node.isText()) { scanWords(node); } } } // We found a text node, so we need to search for things to hilight private void scanWords(QDomNode node) { String value = node.nodeValue(); QDomDocumentFragment fragment = doc.createDocumentFragment(); boolean matchFound = false; int previousPosition = 0; String valueEnd = ""; String regex = buildRegex(); Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(value); while (matcher.find()) { matchFound = true; String valueStart = ""; int start = matcher.start(); int end = matcher.end(); if (value.substring(start).startsWith(" ")) start++; if (value.substring(start, end).endsWith(" ")) end--; if (matcher.start() > 0) { valueStart = value.substring(previousPosition,start); } String valueMiddle = value.substring(start, end); valueEnd = ""; if (matcher.end() < value.length()) { valueEnd = value.substring(end); } previousPosition = end; if (!valueStart.equals("")) { QDomText startText = doc.createTextNode(valueStart); fragment.appendChild(startText); } QDomElement hilight = doc.createElement("en-hilight"); hilight.appendChild(doc.createTextNode(valueMiddle)); fragment.appendChild(hilight); } if (matchFound) { if (previousPosition != value.length()) { QDomText endText = doc.createTextNode(valueEnd); fragment.appendChild(endText); } newNodes.add(fragment); oldNodes.add(node); } } private String buildRegex() { StringBuffer regex = new StringBuffer(); // Remove any empty terms of it screws things up later for (int j=terms.size()-1; j>=0; j--) { if (terms.get(j).trim().equals("")) terms.remove(j); } for (int i=0; i<terms.size(); i++) { String term = terms.get(i); if (term.indexOf("*") > -1) { term = term.replace("*", ""); }/* else { term = "\\b"+term+"\\b"; }*/ regex.append(term); if (i<terms.size()-1) regex.append("|"); } return regex.toString(); } }