On Wed, Mar 2, 2011 at 9:20 AM, Dave Cridland <[email protected]> wrote:
> The current <rtt/> tag syntax is really very complex, and at the same time
> very simgle purpose. Yet what it's doing is, fundamentally, quite generic -
> it's doing remote editing.

Correct.  As an example, see how surprisingly simple the C# code is,
for real time editing.
Real time editing is just common string operations.

       /// <summary>Decode Edit Codes on a string of text.
       /// This follows the XMPP Real Time Text Specification, Version
0.91</summary>
       /// <param name="oldText">Text to execute Edit Codes on.</param>
       /// <param name="rtt">The rtt element containing edit codes</param>
       /// <param name="cursorPos">Cursor position to update</param>
       /// <param name="ignoreDelayCodes">Ignore delay codes
(simulation of typing inter-character delay)</param>
       /// <returns></returns>
       public static string DecodeRawRTT(string text, XmlElement rtt,
ref int cursorPos, ref int delay, bool ignoreDelayCodes)
       {
           int count;
           int pos;
           XmlNode editCode;
           XmlAttribute p;
           XmlAttribute n;
           delay = 0;

           // Verify rtt element is defined
           Debug.Assert(rtt != null);
           if (rtt == null) return text;
           if (!rtt.HasChildNodes) return text;

           // Loop to process the XML edit codes
           while (rtt.HasChildNodes)
           {
               editCode = rtt.FirstChild;
               rtt.RemoveChild(editCode);

               try
               {
                   // Get the "p" attribute (cursor position).  p
always default to end of line if not provided.
                   p = editCode.Attributes["p"];
                   pos = (p == null) ? text.Length : int.Parse(p.Value);
                   if (pos > text.Length) pos = text.Length;
                   if (pos < 0) cursorPos = 0;

                   // Get the "n" attribute (count).  n always default
to 1 if not provided.
                   n = editCode.Attributes["n"];
                   count = (n == null) ? 1 : int.Parse(n.Value);
                   if (count < 0) count = 0;

                   switch (editCode.Name)
                   {

//--------------------------------------------------------------------
                       case "t": // Insert edit code:              <i
p="#">text</i>
                           cursorPos = pos;
                           text = text.Insert(cursorPos, editCode.InnerText);
                           cursorPos = cursorPos + editCode.InnerText.Length;
                           break;

//--------------------------------------------------------------------
                       case "e": // Backspace edit code:           <e
p="#" n="#"/>
                           cursorPos = pos;
                           if (count > cursorPos) count = cursorPos;
                           text = text.Remove(cursorPos - count, count);
                           cursorPos -= count;
                           break;

//--------------------------------------------------------------------
                       case "d": // Delete edit code:              <d
p="#" n="#"/>
                           cursorPos = pos;
                           text = text.Remove(cursorPos, count);
                           break;

//--------------------------------------------------------------------
                       case "r": // Reset edit code:               <r/>
                           cursorPos = 0;
                           text = "";
                           break;

//--------------------------------------------------------------------
                       case "c": // Cursor Position edit code:     <c p="#"/>
                           cursorPos = pos;
                           break;

//--------------------------------------------------------------------
                       case "w": // Delay code                     <w n="#"/>
                           if (!ignoreDelayCodes)
                           {
                               delay = count;
                               goto ExitLoop;
                               // We exit the loop so that the caller
can decide to use a timer for the delay code,
                               // and come back to this loop later to
finish remaining nodes that have not finished processing.
                           }
                           break;
                   }
               }
               catch (Exception ex)
               {
                   Console.Write("EXCEPTION: DecodeRawRTT - " + ex.ToString());
               }
           }
ExitLoop:
           return text;
       }
   }

Reply via email to