LexAbaqus.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. // Scintilla source code edit control
  2. /** @file LexABAQUS.cxx
  3. ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
  4. ** By Sergio Lucato.
  5. ** Sort of completely rewritten by Gertjan Kloosterman
  6. **/
  7. // The License.txt file describes the conditions under which this software may be distributed.
  8. // Code folding copyied and modified from LexBasic.cxx
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <stdarg.h>
  13. #include <assert.h>
  14. #include <ctype.h>
  15. #include "ILexer.h"
  16. #include "Scintilla.h"
  17. #include "SciLexer.h"
  18. #include "WordList.h"
  19. #include "LexAccessor.h"
  20. #include "Accessor.h"
  21. #include "StyleContext.h"
  22. #include "CharacterSet.h"
  23. #include "LexerModule.h"
  24. #ifdef SCI_NAMESPACE
  25. using namespace Scintilla;
  26. #endif
  27. static inline bool IsAKeywordChar(const int ch) {
  28. return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
  29. }
  30. static inline bool IsASetChar(const int ch) {
  31. return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
  32. }
  33. static void ColouriseABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList*[] /* *keywordlists[] */,
  34. Accessor &styler) {
  35. enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \
  36. DAT_LINE_VAL, DAT_LINE_COMMA,\
  37. COMMENT_LINE,\
  38. ST_ERROR, LINE_END } state ;
  39. // Do not leak onto next line
  40. state = LINE_END ;
  41. initStyle = SCE_ABAQUS_DEFAULT;
  42. StyleContext sc(startPos, length, initStyle, styler);
  43. // Things are actually quite simple
  44. // we have commentlines
  45. // keywordlines and datalines
  46. // On a data line there will only be colouring of numbers
  47. // a keyword line is constructed as
  48. // *word,[ paramname[=paramvalue]]*
  49. // if the line ends with a , the keyword line continues onto the new line
  50. for (; sc.More(); sc.Forward()) {
  51. switch ( state ) {
  52. case KW_LINE_KW :
  53. if ( sc.atLineEnd ) {
  54. // finished the line in keyword state, switch to LINE_END
  55. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  56. state = LINE_END ;
  57. } else if ( IsAKeywordChar(sc.ch) ) {
  58. // nothing changes
  59. state = KW_LINE_KW ;
  60. } else if ( sc.ch == ',' ) {
  61. // Well well we say a comma, arguments *MUST* follow
  62. sc.SetState(SCE_ABAQUS_OPERATOR) ;
  63. state = KW_LINE_COMMA ;
  64. } else {
  65. // Flag an error
  66. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  67. state = ST_ERROR ;
  68. }
  69. // Done with processing
  70. break ;
  71. case KW_LINE_COMMA :
  72. // acomma on a keywordline was seen
  73. if ( IsAKeywordChar(sc.ch)) {
  74. sc.SetState(SCE_ABAQUS_ARGUMENT) ;
  75. state = KW_LINE_PAR ;
  76. } else if ( sc.atLineEnd || (sc.ch == ',') ) {
  77. // we remain in keyword mode
  78. state = KW_LINE_COMMA ;
  79. } else if ( sc.ch == ' ' ) {
  80. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  81. state = KW_LINE_COMMA ;
  82. } else {
  83. // Anything else constitutes an error
  84. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  85. state = ST_ERROR ;
  86. }
  87. break ;
  88. case KW_LINE_PAR :
  89. if ( sc.atLineEnd ) {
  90. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  91. state = LINE_END ;
  92. } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {
  93. // remain in this state
  94. state = KW_LINE_PAR ;
  95. } else if ( sc.ch == ',' ) {
  96. sc.SetState(SCE_ABAQUS_OPERATOR) ;
  97. state = KW_LINE_COMMA ;
  98. } else if ( sc.ch == '=' ) {
  99. sc.SetState(SCE_ABAQUS_OPERATOR) ;
  100. state = KW_LINE_EQ ;
  101. } else {
  102. // Anything else constitutes an error
  103. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  104. state = ST_ERROR ;
  105. }
  106. break ;
  107. case KW_LINE_EQ :
  108. if ( sc.ch == ' ' ) {
  109. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  110. // remain in this state
  111. state = KW_LINE_EQ ;
  112. } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {
  113. sc.SetState(SCE_ABAQUS_NUMBER) ;
  114. state = KW_LINE_VAL ;
  115. } else if ( IsAKeywordChar(sc.ch) ) {
  116. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  117. state = KW_LINE_VAL ;
  118. } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
  119. sc.SetState(SCE_ABAQUS_STRING) ;
  120. state = KW_LINE_VAL ;
  121. } else {
  122. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  123. state = ST_ERROR ;
  124. }
  125. break ;
  126. case KW_LINE_VAL :
  127. if ( sc.atLineEnd ) {
  128. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  129. state = LINE_END ;
  130. } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
  131. // nothing changes
  132. state = KW_LINE_VAL ;
  133. } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
  134. ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
  135. (sc.state == SCE_ABAQUS_NUMBER)) {
  136. // remain in number mode
  137. state = KW_LINE_VAL ;
  138. } else if (sc.state == SCE_ABAQUS_STRING) {
  139. // accept everything until a closing quote
  140. if ( sc.ch == '\'' || sc.ch == '\"' ) {
  141. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  142. state = KW_LINE_VAL ;
  143. }
  144. } else if ( sc.ch == ',' ) {
  145. sc.SetState(SCE_ABAQUS_OPERATOR) ;
  146. state = KW_LINE_COMMA ;
  147. } else {
  148. // anything else is an error
  149. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  150. state = ST_ERROR ;
  151. }
  152. break ;
  153. case DAT_LINE_VAL :
  154. if ( sc.atLineEnd ) {
  155. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  156. state = LINE_END ;
  157. } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
  158. // nothing changes
  159. state = DAT_LINE_VAL ;
  160. } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
  161. ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
  162. (sc.state == SCE_ABAQUS_NUMBER)) {
  163. // remain in number mode
  164. state = DAT_LINE_VAL ;
  165. } else if (sc.state == SCE_ABAQUS_STRING) {
  166. // accept everything until a closing quote
  167. if ( sc.ch == '\'' || sc.ch == '\"' ) {
  168. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  169. state = DAT_LINE_VAL ;
  170. }
  171. } else if ( sc.ch == ',' ) {
  172. sc.SetState(SCE_ABAQUS_OPERATOR) ;
  173. state = DAT_LINE_COMMA ;
  174. } else {
  175. // anything else is an error
  176. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  177. state = ST_ERROR ;
  178. }
  179. break ;
  180. case DAT_LINE_COMMA :
  181. // a comma on a data line was seen
  182. if ( sc.atLineEnd ) {
  183. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  184. state = LINE_END ;
  185. } else if ( sc.ch == ' ' ) {
  186. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  187. state = DAT_LINE_COMMA ;
  188. } else if (sc.ch == ',') {
  189. sc.SetState(SCE_ABAQUS_OPERATOR) ;
  190. state = DAT_LINE_COMMA ;
  191. } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
  192. sc.SetState(SCE_ABAQUS_NUMBER) ;
  193. state = DAT_LINE_VAL ;
  194. } else if ( IsAKeywordChar(sc.ch) ) {
  195. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  196. state = DAT_LINE_VAL ;
  197. } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
  198. sc.SetState(SCE_ABAQUS_STRING) ;
  199. state = DAT_LINE_VAL ;
  200. } else {
  201. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  202. state = ST_ERROR ;
  203. }
  204. break ;
  205. case COMMENT_LINE :
  206. if ( sc.atLineEnd ) {
  207. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  208. state = LINE_END ;
  209. }
  210. break ;
  211. case ST_ERROR :
  212. if ( sc.atLineEnd ) {
  213. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  214. state = LINE_END ;
  215. }
  216. break ;
  217. case LINE_END :
  218. if ( sc.atLineEnd || sc.ch == ' ' ) {
  219. // nothing changes
  220. state = LINE_END ;
  221. } else if ( sc.ch == '*' ) {
  222. if ( sc.chNext == '*' ) {
  223. state = COMMENT_LINE ;
  224. sc.SetState(SCE_ABAQUS_COMMENT) ;
  225. } else {
  226. state = KW_LINE_KW ;
  227. sc.SetState(SCE_ABAQUS_STARCOMMAND) ;
  228. }
  229. } else {
  230. // it must be a data line, things are as if we are in DAT_LINE_COMMA
  231. if ( sc.ch == ',' ) {
  232. sc.SetState(SCE_ABAQUS_OPERATOR) ;
  233. state = DAT_LINE_COMMA ;
  234. } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
  235. sc.SetState(SCE_ABAQUS_NUMBER) ;
  236. state = DAT_LINE_VAL ;
  237. } else if ( IsAKeywordChar(sc.ch) ) {
  238. sc.SetState(SCE_ABAQUS_DEFAULT) ;
  239. state = DAT_LINE_VAL ;
  240. } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
  241. sc.SetState(SCE_ABAQUS_STRING) ;
  242. state = DAT_LINE_VAL ;
  243. } else {
  244. sc.SetState(SCE_ABAQUS_PROCESSOR) ;
  245. state = ST_ERROR ;
  246. }
  247. }
  248. break ;
  249. }
  250. }
  251. sc.Complete();
  252. }
  253. //------------------------------------------------------------------------------
  254. // This copyied and modified from LexBasic.cxx
  255. //------------------------------------------------------------------------------
  256. /* Bits:
  257. * 1 - whitespace
  258. * 2 - operator
  259. * 4 - identifier
  260. * 8 - decimal digit
  261. * 16 - hex digit
  262. * 32 - bin digit
  263. */
  264. static int character_classification[128] =
  265. {
  266. 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
  267. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  268. 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
  269. 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
  270. 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  271. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
  272. 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  273. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
  274. };
  275. static bool IsSpace(int c) {
  276. return c < 128 && (character_classification[c] & 1);
  277. }
  278. static bool IsIdentifier(int c) {
  279. return c < 128 && (character_classification[c] & 4);
  280. }
  281. static int LowerCase(int c)
  282. {
  283. if (c >= 'A' && c <= 'Z')
  284. return 'a' + c - 'A';
  285. return c;
  286. }
  287. static Sci_Position LineEnd(Sci_Position line, Accessor &styler)
  288. {
  289. const Sci_Position docLines = styler.GetLine(styler.Length() - 1); // Available last line
  290. Sci_Position eol_pos ;
  291. // if the line is the last line, the eol_pos is styler.Length()
  292. // eol will contain a new line, or a virtual new line
  293. if ( docLines == line )
  294. eol_pos = styler.Length() ;
  295. else
  296. eol_pos = styler.LineStart(line + 1) - 1;
  297. return eol_pos ;
  298. }
  299. static Sci_Position LineStart(Sci_Position line, Accessor &styler)
  300. {
  301. return styler.LineStart(line) ;
  302. }
  303. // LineType
  304. //
  305. // bits determines the line type
  306. // 1 : data line
  307. // 2 : only whitespace
  308. // 3 : data line with only whitespace
  309. // 4 : keyword line
  310. // 5 : block open keyword line
  311. // 6 : block close keyword line
  312. // 7 : keyword line in error
  313. // 8 : comment line
  314. static int LineType(Sci_Position line, Accessor &styler) {
  315. Sci_Position pos = LineStart(line, styler) ;
  316. Sci_Position eol_pos = LineEnd(line, styler) ;
  317. int c ;
  318. char ch = ' ';
  319. Sci_Position i = pos ;
  320. while ( i < eol_pos ) {
  321. c = styler.SafeGetCharAt(i);
  322. ch = static_cast<char>(LowerCase(c));
  323. // We can say something as soon as no whitespace
  324. // was encountered
  325. if ( !IsSpace(c) )
  326. break ;
  327. i++ ;
  328. }
  329. if ( i >= eol_pos ) {
  330. // This is a whitespace line, currently
  331. // classifies as data line
  332. return 3 ;
  333. }
  334. if ( ch != '*' ) {
  335. // This is a data line
  336. return 1 ;
  337. }
  338. if ( i == eol_pos - 1 ) {
  339. // Only a single *, error but make keyword line
  340. return 4+3 ;
  341. }
  342. // This means we can have a second character
  343. // if that is also a * this means a comment
  344. // otherwise it is a keyword.
  345. c = styler.SafeGetCharAt(i+1);
  346. ch = static_cast<char>(LowerCase(c));
  347. if ( ch == '*' ) {
  348. return 8 ;
  349. }
  350. // At this point we know this is a keyword line
  351. // the character at position i is a *
  352. // it is not a comment line
  353. char word[256] ;
  354. int wlen = 0;
  355. word[wlen] = '*' ;
  356. wlen++ ;
  357. i++ ;
  358. while ( (i < eol_pos) && (wlen < 255) ) {
  359. c = styler.SafeGetCharAt(i);
  360. ch = static_cast<char>(LowerCase(c));
  361. if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
  362. break ;
  363. if ( IsIdentifier(c) ) {
  364. word[wlen] = ch ;
  365. wlen++ ;
  366. }
  367. i++ ;
  368. }
  369. word[wlen] = 0 ;
  370. // Make a comparison
  371. if ( !strcmp(word, "*step") ||
  372. !strcmp(word, "*part") ||
  373. !strcmp(word, "*instance") ||
  374. !strcmp(word, "*assembly")) {
  375. return 4+1 ;
  376. }
  377. if ( !strcmp(word, "*endstep") ||
  378. !strcmp(word, "*endpart") ||
  379. !strcmp(word, "*endinstance") ||
  380. !strcmp(word, "*endassembly")) {
  381. return 4+2 ;
  382. }
  383. return 4 ;
  384. }
  385. static void SafeSetLevel(Sci_Position line, int level, Accessor &styler)
  386. {
  387. if ( line < 0 )
  388. return ;
  389. int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));
  390. if ( (level & mask) < 0 )
  391. return ;
  392. if ( styler.LevelAt(line) != level )
  393. styler.SetLevel(line, level) ;
  394. }
  395. static void FoldABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int,
  396. WordList *[], Accessor &styler) {
  397. Sci_Position startLine = styler.GetLine(startPos) ;
  398. Sci_Position endLine = styler.GetLine(startPos+length-1) ;
  399. // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  400. // We want to deal with all the cases
  401. // To know the correct indentlevel, we need to look back to the
  402. // previous command line indentation level
  403. // order of formatting keyline datalines commentlines
  404. Sci_Position beginData = -1 ;
  405. Sci_Position beginComment = -1 ;
  406. Sci_Position prvKeyLine = startLine ;
  407. Sci_Position prvKeyLineTp = 0 ;
  408. // Scan until we find the previous keyword line
  409. // this will give us the level reference that we need
  410. while ( prvKeyLine > 0 ) {
  411. prvKeyLine-- ;
  412. prvKeyLineTp = LineType(prvKeyLine, styler) ;
  413. if ( prvKeyLineTp & 4 )
  414. break ;
  415. }
  416. // Determine the base line level of all lines following
  417. // the previous keyword
  418. // new keyword lines are placed on this level
  419. //if ( prvKeyLineTp & 4 ) {
  420. int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
  421. //}
  422. // uncomment line below if weird behaviour continues
  423. prvKeyLine = -1 ;
  424. // Now start scanning over the lines.
  425. for ( Sci_Position line = startLine; line <= endLine; line++ ) {
  426. int lineType = LineType(line, styler) ;
  427. // Check for comment line
  428. if ( lineType == 8 ) {
  429. if ( beginComment < 0 ) {
  430. beginComment = line ;
  431. }
  432. }
  433. // Check for data line
  434. if ( (lineType == 1) || (lineType == 3) ) {
  435. if ( beginData < 0 ) {
  436. if ( beginComment >= 0 ) {
  437. beginData = beginComment ;
  438. } else {
  439. beginData = line ;
  440. }
  441. }
  442. beginComment = -1 ;
  443. }
  444. // Check for keywordline.
  445. // As soon as a keyword line is encountered, we can set the
  446. // levels of everything from the previous keyword line to this one
  447. if ( lineType & 4 ) {
  448. // this is a keyword, we can now place the previous keyword
  449. // all its data lines and the remainder
  450. // Write comments and data line
  451. if ( beginComment < 0 ) {
  452. beginComment = line ;
  453. }
  454. if ( beginData < 0 ) {
  455. beginData = beginComment ;
  456. if ( prvKeyLineTp != 5 )
  457. SafeSetLevel(prvKeyLine, level, styler) ;
  458. else
  459. SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
  460. } else {
  461. SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
  462. }
  463. int datLevel = level + 1 ;
  464. if ( !(prvKeyLineTp & 4) ) {
  465. datLevel = level ;
  466. }
  467. for ( Sci_Position ll = beginData; ll < beginComment; ll++ )
  468. SafeSetLevel(ll, datLevel, styler) ;
  469. // The keyword we just found is going to be written at another level
  470. // if we have a type 5 and type 6
  471. if ( prvKeyLineTp == 5 ) {
  472. level += 1 ;
  473. }
  474. if ( prvKeyLineTp == 6 ) {
  475. level -= 1 ;
  476. if ( level < 0 ) {
  477. level = 0 ;
  478. }
  479. }
  480. for ( Sci_Position lll = beginComment; lll < line; lll++ )
  481. SafeSetLevel(lll, level, styler) ;
  482. // wrap and reset
  483. beginComment = -1 ;
  484. beginData = -1 ;
  485. prvKeyLine = line ;
  486. prvKeyLineTp = lineType ;
  487. }
  488. }
  489. if ( beginComment < 0 ) {
  490. beginComment = endLine + 1 ;
  491. } else {
  492. // We need to find out whether this comment block is followed by
  493. // a data line or a keyword line
  494. const Sci_Position docLines = styler.GetLine(styler.Length() - 1);
  495. for ( Sci_Position line = endLine + 1; line <= docLines; line++ ) {
  496. Sci_Position lineType = LineType(line, styler) ;
  497. if ( lineType != 8 ) {
  498. if ( !(lineType & 4) ) {
  499. beginComment = endLine + 1 ;
  500. }
  501. break ;
  502. }
  503. }
  504. }
  505. if ( beginData < 0 ) {
  506. beginData = beginComment ;
  507. if ( prvKeyLineTp != 5 )
  508. SafeSetLevel(prvKeyLine, level, styler) ;
  509. else
  510. SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
  511. } else {
  512. SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
  513. }
  514. int datLevel = level + 1 ;
  515. if ( !(prvKeyLineTp & 4) ) {
  516. datLevel = level ;
  517. }
  518. for ( Sci_Position ll = beginData; ll < beginComment; ll++ )
  519. SafeSetLevel(ll, datLevel, styler) ;
  520. if ( prvKeyLineTp == 5 ) {
  521. level += 1 ;
  522. }
  523. if ( prvKeyLineTp == 6 ) {
  524. level -= 1 ;
  525. }
  526. for ( Sci_Position m = beginComment; m <= endLine; m++ )
  527. SafeSetLevel(m, level, styler) ;
  528. }
  529. static const char * const abaqusWordListDesc[] = {
  530. "processors",
  531. "commands",
  532. "slashommands",
  533. "starcommands",
  534. "arguments",
  535. "functions",
  536. 0
  537. };
  538. LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);