/cssed-0.4.0/scintilla/src/LexCSS.cxx

# · C++ · 769 lines · 714 code · 40 blank · 15 comment · 457 complexity · 7b12b0d95350ae2bbdb030ed33c28746 MD5 · raw file

  1. // Scintilla source code edit control
  2. /** @file LexCSS.cxx
  3. ** Lexer for Cascade Style Sheets
  4. ** Written by Jakub Vrána
  5. ** *******************************
  6. ** Modified by Iago Rubio for cssed
  7. ** Tue Dec 16 13:32:20 2003
  8. ** *******************************
  9. **
  10. **/
  11. // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
  12. // The License.txt file describes the conditions under which this software may be distributed.
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <stdio.h>
  17. #include <stdarg.h>
  18. #include "Platform.h"
  19. #include "PropSet.h"
  20. #include "Accessor.h"
  21. #include "StyleContext.h"
  22. #include "KeyWords.h"
  23. #include "Scintilla.h"
  24. #include "SciLexer.h"
  25. static inline bool
  26. IsAWordChar (const unsigned int ch)
  27. {
  28. return (isalnum (ch) || ch == '-' || ch == '_' || ch >= 161);
  29. }
  30. inline bool
  31. IsCssOperator (const char ch)
  32. {
  33. if (!isalnum (ch)
  34. && (ch == '{' || ch == '}' || ch == ':' || ch == '#'|| ch == ',' || ch == ';'
  35. || ch == '.' || ch == '!' || ch == '@'))
  36. return true;
  37. return false;
  38. }
  39. // added
  40. static inline bool
  41. IsValidFunctionParamChar (const unsigned int ch)
  42. {
  43. return (isalnum (ch) || ch == ',' || ch == '?' || ch == '\t'|| ch == '-'|| ch == '_'
  44. || ch == ' ' || ch == '.' || ch == '(' || ch == ')' || ch == ':'|| ch == '\%'
  45. || ch == '&'|| ch == '='|| ch == '/' || ch == '\'' || ch == '\"' || ch >= 161);
  46. }
  47. inline bool
  48. IsValidHexaChar( const char ch )
  49. {
  50. if( ch >=0 && ch <='f' )
  51. return true;
  52. return false;
  53. }
  54. inline bool
  55. IsValidHexaString( char* ch )
  56. {
  57. char *p;
  58. char *end;
  59. unsigned int len;
  60. len = strlen (ch);
  61. p = ch;
  62. end = ch + len;
  63. if( len != 3 && len != 6 )
  64. return false;
  65. while( p <= end )
  66. {
  67. if( !IsValidHexaChar( *p ))
  68. return false;
  69. p++;
  70. }
  71. return true;
  72. }
  73. inline bool
  74. IsNum (char *ch)
  75. {
  76. char *p;
  77. unsigned int len;
  78. unsigned int i = 0;
  79. unsigned int cc = 0;
  80. len = strlen (ch);
  81. p = ch;
  82. while (i < len)
  83. {
  84. if (!isdigit (*p))
  85. {
  86. if (*p == '.')
  87. cc++;
  88. else
  89. return false;
  90. }
  91. i++;
  92. p++;
  93. if (cc > 1)
  94. return false;
  95. }
  96. return true;
  97. }
  98. static void
  99. ColouriseCssDoc (unsigned int startPos, int length, int initStyle,
  100. WordList * keywordlists[], Accessor & styler)
  101. {
  102. WordList & validProperties = *keywordlists[0];
  103. WordList & pseudoClasses = *keywordlists[1];
  104. WordList & validValues = *keywordlists[2];
  105. WordList & commonFunctions = *keywordlists[3];
  106. WordList & validUnits = *keywordlists[4];
  107. WordList & namedColors = *keywordlists[5];
  108. StyleContext sc (startPos, length, initStyle, styler);
  109. int lastState = -1;
  110. int lastStateC = -1;
  111. int op = ' ';
  112. for (; sc.More (); sc.Forward ())
  113. {
  114. if (sc.state == SCE_CSS_COMMENT && sc.Match ('*', '/'))
  115. {
  116. if (lastStateC == -1)
  117. {
  118. unsigned int i = startPos;
  119. for (; i > 0; i--)
  120. {
  121. if ((lastStateC =
  122. styler.StyleAt (i - 1)) !=
  123. SCE_CSS_COMMENT)
  124. {
  125. if (lastStateC ==
  126. SCE_CSS_OPERATOR)
  127. {
  128. op = styler.
  129. SafeGetCharAt
  130. (i - 1);
  131. while (--i)
  132. {
  133. lastState =
  134. styler.
  135. StyleAt
  136. (i -
  137. 1);
  138. if (lastState
  139. !=
  140. SCE_CSS_OPERATOR
  141. &&
  142. lastState
  143. !=
  144. SCE_CSS_COMMENT)
  145. break;
  146. }
  147. if (i == 0)
  148. lastState =
  149. SCE_CSS_DEFAULT;
  150. }
  151. break;
  152. }
  153. }
  154. if (i == 0)
  155. lastStateC = SCE_CSS_DEFAULT;
  156. }
  157. sc.Forward ();
  158. sc.ForwardSetState (lastStateC);
  159. }
  160. if (sc.state == SCE_CSS_FUNCTION)
  161. {
  162. if (sc.ch == ')')
  163. {
  164. if (IsCssOperator (sc.chNext))
  165. {
  166. sc.Forward ();
  167. sc.SetState (SCE_CSS_OPERATOR);
  168. sc.ForwardSetState
  169. (SCE_CSS_IDENTIFIER);
  170. }
  171. else if (sc.chNext == '\'')
  172. {
  173. sc.ForwardSetState
  174. (SCE_CSS_SINGLESTRING);
  175. }
  176. else if (sc.chNext == '\"')
  177. {
  178. sc.ForwardSetState
  179. (SCE_CSS_DOUBLESTRING);
  180. }
  181. else
  182. {
  183. sc.ForwardSetState (SCE_CSS_VALUE);
  184. }
  185. }
  186. else
  187. {
  188. if (!IsValidFunctionParamChar (sc.ch))
  189. {
  190. sc.SetState (SCE_CSS_VALUE);
  191. }
  192. }
  193. continue;
  194. }
  195. if( sc.state == SCE_CSS_ATTR_MATCH && sc.ch == ']' )
  196. sc.ForwardSetState( SCE_CSS_TAG );
  197. else if( sc.state == SCE_CSS_ATTR_MATCH && sc.ch == '\n' && sc.chPrev != '\\' )
  198. sc.ChangeState( SCE_CSS_UNKNOWN_PSEUDOCLASS );
  199. else if( sc.state == SCE_CSS_ATTR_MATCH && sc.ch != ']')
  200. continue;
  201. if( sc.state == SCE_CSS_LANGUAGE && sc.ch == ')'){
  202. sc.ForwardSetState( SCE_CSS_TAG );
  203. }
  204. if (sc.state == SCE_CSS_COMMENT)
  205. continue;
  206. if (sc.state == SCE_CSS_DOUBLESTRING
  207. || sc.state == SCE_CSS_SINGLESTRING)
  208. {
  209. if (sc.ch !=
  210. (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\''))
  211. continue;
  212. unsigned int i = sc.currentPos;
  213. while (i && styler[i - 1] == '\\')
  214. i--;
  215. if ((sc.currentPos - i) % 2 == 1)
  216. continue;
  217. sc.ForwardSetState (SCE_CSS_VALUE);
  218. }
  219. if( sc.state == SCE_CSS_DEFAULT && sc.ch == ','){
  220. sc.ForwardSetState (SCE_CSS_DEFAULT);
  221. }
  222. if (sc.state == SCE_CSS_OPERATOR)
  223. {
  224. if (op == ' ')
  225. {
  226. unsigned int i = startPos;
  227. op = styler.SafeGetCharAt (i - 1);
  228. while (--i)
  229. {
  230. lastState = styler.StyleAt (i - 1);
  231. if (lastState != SCE_CSS_OPERATOR
  232. && lastState != SCE_CSS_COMMENT)
  233. break;
  234. }
  235. }
  236. switch (op)
  237. {
  238. case '@':
  239. if( lastState == SCE_CSS_ATTR_MATCH ){
  240. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  241. }
  242. if (lastState == SCE_CSS_DEFAULT) {
  243. sc.SetState (SCE_CSS_DIRECTIVE);
  244. }
  245. break;
  246. case '{':
  247. if( lastState == SCE_CSS_ATTR_MATCH ){
  248. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  249. }
  250. if (lastState == SCE_CSS_DIRECTIVE)
  251. {
  252. sc.SetState (SCE_CSS_DEFAULT);
  253. }
  254. else if (
  255. lastState == SCE_CSS_TAG ||
  256. lastState == SCE_CSS_CLASS ||
  257. lastState ==SCE_CSS_UNKNOWN_PSEUDOCLASS ||
  258. lastState ==SCE_CSS_PSEUDOCLASS ||
  259. lastState == SCE_CSS_CLASS ||
  260. lastState == SCE_CSS_ID ||
  261. lastState == SCE_CSS_DEFAULT
  262. )
  263. {
  264. sc.SetState (SCE_CSS_IDENTIFIER);
  265. }
  266. break;
  267. case '}':
  268. if( lastState == SCE_CSS_ATTR_MATCH ){
  269. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  270. }
  271. sc.SetState (SCE_CSS_DEFAULT);
  272. break;
  273. case ':':
  274. if( lastState == SCE_CSS_ATTR_MATCH ){
  275. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  276. }
  277. if (lastState == SCE_CSS_TAG
  278. || lastState == SCE_CSS_PSEUDOCLASS
  279. || lastState == SCE_CSS_DEFAULT
  280. || lastState == SCE_CSS_CLASS
  281. || lastState == SCE_CSS_ID
  282. || lastState ==
  283. SCE_CSS_UNKNOWN_PSEUDOCLASS)
  284. {
  285. sc.SetState (SCE_CSS_PSEUDOCLASS);
  286. }
  287. else if (lastState == SCE_CSS_IDENTIFIER
  288. || lastState ==
  289. SCE_CSS_UNKNOWN_IDENTIFIER)
  290. {
  291. sc.SetState (SCE_CSS_VALUE);
  292. }
  293. break;
  294. case '.':
  295. if( lastState == SCE_CSS_CLASS ){
  296. sc.SetState( SCE_CSS_CLASS );
  297. }
  298. else if( lastState == SCE_CSS_ATTR_MATCH )
  299. {
  300. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  301. }
  302. else if (lastState == SCE_CSS_TAG
  303. || lastState == SCE_CSS_DEFAULT)
  304. {
  305. sc.ChangeState (SCE_CSS_CLASS);
  306. }
  307. else if (lastState == SCE_CSS_FUNCTION)
  308. {
  309. sc.ChangeState (SCE_CSS_FUNCTION);
  310. }
  311. else if (lastState == SCE_CSS_COLOR)
  312. {
  313. sc.ChangeState (SCE_CSS_COLOR);
  314. }
  315. else if (lastState == SCE_CSS_NUMBER)
  316. {
  317. sc.ChangeState (SCE_CSS_NUMBER);
  318. }else if( lastState == SCE_CSS_VALUE ){
  319. sc.ChangeState (SCE_CSS_NUMBER);
  320. }
  321. break;
  322. case '#':
  323. if( lastState == SCE_CSS_ATTR_MATCH ){
  324. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  325. }
  326. if (lastState == SCE_CSS_TAG
  327. || lastState == SCE_CSS_DEFAULT)
  328. {
  329. sc.SetState (SCE_CSS_ID);
  330. }
  331. else if(lastState == SCE_CSS_VALUE)
  332. {
  333. if( IsValidHexaChar( sc.ch ) ){
  334. sc.ChangeState (SCE_CSS_HEXACOLOR);
  335. }else{
  336. sc.ChangeState (SCE_CSS_VALUE);
  337. }
  338. }else{
  339. sc.ChangeState (SCE_CSS_VALUE);
  340. }
  341. break;
  342. case ',':
  343. if( lastState == SCE_CSS_ATTR_MATCH ){
  344. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  345. }
  346. if (lastState == SCE_CSS_TAG
  347. || lastState == SCE_CSS_PSEUDOCLASS
  348. || lastState == SCE_CSS_ID
  349. || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS
  350. || lastState == SCE_CSS_CLASS
  351. )
  352. {
  353. sc.SetState (SCE_CSS_DEFAULT);
  354. }
  355. else if (lastState == SCE_CSS_VALUE
  356. || lastState == SCE_CSS_VALID_VALUE
  357. || lastState == SCE_CSS_IMPORTANT
  358. || lastState == SCE_CSS_FUNCTION
  359. || lastState == SCE_CSS_NUMBER
  360. || lastState == SCE_CSS_UNIT)
  361. {
  362. sc.SetState (SCE_CSS_VALUE);
  363. }
  364. break;
  365. case ')':
  366. if( lastState == SCE_CSS_ATTR_MATCH ){
  367. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  368. }
  369. if (lastState == SCE_CSS_FUNCTION)
  370. {
  371. sc.ForwardSetState (SCE_CSS_DEFAULT);
  372. }
  373. else
  374. {
  375. sc.SetState (SCE_CSS_VALUE);
  376. }
  377. break;
  378. case ';':
  379. if( lastState == SCE_CSS_ATTR_MATCH ){
  380. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  381. }
  382. if (lastState == SCE_CSS_DIRECTIVE)
  383. {
  384. sc.SetState (SCE_CSS_DEFAULT);
  385. }
  386. else if (lastState == SCE_CSS_VALUE
  387. || lastState == SCE_CSS_VALID_VALUE
  388. || lastState == SCE_CSS_IMPORTANT
  389. || lastState == SCE_CSS_FUNCTION
  390. || lastState == SCE_CSS_NUMBER
  391. || lastState == SCE_CSS_UNIT
  392. || lastState == SCE_CSS_COLOR
  393. || lastState == SCE_CSS_HEXACOLOR
  394. )
  395. {
  396. sc.SetState (SCE_CSS_IDENTIFIER);
  397. }
  398. break;
  399. case '!':
  400. if( lastState == SCE_CSS_ATTR_MATCH ){
  401. sc.ChangeState( SCE_CSS_ATTR_MATCH );
  402. }
  403. if (lastState == SCE_CSS_VALUE)
  404. {
  405. sc.SetState (SCE_CSS_IMPORTANT);
  406. }
  407. break;
  408. }
  409. }
  410. if (IsAWordChar (sc.ch) || sc.ch == '*') // allow globbing pattern matching
  411. {
  412. if (sc.state == SCE_CSS_DEFAULT)
  413. sc.SetState (SCE_CSS_TAG);
  414. }
  415. if( sc.state == SCE_CSS_TAG && sc.ch == '['){
  416. sc.SetState (SCE_CSS_ATTR_MATCH);
  417. }
  418. if(sc.ch==' ' &&
  419. (sc.state == SCE_CSS_ID
  420. || sc.state == SCE_CSS_CLASS
  421. || sc.state == SCE_CSS_PSEUDOCLASS
  422. || sc.state == SCE_CSS_TAG)
  423. ){
  424. sc.SetState(SCE_CSS_DEFAULT);
  425. }
  426. if (IsAWordChar (sc.chPrev)
  427. && (sc.state == SCE_CSS_IDENTIFIER
  428. || sc.state == SCE_CSS_UNKNOWN_IDENTIFIER
  429. || sc.state == SCE_CSS_PSEUDOCLASS
  430. || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS
  431. || sc.state == SCE_CSS_IMPORTANT
  432. || sc.state == SCE_CSS_VALUE
  433. || sc.state == SCE_CSS_VALID_VALUE
  434. || sc.state == SCE_CSS_FUNCTION
  435. || sc.state == SCE_CSS_NUMBER
  436. || sc.state == SCE_CSS_UNIT
  437. || sc.state == SCE_CSS_COLOR
  438. || sc.state == SCE_CSS_HEXACOLOR
  439. || sc.state == SCE_CSS_DIRECTIVE
  440. )
  441. )
  442. {
  443. char s[100];
  444. sc.GetCurrentLowered (s, sizeof (s));
  445. char *s2 = s;
  446. while (*s2 && !IsAWordChar (*s2))
  447. s2++;
  448. switch (sc.state)
  449. {
  450. case SCE_CSS_DIRECTIVE:
  451. if( strcmp(s2,"page") ==0 || strcmp(s2, "font-face") == 0){
  452. sc.ForwardSetState( SCE_CSS_TAG );
  453. }
  454. break;
  455. case SCE_CSS_VALUE:
  456. if (validValues.InList (s2))
  457. {
  458. if( sc.ch == ' ' || sc.ch == '\t' || sc.ch == '\n' ){
  459. sc.ChangeState (SCE_CSS_VALID_VALUE);
  460. sc.SetState (SCE_CSS_VALUE);
  461. }else if( sc.ch == ';'){
  462. sc.ChangeState (SCE_CSS_VALID_VALUE);
  463. sc.SetState (SCE_CSS_OPERATOR);
  464. sc.ForwardSetState( SCE_CSS_IDENTIFIER );
  465. }else if( sc.ch == ',' ){
  466. sc.ChangeState (SCE_CSS_VALID_VALUE);
  467. sc.SetState (SCE_CSS_OPERATOR);
  468. sc.ForwardSetState( SCE_CSS_VALUE );
  469. }
  470. }
  471. else if (commonFunctions.InList (s2))
  472. {
  473. sc.ChangeState (SCE_CSS_FUNCTION);
  474. }
  475. else if ( IsNum (s2) )
  476. {
  477. sc.ChangeState (SCE_CSS_NUMBER);
  478. }
  479. else if (namedColors.InList (s2))
  480. {
  481. if (sc.ch == ' ')
  482. {
  483. sc.ChangeState (SCE_CSS_COLOR);
  484. sc.ForwardSetState (SCE_CSS_VALUE);
  485. }
  486. else if (IsCssOperator (sc.ch))
  487. {
  488. sc.ChangeState (SCE_CSS_COLOR);
  489. sc.SetState (SCE_CSS_OPERATOR);
  490. if (sc.ch == ';')
  491. sc.ForwardSetState(SCE_CSS_IDENTIFIER);
  492. else
  493. sc.ChangeState(SCE_CSS_VALUE);
  494. }
  495. }
  496. else if (validUnits.InList (s2))
  497. {
  498. sc.ChangeState (SCE_CSS_UNIT);
  499. if (sc.ch == ' ')
  500. sc.ForwardSetState (SCE_CSS_VALUE);
  501. }
  502. break;
  503. case SCE_CSS_NUMBER:
  504. if( sc.ch == ' ' || sc.ch == '\t' || '\n'){
  505. if( sc.chNext == '%' ){
  506. sc.ForwardSetState( SCE_CSS_UNIT );
  507. }else{
  508. sc.SetState( SCE_CSS_VALUE );
  509. }
  510. }
  511. else if( sc.ch == ';' )
  512. {
  513. sc.SetState( SCE_CSS_OPERATOR );
  514. sc.ForwardSetState(SCE_CSS_IDENTIFIER);
  515. }
  516. else if( sc.ch == '%' )
  517. {
  518. sc.SetState (SCE_CSS_UNIT);
  519. sc.ForwardSetState ( SCE_CSS_VALUE );
  520. }
  521. else if (isalpha( sc.ch ))
  522. {
  523. sc.ChangeState (SCE_CSS_VALUE);
  524. }
  525. break;
  526. case SCE_CSS_UNIT:
  527. if( !validUnits.InList(s2) ){
  528. if( namedColors.InList(s2) ){
  529. sc.ChangeState ( SCE_CSS_COLOR );
  530. if( sc.ch == ' ' ){
  531. sc.SetState(SCE_CSS_VALUE);
  532. }
  533. }else{
  534. sc.ChangeState(SCE_CSS_VALUE);
  535. }
  536. }
  537. break;
  538. case SCE_CSS_COLOR:
  539. if( sc.ch == ' ' || sc.ch == '\t' || '\n'){
  540. sc.SetState( SCE_CSS_VALUE );
  541. }
  542. else if( sc.ch == ';' )
  543. {
  544. sc.SetState( SCE_CSS_OPERATOR );
  545. sc.ForwardSetState(SCE_CSS_IDENTIFIER);
  546. }
  547. break;
  548. case SCE_CSS_VALID_VALUE:
  549. if (commonFunctions.InList (s2))
  550. sc.SetState (SCE_CSS_FUNCTION);
  551. else if (!validValues.InList (s2))
  552. sc.SetState (SCE_CSS_VALUE);
  553. break;
  554. case SCE_CSS_HEXACOLOR:
  555. if( sc.ch == ' '|| sc.ch == '\n' || sc.ch == '\t'){
  556. if( !IsValidHexaString( s2 ) )
  557. sc.ChangeState( SCE_CSS_VALUE );
  558. else
  559. sc.SetState( SCE_CSS_VALUE );
  560. }else if( sc.ch == ';' ){
  561. if( !IsValidHexaString( s2 ) )
  562. sc.ChangeState( SCE_CSS_VALUE );
  563. else
  564. sc.SetState( SCE_CSS_VALUE );
  565. }
  566. break;
  567. case SCE_CSS_IDENTIFIER:
  568. if( sc.ch == '"' || sc.ch == '\'' )
  569. sc.ChangeState( SCE_CSS_UNKNOWN_IDENTIFIER );
  570. if (!validProperties.InList (s2))
  571. sc.ChangeState (SCE_CSS_UNKNOWN_IDENTIFIER);
  572. break;
  573. case SCE_CSS_UNKNOWN_IDENTIFIER:
  574. if (validProperties.InList (s2))
  575. sc.ChangeState (SCE_CSS_IDENTIFIER);
  576. break;
  577. case SCE_CSS_PSEUDOCLASS:
  578. if( strcmp("lang",s2)==0){
  579. sc.ChangeState (SCE_CSS_LANGUAGE);
  580. }
  581. else if( sc.ch==' ' ){
  582. sc.SetState (SCE_CSS_DEFAULT);
  583. }
  584. else if (!pseudoClasses.InList (s2))
  585. {
  586. sc.ChangeState (SCE_CSS_UNKNOWN_PSEUDOCLASS);
  587. }
  588. break;
  589. case SCE_CSS_UNKNOWN_PSEUDOCLASS:
  590. if( strcmp("lang",s2)==0){
  591. sc.ChangeState (SCE_CSS_LANGUAGE);
  592. }
  593. else if (pseudoClasses.InList (s2))
  594. sc.ChangeState (SCE_CSS_PSEUDOCLASS);
  595. break;
  596. case SCE_CSS_IMPORTANT:
  597. if( sc.ch == ' ' || sc.ch == '\t' || sc.ch == '\n' ){
  598. if (strcmp (s2, "important") != 0)
  599. sc.ChangeState( SCE_CSS_VALUE );
  600. else
  601. sc.SetState( SCE_CSS_VALUE );
  602. }
  603. else if (sc.ch == ';' )
  604. {
  605. if (strcmp (s2, "important") != 0)
  606. sc.ChangeState( SCE_CSS_VALUE );
  607. else
  608. sc.SetState( SCE_CSS_VALUE );
  609. }
  610. break;
  611. }
  612. }
  613. if( sc.state == SCE_CSS_VALUE && isdigit(sc.ch) )
  614. sc.ChangeState( SCE_CSS_NUMBER);
  615. if( sc.state == SCE_CSS_IDENTIFIER && (sc.ch == '"' || sc.ch == '\'') )
  616. sc.ChangeState( SCE_CSS_UNKNOWN_IDENTIFIER );
  617. if (sc.Match ('/', '*'))
  618. {
  619. lastStateC = sc.state;
  620. sc.SetState (SCE_CSS_COMMENT);
  621. sc.Forward ();
  622. }
  623. else if ((sc.state == SCE_CSS_VALUE
  624. || sc.state == SCE_CSS_VALID_VALUE
  625. || sc.state == SCE_CSS_FUNCTION
  626. || sc.state == SCE_CSS_NUMBER
  627. || sc.state == SCE_CSS_UNIT
  628. || sc.state == SCE_CSS_COLOR
  629. || sc.state == SCE_CSS_HEXACOLOR
  630. )
  631. && (sc.ch == '\"' || sc.ch == '\''))
  632. {
  633. sc.SetState ((sc.ch ==
  634. '\"' ? SCE_CSS_DOUBLESTRING :
  635. SCE_CSS_SINGLESTRING));
  636. }
  637. else if (IsCssOperator (static_cast < char >(sc.ch))
  638. && (sc.state != SCE_CSS_VALUE
  639. || sc.state != SCE_CSS_VALID_VALUE
  640. || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
  641. && (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';'
  642. || sc.ch == '{'))
  643. {
  644. if (sc.state != SCE_CSS_OPERATOR)
  645. lastState = sc.state;
  646. if (sc.state != SCE_CSS_NUMBER)
  647. sc.SetState (SCE_CSS_OPERATOR);
  648. else
  649. sc.ChangeState (SCE_CSS_NUMBER);
  650. op = sc.ch;
  651. }
  652. }
  653. sc.Complete ();
  654. }
  655. /* FOLDING */
  656. static void
  657. FoldCSSDoc (unsigned int startPos, int length, int, WordList *[],
  658. Accessor & styler)
  659. {
  660. bool foldComment = styler.GetPropertyInt ("fold.comment") != 0;
  661. bool foldCompact = styler.GetPropertyInt ("fold.compact", 1) != 0;
  662. unsigned int endPos = startPos + length;
  663. int visibleChars = 0;
  664. int lineCurrent = styler.GetLine (startPos);
  665. int levelPrev = styler.LevelAt (lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  666. int levelCurrent = levelPrev;
  667. char chNext = styler[startPos];
  668. bool inComment = (styler.StyleAt (startPos - 1) == SCE_CSS_COMMENT);
  669. for (unsigned int i = startPos; i < endPos; i++)
  670. {
  671. char ch = chNext;
  672. chNext = styler.SafeGetCharAt (i + 1);
  673. int style = styler.StyleAt (i);
  674. bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
  675. if (foldComment)
  676. {
  677. if (!inComment && (style == SCE_CSS_COMMENT))
  678. levelCurrent++;
  679. else if (inComment && (style != SCE_CSS_COMMENT))
  680. levelCurrent--;
  681. inComment = (style == SCE_CSS_COMMENT);
  682. }
  683. if (style == SCE_CSS_OPERATOR)
  684. {
  685. if (ch == '{')
  686. {
  687. levelCurrent++;
  688. }
  689. else if (ch == '}')
  690. {
  691. levelCurrent--;
  692. }
  693. }
  694. if (atEOL)
  695. {
  696. int lev = levelPrev;
  697. if (visibleChars == 0 && foldCompact)
  698. lev |= SC_FOLDLEVELWHITEFLAG;
  699. if ((levelCurrent > levelPrev) && (visibleChars > 0))
  700. lev |= SC_FOLDLEVELHEADERFLAG;
  701. if (lev != styler.LevelAt (lineCurrent))
  702. {
  703. styler.SetLevel (lineCurrent, lev);
  704. }
  705. lineCurrent++;
  706. levelPrev = levelCurrent;
  707. visibleChars = 0;
  708. }
  709. if (!isspacechar (ch))
  710. visibleChars++;
  711. }
  712. // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  713. int flagsNext =
  714. styler.LevelAt (lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  715. styler.SetLevel (lineCurrent, levelPrev | flagsNext);
  716. }
  717. static const char *const cssWordListDesc[] = {
  718. "Valid properties",
  719. "Pseudo classes",
  720. "Valid fixed values",
  721. "Well known functions",
  722. "Valid units",
  723. "Named colours",
  724. 0
  725. };
  726. LexerModule lmCss (SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc,
  727. cssWordListDesc);