Back to index

texmacs  1.0.7.15
mathemagix_language.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : mathemagix_language.cpp
00004 * DESCRIPTION: the "mathemagix" language
00005 * COPYRIGHT  : (C) 2008  Francis Jamet
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "analyze.hpp"
00013 #include "impl_language.hpp"
00014 #include "scheme.hpp"
00015 #define COLOR_MARKUP "#500d04"
00016 
00017 static void parse_number (string s, int& pos);
00018 static void parse_string (string s, int& pos);
00019 static void parse_alpha (string s, int& pos);
00020 
00021 mathemagix_language_rep::mathemagix_language_rep (string name):
00022   language_rep (name), colored ("")
00023 { 
00024   eval ("(use-modules (utils misc tm-keywords))");
00025   list<string> l= as_list_string (eval ("(map symbol->string highlight-any)"));
00026   while (!is_nil (l)) {
00027     colored (l->item)= "blue";
00028     l= l->next;
00029   }
00030 }
00031 
00032 text_property
00033 mathemagix_language_rep::advance (tree t, int& pos) {
00034   string s= t->label;
00035   if (pos==N(s)) return &tp_normal_rep;
00036   char c= s[pos];
00037   if (c == ' ') {
00038     pos++; return &tp_space_rep; }
00039   if (c >= '0' && c <= '9') {
00040     parse_number (s, pos); return &tp_normal_rep; }
00041   if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
00042       (c == '_') || (c == '$')) {
00043     parse_alpha (s, pos); return &tp_normal_rep; }
00044   tm_char_forwards (s, pos);
00045   return &tp_normal_rep;
00046 }
00047 
00048 array<int>
00049 mathemagix_language_rep::get_hyphens (string s) {
00050   int i;
00051   array<int> penalty (N(s)+1);
00052   penalty[0]= HYPH_INVALID;
00053   for (i=1; i<N(s); i++)
00054     if (s[i-1] == '-' && is_alpha (s[i]))
00055       penalty[i]= HYPH_STD;
00056     else penalty[i]= HYPH_INVALID;
00057   penalty[i]= HYPH_INVALID;
00058   return penalty;
00059 }
00060 
00061 void
00062 mathemagix_language_rep::hyphenate (
00063   string s, int after, string& left, string& right)
00064 { 
00065   left = s(0, after);
00066   right= s(after, N(s));
00067 }
00068 
00069 static void
00070 mathemagix_color_setup_constants (hashmap<string, string> & t) {
00071   string c= "#2060c0";
00072   t ("cpp_flags")= c;
00073   t ("cpp_libs")= c;
00074   t ("cpp_preamble")= c;
00075   t ("cpp_macro")= c;
00076   t ("cpp_include")= c;
00077   t ("true")= c;
00078   t ("false")= c;
00079   t ("mmout")= c;
00080   t ("mmin")= c;
00081   t ("mmerr")= c;
00082   t ("blank")= c;
00083   t ("stroke")= c;
00084   t ("indent")= c;
00085   t ("unindent")= c;
00086   t ("lf")= c;
00087   t ("hrule")= c;
00088   t ("flush_now")= c;
00089   t ("nil")= c;
00090 }
00091 
00092 static void
00093 mathemagix_color_setup_keywords (hashmap<string, string> & t)  {
00094   string c= "#8020c0"; string d= "modifier"; string e= "class";
00095   t ("abstract")= c;
00096   t ("alias")= c;
00097   t ("and")= c;
00098   t ("assume")= d;
00099   t ("begin")= c;
00100   t ("break")= c;
00101   t ("case")= c;
00102   t ("cast")= c;
00103   t ("catch")= c;
00104   t ("category")= e;
00105   t ("class")= e;
00106   t ("concrete")= c;
00107   t ("constant")= c;
00108   t ("constructor")= c;
00109   t ("continue")= c;
00110   t ("convert")= c;
00111   t ("debugger")= c;
00112   t ("destructor")= c;
00113   t ("direct")= c;
00114   t ("div")= c;
00115   t ("do")= c;
00116   t ("downto")= c;
00117   t ("downgrade")= c;
00118   t ("else")= c;
00119   t ("evolutive")= c;
00120   t ("exists")= d;
00121   t ("explode")= c;
00122   t ("export")= d;
00123   t ("extend")= c;
00124   t ("extern")= c;
00125   t ("for")= c;
00126   t ("forall")= d;
00127   t ("foreach")= c;
00128   t ("foreign")= c;
00129   t ("from")= c;
00130   t ("fuse")= c;
00131   t ("generate")= c;
00132   t ("has")= c;
00133   t ("help")= c;
00134   t ("hidden")= c;
00135   t ("holds")= c;
00136   t ("if")= c;
00137   t ("import")= c;
00138   t ("in")= c;
00139   t ("include")= c;
00140   t ("indirect")= c;
00141   t ("infix")= c;
00142   t ("inherit")= c;
00143   t ("inline")= d;
00144   t ("inplace")= c;
00145   t ("interactive")= c;
00146   t ("intern")= c;
00147   t ("join")= c;
00148   t ("keyword")= c;
00149   t ("literal")= c;
00150   t ("lambda")= c;
00151   t ("literal_integer")= c;
00152   t ("literal_floating")= c;
00153   t ("literal_string")= c;
00154   t ("literal_constant")= c;
00155   t ("locked")= c;
00156   t ("loop")= c;
00157   t ("macro")= c;
00158   t ("map")= c;
00159   t ("melt")= c;
00160   t ("method")= c;
00161   t ("mod")= c;
00162   t ("module")= e;
00163   t ("mutable")= c;
00164   t ("operator")= c;
00165   t ("or")= c;
00166   t ("packed")= c;
00167   t ("penalty")= c;
00168   t ("postfix")= "postfix";
00169   t ("prefer")= c;
00170   t ("prefix")= c;
00171   t ("private")= c;
00172   t ("protected")= c;
00173   t ("public")= c;
00174   t ("outline")= c;
00175   t ("quit")= c;
00176   t ("quo")= c;
00177   t ("raise")= c;
00178   t ("rem")= c ;
00179   t ("require")= c;
00180   t ("return")= c ;
00181   t ("sequel")= c;
00182   t ("split")= c;
00183   t ("step")= c;
00184   t ("supports?")= c;
00185   t ("then")= c;
00186   t ("this")= c;
00187   t ("to")= c;
00188   t ("try")= c;
00189   t ("type")= c;
00190   t ("unpacked")= c;
00191   t ("until")= c;
00192   t ("upgrade")= c;
00193   t ("use")= c;
00194   t ("value")= c;
00195   t ("while")= c;
00196   t ("with")= c;
00197   t ("xor")= c;
00198 }
00199 
00200 static void
00201 mathemagix_color_setup_otherlexeme (hashmap<string, string>& t) {
00202   string c= "black";
00203   t ("==<gtr>")= c; 
00204   t ("==")= c;
00205   t (":=")= c;
00206   t ("+=")= c;
00207   t ("-=")= c; 
00208   t ("*=")= c;
00209   t ("/=")= c;
00210   t (":=<gtr>")= c;
00211   t (":-<gtr>")= c;
00212   t ("yield")= c;   
00213   t (",")= c;
00214   t (";")= c;
00215   t (")")= c;
00216   t ("[")= c;
00217   t ("]")= c;
00218   t ("{")= c;
00219   t ("}")= c;
00220   t ("<less><less>")= c;
00221   t ("<less><less>*")= c;
00222   t ("<less><less>%")= c;
00223   t ("<gtr><gtr>")= c;
00224   t ("|")= c;
00225 }
00226 
00227 static inline bool
00228 belongs_to_identifier (char c) {
00229   return ((c<='9' && c>='0') ||
00230          (c<='Z' && c>='A') ||
00231         (c<='z' && c>='a') ||
00232           c=='_' || c=='$'  || c=='?');
00233 }
00234 
00235 static inline bool
00236 is_number (char c) {
00237   return (c>='0' && c<='9');
00238 }
00239 
00240 static void
00241 parse_identifier (hashmap<string, string>& t,
00242                 string s, int& pos, bool postfix) {
00243   int i=pos;
00244   if (pos>=N(s)) return;
00245   if (is_number (s[i])) return;
00246   if (postfix && s[i]=='.') i++;
00247   while (i<N(s) && belongs_to_identifier (s[i])) i++;
00248   if (!(t->contains (s (pos, i)))) pos= i;
00249 }
00250 
00251 static void
00252 parse_identifier_or_markup (hashmap<string, string>& t,
00253                 string s, int& pos, bool postfix, bool& is_markup) {
00254   int i=pos;
00255   is_markup= false;
00256   if (pos>=N(s)) return;
00257   if (is_number (s[i])) return;
00258   if (postfix && s[i]=='.') i++;
00259   while (i<N(s) && belongs_to_identifier (s[i])) {
00260     if (s[i]=='$') is_markup= true;
00261     i++;
00262   }
00263   if (!(t->contains (s (pos, i)))) pos= i;
00264 }
00265 
00266 static void
00267 parse_alpha (string s, int& pos) {
00268   static hashmap<string,string> empty;
00269   parse_identifier (empty, s, pos, false);
00270 }
00271 
00272 static void
00273 parse_blanks (string s, int& pos) {
00274   while (pos<N(s) && (s[pos]==' ' || s[pos]=='\t')) pos++;
00275 }
00276 
00277 static void
00278 parse_string (string s, int& pos) {
00279   if (pos>=N(s)) return;
00280   switch (s[pos])  {
00281   case '\042':
00282     do pos++;
00283     while((pos<N(s)) &&
00284          ((s[pos-1]=='\\' && s[pos]=='\042') || s[pos]!='\042'));
00285     if (s[pos]=='\042') pos++;
00286     return;
00287   case '/':
00288     if (pos+1<N(s) && s[pos+1]=='\042') {
00289       pos=pos+2;
00290       do {
00291        if (pos+1<N(s) && s[pos]=='\042' && s[pos+1]=='/') {
00292          pos=pos+2; return; }
00293        pos++;
00294       } while (pos<N(s));
00295     }
00296   }
00297 }
00298   
00299 static void
00300 parse_keyword (hashmap<string,string>& t, string s, int& pos) {
00301   int i= pos;
00302   if (pos>=N(s)) return;
00303   if (is_number (s[i])) return;
00304   while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
00305   string r= s (pos, i);
00306   if (t->contains (r) && t(r)=="#8020c0") { pos=i; return; }
00307 }
00308 
00309 static void
00310 parse_modifier (hashmap<string,string>& t, string s, int& pos) {
00311   int i= pos;
00312   if (pos>=N(s)) return;
00313   if (is_number (s[i])) return;
00314   while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
00315   string r= s (pos, i);
00316   if (t->contains (r) && t(r)=="modifier") { pos=i; return; }
00317 }
00318 
00319 static void
00320 parse_class (hashmap<string,string>& t, string s, int& pos) {
00321   int i= pos;
00322   if (pos>=N(s)) return;
00323   if (is_number (s[i])) return;
00324   while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
00325   string r= s (pos, i);
00326   if (t->contains (r) && t(r)=="class") { pos=i; return; }
00327 }
00328 
00329 
00330 static void
00331 parse_postfix (hashmap<string,string>& t, string s, int& pos) {
00332   int i= pos;
00333   if (pos>=N(s)) return;
00334   if (is_number (s[i])) return;
00335   while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
00336   string r= s (pos, i);
00337   if (t->contains (r) && t(r)=="postfix") { pos=i; return; }
00338 }
00339 
00340 static void
00341 parse_constant (hashmap<string,string>& t, string s, int& pos) {
00342   int i=pos;
00343   if (pos>=N(s)) return;
00344   if (is_number (s[i])) return;
00345   while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
00346   string r= s (pos, i);
00347   if (t->contains (r) && t(r)=="#2060c0") { pos=i; return; }
00348 }
00349 
00350 static void
00351 parse_other_lexeme (hashmap<string,string>& t, string s, int& pos) {
00352   int i;
00353   for (i=12; i>=1; i--) {
00354     string r=s(pos,pos+i);
00355     if (t->contains(r) && t(r)=="black") {
00356       pos=pos+i; return; }
00357   }
00358 }
00359 
00360 static void
00361 parse_number (string s, int& pos) {
00362   int i= pos;
00363   if (pos>=N(s)) return;
00364   if (s[i] == '.') return;
00365   while (i<N(s) && 
00366         (is_number (s[i]) ||
00367          (s[i] == '.' && (i+1<N(s)) &&
00368           (is_number (s[i+1]) ||
00369            s[i+1] == 'e' || s[i+1] == 'E')))) i++;
00370   if (i == pos) return;
00371   if (i<N(s) && (s[i] == 'e' || s[i] == 'E')) {
00372     i++;
00373     if (i<N(s) && s[i] == '-') i++;
00374     while (i<N(s) && (is_number (s[i]))) i++;
00375   }
00376   pos= i;
00377 }
00378 
00379 static void
00380 parse_no_declare_type (string s, int& pos) {
00381   if (pos+1<N(s) && s[pos]==':' && s[pos+1]==':') pos=pos+2;
00382 }
00383 
00384 static void
00385 parse_declare_type (string s, int& pos) {
00386   if (pos>=N(s)) return;
00387   if (s[pos]!=':') return;
00388   if (pos+1<N(s) && s[pos+1]=='=') return;
00389   pos++;
00390   if (!test (s, pos, "<gtr>")) return;
00391   pos+=5;
00392 }
00393 
00394 static void
00395 parse_comment (string s, int& pos) {
00396   if (pos>=N(s)) return;
00397   if (s[pos]!='/') return;
00398   if (pos+1<N(s) && s[pos+1]=='/') {pos=N(s);return;}
00399   if (pos+1<N(s) && s[pos+1]=='{') {
00400     pos= pos+2;
00401     while ((pos<N(s) && s[pos]!='}') || (pos+1<N(s) && s[pos+1]!='/')) pos++;
00402     pos= min(pos+2,N(s));
00403   }
00404 }
00405 
00406 static void
00407 parse_end_comment (string s, int& pos) {
00408   if (pos+1<N(s) && s[pos]=='}' && s[pos+1]=='/') pos=pos+2; 
00409 }
00410   
00411 
00412 static void
00413 parse_parenthesized (string s, int& pos) {
00414   int i=pos;
00415   if (pos>=N(s)) return;
00416   if (s[i]!='(') return;
00417   int nbpar=0;
00418   while(i<N(s)) {
00419     switch (s[i]) {
00420     case '(':
00421       nbpar++;break;
00422     case ')':if (nbpar>0) nbpar--;
00423       if (nbpar==0) {i++;pos=i;return;}
00424       break;
00425     case '/':
00426       if (i+1<N(s) && 
00427          (s[i+1]=='\042' || s[i+1]=='{' || s[i+1]=='/')) {
00428        pos= i; return; }
00429       break;
00430     case '\042':
00431       pos=i;
00432       return;
00433     }
00434     i++;
00435   }
00436   pos=i;
00437 }
00438 
00439 static void
00440 parse_backquote (string s, int & pos) {
00441   if (pos>=N(s)) return;
00442   if (s[pos]=='\047') pos++;
00443 }
00444 
00445 static void
00446 parse_declare_function (string s, int& pos) {
00447   if (pos+1>=N(s)) return;
00448   if (s[pos]==':' && s[pos+1]=='=') { pos=pos+2; return; }
00449   if (s[pos]=='=' && s[pos+1]=='=') { pos=pos+2; return; }
00450 }
00451 
00452 static void
00453 parse_declare_macro (string s, int& pos) {
00454   if (test(s,pos,"==<gtr>")) { pos=pos+7; return; }
00455   if (test(s,pos,":=<gtr>")) { pos=pos+7; return; }
00456 }
00457 
00458 string
00459 mathemagix_language_rep::get_color (tree t, int start, int end) {
00460   static bool setup_done= false;
00461   if (!setup_done) {
00462     mathemagix_color_setup_constants (colored);
00463     mathemagix_color_setup_keywords (colored);
00464     mathemagix_color_setup_otherlexeme (colored);
00465     setup_done= true;
00466   }
00467 
00468   static string none= "";
00469   if (start >= end) return none;
00470   string s= t->label;
00471   int pos=0;int opos;
00472   bool backquote= false;
00473   bool after_backquote;
00474   bool postfix= false;
00475   bool possible_function= true;
00476   bool possible_type= false;
00477   bool possible_class= false;
00478   bool possible_future_type= false;
00479   bool possible_future_function= true;
00480   bool possible_future_class= false;
00481   string type;
00482   bool is_markup;
00483   do {
00484     do {
00485       opos=pos;
00486       parse_string (s, pos);
00487       if (opos<pos) break;
00488       parse_comment (s, pos);
00489       if (opos<pos) break;
00490       parse_end_comment (s, pos);
00491       if (opos<pos) { 
00492        if (pos>start) {return "brown";} 
00493        else break;
00494       }
00495       pos++;
00496     }
00497     while(false);
00498   }
00499   while(pos<N(s));
00500   pos=0;
00501   do {
00502     type= none;
00503     do {
00504       after_backquote= backquote;
00505       possible_function= possible_future_function;
00506       possible_type= possible_future_type;
00507       possible_class= possible_future_class;
00508       opos= pos;
00509       parse_blanks (s, pos);
00510       if (opos<pos) break;
00511       parse_string (s, pos);
00512       if (opos<pos) {
00513        type= "string";
00514        backquote= false;
00515        postfix= false;
00516        possible_future_function= false;
00517        possible_future_type= false;
00518        possible_future_class= false;
00519        possible_type= false;
00520        break;
00521       }
00522       parse_comment (s, pos);
00523       if (opos<pos) {
00524        type= "comment";
00525        backquote= false;
00526        postfix= false;
00527        possible_future_type= false;
00528        possible_type= false;
00529        break;
00530       }
00531       parse_modifier (colored, s, pos);
00532       if (opos<pos) {
00533        type="keyword";
00534        backquote= false;
00535        postfix= false;
00536        possible_future_type= false;
00537        possible_type= false;
00538        possible_function= false;
00539        break;
00540          }
00541       parse_postfix (colored, s, pos);
00542       if (opos<pos) {
00543        type="keyword";
00544        backquote= false;
00545        postfix= true;
00546        possible_future_type= false;
00547        possible_future_class= false;
00548        possible_type= false;
00549        possible_function= false;
00550        possible_future_class= false;
00551        break;
00552       }
00553       parse_class (colored, s, pos);
00554       if (opos<pos) {
00555        type= "keyword";
00556        backquote=false;
00557        postfix=false;
00558        possible_future_type= false;
00559        possible_type= false;
00560        possible_future_class=true;
00561        possible_future_function= false;
00562        break;
00563       }
00564       parse_keyword (colored, s, pos);
00565       if (opos<pos) {
00566        type= "keyword";
00567        backquote= false;
00568        postfix= false;
00569        possible_future_type= false;
00570        possible_type= false;
00571        possible_function= false;
00572        possible_future_function= false;
00573        possible_future_class= false;
00574        break;
00575       }
00576       parse_other_lexeme (colored, s, pos);  //not left parenthesis
00577       if (opos<pos) {
00578        type= "other_lexeme";
00579        backquote= false;
00580        postfix= false;
00581        possible_function= false;
00582        possible_future_function= true;
00583        possible_future_type= false;
00584        possible_future_class= false;
00585        possible_type= false;
00586        break;
00587       }
00588       parse_constant (colored, s, pos);
00589       if (opos<pos) {
00590        type= "constant";
00591        backquote= false;
00592        postfix= false;
00593        possible_future_function= false;
00594        possible_future_class= false;
00595        break;
00596       }
00597       parse_number (s, pos);
00598       if (opos<pos) {
00599        type= "number";
00600        backquote= false;
00601        postfix= false;
00602        possible_future_function= false;
00603        possible_future_class= false;
00604        break;
00605       }
00606       parse_no_declare_type (s, pos); // :: 
00607       if (opos<pos) {
00608        type= "no_declare_type";
00609        possible_type= false;
00610        possible_future_type= false;
00611        possible_function= false;
00612        possible_future_function= false;
00613        possible_future_class= false;
00614        break;
00615       }  
00616       parse_backquote (s, pos);
00617       if (opos<pos) {
00618        backquote= true;
00619        postfix= false;
00620        possible_future_function= false;
00621        possible_future_class= false;
00622        break;
00623       }
00624       parse_declare_type (s, pos); // : and :>
00625       if (opos<pos) {
00626        type= "declare_type";
00627        backquote= false;
00628        postfix= false;
00629        if (!after_backquote) possible_future_type=true; 
00630        possible_function= false;
00631        possible_future_function= false;
00632        possible_future_class= false;
00633        break;
00634       }
00635       parse_identifier_or_markup (colored, s, pos, postfix, is_markup);
00636       if (opos<pos) {
00637        if (is_markup) {type= "identifier_markup";} else type= "identifier";
00638        backquote= false;
00639        postfix= false;
00640        possible_future_function=false;
00641        possible_future_class= false;
00642        break;
00643       }
00644       parse_parenthesized (s, pos);
00645       // stops after well parenthesized ) or before  // or /{ or " or /"
00646       if (opos<pos && pos<=start) {
00647        type="left_parenthesis";
00648        backquote= false;
00649        postfix= false;
00650        possible_function= false;
00651        possible_future_function= true;
00652        possible_future_class= false;
00653        break;
00654       }
00655       if (opos<pos && possible_type==true)
00656        return "dark green";
00657       if (opos<pos && after_backquote)  
00658        return none;
00659       backquote= false;
00660       postfix= false;
00661       pos= opos;
00662       pos++;
00663     }
00664     while (false);
00665   }
00666   while (pos<=start);
00667   if (possible_type) return "dark green";
00668   if (type=="string") return "#a06040";
00669   if (type=="comment") return "brown";
00670   if (type=="keyword" && !after_backquote) return "#8020c0";
00671   if (type=="other_lexeme") return none;
00672   if (type=="constant") return "#2060c0";
00673   if (type=="number") return "#2060c0";
00674   if (type=="no_declare_type") return none;
00675   if (type=="declare_type") return none;
00676   if (type=="left_parenthesis") return none;
00677   if (type=="identifier" && possible_function==false && possible_class==false) 
00678     return none;
00679   if (type=="identifier_markup" && possible_function==false
00680       && possible_class==false) 
00681     return COLOR_MARKUP;
00682   if ( (type=="identifier" || type=="identifier_markup") && possible_function) {
00683     possible_function= false;
00684     do {
00685       do {
00686        opos=pos;
00687        parse_blanks (s, pos);
00688        if (opos<pos) break;
00689        parse_identifier (colored, s, pos,false);
00690        if (opos<pos) { possible_function= true; break; }
00691        parse_number (s, pos);
00692        if (opos<pos) { possible_function= true; break; }
00693        parse_constant (colored, s, pos);
00694        if (opos<pos) { possible_function= true; break; }
00695        parse_comment (s, pos);
00696        if (opos<pos) break;
00697        parse_parenthesized (s, pos);
00698        if (opos<pos) { possible_function= true; break; }
00699       }
00700       while (false);
00701     }
00702     while (opos!=pos);
00703     if (!possible_function) {
00704       if (type=="identifier") {return none;} else return COLOR_MARKUP;
00705     }
00706     do {
00707       do {
00708        opos=pos;
00709        parse_blanks (s, pos);
00710        if (opos<pos) break;
00711        parse_identifier (colored, s, pos,false);
00712        if (opos<pos) break;
00713        parse_number(s,pos);
00714        if (opos<pos) break;
00715        parse_constant (colored, s, pos);
00716        if (opos<pos) break;
00717        parse_comment(s,pos);
00718        if (opos<pos) break;
00719        parse_parenthesized (s, pos);
00720        if (opos<pos) break;
00721        parse_no_declare_type (s, pos);
00722        if (opos<pos) break;
00723        parse_declare_type (s, pos);
00724        if (opos<pos) break;
00725        parse_declare_macro(s,pos);
00726        if (opos<pos) return "#00d000";
00727        parse_declare_function (s, pos);
00728        if (opos<pos) return "#0000e0";
00729        if (type=="identifier") {return none;} else return COLOR_MARKUP;
00730       }
00731       while (false);
00732     }
00733     while (pos<N(s));
00734   }
00735   if ( (type=="identifier" || type=="identifier_markup") && possible_class) {
00736   do {
00737     do {
00738       opos=pos;
00739       parse_blanks (s, pos);
00740       if (opos<pos) break;
00741       parse_identifier (colored, s, pos,false);
00742       if (opos<pos) break;
00743       parse_number(s,pos);
00744       if (opos<pos) break;
00745       parse_constant (colored, s, pos);
00746       if (opos<pos) break;
00747       parse_comment(s,pos);
00748       if (opos<pos) break;
00749       parse_parenthesized (s, pos);
00750       if (opos<pos) break;
00751       parse_no_declare_type (s, pos);
00752       if (opos<pos) break;
00753       parse_declare_type (s, pos);
00754       if (opos<pos) break;
00755       parse_declare_function (s, pos);
00756       if (opos<pos) return "#0000e0";
00757       if (type=="identifier") {return none;} else return COLOR_MARKUP;
00758     }
00759     while (false);
00760   }
00761   while (pos<N(s));
00762   }
00763   if (type=="identifier_markup") {return COLOR_MARKUP;} else return none;
00764 }