/// <summary> /// Parse and highlight keywords. /// </summary> /// <param name="doc">Document to highlight.</param> /// <param name="dirtyBegin">Index to start highlighting. On return, start index of the range to be invalidated.</param> /// <param name="dirtyEnd">Index to end highlighting. On return, end index of the range to be invalidated.</param> public void Highlight(Document doc, ref int dirtyBegin, ref int dirtyEnd) { if (dirtyBegin < 0 || doc.Length < dirtyBegin) { throw new ArgumentOutOfRangeException("dirtyBegin"); } if (dirtyEnd < 0 || doc.Length < dirtyEnd) { throw new ArgumentOutOfRangeException("dirtyEnd"); } char nextCh; int index, nextIndex; // Determine range to highlight dirtyBegin = Utl.FindReparsePoint(_ReparsePoints, dirtyBegin); dirtyEnd = Utl.FindReparseEndPoint(doc, dirtyEnd); // seek each tags index = 0; while (0 <= index && index < dirtyEnd) { if (Utl.TryHighlight(doc, _Enclosures, index, dirtyEnd, null, out nextIndex)) { Utl.EntryReparsePoint(_ReparsePoints, index); index = nextIndex; } else if (doc[index] == '<') { Utl.EntryReparsePoint(_ReparsePoints, index); // set class for '<' doc.SetCharClass(index, CharClass.Delimiter); index++; if (dirtyEnd <= index) { return; } // if next char is '?' or '/', highlight it too nextCh = doc[index]; if (nextCh == '?' || nextCh == '/' || nextCh == '!') { doc.SetCharClass(index, CharClass.Delimiter); index++; if (dirtyEnd <= index) { return; } } // skip whitespaces while (Char.IsWhiteSpace(doc[index])) { doc.SetCharClass(index, CharClass.Normal); index++; if (dirtyEnd <= index) { return; } } // highlight element name nextIndex = Utl.FindNextToken(doc, index, DefaultWordCharSet); for (int i = index; i < nextIndex; i++) { doc.SetCharClass(i, CharClass.ElementName); } index = nextIndex; // highlight attributes while (index < dirtyEnd && doc[index] != '>') { // highlight enclosing part if this token begins a part if (Utl.TryHighlight(doc, _Enclosures, index, dirtyEnd, null, out nextIndex)) { // successfully highlighted. skip to next. index = nextIndex; continue; } // this token is normal class; reset classes and seek to next token nextIndex = Utl.FindNextToken(doc, index, DefaultWordCharSet); for (int i = index; i < nextIndex; i++) { doc.SetCharClass(i, CharClass.Attribute); } index = nextIndex; } // highlight '>' if (index < dirtyEnd) { doc.SetCharClass(index, CharClass.Delimiter); if (1 <= index && doc[index - 1] == '/') { doc.SetCharClass(index - 1, CharClass.Delimiter); } index++; } } else if (doc[index] == '&') { int seekEndIndex; bool wasEntity; CharClass klass; // find end position of this token FindEntityEnd(doc, index, out seekEndIndex, out wasEntity); DebugUtl.Assert(0 <= seekEndIndex && seekEndIndex <= doc.Length); // highlight this token klass = wasEntity ? CharClass.Entity : CharClass.Normal; for (int i = index; i < seekEndIndex; i++) { doc.SetCharClass(i, klass); } index = seekEndIndex; } else { // normal character. doc.SetCharClass(index, CharClass.Normal); index++; } } }
void texToken() { switch (la.kind) { case 1: { Get(); Highlight(t, CharClass.LatexCommand); if (curlyBracketDepth <= 0) { Debug.Assert(curlyBracketDepth == 0); sectionLevel = 0; } break; } case 2: { Get(); Highlight(t, CharClass.LatexCommand); sectionLevel = 1; break; } case 3: { Get(); Highlight(t, CharClass.LatexCommand); sectionLevel = 2; break; } case 4: { Get(); Highlight(t, CharClass.LatexCommand); sectionLevel = 3; break; } case 5: { Get(); Highlight(t, CharClass.LatexEquation); break; } case 6: { Get(); Highlight(t, CharClass.LatexBracket); Utl.EntryReparsePoint(_ReparsePoints, t.pos); break; } case 7: { Get(); Highlight(t, CharClass.LatexCurlyBracket); curlyBracketDepth++; break; } case 8: { Get(); curlyBracketDepth--; if (curlyBracketDepth <= 0) { curlyBracketDepth = 0; sectionLevel = 0; } Highlight(t, CharClass.LatexCurlyBracket); break; } case 10: { Get(); Highlight(t, CharClass.Comment); break; } case 9: { Get(); Highlight(t, CharClass.Normal); break; } case 11: { Get(); Highlight(t, CharClass.Normal); break; } case 12: { Get(); Highlight(t, CharClass.Normal); break; } default: SynErr(14); break; } }