source: trunk/workflow/js/resourceeditor/highlight.js @ 795

Revision 795, 19.6 KB checked in by viani, 15 years ago (diff)

Ticket #488 - Inclusão do módulo workflow no ramo trunk do repositório Expresso.

  • Property svn:executable set to *
Line 
1    /******************************************************************
2     highlight.js                                           Muze Helene
3     ------------------------------------------------------------------
4     Author: Muze (info@muze.nl)
5     Date: 28 februari 2004
6
7     Copyright 2002 Muze
8
9     This file is part of Helene.
10
11     Helene is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published
13     by the Free Software Foundation; either version 2 of the License,
14     or (at your option) any later version.
15 
16     Helene is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     You should have received a copy of the GNU General Public License
22     along with Helene; if not, write to the Free Software
23     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
24     02111-1307  USA
25
26    -------------------------------------------------------------------
27
28     This file contains the syntax highlighting parser
29
30    ******************************************************************/
31  // Parsing smarty tags http://smarty.php.net/
32  // Cofigure the smarty delimiters below ('{%' and '%}' by default)
33  // Unset this flag if you need to parse only PHP
34  var parseSmarty = true;
35
36        /* states */
37        var YY_STATE_HTML = 0;
38        var YY_STATE_PINP = 1;
39        var YY_STATE_DQSTRING = 2;
40        var YY_STATE_SQSTRING = 3;
41  var YY_STATE_SCRIPT = 4;
42  var YY_STATE_BLOCKCOMMENT = 5;
43
44  /* Smarty states */
45  var YYS_STATE_TAG = 101;
46  var YYS_STATE_PARAM = 102;
47  var YYS_STATE_QPARAM = 103;
48
49        /* tokens */
50        var T_VAR = 0;
51        var T_IDENT = 1;
52        var T_FUNCTION = 2;
53        var T_TOKEN = 3;
54        var T_UNKNOWN = 4;
55        var T_PINP_START = 5;
56        var T_PINP_BLOCK = 6;
57        var T_PINP_END = 7;
58        var T_SPACE = 8;
59        var T_DQUOTE = 9;
60        var T_SQUOTE = 10;
61        var T_ESCAPE = 11;
62        var T_SPECIAL_CHAR = 12;
63        var T_OPERATOR = 13;
64        var T_SINGLE_COMMENTS = 14;
65        var T_BLOCKCOMMENT = 15;
66        var T_BLOCKCOMMENT_END = 16;
67        var T_PHP_START = 17;
68        var T_PHP_END = 18;
69        var T_SCRIPT_START = 19;
70        var T_SCRIPT_END = 20;
71        var T_TAB = 21;
72        var T_EMPTY_LINE = 22;
73
74  /*Smarty tokens*/
75  var TS_SMARTY_START = 101;
76  var TS_SMARTY_END = 102;
77  var TS_KEYWORD = 103;
78  var TS_ATTRIBUTE = 104;
79  var TS_ATTRVALUE = 105;
80  var TS_VAR = 106;
81        var TS_ENDTAG = 107;
82
83        var hLines = new Array();
84        var debug = 0;
85        var scannerPos = 0;
86  var hStyles = new Array();
87        var hStateStyles = new Array();
88
89  // May be there is the better place for it but now there
90  initStyleDefault();
91        // Making object from keywords, it makes a big perfomance overhead in IE
92        // and slightly better perfomance in Mozilla
93        // You can define any amount of keyword groups
94        // Words should match ([a-z0-9][a-z0-9_]*) and should be separated by spaces
95        var hPHPKeywords = cacheKeywords( /// TODO: Add more keywords here
96                "",
97                "" // standart functions
98                );     
99        var hSmartyKeywords = cacheKeywords(
100                "",
101                "",
102                "" 
103                );
104
105        function hLineToken(tokenType, tokenData) {
106                this.type = tokenType;
107                this.data = tokenData;
108                this.reallength = tokenData.length;
109    this.newState = -1;
110
111                switch (this.data) {
112                        case '<':       
113                                this.data='&lt;';
114                        break;
115                        case '>':
116                                this.data='&gt;';
117                        break;
118                        case '&':
119                                this.data='&amp;';
120                        break;
121                }
122       
123                switch (this.type) {
124                        case T_PINP_START:
125                        case T_PHP_START:
126                        case T_PINP_END:
127                        case T_PHP_END:
128                        case T_SCRIPT_START:
129                        case T_SINGLE_COMMENTS:
130                        case T_BLOCKCOMMENT:
131                        case T_BLOCKCOMMENT_END:
132                                this.data = this.data.replace(/[<]/g, '&lt;');
133                this.data = this.data.replace(/[>]/g, '&gt;');
134                                var myTabRest = scannerPos % 8;
135                var addLength = 8 - myTabRest;
136                                this.data = this.data.replace(/[\t]/g, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
137                scannerPos += (addLength -1);
138                        break;
139                        case T_SCRIPT_END:
140                                this.data = this.data.replace(/[<]/g, '&lt;');
141                                this.data = this.data.replace(/[>]/g, '&gt;');
142                        case T_SPACE:
143                                this.data = this.data.replace(/[ ]/g, '&nbsp;');
144                        break;
145                        case T_TAB:
146                                var myTabRest = scannerPos % 8;
147                                var addLength = 8 - myTabRest;
148                                // alert( 'scannerPos ' + scannerPos + ' myTabRest ' + myTabRest + ' addLength ' + addLength);
149                                this.data = this.data.replace(/[\t]/g, '<span style="padding-left: '+ (addLength*letterWidth) + 'px;"></span>');
150                                scannerPos += (addLength -1);
151                        break;
152                        case T_EMPTY_LINE:
153                                this.data = '<span style="padding-left: 1px;"></span>';
154                        break;
155                }
156                scannerPos += tokenData.length;
157        }
158
159        function getToken(sData) {
160                var re, match;
161
162                /* empty line, required for Firefox 1.5.x */
163                if (sData == "")
164                {
165                        result = new hLineToken(T_EMPTY_LINE, "");
166                        return result;
167                }
168
169                /* white space */
170                re = /^([ ]+)/;
171                match = re.exec(sData);
172                if (match) {
173                        result = new hLineToken(T_SPACE, match[1]);
174                        return result;
175                }
176
177                re = /^([\t])/;
178                match = re.exec(sData);
179                if (match) {
180                        result = new hLineToken(T_TAB, match[1]);
181                        return result;
182                }
183
184    /* Smarty tokens */
185    if(parseSmarty) {
186        re = /^\{\$[a-z_][a-z0-9_]*/i;           // Matches $smarty->left_delimiter
187        match = re.exec(sData);
188        if(match) {
189                return new hLineToken(TS_SMARTY_START, match[0]);
190        }
191
192        re = /^\{/;           // Matches $smarty->left_delimiter
193        match = re.exec(sData);
194        if(match) {
195                return new hLineToken(TS_SMARTY_START, match[0]);
196        }
197
198        re = /^\}/;           // Matches $smarty->right_delimiter
199        match = re.exec(sData);
200        if(match) {
201                return new hLineToken(TS_SMARTY_END, match[0]);
202        }
203         
204                //re = /^\/[a-z0-9][a-z0-9_]*/i;
205                //match = re.exec(sData);
206                //if (match) {
207            //  result = new hLineToken(TS_ENDTAG, match[0]);
208                //      return result;
209                //}             
210    }
211    /* end of smarty tokens */
212
213                /* variable or ident */
214                re = /^([$]|->)?([a-z0-9_][a-z0-9_]*)/i;
215                match = re.exec(sData);
216                if (match) {
217                        if (match[1]) {
218                                result = new hLineToken(T_VAR, match[0]);
219                        } else {
220                                result = new hLineToken(T_IDENT, match[2]);
221                        }
222                        return result;
223                }
224
225                /* single tokens */
226                re = /^([(){},"'\\])/;
227                match = re.exec(sData);
228                if (match) {
229                        switch (match[1]) {
230                                case '\\':
231                                        result = new hLineToken(T_ESCAPE, match[1]);
232                                break;
233                                case '"':
234                                        result = new hLineToken(T_DQUOTE, match[1]);
235                                break;
236                                case "'":
237                                        result = new hLineToken(T_SQUOTE, match[1]);
238                                break;
239                                default:
240                                        result = new hLineToken(T_SPECIAL_CHAR, match[1]);
241                                break;
242                        }
243                        return result;
244                }
245
246                re = /^((\<\!\-\-)|(\-\-\>))/;
247                match = re.exec(sData);
248                if (match) {
249                        if (match[2]) {
250                                result = new hLineToken(T_BLOCKCOMMENT, match[2]);
251                        } else {
252                                result = new hLineToken(T_BLOCKCOMMENT_END, match[3]);
253                        }
254                        return result;
255                }
256
257                /* comments */
258                re = /^(\/\/.*)/;
259                match = re.exec(sData);
260                if (match) {
261                        result = new hLineToken(T_SINGLE_COMMENTS, match[1]);
262                        return result;
263                }
264
265                /* php end tags */
266                re = /^(>)/;
267                match = re.exec(sData);
268                if (match) {
269                        result = new hLineToken(T_PHP_END, match[0]);
270                        return result;
271                }
272
273                re = /^([\-\+\.\*\/\=\%])/;
274                match = re.exec(sData);
275                if (match) {
276                        result = new hLineToken(T_OPERATOR, match[1]);
277                        return result;
278                }
279
280
281                /* pinp/php tags */
282        re = /^((<))/i;
283                match = re.exec(sData);
284                if (match) {
285                        if (match[3]) {
286                                result = new hLineToken(T_PINP_END, match[0]);
287                        } else
288                        if (match[2]) {
289                                result = new hLineToken(T_PINP_START, match[0]);
290                        } else {
291                                result = new hLineToken(T_PINP_START, match[0]);
292                        }
293                        return result;
294                }
295
296                /* javascript */
297                re = /^<(\/)?script[^>]*>/;
298                match = re.exec(sData);
299                if (match) {
300                        if (match[1]) {
301                                result = new hLineToken(T_SCRIPT_END, match[0]);
302                        } else {
303                                result = new hLineToken(T_SCRIPT_START, match[0]);
304                        }
305                        return result;
306                }
307                               
308                return new hLineToken(T_UNKNOWN, sData.charAt(0));
309        }
310
311        function hLineParseString(sData) {
312                var token;
313                this.tokens = new Array();
314
315                scannerPos = 0;
316                do
317                {
318                        token = getToken(sData);
319                        this.tokens[this.tokens.length] = token;       
320                        sData=sData.substring(token.reallength);
321                } while (sData != '');
322        }
323
324      function getElmSpan(token) { /// In the past styles were here
325                var result = '';                                                        // UPDATE: it is better to produce whole span tag here
326    var cls = hStyles[token.type];
327    if(cls!='') result = '<span class="'+cls+'">';
328                else result = '<span>';
329                return result;
330        }
331      function getStateSpan(token) { /// Style span for states
332                var result = '';                                                                // UPDATE: it is better to produce whole span tag here
333    var cls = hStateStyles[token.newState];
334    if(cls!='') result = '<span class="'+cls+'">';
335                else result = '<span>';
336                return result;
337        }
338
339        function hLineDoHighlight(callback) {
340                var state = new Array();
341                var result = '';
342                if (this.lineNo) {
343                        /* load parent state */
344                        state = state.concat(hLines[this.lineNo-1].getEndState());
345//                      alert((this.lineNo-1)+':'+state.length);
346                }
347                for (var i = 0; i<state.length; i++) {
348                        if (!state[i].noMultiLine) {
349                                result += getStateSpan(state[i]);
350                        }
351                }
352                if (this.tokens) {
353                        for (var i=0; i<this.tokens.length; i++) {
354                                var cState = 0;
355                                var token = this.tokens[i];
356                                if (state.length) {
357          cState = state[state.length-1].newState;
358          status = cState;
359                                }
360
361        switch (cState) {         // In the past state was the type of opening token
362          case YY_STATE_HTML:     // It is a real state now
363                                                switch (token.type) {
364              //Smarty highlighting
365              case TS_SMARTY_START:
366                token.newState = YYS_STATE_TAG;
367                result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
368                state.push(token);
369              break;
370              //End of smarty highlighting
371                                                        case T_PHP_START:
372                                                        case T_PINP_START:
373                                                                token.newState = YY_STATE_PINP; // We fix the new state here
374                                                                if (i == 1 && this.tokens[i-1].type == T_SPACE) {
375                                                                        result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
376                                                                } else {
377                                                                        result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
378                                                                }
379                                                                state.push(token); // But we still saving opening token
380                                                        break;
381                                                        case T_SCRIPT_START:
382                token.newState = YY_STATE_SCRIPT;
383                                                                if (i == 1 && this.tokens[i-1].type == T_SPACE) {
384                                                                        result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
385                                                                } else {
386                                                                        result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
387                                                                }
388                                                                state.push(token);
389                                                        break;
390                                                        case T_BLOCKCOMMENT:
391                if(token.newState<0) token.newState = YY_STATE_BLOCKCOMMENT;
392                                                                result += getStateSpan(token);
393                                                                result += token.data;
394                                                                state.push(token);
395                                                        break;
396                                                        default:
397                                                                result += token.data;
398                                                        break;
399                                                }
400                                        break;
401          case YY_STATE_SCRIPT:
402                                                switch (token.type) {
403                                                        case T_PHP_START:
404                                                        case T_PINP_START:
405                token.newState = YY_STATE_PINP;
406                                                                if (i == 1 && this.tokens[i-1].type == T_SPACE) {
407                                                                        result = getStateSpan(token) + result + getElmSpan(token) + token.data + '</span>';
408                                                                } else {
409                                                                        result += getStateSpan(token) + getElmSpan(token) + token.data + '</span>';
410                                                                }
411                                                                state.push(token);
412                                                        break;
413                                                        case T_SCRIPT_END:
414                                                                result += getElmSpan(token)+token.data+'</span>';
415                                                                result += '</span>';
416                                                                state.pop();
417                                                        break;
418                                                        default:
419                                                                result += token.data;
420                                                        break;
421                                                }
422                                        break;
423          case YY_STATE_PINP:
424                                                switch (token.type) {
425                                                        case T_IDENT:
426                                                                var lower_data = token.data.toLowerCase();
427                                                                var t = hPHPKeywords[lower_data];
428                                                                if(typeof(t)!='undefined') {
429                                                                        result += '<span class="h_phpkeywords'+t+'">';
430                                                                } else {
431                                                                        result += getElmSpan(token);
432                                                                }
433                                                                result += token.data + '</span>';
434                                                        break;
435                                                        case T_DQUOTE:
436                token.newState = YY_STATE_DQSTRING;
437                                                        case T_SQUOTE:
438                if(token.newState<0) token.newState = YY_STATE_SQSTRING;
439                                                        case T_BLOCKCOMMENT:
440                if(token.newState<0) token.newState = YY_STATE_BLOCKCOMMENT;
441                                                                result += getStateSpan(token);
442                                                                result += token.data;
443                                                                state.push(token);
444                                                        break;
445                                                        case T_PHP_END:
446                                                        case T_PINP_END:
447                                                                result += getElmSpan(token)+token.data+'</span>';
448                                                                result += '</span>';
449                                                                state.pop();
450                                                        break;
451                                                        case T_VAR:
452                                                        case T_OPERATOR:
453                                                        case T_SPECIAL_CHAR:
454                                                        case T_SINGLE_COMMENTS:
455                                                                result += getElmSpan(token);
456                                                                result += token.data;
457                                                                result += '</span>';
458                                                        break;
459                                                        default:
460                                                                result += token.data;
461                                                        break;
462                                                }
463                                        break;
464          case YY_STATE_BLOCKCOMMENT:
465                                                switch (token.type) {
466                                                        case T_BLOCKCOMMENT_END:
467                                                                result += token.data+'</span>';
468                                                                state.pop();
469                                                        break;
470                                                        default:
471                                                                result += token.data;
472                                                        break;
473                                                }
474                                        break;
475          case YY_STATE_DQSTRING:
476                                                switch (token.type) {
477              case T_DQUOTE:
478                                                                result += token.data+'</span>';
479                                                                state.pop();
480                                                        break;
481                                                        case T_ESCAPE:
482                                                                result += token.data;
483                                                                token = this.tokens[++i];
484                                                                result += token.data;
485                                                        break;
486                                                        case T_VAR:
487                                                                result += getElmSpan(token);
488                                                                result += token.data;
489                                                                result += '</span>';
490                                                        break;
491                                                        default:
492                                                                result += token.data;
493                                                        break;
494                                                }
495                                        break;
496                                      case YY_STATE_SQSTRING:
497                                                switch (token.type) {
498                                                      case T_SQUOTE:
499                                                                result += token.data+'</span>';
500                                                                state.pop();
501                                                        break;
502                                                        case T_ESCAPE:
503                                                                result += token.data;
504                                                                token = this.tokens[++i];
505                                                                result += token.data;
506                                                        break;
507                                                        default:
508                                                                result += token.data;
509                                                        break;
510                                                }
511                                        break;
512          case YYS_STATE_TAG:
513            switch (token.type) {
514              case TS_SMARTY_END:
515                result += getElmSpan(token) + token.data + '</span></span>';
516                state.pop();
517              break;
518                                                        case TS_ENDTAG:
519                                                                var t = hSmartyKeywords[token.data.substr(1)];
520                                                                if(t==1) {      // Only the first group has closing tags
521                                                                        result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
522                                                                } else {
523                                                                        result += token.data;
524                                                                }
525                                                        break;
526                                                        case T_VAR:
527                result += getElmSpan(token) + token.data + '</span>';
528                //result += token.data;
529                                                                break;                                                         
530                                                        case T_IDENT:
531                                                                var t = hSmartyKeywords[token.data];
532                                                                if(typeof(t)!='undefined' /*&&
533                                                                        (t>3 || // first three groups of keywords may appear
534                                                                                (i>0 && this.tokens[i-1].type==TS_SMARTY_START))        // immediately after TS_SMARTY_START token only
535                                                                                */) {
536                                                                        result += '<span class="h_smartykeywords'+t+'">' + token.data + '</span>';
537                                                                } else {
538                                                                        result += token.data;
539                                                                }
540                                                        break;
541              default:
542                                                        result += token.data;
543              break;
544            }
545          break;
546                                        default:
547                                                result += token.data;
548                                        break;
549                                }
550                        }
551//                      alert(this.lineNo+'::'+this.tokens.length+'::'+result);
552
553                }
554                var stateChanged = 0;
555                if (state.length != this.getEndState().length) {
556                        stateChanged = 1;
557                }
558
559                for (i=state.length-1; i>=0; i--) {
560                        if (!stateChanged && state[i].type!=this.getEndState()[i].type) {
561                                stateChanged = 1;
562                        }
563                        if (!state[i].noMultiLine) {
564                                result += getElmSpan(state[i]);
565                        }
566                }
567
568                /* report update */
569                if (callback) {
570//                      alert(this.lineNo+"::"+result);
571                        if (result) {
572//                              alert(this.lineNo+': 2 eol chars: "'+result.substr(result.length-2)+'"');
573                        }
574                        callback(this.lineNo, result);
575                }
576                this.setEndState(state);
577              if (stateChanged) {
578                        if (debug) alert('updating: '+this.lineNo+1);
579      /// This makes a stack overflow
580      /// so we are returning 'true' that means next line must be updated
581      //~ hLines[this.lineNo+1].doHighlight(callback);
582                      return true;
583                }
584    /// Next line need not be updated
585    return false;
586        }
587
588        function hLineSetEndState(newEndState) {
589//              alert(this.lineNo+': new endstate: '+newEndState.length);
590                var frop=new Array();
591                if (newEndState.length) {
592//                      alert(':'+newEndState.toString()+':');
593                        this.endState=frop.concat(newEndState); //newEndState; //.toSource();
594                } else {
595                        this.endState=new Array();
596                }
597/*
598                var line = hLines[2];
599                if (line) {
600                        alert(this.lineNo+'->'+line.endState.length);
601                }
602*/
603        }
604
605        function hLineGetEndState() {
606                return this.endState;
607        }
608
609        function hLineRemove() {
610                if (this.lineNo < (hLines.length-1)) {
611                        var len = hLines.length-1;
612                        for (var i=this.lineNo; i<len; i++) {
613                                hLines[i] = hLines[i+1];
614                                hLines[i].lineNo = i;
615                        }
616                }
617                hLines.pop();
618        }
619
620        function hLine(lineNo, lineString) {
621                this.lineNo = lineNo;
622                if (lineNo && (lineNo != hLines.length)) {
623                        var hLinesLen = hLines.length;
624                        for (var i=hLinesLen; i>lineNo; i--) {
625                                hLines[i] = hLines[i-1];
626                                hLines[i].lineNo = i;
627                        }
628                }
629                hLines[lineNo] = this;
630                this.tokens = new Array();
631                this.setEndState = hLineSetEndState;
632                this.setEndState(new Array());
633                this.getEndState = hLineGetEndState;
634                this.remove = hLineRemove;
635
636                this.parseString = hLineParseString;
637                this.parseString(lineString);
638
639                if (debug) alert(this.lineNo);
640                this.doHighlight = hLineDoHighlight;
641        }
642
643        function highlightUpdateLine(lineNo, lineContent, callback) {
644//              alert('update line: '+lineNo+'::'+lineContent);
645                hLines[lineNo].parseString(lineContent);
646              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
647        }
648
649        function highlightDeleteLine(lineNo, callback) {
650//              alert('remove line: '+lineNo);
651                line = hLines[lineNo];
652                line.remove();
653              if (hLines.length && (lineNo < hLines.length))
654      while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
655        }
656
657        function highlightReset() {
658                hLines = new Array();
659                new hLine(0, '');
660        }
661
662        function highlightInsertLine(lineNo, lineContent, callback) {
663                if (lineNo) {
664                        lineNo -= 1;
665                }
666//              alert('insert at: '+lineNo+'::'+lineContent);
667                line = new hLine(lineNo, lineContent);
668              while(line.doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
669        }
670
671        function highlightAppendLine(lineNo, lineContent, callback) {
672//              alert('append at: '+(lineNo+1)+'::'+lineContent);
673                line = new hLine(lineNo+1, new String(lineContent));
674              while(hLines[lineNo].doHighlight(callback) && lineNo < hLines.length-1) lineNo++;
675        }
676
677  function initStyleDefault() {
678    hStyles[T_PINP_START] =
679    hStyles[T_PINP_END] =
680    hStyles[T_PHP_START] = //'h_pinp';
681    hStyles[T_PHP_END] = //'h_pinp';
682    hStyles[T_VAR] = 'h_var';
683    hStyles[T_IDENT] = 'h_ident';
684    hStyles[T_DQUOTE] = 'h_doublequote';
685    hStyles[T_SQUOTE] = 'h_singlequote';
686    hStyles[T_SPECIAL_CHAR] = 'h_special_char';
687    hStyles[T_OPERATOR] = 'h_operator';
688    hStyles[T_SINGLE_COMMENTS] = 'h_single_comments';
689    hStyles[T_BLOCKCOMMENT] = 'h_blockcomment';
690    hStyles[TS_SMARTY_START] = 'h_smartymarkers';
691    hStyles[TS_SMARTY_END] = 'h_smartymarkers';
692               
693        hStateStyles[YY_STATE_HTML] = '';
694        hStateStyles[YY_STATE_PINP] = 'h_pinp_block';
695        hStateStyles[YY_STATE_DQSTRING] = 'h_doublequote';
696        hStateStyles[YY_STATE_SQSTRING] = 'h_singlequote';
697        hStateStyles[YY_STATE_BLOCKCOMMENT] = 'h_blockcomment';
698        hStateStyles[YY_STATE_SCRIPT] = 'h_scriptblock';
699        hStateStyles[YYS_STATE_TAG] = 'h_smartytag';
700  }
701        function cacheKeywords() {
702                var res = new Object();
703                for(var i=0;i<arguments.length;i++) {
704                        var t = String(arguments[i]).split(" ");
705                        for(var j=0;j<t.length;j++)
706                                res[t[j]]=i+1;
707                }
708                return res;
709        }
Note: See TracBrowser for help on using the repository browser.