1 22 23 package org.armedbear.j; 24 25 import java.util.ArrayList ; 26 27 public final class RubyTagger extends Tagger 28 { 29 private static final int STATE_NEUTRAL = 0; 31 private static final int STATE_CLASS_NAME = 1; 32 private static final int STATE_FUNCTION_NAME = 2; 33 private static final int STATE_SINGLE_QUOTE = 3; 34 private static final int STATE_DOUBLE_QUOTE = 4; 35 private static final int STATE_TRIPLE_SINGLE = 5; 36 private static final int STATE_TRIPLE_DOUBLE = 6; 37 38 private static final RubyMode mode = RubyMode.getMode(); 39 40 public RubyTagger(SystemBuffer buffer) 41 { 42 super(buffer); 43 } 44 45 public void run() 46 { 47 ArrayList tags = new ArrayList (); 48 Position pos = new Position(buffer.getFirstLine(), 0); 49 int state = STATE_NEUTRAL; 50 while (!pos.atEnd()) { 51 char c = pos.getChar(); 52 if (Character.isWhitespace(c)) { 53 pos.skipWhitespace(); 54 continue; 55 } 56 if (c == '\\') { 57 if (pos.getOffset() < pos.getLineLength()-1) { 59 pos.skip(2); 60 } else { 61 pos.setLine(pos.getNextLine()); 62 pos.setOffset(0); 63 } 64 continue; 65 } 66 if (state == STATE_SINGLE_QUOTE) { 67 if (c == '\'') 68 state = STATE_NEUTRAL; 69 pos.next(); 70 continue; 71 } 72 if (state == STATE_DOUBLE_QUOTE) { 73 if (c == '"') 74 state = STATE_NEUTRAL; 75 pos.next(); 76 continue; 77 } 78 if (state == STATE_TRIPLE_SINGLE) { 79 if (c == '\'' && pos.lookingAt("'''")) { 80 pos.skip(3); 81 state = STATE_NEUTRAL; 82 } else 83 pos.next(); 84 continue; 85 } 86 if (state == STATE_TRIPLE_DOUBLE) { 87 if (c == '"' && pos.lookingAt("\"\"\"")) { 88 pos.skip(3); 89 state = STATE_NEUTRAL; 90 } else 91 pos.next(); 92 continue; 93 } 94 if (c == '\'') { 95 if (pos.lookingAt("'''")) { 96 state = STATE_TRIPLE_SINGLE; 97 pos.skip(3); 98 } else { 99 state = STATE_SINGLE_QUOTE; 100 pos.next(); 101 } 102 continue; 103 } 104 if (c == '"') { 105 if (pos.lookingAt("\"\"\"")) { 106 state = STATE_TRIPLE_DOUBLE; 107 pos.skip(3); 108 } else { 109 state = STATE_DOUBLE_QUOTE; 110 pos.next(); 111 } 112 continue; 113 } 114 if (c == '#') { 115 pos.setLine(pos.getNextLine()); 117 pos.setOffset(0); 118 continue; 119 } 120 if (mode.isIdentifierStart(c)) { 121 Position start = pos.copy(); 122 String token = gatherToken(pos); 123 if (state == STATE_CLASS_NAME) { 124 LocalTag tag = new RubyTag("class " + token, start, TAG_CLASS); 125 tags.add(tag); 126 state = STATE_NEUTRAL; 127 } else if (state == STATE_FUNCTION_NAME) { 128 LocalTag tag = new RubyTag(token, start, TAG_FUNCTION); 129 tags.add(tag); 130 state = STATE_NEUTRAL; 131 } else if (token.equals("class")) { 132 state = STATE_CLASS_NAME; 133 } else if (token.equals("def")) { 134 state = STATE_FUNCTION_NAME; 135 } 136 continue; 137 } 138 pos.next(); 139 } 140 buffer.setTags(tags); 141 } 142 143 private static String gatherToken(Position pos) 144 { 145 FastStringBuffer sb = new FastStringBuffer(); 146 char c; 147 while (mode.isIdentifierPart(c = pos.getChar())) { 148 sb.append(c); 149 if (!pos.next()) 150 break; 151 } 152 return sb.toString(); 153 } 154 } 155 | Popular Tags |