//---------------------------------------------------------------------------- // COMPONENT NAME: LPEX Editor // // © Copyright IBM Corporation 2006, 2007 // All Rights Reserved. // // DESCRIPTION: // WordsCommand - sample user-defined command (words) //---------------------------------------------------------------------------- package com.ibm.lpex.samples; import com.ibm.lpex.core.LpexCommand; import com.ibm.lpex.core.LpexDocumentLocation; import com.ibm.lpex.core.LpexView; /** * Sample command <b>words</b> - count the words in the current view. * Displays the number of visible words and non-space characters in the text. * If a selection is in effect, only the selected text is considered. * * <p>A simple scanning for letters and digits is used, rather than a * BreakIterator, which is sufficient for most types of programming source * documents. A word can be optionally defined to consist of any consecutive * non-whitespace characters.</p> * * <p>Here is the WordsCommand * <a href="doc-files/WordsCommand.java.html">source code</a>.</p> * * <p>To run this sample: * <ul> * <li>Define this user command via an editor preference page, where available, * or from the editor command line: * <pre>set commandClass.words com.ibm.lpex.samples.WordsCommand</pre></li> * <li>Run it from the editor command line: * <pre>words [any]</pre></li> * </ul></p> * * @see com.ibm.lpex.samples All the samples */ public class WordsCommand implements LpexCommand { /** * Runs this command. Displays the number of words, characters, and * lines in the visible text or selection. * * @param lpexView the document view in which the command was issued * @param parameters optional parameter: "?" for help, or "any" to define * a word as a string of any non-whitespace characters */ public boolean doCommand(LpexView lpexView, String parameters) { if (lpexView != null) { // word == any string of consecutive non-space(s)? boolean wordIsAny = false; parameters = parameters.trim(); if (parameters.length() != 0) { if ("?".equals(parameters)) { lpexView.doCommand("set messageText Syntax: words [any]"); return true; } if ("any".equals(parameters)) { wordIsAny = true; } else { lpexView.doCommand("set messageText \"" + parameters + "\" is not a correct parameter for the words command."); return false; } } int words = 0; int characters = 0; int lines = 0; // determine the range of elements to set int firstElement, lastElement; boolean selection; // 1.- visible selection in this view if (lpexView.queryOn("block.inView") && lpexView.queryOn("block.anythingSelected")) { selection = true; int linesBeforeStart = lpexView.queryInt("lines.beforeStart"); firstElement = lpexView.queryInt("block.topElement") - linesBeforeStart; lastElement = lpexView.queryInt("block.bottomElement") - linesBeforeStart; } // 2.- no selected text (is visible) in this view else { selection = false; firstElement = 1; lastElement = lpexView.elements(); } // go through all the visible text lines in range LpexDocumentLocation loc = new LpexDocumentLocation(1, 1); for (int e = firstElement; e <= lastElement; e++) { if (!lpexView.show(e)) { loc.element = e; if (lpexView.queryOn("visible", loc)) { lines++; String text = selection? lpexView.query("block.elementText", loc) : lpexView.elementText(e); boolean inWord = false; for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); // TODO should handle surrogates (JDK5)! if (Character.isWhitespace(c)) { inWord = false; } else { characters++; if (wordIsAny || Character.isLetterOrDigit(c)) { if (!inWord) { inWord = true; words++; } } else { inWord = false; } } } } } } // simple display of the result lpexView.doCommand("set messageText words: " + (words == 1? "1 word, " : words + " words, ") + (characters == 1? "1 non-space character, " : characters + " non-space characters, ") + (lines == 1? "1 line." : lines + " lines.")); } return true; } }