Пример #1
0
        public Highlighter(Raw raw)
        {
            styleDataOf      = new Dictionary <string, StyleData>();
            textListOf       = new Dictionary <string, string[]>();
            keywordDataOf    = new Dictionary <string, Rules.KeywordData>();
            customStyleDatas = new List <StyleData>();
            foreach (Raw.RawList listI in raw.lists)
            {
                textListOf[listI.name.ToLowerInvariant()] = listI.items.ToArray();
            }
            {
                bool first = true;
                foreach (Raw.ItemData itemDataI in raw.itemDatas)
                {
                    StyleData data = new StyleData();
                    data.ds   = Ds.GetByName(itemDataI.defStyleNum);
                    data.name = itemDataI.name;

                    data.color     = HighlighterUtil.ParseColor(itemDataI.color);
                    data.italic    = GetVariantBool(itemDataI.italic);
                    data.bold      = GetVariantBool(itemDataI.bold);
                    data.underline = GetVariantBool(itemDataI.underline);
                    data.strikeout = GetVariantBool(itemDataI.strikeout);
                    if (data.color == null && data.italic == null && data.bold == null && data.underline == null && data.strikeout == null)
                    {
                        data.index = data.ds.index;
                    }
                    else
                    {
                        data.index = (short)(Ds.all.Count + customStyleDatas.Count);
                        customStyleDatas.Add(data);
                    }

                    styleDataOf[data.name.ToLowerInvariant()] = data;
                    if (first)
                    {
                        first            = false;
                        defaultStyleData = data;
                    }
                }
            }

            List <Rules.Context> contextList = new List <Rules.Context>();

            contextOf = new Dictionary <string, Rules.Context>();
            foreach (Raw.Context contextI in raw.contexts)
            {
                string        name    = contextI.name;
                Rules.Context context = new Rules.Context();
                context.name = name;
                contextOf[name.ToLowerInvariant()] = context;
                contextList.Add(context);
            }
            List <Rules.RegExpr> regExprRules = new List <Rules.RegExpr>();

            foreach (Raw.Context contextI in raw.contexts)
            {
                Rules.Context context = contextOf[contextI.name.ToLowerInvariant()];
                {
                    StyleData styleData = null;
                    string    attribute = contextI.attribute;
                    if (attribute != null)
                    {
                        styleDataOf.TryGetValue(attribute.ToLowerInvariant(), out styleData);
                    }
                    if (styleData == null)
                    {
                        styleData = defaultStyleData;
                    }
                    context.attribute = styleData;
                }
                StyleData currentAttribute = context.attribute;
                context.lineEndContext     = GetSwitchInfo(contextI.lineEndContext);
                context.fallthrough        = GetBool(contextI.fallthrough);
                context.fallthroughContext = GetSwitchInfo(contextI.fallthroughContext);

                List <Rules.Rule> contextRules = new List <Rules.Rule>();
                foreach (Raw.Rule ruleI in contextI.rules)
                {
                    Rules.Rule rule = ParseRule(ruleI, regExprRules, context.attribute);
                    if (rule != null)
                    {
                        contextRules.Add(rule);
                    }
                }
                context.childs = contextRules.ToArray();
            }
            awakePositions = new int[regExprRules.Count];
            for (int i = 0; i < regExprRules.Count; i++)
            {
                Rules.RegExpr rule = regExprRules[i];
                rule.awakePositions = awakePositions;
                rule.awakeIndex     = i;
            }
            contexts    = contextList.ToArray();
            styleDataOf = null;
            contextOf   = null;
            textListOf  = null;
        }
Пример #2
0
        public bool Parse(LineArray lines, int maxMilliseconds)
        {
#if HIGHLIGHTER_DEBUG
            if (_debugStopwatch == null)
            {
                _debugStopwatch = new System.Diagnostics.Stopwatch();
                _debugStopwatch.Start();
                Console.WriteLine("HIGHLIGHTER START");
            }
#endif
            DateTime startTime = DateTime.Now;
            int      changesBeforeTimeCheck = 0;
            bool     timeElapsed            = false;
            bool     changed = false;
            stack = new PredictableList <Rules.Context>(8);
            stack.Add(contexts[0]);
            Rules.Context[] state           = stack.ToArray();
            bool            needSetStack    = false;
            bool            lastLineChanged = false;
            for (int i = 0; i < lines.blocksCount; i++)
            {
                LineBlock block = lines.blocks[i];
                if (timeElapsed && lastLineChanged)
                {
                    while (block.count == 0)
                    {
                        i++;
                        if (i >= lines.blocksCount)
                        {
                            block = null;
                            break;
                        }
                        block = lines.blocks[i];
                    }
                    if (block != null)
                    {
                        block.valid &= ~LineBlock.ColorValid;
                        Line line = block.array[0];
                        line.startState = state;
                        line.endState   = null;
                    }
                    stack = null;
                    return(changed);
                }
                {
                    bool noChangesInBlock = (block.valid & LineBlock.ColorValid) != 0 && !lastLineChanged;
                    if (noChangesInBlock && block.count > 0)
                    {
                        Rules.Context[] nextState = block.array[block.count - 1].endState;
                        if (nextState == null)
                        {
                            noChangesInBlock = false;
                        }
                        else
                        {
                            state = nextState;
                        }
                    }
                    if (noChangesInBlock)
                    {
                        needSetStack = true;
                        continue;
                    }
                }
                block.valid |= LineBlock.ColorValid;
                for (int j = 0; j < block.count; j++)
                {
                    Line line = block.array[j];
                    if (AreEquals(line.startState, state) && line.endState != null)
                    {
                        state           = line.endState;
                        needSetStack    = true;
                        lastLineChanged = false;
                        continue;
                    }
                    if (needSetStack)
                    {
                        needSetStack = false;
                        stack.Resize(state.Length);
                        Array.Copy(state, stack.buffer, stack.count);
                    }
                    line.startState = state;
                    string text = line.Text;
                    Array.Clear(awakePositions, 0, awakePositions.Length);
                    int        position    = 0;
                    int        count       = line.charsCount;
                    Rules.Rule lastMatched = null;
                    while (position < count)
                    {
                        Rules.Context context = stack.count > 0 ? stack.Peek() : contexts[0];
                        lastMatched = null;
                        foreach (Rules.Rule rule in context.childs)
                        {
                            int nextPosition;
                            if ((rule.column == -1 || position == rule.column) && rule.Match(text, position, out nextPosition))
                            {
                                if (!rule.lookAhead)
                                {
                                    for (; position < nextPosition; position++)
                                    {
                                        line.chars[position].style = rule.attribute.index;
                                    }
                                }
                                if (rule.childs != null && position < count)
                                {
                                    foreach (Rules.Rule childRule in rule.childs)
                                    {
                                        int childNextPosition;
                                        if (childRule.Match(text, nextPosition, out childNextPosition))
                                        {
                                            for (; position < childNextPosition; position++)
                                            {
                                                line.chars[position].style = childRule.attribute.index;
                                            }
                                            Switch(rule.context);
                                        }
                                    }
                                }
                                Switch(rule.context);
                                lastMatched = rule;
                                break;
                            }
                        }
                        if (lastMatched == null)
                        {
                            if (context.fallthrough)
                            {
                                Switch(context.fallthroughContext);
                            }
                            else
                            {
                                line.chars[position].style = context.attribute.index;
                                position++;
                            }
                        }
                    }
                    if (lastMatched == null || !lastMatched.isLineContinue)
                    {
                        while (stack.count > 0)
                        {
                            Rules.Context contextI = stack.Peek();
                            if (contextI.lineEndContext.next == null && contextI.lineEndContext.pops == 0)
                            {
                                break;
                            }
                            Switch(contextI.lineEndContext);
                        }
                    }
                    if (AreEquals(stack, state))
                    {
                        line.endState = state;
                    }
                    else
                    {
                        state         = stack.ToArray();
                        line.endState = state;
                    }
                    changesBeforeTimeCheck++;
                    lastLineChanged = true;
                    changed         = true;
                }
                if (changesBeforeTimeCheck > 50)
                {
                    changesBeforeTimeCheck = 0;
                    DateTime nextTime = DateTime.Now;
                    timeElapsed = (nextTime - startTime).TotalMilliseconds > maxMilliseconds;
                    if (timeElapsed)
                    {
                        startTime = nextTime;
                    }
                }
            }
            stack = null;
            lastParsingChanged = changed;
            if (!changed && lines.ranges != null)
            {
                foreach (StyleRange range in lines.ranges)
                {
                    lines.SetStyleRange(range);
                }
            }
#if HIGHLIGHTER_DEBUG
            if (!changed)
            {
                _debugStopwatch.Stop();
                Console.WriteLine("HIGHLIGHTER TIME: " + (_debugStopwatch.Elapsed.TotalMilliseconds / 1000).ToString("0.00"));
            }
#endif
            return(changed);
        }
Пример #3
0
 private Rules.Rule ParseRule(Raw.Rule rawRule, List <Rules.RegExpr> regExprRules, StyleData parentStyleData)
 {
     Rules.Rule commonRule = null;
     if (rawRule.type == "keyword")
     {
         string[] list;
         string   key = rawRule.String.ToLowerInvariant();
         textListOf.TryGetValue(key, out list);
         if (list != null)
         {
             bool casesensitive = GetBool(rawRule.general.keywordsCasesensitive, true);
             Rules.KeywordData cachedData;
             keywordDataOf.TryGetValue(key, out cachedData);
             Rules.KeywordData data = null;
             for (Rules.KeywordData dataI = cachedData; dataI != null; dataI = dataI.next)
             {
                 if (dataI.casesensitive == casesensitive)
                 {
                     data = dataI;
                     break;
                 }
             }
             if (data == null)
             {
                 data = new Rules.KeywordData(list, casesensitive, cachedData);
                 keywordDataOf[key] = data;
             }
             commonRule = new Rules.Keyword(
                 data,
                 rawRule.general.keywordsWeakDeliminator ?? "",
                 rawRule.general.keywordsAdditionalDeliminator ?? "");
         }
     }
     else if (rawRule.type == "DetectChar")
     {
         Rules.DetectChar rule = new Rules.DetectChar();
         rule.char0 = CharOf(rawRule.char0);
         commonRule = rule;
     }
     else if (rawRule.type == "Detect2Chars")
     {
         Rules.Detect2Chars rule = new Rules.Detect2Chars();
         rule.char0 = CharOf(rawRule.char0);
         rule.char1 = CharOf(rawRule.char1);
         commonRule = rule;
     }
     else if (rawRule.type == "AnyChar")
     {
         Rules.AnyChar rule = new Rules.AnyChar();
         rule.chars = rawRule.String;
         commonRule = rule;
     }
     else if (rawRule.type == "StringDetect")
     {
         Rules.StringDetect rule = new Rules.StringDetect();
         rule.insensitive = GetBool(rawRule.insensitive);
         rule.text        = rawRule.String;
         commonRule       = rule;
     }
     else if (rawRule.type == "WordDetect")
     {
         commonRule = new Rules.WordDetect(rawRule.String, GetBool(rawRule.insensitive));
     }
     else if (rawRule.type == "RegExpr")
     {
         Rules.RegExpr rule  = new Rules.RegExpr();
         string        regex = rawRule.String;
         rule.regex = new Regex(
             HighlighterUtil.FixRegexUnicodeChars(GetBool(rawRule.minimal) ? HighlighterUtil.LazyOfRegex(regex) : regex),
             (GetBool(rawRule.insensitive) ? RegexOptions.IgnoreCase : RegexOptions.None)
             );
         commonRule = rule;
         regExprRules.Add(rule);
     }
     else if (rawRule.type == "Int")
     {
         commonRule = new Rules.Int();
     }
     else if (rawRule.type == "Float")
     {
         commonRule = new Rules.Float();
     }
     else if (rawRule.type == "HlCOct")
     {
         commonRule = new Rules.HlCOct();
     }
     else if (rawRule.type == "HlCHex")
     {
         commonRule = new Rules.HlCHex();
     }
     else if (rawRule.type == "RangeDetect")
     {
         Rules.RangeDetect rule = new Rules.RangeDetect();
         rule.char0 = CharOf(rawRule.char0);
         rule.char1 = CharOf(rawRule.char1);
         commonRule = rule;
     }
     else if (rawRule.type == "DetectSpaces")
     {
         commonRule = new Rules.DetectSpaces();
     }
     else if (rawRule.type == "DetectIdentifier")
     {
         commonRule = new Rules.DetectIdentifier();
     }
     else if (rawRule.type == "HlCStringChar")
     {
         commonRule = new Rules.HlCStringChar();
     }
     else if (rawRule.type == "HlCChar")
     {
         commonRule = new Rules.HlCChar();
     }
     else if (rawRule.type == "LineContinue")
     {
         commonRule = new Rules.LineContinue();
     }
     if (commonRule != null)
     {
         {
             StyleData styleData = null;
             string    attribute = rawRule.attribute;
             if (attribute != null)
             {
                 styleDataOf.TryGetValue(attribute.ToLowerInvariant(), out styleData);
             }
             if (styleData == null)
             {
                 styleData = parentStyleData ?? defaultStyleData;
             }
             commonRule.attribute = styleData;
         }
         commonRule.lookAhead = GetBool(rawRule.lookAhead);
         int column = GetInt(rawRule.column, -1);
         if (GetBool(rawRule.firstNonSpace))
         {
             commonRule.column = 0;
         }
         else
         {
             commonRule.column = column;
         }
         commonRule.context = GetSwitchInfo(!string.IsNullOrEmpty(rawRule.context) ? rawRule.context : "#stay");
         List <Rules.Rule> childs = null;
         foreach (Raw.Rule childI in rawRule.childs)
         {
             Rules.Rule child = ParseRule(childI, regExprRules, commonRule.attribute);
             if (child != null)
             {
                 if (childs == null)
                 {
                     childs = new List <Rules.Rule>();
                 }
                 childs.Add(child);
             }
         }
         if (childs != null)
         {
             commonRule.childs = childs.ToArray();
         }
     }
     return(commonRule);
 }