package flow.netbeans.markdown.spellchecker; import javax.swing.event.ChangeListener; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import org.netbeans.lib.editor.util.swing.DocumentUtilities; import org.netbeans.modules.spellchecker.spi.language.TokenList; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.util.Exceptions; /** * * @author Holger Stenger */ public class MarkdownTokenList implements TokenList { private final Document doc; private CharSequence currentWordText; private int currentWordStartOffset; private boolean hidden; private int nextSearchOffset; MarkdownTokenList(Document doc) { this.doc = doc; this.hidden = false; } @Override public void setStartOffset(final int startOffset) { currentWordText = null; currentWordStartOffset = -1; CharSequence content = DocumentUtilities.getText(doc); nextSearchOffset = findCurrentWordStart(content, startOffset); FileObject fileObject = FileUtil.getConfigFile("Spellcheckers/Markdown"); //NOI18N Boolean b = (Boolean) fileObject.getAttribute("Hidden");//NOI18N hidden = Boolean.TRUE.equals(b); } @Override public boolean nextWord() { if (hidden) { return false; } try { CharSequence content = DocumentUtilities.getText(doc); final int startOffset = findNextWordStart(content, nextSearchOffset); final int endOffset = findCurrentWordEnd(content, startOffset); if (startOffset < endOffset) { currentWordStartOffset = startOffset; nextSearchOffset = endOffset; currentWordText = doc.getText(startOffset, endOffset - startOffset); return true; } else { nextSearchOffset = content.length(); return false; } } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); return false; } } /** * Finds the index of the first letter character at or after the given index. * @param content The character sequence to search. * @param fromIndex The index to begin searching. * @return The index of a letter character of the length of the character sequence * if no letter character was found. */ private int findNextWordStart(CharSequence content, int fromIndex) { return findNextWordBoundary(content, fromIndex, false); } /** * Finds the index of the first non-letter character at or after the given index. * @param content The character sequence to search. * @param fromIndex The index to begin searching. * @return The index of a non-letter character of the length of the character * sequence if no non-letter character was found. */ private int findCurrentWordEnd(CharSequence content, int fromIndex) { return findNextWordBoundary(content, fromIndex, true); } /** * Finds the index of the first letter of the word which contains the given index. * @param content The character sequence to search. * @param fromIndex The index to begin searching. * @return The index of the first letter character which is preceded by a non-letter * character or the start of the character sequence if the given index points * to a letter character. The given index if it points to a non-letter character * or is outside the range of valid indices. */ private int findCurrentWordStart(CharSequence content, int fromIndex) { int index = fromIndex; while ((index > 0) && (index < content.length()) && Character.isLetter(content.charAt(index - 1))) { index--; } return index; } private int findNextWordBoundary(CharSequence content, int fromIndex, boolean findEnd) { int index = fromIndex; while ((index < content.length()) && (findEnd == Character.isLetter(content.charAt(index)))) { index++; } return index; } @Override public int getCurrentWordStartOffset() { return currentWordStartOffset; } @Override public CharSequence getCurrentWordText() { return currentWordText; } @Override public void addChangeListener(ChangeListener cl) { } @Override public void removeChangeListener(ChangeListener cl) { } }