PageRenderTime 28ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/jext-5.0/src/lib/org/gjt/sp/jedit/syntax/HTMLTokenMarker.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 408 lines | 365 code | 13 blank | 30 comment | 73 complexity | da4f8411398efdee3075e266285acb95 MD5 | raw file
  1. /*
  2. * HTMLTokenMarker.java - HTML token marker
  3. * Copyright (C) 1998, 1999 Slava Pestov
  4. * Portions Copyright (C) 2001 by Romain Guy
  5. * (this includes attributes colorizing)
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. package org.gjt.sp.jedit.syntax;
  22. import javax.swing.text.Segment;
  23. /**
  24. * HTML token marker.
  25. *
  26. * @author Slava Pestov
  27. * @version $Id: HTMLTokenMarker.java,v 1.3 2001/12/01 18:54:31 gfx Exp $
  28. */
  29. public class HTMLTokenMarker extends TokenMarker
  30. {
  31. public static final byte JAVASCRIPT = Token.INTERNAL_FIRST;
  32. public static final byte HTML_LITERAL_QUOTE = Token.INTERNAL_FIRST + 1;
  33. public static final byte HTML_LITERAL_NO_QUOTE = Token.INTERNAL_FIRST + 2;
  34. public static final byte INSIDE_TAG = Token.INTERNAL_FIRST + 3;
  35. public HTMLTokenMarker()
  36. {
  37. this(true);
  38. }
  39. public HTMLTokenMarker(boolean js)
  40. {
  41. this.js = js;
  42. keywords = JavaScriptTokenMarker.getKeywords();
  43. }
  44. public byte markTokensImpl(byte token, Segment line, int lineIndex)
  45. {
  46. char[] array = line.array;
  47. int offset = line.offset;
  48. lastOffset = offset;
  49. lastKeyword = offset;
  50. int length = line.count + offset;
  51. boolean backslash = false;
  52. lastWhitespace = offset - 1;
  53. loop:
  54. for (int i = offset; i < length; i++)
  55. {
  56. int i1 = (i + 1);
  57. char c = array[i];
  58. if (c == '\\')
  59. {
  60. backslash = !backslash;
  61. if (token == JAVASCRIPT)
  62. continue;
  63. }
  64. switch (token)
  65. {
  66. case Token.NULL: // HTML text
  67. backslash = false;
  68. switch (c)
  69. {
  70. case '\\':
  71. addToken(i - lastOffset, token);
  72. lastOffset = lastKeyword = i;
  73. token = Token.OPERATOR;
  74. break;
  75. case '<':
  76. addToken(i - lastOffset, token);
  77. lastOffset = lastKeyword = i;
  78. if (SyntaxUtilities.regionMatches(false, line, i1, "!--"))
  79. {
  80. i += 3;
  81. token = Token.COMMENT1;
  82. } else if (js && SyntaxUtilities.regionMatches(true, line, i1, "script")) {
  83. addToken(1, Token.KEYWORD1);
  84. //addToken(6, Token.METHOD);
  85. //lastOffset = lastKeyword = (i += 7);
  86. lastOffset = lastKeyword = i1;
  87. token = Token.METHOD;//JAVASCRIPT;
  88. javascript = true;
  89. } else {
  90. addToken(1, Token.KEYWORD1);
  91. lastOffset = lastKeyword = i1;
  92. token = Token.METHOD;
  93. }
  94. break;
  95. case '&':
  96. addToken(i - lastOffset, token);
  97. lastOffset = lastKeyword = i;
  98. token = Token.KEYWORD2;
  99. break;
  100. }
  101. break;
  102. case Token.OPERATOR:
  103. backslash = false;
  104. if (c != '<')
  105. {
  106. addToken(i1 - lastOffset, token);
  107. lastOffset = lastKeyword = i1;
  108. token = Token.NULL;
  109. }
  110. break;
  111. case Token.METHOD: // Inside a tag
  112. backslash = false;
  113. if (c == '>')
  114. {
  115. addToken(i - lastOffset, token);
  116. addToken(1, Token.KEYWORD1);
  117. lastOffset = lastKeyword = i1;
  118. if (!javascript)
  119. token = Token.NULL;
  120. else
  121. {
  122. javascript = false;
  123. lastWhitespace = i;
  124. token = JAVASCRIPT;
  125. }
  126. } else if (c == ':') {
  127. addToken(i1 - lastOffset, Token.LITERAL2);
  128. lastOffset = lastKeyword = i1;
  129. } else if (c == ' ' || c == '\t') {
  130. addToken(i1 - lastOffset, token);
  131. lastOffset = lastKeyword = i1;
  132. token = INSIDE_TAG;
  133. }
  134. break;
  135. case INSIDE_TAG:
  136. if (c == '>')
  137. {
  138. addToken(i - lastOffset, Token.METHOD);
  139. addToken(1, Token.KEYWORD1);
  140. lastOffset = lastKeyword = i1;
  141. if (!javascript)
  142. token = Token.NULL;
  143. else
  144. {
  145. javascript = false;
  146. token = JAVASCRIPT;
  147. }
  148. } else if (c == '/' || c == '?') {
  149. addToken(1, Token.METHOD);
  150. lastOffset = lastKeyword = i1;
  151. token = Token.METHOD;
  152. } else {//if (c != ' ' && c != '\t') {
  153. addToken(i - lastOffset, Token.NULL);
  154. lastOffset = lastKeyword = i;
  155. token = Token.KEYWORD3;
  156. }
  157. break;
  158. case Token.KEYWORD2: // Inside an entity
  159. backslash = false;
  160. if (c == ';')
  161. {
  162. addToken(i1 - lastOffset, token);
  163. lastOffset = lastKeyword = i1;
  164. token = Token.NULL;
  165. }
  166. break;
  167. case Token.KEYWORD3: // Inside an attribute
  168. if (c == '/' || c == '?')
  169. {
  170. addToken(i - lastOffset, token);
  171. addToken(1, Token.METHOD);
  172. lastOffset = lastKeyword = i1;
  173. //token = INSIDE_TAG;
  174. } else if (c == '=') {
  175. addToken(i - lastOffset, token);
  176. addToken(1, Token.LABEL);
  177. lastOffset = lastKeyword = i1;
  178. if (i1 < array.length && array[i1] == '"')
  179. {
  180. token = HTML_LITERAL_QUOTE;
  181. i++;
  182. } else {
  183. token = HTML_LITERAL_NO_QUOTE;
  184. }
  185. } else if (c == '>') {
  186. addToken(i - lastOffset, token);
  187. addToken(1, Token.KEYWORD1);
  188. lastOffset = lastKeyword = i1;
  189. token = Token.NULL;
  190. } else if (c == ' ' || c == '\t') {
  191. addToken(i1 - lastOffset, token);
  192. lastOffset = lastKeyword = i1;
  193. token = INSIDE_TAG;
  194. }
  195. break;
  196. case HTML_LITERAL_QUOTE:
  197. if (c == '"')
  198. {
  199. addToken(i1 - lastOffset, Token.LITERAL1);
  200. lastOffset = lastKeyword = i1;
  201. token = INSIDE_TAG;
  202. }
  203. break;
  204. case HTML_LITERAL_NO_QUOTE:
  205. if (c == ' ' || c == '\t')
  206. {
  207. addToken(i1 - lastOffset, Token.LITERAL1);
  208. lastOffset = lastKeyword = i1;
  209. token = INSIDE_TAG;
  210. } else if (c == '>') {
  211. addToken(i - lastOffset, Token.LITERAL1);
  212. addToken(1, Token.KEYWORD1);
  213. lastOffset = lastKeyword = i1;
  214. token = Token.NULL;
  215. }
  216. break;
  217. case Token.COMMENT1: // Inside a comment
  218. backslash = false;
  219. if (SyntaxUtilities.regionMatches(false, line, i, "-->"))
  220. {
  221. addToken((i + 3) - lastOffset, token);
  222. lastOffset = lastKeyword = i + 3;
  223. token = Token.NULL;
  224. }
  225. break;
  226. case JAVASCRIPT: // Inside a JavaScript
  227. switch (c)
  228. {
  229. case '<':
  230. backslash = false;
  231. doKeyword(line, i, c);
  232. if (SyntaxUtilities.regionMatches(true, line, i1, "/script>"))
  233. {
  234. addToken(i - lastOffset, Token.NULL);
  235. addToken(1, Token.KEYWORD1);
  236. addToken(7, Token.METHOD);
  237. addToken(1, Token.KEYWORD1);
  238. lastOffset = lastKeyword = (i += 9);
  239. token = Token.NULL;
  240. }
  241. break;
  242. case '(':
  243. if (backslash)
  244. {
  245. doKeyword(line, i, c);
  246. backslash = false;
  247. } else {
  248. if (doKeyword(line, i, c))
  249. break;
  250. addToken(lastWhitespace - lastOffset + 1, Token.NULL);
  251. addToken(i - lastWhitespace - 1, Token.METHOD);
  252. addToken(1, Token.NULL);
  253. token = JAVASCRIPT;
  254. lastOffset = lastKeyword = i1;
  255. lastWhitespace = i;
  256. }
  257. break;
  258. case '"':
  259. if (backslash)
  260. backslash = false;
  261. else
  262. {
  263. doKeyword(line, i, c);
  264. addToken(i - lastOffset, Token.NULL);
  265. lastOffset = lastKeyword = i;
  266. token = Token.LITERAL1;
  267. }
  268. break;
  269. case '\'':
  270. if (backslash)
  271. backslash = false;
  272. else
  273. {
  274. doKeyword(line, i, c);
  275. addToken(i - lastOffset, Token.NULL);
  276. lastOffset = lastKeyword = i;
  277. token = Token.LITERAL2;
  278. }
  279. break;
  280. case '/':
  281. backslash = false;
  282. doKeyword(line, i, c);
  283. if (length - i > 1)
  284. {
  285. addToken(i - lastOffset, Token.NULL);
  286. lastOffset = lastKeyword = i;
  287. if (array[i1] == '/')
  288. {
  289. addToken(length - i, Token.COMMENT2);
  290. lastOffset = lastKeyword = length;
  291. break loop;
  292. } else if (array[i1] == '*') {
  293. token = Token.COMMENT2;
  294. }
  295. }
  296. break;
  297. default:
  298. backslash = false;
  299. if (!Character.isLetterOrDigit(c) && c != '_')
  300. doKeyword(line, i, c);
  301. if (CTokenMarker.METHOD_DELIMITERS.indexOf(c) != -1)
  302. {
  303. lastWhitespace = i;
  304. }
  305. break;
  306. }
  307. break;
  308. case Token.LITERAL1: // JavaScript "..."
  309. if (backslash)
  310. backslash = false;
  311. else if (c == '"')
  312. {
  313. addToken(i1 - lastOffset, Token.LITERAL1);
  314. lastOffset = lastKeyword = i1;
  315. token = JAVASCRIPT;
  316. }
  317. break;
  318. case Token.LITERAL2: // JavaScript '...'
  319. if (backslash)
  320. backslash = false;
  321. else if (c == '\'')
  322. {
  323. addToken(i1 - lastOffset, Token.LITERAL1);
  324. lastOffset = lastKeyword = i1;
  325. token = JAVASCRIPT;
  326. }
  327. break;
  328. case Token.COMMENT2: // Inside a JavaScript comment
  329. backslash = false;
  330. if (c == '*' && length - i > 1 && array[i1] == '/')
  331. {
  332. addToken((i += 2) - lastOffset, Token.COMMENT1);
  333. lastOffset = lastKeyword = i;
  334. token = JAVASCRIPT;
  335. }
  336. break;
  337. default:
  338. throw new InternalError("Invalid state: " + token);
  339. }
  340. }
  341. switch (token)
  342. {
  343. case Token.LITERAL1:
  344. case Token.LITERAL2:
  345. addToken(length - lastOffset, Token.INVALID);
  346. token = JAVASCRIPT;
  347. break;
  348. case Token.KEYWORD2:
  349. addToken(length - lastOffset, Token.INVALID);
  350. token = Token.NULL;
  351. break;
  352. case JAVASCRIPT:
  353. doKeyword(line, length, '\0');
  354. addToken(length - lastOffset, Token.NULL);
  355. break;
  356. case Token.COMMENT2:
  357. addToken(length - lastOffset, Token.COMMENT1);
  358. break;
  359. case INSIDE_TAG:
  360. break;
  361. case HTML_LITERAL_QUOTE: case HTML_LITERAL_NO_QUOTE:
  362. addToken(length - lastOffset, Token.LITERAL1);
  363. break;
  364. default:
  365. addToken(length - lastOffset, token);
  366. break;
  367. }
  368. return token;
  369. }
  370. // private members
  371. private KeywordMap keywords;
  372. private boolean js;
  373. private boolean javascript;
  374. private int lastOffset;
  375. private int lastKeyword;
  376. private int lastWhitespace;
  377. private boolean doKeyword(Segment line, int i, char c)
  378. {
  379. int i1 = i + 1;
  380. int len = i - lastKeyword;
  381. byte id = keywords.lookup(line, lastKeyword, len);
  382. if (id != Token.NULL)
  383. {
  384. if (lastKeyword != lastOffset)
  385. addToken(lastKeyword - lastOffset, Token.NULL);
  386. addToken(len, id);
  387. lastKeyword = i1;
  388. lastOffset = i;
  389. lastWhitespace = i;
  390. return true;
  391. }
  392. lastKeyword = i1;
  393. return false;
  394. }
  395. }