ts.move(searchOffset);
if(!isEndMacro) { // of not an end macro
boolean isPair = false; // is not pair so far (check below)
if(macroName != null) {
LatteMacro mcr = MacroDefinitions.getMacro(macroName);
if(mcr != null) {
isPair = mcr.isPair();
pairMacroNames.add(mcr.getEndMacroName());
}
for(String m : MacroDefinitions.FRIEND_MACROS.keySet()) { // checking for friend macro
for(LatteMacro f : MacroDefinitions.FRIEND_MACROS.get(m)) {
if(f.getMacroName().equals(macroName) || m.equals(macroName)) {
if(!m.equals(macroName)) {
if(!friends.contains(m)) {
friends.add(m);
}
}
for(LatteMacro macro : MacroDefinitions.FRIEND_MACROS.get(m)) {
if(!friends.contains(macro.getMacroName())) {
friends.add(macro.getMacroName());
}
if(!friends.contains(macro.getEndMacroName())) {
friends.add(macro.getEndMacroName());
}
}
isPair = true; // isPair = has friends
break;
}
}
}
}
if(!isPair) {
// it is not pair macro, return zero length offset = hack against matching error (red hi-light)
return new int[] { searchOffset, searchOffset };
}
} else {
for(LatteMacro m : MacroDefinitions.getMacrosByEnd(macroName)) {
if(!pairMacroNames.contains(m.getMacroName())) {
pairMacroNames.add(m.getMacroName()); // finds start macro by end macro
}
}
}
// moves sequence offset accordingly to start/end macro (start forward, end backward )
if(!isEndMacro) {
ts.moveNext();
if(ts.offset() >= mStart + mLength) {
ts.movePrevious();
}
} else {
ts.movePrevious();
if(ts.offset() < mStart) {
ts.moveNext();
}
}
// finds start/friend/end macro
while(isEndMacro ? ts.movePrevious() : ts.moveNext()) {
Token<LatteTopTokenId> t = ts.token();
if(t.id() == LatteTopTokenId.LATTE) { // process only latte
Syntax syntax = (Syntax) t.getProperty("syntax");
if(!syntax.isOpening(t.text().toString())) { // process only macros
continue;
}
// go through inside macro tokens
TokenSequence<LatteTokenId> ts2 = LexUtils.getSequence(t);
ts2.moveStart();
boolean isEndMacro2 = false; // is parsed macro end macro?
int i = 0; // used for checking end macro slash position
while(ts2.moveNext() && i < 3) {
Token<LatteTokenId> t2 = ts2.token();
if(t2.id() == LatteTokenId.MACRO) { // macro name token reached
String macroName2 = t2.text().toString();
if(embeddedMacros == 0) { // only if we are at the same nesting level
if((pairMacroNames.contains(macroName2) && isEndMacro != isEndMacro2)
|| friends.contains(macroName2)) { // it is start/friend/end macro
return new int[] {
ts.offset(), ts.offset() + ts2.offset() + t2.length(), // hi-light {macro
ts.offset() + t.length() - syntax.closing().length(), ts.offset() + t.length() // hi-light }
};
}
}
// it is not a macro we want
LatteMacro m = MacroDefinitions.getMacro(macroName2);
if(m != null && m.isPair()) { // if it is pair macro
if(!isEndMacro2) {
embeddedMacros++; // add nesting level if start macro
} else {
embeddedMacros--; // remove nesting level if end macro
}