/* * 02/21/2004 * * Token.java - A token used in syntax highlighting. * * This library is distributed under a modified BSD license. See the included * RSyntaxTextArea.License.txt file for details. */ package org.fife.ui.rsyntaxtextarea; import java.awt.Rectangle; import javax.swing.text.TabExpander; /** * A generic token that functions as a node in a linked list of syntax * highlighted tokens for some language.<p> * * A <code>Token</code> is a piece of text representing some logical token in * source code for a programming language. For example, the line of C code:<p> * <pre> * int i = 0; * </pre> * would be broken into 8 <code>Token</code>s: the first representing * <code>int</code>, the second whitespace, the third <code>i</code>, the fourth * whitespace, the fifth <code>=</code>, etc.<p> * * <b>Note:</b> The tokens returned by {@link RSyntaxDocument}s are pooled and * should always be treated as immutable. Modifying tokens you did not create * yourself can and will result in rendering issues and/or runtime exceptions. * You have been warned! * * @author Robert Futrell * @version 0.3 */ public interface Token extends TokenTypes { /** * Appends HTML code for painting this token, using the given text area's * color scheme. * * @param sb The buffer to append to. * @param textArea The text area whose color scheme to use. * @param fontFamily Whether to include the font family in the HTML for * this token. You can pass <code>false</code> for this parameter * if, for example, you are making all your HTML be monospaced, * and don't want any crazy fonts being used in the editor to be * reflected in your HTML. * @return The buffer appended to. * @see #getHTMLRepresentation(RSyntaxTextArea) */ public StringBuilder appendHTMLRepresentation(StringBuilder sb, RSyntaxTextArea textArea, boolean fontFamily); /** * Appends HTML code for painting this token, using the given text area's * color scheme. * * @param sb The buffer to append to. * @param textArea The text area whose color scheme to use. * @param fontFamily Whether to include the font family in the HTML for * this token. You can pass <code>false</code> for this parameter * if, for example, you are making all your HTML be monospaced, * and don't want any crazy fonts being used in the editor to be * reflected in your HTML. * @param tabsToSpaces Whether to convert tabs into spaces. * @return The buffer appended to. * @see #getHTMLRepresentation(RSyntaxTextArea) */ public StringBuilder appendHTMLRepresentation(StringBuilder sb, RSyntaxTextArea textArea, boolean fontFamily, boolean tabsToSpaces); /** * Returns the character at the specified offset in the token. * * @param index The index. This should be in the range * <code>0-({@link #length()}-1)</code>. * @return The character. * @see #length() */ public char charAt(int index); /** * Returns whether the token straddles the specified position in the * document. * * @param pos The position in the document to check. * @return Whether the specified position is straddled by this token. */ public boolean containsPosition(int pos); /** * Returns the position in the token's internal char array corresponding * to the specified document position.<p> * Note that this method does NOT do any bounds checking; you can pass in * a document position that does not correspond to a position in this * token, and you will not receive an Exception or any other notification; * it is up to the caller to ensure valid input. * * @param pos A position in the document that is represented by this token. * @return The corresponding token position >= <code>textOffset</code> * and < <code>textOffset+textCount</code>. * @see #tokenToDocument */ public int documentToToken(int pos); /** * Returns whether this token's lexeme ends with the specified characters. * * @param ch The characters. * @return Whether this token's lexeme ends with the specified characters. * @see #startsWith(char[]) */ public boolean endsWith(char[] ch); /** * Returns the end offset of this token in the document (exclusive). In * other words, the token ranges from * <code>[getOffset(), getEndOffset())</code>. * * @return The end offset of this token. * @see #getOffset() */ public int getEndOffset(); /** * Returns a <code>String</code> containing HTML code for painting this * token, using the given text area's color scheme. * * @param textArea The text area whose color scheme to use. * @return The HTML representation of the token. * @see #appendHTMLRepresentation(StringBuilder, RSyntaxTextArea, boolean) */ public String getHTMLRepresentation(RSyntaxTextArea textArea); /** * Returns the language index of this token. * * @return The language index. A value of <code>0</code> denotes the * "main" language, any positive value denotes a specific secondary * language. * @see #setLanguageIndex(int) */ public int getLanguageIndex(); /** * Returns the last token in this list that is not whitespace or a * comment. * * @return The last non-comment, non-whitespace token, or <code>null</code> * if there isn't one. */ public Token getLastNonCommentNonWhitespaceToken(); /** * Returns the last paintable token in this token list, or <code>null</code> * if there is no paintable token. * * @return The last paintable token in this token list. */ public Token getLastPaintableToken(); /** * Returns the text of this token, as a string.<p> * * Note that this method isn't used much by the * <code>ryntaxtextarea</code> package internally, as it tries to limit * memory allocation. * * @return The text of this token. */ public String getLexeme(); /** * Determines the offset into this token list (i.e., into the * document) that covers pixel location <code>x</code> if the token list * starts at pixel location <code>x0</code><p>. * This method will return the document position "closest" to the * x-coordinate (i.e., if they click on the "right-half" of the * <code>w</code> in <code>awe</code>, the caret will be placed in * between the <code>w</code> and <code>e</code>; similarly, clicking on * the left-half places the caret between the <code>a</code> and * <code>w</code>). This makes it useful for methods such as * <code>viewToModel</code> found in <code>javax.swing.text.View</code> * subclasses. * * @param textArea The text area from which the token list was derived. * @param e How to expand tabs. * @param x0 The pixel x-location that is the beginning of * <code>tokenList</code>. * @param x The pixel-position for which you want to get the corresponding * offset. * @return The position (in the document, NOT into the token list!) that * covers the pixel location. If <code>tokenList</code> is * <code>null</code> or has type <code>Token.NULL</code>, then * <code>-1</code> is returned; the caller should recognize this and * return the actual end position of the (empty) line. */ public int getListOffset(RSyntaxTextArea textArea, TabExpander e, float x0, float x); /** * Returns the token after this one in the linked list. * * @return The next token. */ public Token getNextToken(); /** * Returns the offset into the document at which this token resides. * * @return The offset into the document. * @see #getEndOffset() */ public int getOffset(); /** * Returns the position in the document that represents the last character * in the token that will fit into <code>endBeforeX-startX</code> pixels. * For example, if you're using a monospaced 8-pixel-per-character font, * have the token "while" and <code>startX</code> is <code>0</code> and * <code>endBeforeX</code> is <code>30</code>, this method will return the * document position of the "i" in "while", because the "i" ends at pixel * <code>24</code>, while the "l" ends at <code>32</code>. If not even the * first character fits in <code>endBeforeX-startX</code>, the first * character's position is still returned so calling methods don't go into * infinite loops. * * @param textArea The text area in which this token is being painted. * @param e How to expand tabs. * @param startX The x-coordinate at which the token will be painted. This * is needed because of tabs. * @param endBeforeX The x-coordinate for which you want to find the last * character of <code>t</code> which comes before it. * @return The last document position that will fit in the specified amount * of pixels. */ /* * @see #getTokenListOffsetBeforeX * FIXME: This method does not compute correctly! It needs to be abstract * and implemented by subclasses. */ public int getOffsetBeforeX(RSyntaxTextArea textArea, TabExpander e, float startX, float endBeforeX); /** * Returns the character array backing the lexeme of this token. This * value should be treated as read-only. * * @return A character array containing the lexeme of this token. * @see #getTextOffset() * @see #length() */ public char[] getTextArray(); /** * Returns the offset into the character array of the lexeme in * {@link #getTextArray()}. * * @return The offset of the lexeme in the character array. * @see #getTextArray() */ public int getTextOffset(); /** * Returns the type of this token. * * @return The type of this token. * @see TokenTypes * @see #setType(int) */ public int getType(); /** * Returns the width of this token given the specified parameters. * * @param textArea The text area in which the token is being painted. * @param e Describes how to expand tabs. This parameter cannot be * <code>null</code>. * @param x0 The pixel-location at which the token begins. This is needed * because of tabs. * @return The width of the token, in pixels. * @see #getWidthUpTo */ public float getWidth(RSyntaxTextArea textArea, TabExpander e, float x0); /** * Returns the width of a specified number of characters in this token. * For example, for the token "while", specifying a value of <code>3</code> * here returns the width of the "whi" portion of the token. * * @param numChars The number of characters for which to get the width. * @param textArea The text area in which the token is being painted. * @param e How to expand tabs. This value cannot be <code>null</code>. * @param x0 The pixel-location at which this token begins. This is needed * because of tabs. * @return The width of the specified number of characters in this token. * @see #getWidth */ public float getWidthUpTo(int numChars, RSyntaxTextArea textArea, TabExpander e, float x0); /** * Returns whether this token's lexeme matches a specific character array. * * @param lexeme The lexeme to check for. * @return Whether this token has that lexeme. * @see #is(int, char[]) * @see #is(int, String) * @see #isSingleChar(int, char) * @see #startsWith(char[]) */ public boolean is(char[] lexeme); /** * Returns whether this token is of the specified type, with the specified * lexeme.<p> * This method is preferred over the other overload in performance-critical * code where this operation may be called frequently, since it does not * involve any String allocations. * * @param type The type to check for. * @param lexeme The lexeme to check for. * @return Whether this token has that type and lexeme. * @see #is(int, String) * @see #is(char[]) * @see #isSingleChar(int, char) * @see #startsWith(char[]) */ public boolean is(int type, char[] lexeme); /** * Returns whether this token is of the specified type, with the specified * lexeme.<p> * The other overload of this method is preferred over this one in * performance-critical code, as this one involves a String allocation * while the other does not. * * @param type The type to check for. * @param lexeme The lexeme to check for. * @return Whether this token has that type and lexeme. * @see #is(int, char[]) * @see #isSingleChar(int, char) * @see #startsWith(char[]) */ public boolean is(int type, String lexeme); /** * Returns whether this token is a comment. * * @return Whether this token is a comment. * @see #isWhitespace() * @see #isCommentOrWhitespace() */ public boolean isComment(); /** * Returns whether this token is a comment or whitespace. * * @return Whether this token is a comment or whitespace. * @see #isComment() * @see #isWhitespace() */ public boolean isCommentOrWhitespace(); /** * Returns whether this token is a hyperlink. * * @return Whether this token is a hyperlink. * @see #setHyperlink(boolean) */ public boolean isHyperlink(); /** * Returns whether this token is an identifier. * * @return Whether this token is an identifier. */ public boolean isIdentifier(); /** * Returns whether this token is a {@link #SEPARATOR} representing a single * left curly brace. * * @return Whether this token is a left curly brace. * @see #isRightCurly() */ public boolean isLeftCurly(); /** * Returns whether this token is a {@link #SEPARATOR} representing a single * right curly brace. * * @return Whether this token is a right curly brace. * @see #isLeftCurly() */ public boolean isRightCurly(); /** * Returns whether or not this token is "paintable;" i.e., whether or not * the type of this token is one such that it has an associated syntax * style. What this boils down to is whether the token type is greater * than <code>Token.NULL</code>. * * @return Whether or not this token is paintable. */ public boolean isPaintable(); /** * Returns whether this token is the specified single character. * * @param ch The character to check for. * @return Whether this token's lexeme is the single character specified. * @see #isSingleChar(int, char) */ public boolean isSingleChar(char ch); /** * Returns whether this token is the specified single character, and of a * specific type. * * @param type The token type. * @param ch The character to check for. * @return Whether this token is of the specified type, and with a lexeme * Equaling the single character specified. * @see #isSingleChar(char) */ public boolean isSingleChar(int type, char ch); /** * Returns whether or not this token is whitespace. * * @return <code>true</code> iff this token is whitespace. * @see #isComment() * @see #isCommentOrWhitespace() */ public boolean isWhitespace(); /** * Returns the length of this token. * * @return The length of this token. * @see #getOffset() */ public int length(); /** * Returns the bounding box for the specified document location. The * location must be in the specified token list; if it isn't, * <code>null</code> is returned. * * @param textArea The text area from which the token list was derived. * @param e How to expand tabs. * @param pos The position in the document for which to get the bounding * box in the view. * @param x0 The pixel x-location that is the beginning of * <code>tokenList</code>. * @param rect The rectangle in which we'll be returning the results. This * object is reused to keep from frequent memory allocations. * @return The bounding box for the specified position in the model. */ public Rectangle listOffsetToView(RSyntaxTextArea textArea, TabExpander e, int pos, int x0, Rectangle rect); /** * Sets whether this token is a hyperlink. * * @param hyperlink Whether this token is a hyperlink. * @see #isHyperlink() */ public void setHyperlink(boolean hyperlink); /** * Sets the language index for this token. If this value is positive, it * denotes a specific "secondary" language this token represents (such as * JavaScript code or CSS embedded in an HTML file). If this value is * <code>0</code>, this token is in the "main" language being edited. * Negative values are invalid and treated as <code>0</code>. * * @param languageIndex The new language index. A value of * <code>0</code> denotes the "main" language, any positive value * denotes a specific secondary language. Negative values will * be treated as <code>0</code>. * @see #getLanguageIndex() */ public void setLanguageIndex(int languageIndex); /** * Sets the type of this token. * * @param type The new token type. * @see TokenTypes * @see #getType() */ public void setType(int type); /** * Returns whether this token starts with the specified characters. * * @param chars The characters. * @return Whether this token starts with those characters. * @see #endsWith(char[]) * @see #is(int, char[]) */ public boolean startsWith(char[] chars); /** * Returns the position in the document corresponding to the specified * position in this token's internal char array (<code>textOffset</code> - * <code>textOffset+textCount-1</code>).<p> * Note that this method does NOT do any bounds checking; you can pass in * an invalid token position, and you will not receive an Exception or any * other indication that the returned document position is invalid. It is * up to the user to ensure valid input. * * @param pos A position in the token's internal char array * (<code>textOffset</code> - <code>textOffset+textCount</code>). * @return The corresponding position in the document. * @see #documentToToken(int) */ public int tokenToDocument(int pos); }