private void CheckTokenListAndOutput(SideObject sideObject, Token token)
        {
            // ok so is this token on the keywords & functions list?
            object o = highlightingStyles[token.Value.ToUpperInvariant()];
            if (o != null)
            {
                // yes...
                if (sideObject.InSquareStringState && ((HighlightColour)o != HighlightColour.Datatype))
                {
                    // but we're in square string state and it's not a datatype... so plain text colour
                    SetColour(HighlightColour.PlainText, sideObject);
                }
                else
                {
                    // ok to set the colour to the one associated with the token
                    SetColour((HighlightColour)o, sideObject);
                }
            }
            else
            {
                // no - so plain text colour
                SetColour(HighlightColour.PlainText, sideObject);
            }

            // and append the token
            sideObject.Text.Append(token.Value);
        }
        void getSQLFormattedString(string lineInput, SideObject sideObject)
        {
            // get a tokenised version of the input string
            StringTokenizer st = new StringTokenizer(lineInput);
            Token t;

            while ((t = st.Next()) != null)
            {
                if (sideObject.InCommentState)
                {
                    // ok we're in comment state - set the colour & output the current token
                    SetColour(HighlightColour.Comment, sideObject);
                    sideObject.Text.Append(t.Value);

                    // if this token isn't an end comment
                    if (t.Kind != TokenKind.EndComment)
                    {
                        // then keep reading...
                        while ((t = st.Next()) != null)
                        {
                            // ... output the current token ...
                            sideObject.Text.Append(t.Value);

                            // ... and if we're an end comment ...
                            if (t.Kind == TokenKind.EndComment)
                            {
                                // ... then cancel comment state and stop reading ...
                                sideObject.InCommentState = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        // the first token on the line was an end comment - so we're no longer in the comment state
                        sideObject.InCommentState = false;
                    }
                }
                else
                {
                    if (sideObject.InSquareStringState)
                    {
                        // ok we're in square string state - check the token list and output the current token
                        CheckTokenListAndOutput(sideObject, t);

                        // if this token isn't an end square
                        if (t.Kind != TokenKind.EndSquare)
                        {
                            // then keep reading...
                            while ((t = st.Next()) != null)
                            {
                                // ... check the token list and output the current token ...
                                CheckTokenListAndOutput(sideObject, t);

                                // ... and if we're an end square ...
                                if (t.Kind == TokenKind.EndSquare)
                                {
                                    // ... then cancel square string state and stop reading ...
                                    sideObject.InSquareStringState = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // the first token on the line was an end square - so we're no longer in the square string state
                            sideObject.InSquareStringState = false;
                        }
                    }
                    else
                    {
                        if (t.Kind == TokenKind.EOLComment)
                        {
                            // set comment highlight & output token
                            SetColour(HighlightColour.Comment, sideObject);
                            sideObject.Text.Append(t.Value);

                            // now read to the end of the line
                            while ((t = st.Next()) != null)
                            {
                                // and output each token (still in comment highlight)
                                sideObject.Text.Append(t.Value);
                            }
                        }
                        else if (t.Kind == TokenKind.StartComment)
                        {
                            // set comment highlight & output token
                            SetColour(HighlightColour.Comment, sideObject);
                            sideObject.Text.Append(t.Value);

                            // remember we're now in comment state
                            sideObject.InCommentState = true;
                        }
                        else if (t.Kind == TokenKind.StartSquare)
                        {
                            // set plain text highlight & output token
                            SetColour(HighlightColour.PlainText, sideObject);
                            sideObject.Text.Append(t.Value);

                            // remember we're now in square string state
                            sideObject.InSquareStringState = true;
                        }
                        else if (t.Kind == TokenKind.QuotedString)
                        {
                            // set string highlight & output token
                            SetColour(HighlightColour.String, sideObject);
                            sideObject.Text.Append(t.Value);
                        }
                        else if (t.Kind == TokenKind.Number)
                        {
                            // set number highlight & output token
                            SetColour(HighlightColour.Number, sideObject);
                            sideObject.Text.Append(t.Value);
                        }
                        else
                        {
                            // check keywords, functions etc & output token
                            CheckTokenListAndOutput(sideObject, t);
                        }
                    }
                }
            }
        }
        private static void SetHighlight(HighlightColour colour, SideObject sideObject)
        {
            // if the highlight needs to be set
            if (sideObject.lastHighlightIndex != colour)
            {
                // then set the highlight
                int i = (int)colour;
                sideObject.Text.Append("\\highlight").Append(i.ToString()).Append(" ");

                // and record the fact
                sideObject.lastHighlightIndex = colour;
            }
        }
        private static void AppendLineNumber(SideObject left, SideObject right, int cnt)
        {
            // set the highlight to white
            SetHighlight(HighlightColour.White, left);
            SetHighlight(HighlightColour.White, right);

            // set the line number colour
            SetColour(HighlightColour.LineNumber, left);
            SetColour(HighlightColour.LineNumber, right);

            // and append the line number text to the left & right
            left.Text.Append(cnt.ToString().PadLeft(4)).Append(" ");
            right.Text.Append(cnt.ToString().PadLeft(4)).Append(" ");
        }
 private static void AppendLineBreak(SideObject left, SideObject right)
 {
     // append a line break to both the left & right
     left.Text.Append("\\par\n");
     right.Text.Append("\\par\n");
 }
 private static void AppendHeader(SideObject sideObject)
 {
     // append the standard header (including font setting & colour table) to side
     sideObject.Text.Append(@"{\rtf1\fbidis\ansi\ansicpg1255\deff0\deflang1037{\fonttbl{");
     sideObject.Text.Append(@"\f0\fnil\fcharset0Lucida Console;}");
     sideObject.Text.Append("}\n");
     sideObject.Text.Append(@"{\colortbl ;\red0\green0\blue0;\red255\green211\blue211;\red211\green255\blue211;\red211\green211\blue255;\red255\green255\blue255;\red0\green128\blue128;\red0\green0\blue255;\red255\green0\blue255;\red128\green128\blue128;\red0\green128\blue0;\red0\green0\blue128;\red255\green0\blue0;\red128\green0\blue0;");
     sideObject.Text.Append("}\n");
     sideObject.Text.Append(@"\viewkind4\uc1\pard\ltrpar\fs16 ");
 }
        public void CompareText()
        {
            // load the source and destination as TextFile objects
            DiffList_TextFile tfSource = new DiffList_TextFile(leftText_);
            DiffList_TextFile tfDestination = new DiffList_TextFile(rightText_);

            // use DiffEngine to generate the difference list
            DiffEngine de = new DiffEngine();
            de.ProcessDiff(tfSource, tfDestination, DiffEngineLevel.SlowPerfect);
            ArrayList DiffLines = de.DiffReport();

            // create the objects to track the left & right sides
            SideObject leftState = new SideObject();
            SideObject rightState = new SideObject();

            // add the RTF header to the left & right side objects
            AppendHeader(leftState);
            AppendHeader(rightState);

            // initialise our variables
            int cnt = 1;
            int i = 0;

            // now go through the result spans
            foreach (DiffResultSpan drs in DiffLines)
            {
                // what is this Diff's status?
                switch (drs.Status)
                {
                    // a source line was deleted
                    case DiffResultSpanStatus.DeleteSource:
                    {
                        // for each line in the diff
                        for (i = 0; i < drs.Length; i++)
                        {
                            // put the line number on the left & right
                            AppendLineNumber(leftState, rightState, cnt);

                            // set highlight and output line on the left only
                            SetHighlight(HighlightColour.DeletedLine, leftState);
                            getSQLFormattedString(((TextLine)tfSource.GetByIndex(drs.SourceIndex + i)).Line, leftState);

                            // put in the line break
                            AppendLineBreak(leftState, rightState);

                            // increase the line count
                            cnt++;
                        }
                    } break;

                    // there was no change
                    case DiffResultSpanStatus.NoChange:
                    {
                        for (i = 0; i < drs.Length; i++)
                        {
                            // put the line number on the left & right
                            AppendLineNumber(leftState, rightState, cnt);

                            // output line on the left & right
                            getSQLFormattedString(((TextLine)tfSource.GetByIndex(drs.SourceIndex + i)).Line, leftState);
                            getSQLFormattedString(((TextLine)tfDestination.GetByIndex(drs.DestIndex + i)).Line, rightState);

                            // put in the line break
                            AppendLineBreak(leftState, rightState);

                            // increase the line count
                            cnt++;
                        }
                    } break;

                    // a target line was added
                    case DiffResultSpanStatus.AddDestination:
                    {
                        for (i = 0; i < drs.Length; i++)
                        {
                            // put the line number on the left & right
                            AppendLineNumber(leftState, rightState, cnt);

                            // set highlight and output line on the right only
                            SetHighlight(HighlightColour.AddedLine, rightState);
                            getSQLFormattedString(((TextLine)tfDestination.GetByIndex(drs.DestIndex + i)).Line, rightState);

                            // put in the line break
                            AppendLineBreak(leftState, rightState);

                            // increase the line count
                            cnt++;
                        }
                    } break;

                    // the text of the line changed
                    case DiffResultSpanStatus.Replace:
                    {
                        for (i = 0; i < drs.Length; i++)
                        {
                            // put the line number on the left & right
                            AppendLineNumber(leftState, rightState, cnt);

                            // set highlight & output line on the left & right
                            SetHighlight(HighlightColour.ChangedLine, leftState);
                            SetHighlight(HighlightColour.ChangedLine, rightState);
                            getSQLFormattedString(((TextLine)tfSource.GetByIndex(drs.SourceIndex + i)).Line, leftState);
                            getSQLFormattedString(((TextLine)tfDestination.GetByIndex(drs.DestIndex + i)).Line, rightState);

                            // put in the line break
                            AppendLineBreak(leftState, rightState);

                            // increase the line count
                            cnt++;
                        }
                    } break;
                }
            }

            // now set the built text into the left & right rich text boxes
            rtbLeft.Rtf = leftState.Text.ToString();
            rtbRight.Rtf = rightState.Text.ToString();
        }