//----------------------------------------------------------------------------
// 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;
}
}