package org.fife.ui.rsyntaxtextarea;
import javax.swing.text.TabExpander;
/**
* Utility methods for dealing with tokens.
*
* @author Robert Futrell
* @version 1.0
*/
public class TokenUtils {
private TokenUtils() {}
/**
* Modifies the passed-in token list to start at the specified offset.
* For example, if the token list covered positions 20-60 in the document
* (inclusive) like so:
* <pre>
* [token1] -> [token2] -> [token3] -> [token4]
* 20 30 31 40 41 50 51 60
* </pre>
* and you used this method to make the token list start at position 44,
* then the token list would be modified to be the following:
* <pre>
* [part-of-old-token3] -> [token4]
* 44 50 51 60
* </pre>
* Tokens that come before the specified position are forever lost, and
* the token containing that position is made to begin at that position if
* necessary. All token types remain the same as they were originally.<p>
*
* This method can be useful if you are only interested in part of a token
* list (i.e., the line it represents), but you don't want to modify the
* token list yourself.
*
* @param tokenList The list to make start at the specified position.
* This parameter is modified.
* @param pos The position at which the new token list is to start. If
* this position is not in the passed-in token list,
* returned token list will either be <code>null</code> or the
* unpaintable token(s) at the end of the passed-in token list.
* @param e How to expand tabs.
* @param textArea The text area from which the token list came.
* @param x0 The initial x-pixel position of the old token list.
* @return Information about the "sub" token list. This will be
* <code>null</code> if <code>pos</code> was not a valid offset
* into the token list.
* @see #getSubTokenList(Token, int, TabExpander, RSyntaxTextArea, float, TokenImpl)
*/
public static TokenSubList getSubTokenList(Token tokenList, int pos,
TabExpander e,
final RSyntaxTextArea textArea,
float x0) {
return getSubTokenList(tokenList, pos, e, textArea, x0, null);
}
/**
* Modifies the passed-in token list to start at the specified offset.
* For example, if the token list covered positions 20-60 in the document
* (inclusive) like so:
* <pre>
* [token1] -> [token2] -> [token3] -> [token4]
* 20 30 31 40 41 50 51 60
* </pre>
* and you used this method to make the token list start at position 44,
* then the token list would be modified to be the following:
* <pre>
* [part-of-old-token3] -> [token4]
* 44 50 51 60
* </pre>
* Tokens that come before the specified position are forever lost, and
* the token containing that position is made to begin at that position if
* necessary. All token types remain the same as they were originally.<p>
*
* This method can be useful if you are only interested in part of a token
* list (i.e., the line it represents), but you don't want to modify the
* token list yourself.
*
* @param tokenList The list to make start at the specified position.
* This parameter is modified.
* @param pos The position at which the new token list is to start. If
* this position is not in the passed-in token list,
* returned token list will either be <code>null</code> or the
* unpaintable token(s) at the end of the passed-in token list.
* @param e How to expand tabs.
* @param textArea The text area from which the token list came.
* @param x0 The initial x-pixel position of the old token list.
* @param tempToken A temporary token to use when creating the token list
* result. This may be <code>null</code> but callers can pass in
* a "buffer" token for performance if desired.
* @return Information about the "sub" token list. This will be
* <code>null</code> if <code>pos</code> was not a valid offset
* into the token list.
* @see #getSubTokenList(Token, int, TabExpander, RSyntaxTextArea, float)
*/
public static TokenSubList getSubTokenList(Token tokenList, int pos,
TabExpander e,
final RSyntaxTextArea textArea,
float x0,
TokenImpl tempToken) {
if (tempToken==null) {
tempToken = new TokenImpl();
}
Token t = tokenList;
// Loop through the token list until you find the one that contains
// pos. Remember the cumulative width of all of these tokens.
while (t!=null && t.isPaintable() && !t.containsPosition(pos)) {
x0 += t.getWidth(textArea, e, x0);
t = t.getNextToken();
}
// Make the token that contains pos start at pos.
if (t!=null && t.isPaintable()) {
if (t.getOffset()!=pos) {
// Number of chars between p0 and token start.
int difference = pos - t.getOffset();
x0 += t.getWidthUpTo(t.length()-difference+1, textArea, e, x0);
tempToken.copyFrom(t);
tempToken.makeStartAt(pos);
return new TokenSubList(tempToken, x0);
}
else { // t.getOffset()==pos
return new TokenSubList(t, x0);
}
}
// This could be a null token, so we need to just return it.
return new TokenSubList(tokenList, x0);
//return null;
}
public static class TokenSubList {
/**
* The "sub" token list.
*/
public Token tokenList;
/**
* The width, in pixels, of the part of the token list "removed from
* the front." This way, you know the x-offset of the "new" token list.
*/
public float x;
public TokenSubList(Token tokenList, float x) {
this.tokenList = tokenList;
this.x = x;
}
}
}