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); }
/// Format string such that all values/variables/operators are separated by a single space /// e.g. "x+7 *(3+y) <= -10" should be formatted as "x + 7 * ( 3 + y ) <= - 10" /// Note that compound operators (<= and >= and ==) should be treated as a single symbol /// Note also that anything inside array index should not be formatted: x[3*2+7] for example should be left as is public static string Format(string line) { line = line.Trim(); var sections = new List <string>(); string substring = ""; bool lastWasOperator = false; bool inArrayIndexer = false; for (int i = 0; i < line.Length; i++) { char currentChar = line[i]; bool isOperator = CompilerSymbols.allMathOperators.Contains(currentChar.ToString()); if (currentChar == '[') { inArrayIndexer = true; } else if (currentChar == ']') { inArrayIndexer = false; } if ((currentChar == spaceChar || isOperator || lastWasOperator) && !inArrayIndexer) { if (!string.IsNullOrEmpty(substring)) { sections.Add(substring); } substring = ""; } if (isOperator || currentChar != spaceChar) { substring += currentChar; } if (i == line.Length - 1) { if (!string.IsNullOrEmpty(substring)) { sections.Add(substring); } } lastWasOperator = isOperator; } string formattedLine = ""; string lastAddedSection = ""; for (int i = 0; i < sections.Count; i++) { // Remove previous space if compound operator string compound = lastAddedSection + sections[i]; if (CompilerSymbols.ArrayContainsString(CompilerSymbols.compoundOperators, compound)) { formattedLine = formattedLine.Substring(0, formattedLine.Length - 1); } formattedLine += sections[i]; if (i != sections.Count - 1) { formattedLine += spaceChar; } lastAddedSection = sections[i]; } return(formattedLine); }