Пример #1
0
    public void HighlightTest()
    {
        string initString = "// This is highlighted string";
        int    prevLength = initString.Length;

        SyntaxTheme theme = ScriptableObject.CreateInstance <SyntaxTheme>();

        string testString  = SyntaxHighlighter.HighlightCode(initString, theme);
        int    finalLength = testString.Length;

        Assert.AreNotEqual(string.Empty, testString);
        Assert.AreNotEqual(prevLength, finalLength);
        Assert.AreNotEqual(initString, testString);
    }
Пример #2
0
    public static string HighlightCode(string code, SyntaxTheme theme)
    {
        string highlightedCode = "";

        string[] lines = code.Split('\n');
        for (int i = 0; i < lines.Length; i++)
        {
            ;
            highlightedCode += HighlightLine(lines[i], theme);
            if (i != lines.Length - 1)
            {
                highlightedCode += '\n';
            }
        }

        return(highlightedCode);
    }
Пример #3
0
    // Highlights in-game written code with a given theme
    public static string HighlightCode(string code, SyntaxTheme theme)
    {
        string highlightedCode = "";           // Init string

        string[] codeLines = code.Split('\n'); // Split by new line

        // Iterate over each line, adding a highlighted line (Unity's rich text) to a string
        for (int i = 0; i < codeLines.Length; i++)
        {
            highlightedCode += Highlight(codeLines[i], theme);

            if (i != codeLines.Length - 1) // if i does not exceed array length, add a new line
            {
                highlightedCode += '\n';
            }
        }

        return(highlightedCode); // Return highlighted code
    }
Пример #4
0
    static string HighlightLine(string line, SyntaxTheme theme)
    {
        var cols            = new List <Color>();
        var startEndIndices = new List <Vector2Int>();

        string[] sections      = CompilerFormatter.Format(line).Split(' ');
        int      nonSpaceIndex = 0;
        bool     isComment     = false;

        for (int i = 0; i < sections.Length; i++)
        {
            Color  colour  = Color.clear;
            string section = sections[i];

            if (section == CompilerSymbols.commentMarker || isComment)
            {
                colour    = theme.comment;
                isComment = true;
            }
            else if (section == CompilerSymbols.usingKeyword)
            {
                colour = theme.usingKeyword;
            }
            else if (CompilerSymbols.ArrayContainsString(CompilerSymbols.types, section))
            {
                colour = theme.types;
            }
            else if (CompilerSymbols.ArrayContainsString(CompilerSymbols.reservedNames, section))
            {
                colour = theme.reservedNames;
            }
            else if (CompilerSymbols.allOperators.Contains(section.ToLower()))
            {
                colour = theme.allOperators;
            }
            else if (CompilerSymbols.ArrayContainsString(CompilerSymbols.builtinFunctions, section))
            {
                colour = theme.builtinFunctions;
            }
            else if (CompilerSymbols.brackets.Contains(section.ToLower()))
            {
                colour = theme.brackets;
            }
            else if (float.TryParse(section.Replace('.', ','), out _))
            {
                colour = theme.value;
            }
            else
            {
                colour = theme.variable;
            }

            if (colour != Color.clear)
            {
                cols.Add(colour);
                int endIndex = nonSpaceIndex + sections[i].Length;
                startEndIndices.Add(new Vector2Int(nonSpaceIndex, endIndex));
            }
            nonSpaceIndex += sections[i].Length;
        }

        if (cols.Count > 0)
        {
            nonSpaceIndex = 0;
            int colIndex         = 0;
            int actualStartIndex = -1;
            for (int i = 0; i <= line.Length; i++)
            {
                if (startEndIndices[colIndex].x == nonSpaceIndex)
                {
                    actualStartIndex = i;
                }
                else if (startEndIndices[colIndex].y == nonSpaceIndex)
                {
                    //print (colIndex + " replace: " + startEndIndices[colIndex] +" with:  " + new Vector2Int (actualStartIndex, i));
                    startEndIndices[colIndex] = new Vector2Int(actualStartIndex, i);

                    colIndex++;
                    if (colIndex >= cols.Count)
                    {
                        break;
                    }
                    i--;
                    continue;
                }

                if (i < line.Length)
                {
                    char c = line[i];
                    if (c != ' ')
                    {
                        nonSpaceIndex++;
                    }
                }
            }
        }

        for (int i = cols.Count - 1; i >= 0; i--)
        {
            var    col           = cols[i];
            var    startEndIndex = startEndIndices[i];
            string colString     = ColorUtility.ToHtmlStringRGB(col);

            line = line.Insert(startEndIndex.y, "</color>");
            line = line.Insert(startEndIndex.x, $"<color=#{colString}>");
            //print ("insert: " + startEndIndex.x + " " + startEndIndex.y);
        }

        return(line);
    }
Пример #5
0
    static string HighlightLine(string line, SyntaxTheme theme)
    {
        var cols            = new List <Color> ();
        var startEndIndices = new List <Vector2Int> ();

        string[] sections      = CompilerFormatter.Format(line).Split(' ');
        int      nonSpaceIndex = 0;
        bool     isComment     = false;

        for (int i = 0; i < sections.Length; i++)
        {
            Color  colour  = Color.clear;
            string section = sections[i];

            if (section == VirtualCompiler.commentMarker || isComment)
            {
                colour    = theme.comment;
                isComment = true;
            }
            else if (section == "if" || section == "elseif" || section == "else")
            {
                colour = theme.conditionKeyword;
            }
            else if (section == "loop")
            {
                colour = theme.loopKeyword;
            }
            else if (VirtualCompiler.ArrayContainsString(VirtualCompiler.mathOperators, section))
            {
                colour = theme.mathOperator;
            }
            else if (VirtualCompiler.ArrayContainsString(VirtualCompiler.comparisonOperators, section))
            {
                colour = theme.comparisonOperator;
            }
            else if (section == "(" || section == ")")
            {
                colour = theme.parentheses;
            }
            else if (section == "{" || section == "}")
            {
                colour = theme.curlyBrackets;
            }
            else if (float.TryParse(section.Replace('.', ','), out _))
            {
                colour = theme.value;
            }
            else if (section == "=")
            {
                colour = theme.assignment;
            }
            else
            {
                colour = theme.variable;
            }

            if (colour != Color.clear)
            {
                cols.Add(colour);
                int endIndex = nonSpaceIndex + sections[i].Length;
                startEndIndices.Add(new Vector2Int(nonSpaceIndex, endIndex));
            }
            nonSpaceIndex += sections[i].Length;
        }

        if (cols.Count > 0)
        {
            nonSpaceIndex = 0;
            int colIndex         = 0;
            int actualStartIndex = -1;
            for (int i = 0; i <= line.Length; i++)
            {
                if (startEndIndices[colIndex].x == nonSpaceIndex)
                {
                    actualStartIndex = i;
                }
                else if (startEndIndices[colIndex].y == nonSpaceIndex)
                {
                    //print (colIndex + " replace: " + startEndIndices[colIndex] +" with:  " + new Vector2Int (actualStartIndex, i));
                    startEndIndices[colIndex] = new Vector2Int(actualStartIndex, i);

                    colIndex++;
                    if (colIndex >= cols.Count)
                    {
                        break;
                    }
                    i--;
                    continue;
                }

                if (i < line.Length)
                {
                    char c = line[i];
                    if (c != ' ')
                    {
                        nonSpaceIndex++;
                    }
                }
            }
        }

        for (int i = cols.Count - 1; i >= 0; i--)
        {
            var    col           = cols[i];
            var    startEndIndex = startEndIndices[i];
            string colString     = ColorUtility.ToHtmlStringRGB(col);

            line = line.Insert(startEndIndex.y, "</color>");
            line = line.Insert(startEndIndex.x, $"<color=#{colString}>");
            //print ("insert: " + startEndIndex.x + " " + startEndIndex.y);
        }

        return(line);
    }
Пример #6
0
    // Highlights a line
    static string Highlight(string line, SyntaxTheme theme)
    {
        List <Color>      colors       = new List <Color>();      // Init list of colors
        List <Vector2Int> wordStartEnd = new List <Vector2Int>(); // Init list of integers - indices of where words start & end
        int notSpace = 0;                                         // Where does a word start?

        // Divide a code by breakChars (e.g. stop characters, commas, parentheses, brackets)
        // This allows me to highlight code even if it is a single word
        // E.g. by default, a word "Debug" would be highlighted, but not in a word "Debug.Log()"
        // This is because a program had seen it as a single word
        // What I'm essentially doing here is converting "Debug.Log()" to something like "Debug . Log ( )"
        // By putting spaces in between characters, a program started picking it up correctly
        // The code still compiles
        string subLine = "";

        subLine = line;

        for (int i = 0; i < subLine.Length; i++)
        {
            char currentChar = subLine[i];

            for (int j = 0; j < Keywords.breakChars.Length; j++)
            {
                string current = Keywords.breakChars[j];

                if (currentChar.ToString() == current)
                {
                    if (subLine.Length > 0)
                    {
                        if ((i - 1 != -1) && subLine[i - 1].ToString() != " ")
                        {
                            subLine = subLine.Insert(i, " ");
                        }

                        if (i + 1 < subLine.Length && subLine[i + 1].ToString() != " ")
                        {
                            subLine = subLine.Insert(i + 1, " ");
                        }
                    }
                }
            }
        }

        // Split words by spaces
        string[] words = subLine.Split(' ');

        // Highlight words
        for (int i = 0; i < words.Length; i++)
        {
            Color c = Color.clear;

            // Highlight comment lines
            if (words[i].StartsWith(Keywords.commentMark) == true)
            {
                line = line.TrimEnd(' ');
                int beginning = line.IndexOf('/');
                int end       = line.Length;
                wordStartEnd.Add(new Vector2Int(beginning, end));

                c = theme.commentColor;
                colors.Add(c);

                break;
            }

            // Highlight strings & single characters (words between '' and "");
            if (words[i].StartsWith(Keywords.charMark) || words[i].StartsWith(Keywords.quotationMark))
            {
                c = theme.stringColor;
            }

            // Highlight C# keywords (e.g. int)
            for (int j = 0; j < Keywords.blueWords.Length; j++)
            {
                string word = Keywords.blueWords[j];
                if (words[i] == word)
                {
                    c = theme.variableColor;
                }
            }

            // Highlight Unity keywords (e.g. "Update")
            for (int j = 0; j < Keywords.unityKeywords.Length; j++)
            {
                string word = Keywords.unityKeywords[j];
                if (words[i] == word)
                {
                    c = theme.unityKeyword;
                }
            }

            // Highlight Unity classes names (e.g. "Debug")
            for (int j = 0; j < Keywords.unityClasses.Length; j++)
            {
                string word = Keywords.unityClasses[j];
                if (words[i] == word)
                {
                    c = theme.unityClass;
                }
            }

            // Highlight custom classes made by me (e.g. "EventTrigger")
            for (int j = 0; j < Keywords.customClasses.Length; j++)
            {
                string word = Keywords.customClasses[j];
                if (words[i] == word)
                {
                    c = theme.unityClass;
                }
            }

            // If a word has been highlighted, add its indices and colors to the list
            if (c != Color.clear)
            {
                colors.Add(c);
                int end = notSpace + words[i].Length;
                wordStartEnd.Add(new Vector2Int(notSpace, end));
            }
            notSpace += words[i].Length; // Increment notSpace by word's length
        }

        if (colors.Count > 0) // If a line is to be highlighted
        {
            notSpace = 0;
            int colorIndex       = 0;
            int actualStartIndex = -1;

            for (int i = 0; i <= line.Length; i++)
            {
                if (wordStartEnd[colorIndex].x == notSpace) // check for actual start and end position
                {
                    actualStartIndex = i;
                }
                else if (wordStartEnd[colorIndex].y == notSpace) // If there is an end tag (</color>) in the middle of the word
                {
                    wordStartEnd[colorIndex] = new Vector2Int(actualStartIndex, i);
                    colorIndex++;

                    if (colorIndex >= colors.Count) // if colorIndex exceeded number of colors, break
                    {
                        break;
                    }

                    i--; // decrement i
                    continue;
                }

                if (i < line.Length) // look for spaces in a line
                {
                    char character = line[i];

                    if (character != ' ')
                    {
                        notSpace++;
                    }
                }
            }
        }

        for (int i = colors.Count - 1; i >= 0; i--) // Insert rich text in a string
        {
            var    color       = colors[i];
            var    startEnd    = wordStartEnd[i];
            string colorString = ColorUtility.ToHtmlStringRGB(color); // Convert a color to a string

            line = line.Insert(startEnd.y, "</color>");
            line = line.Insert(startEnd.x, $"<color=#{colorString}>");
        }

        return(line);
    }