One of the greatest advantages digital content provides is its immediate malleability. With the right software changes can be made quickly and globally. A hallmark of this flexibility is the great big undo/redo stack that nearly every piece of software maintains.
An application normally implements undo by recording inverse operations for every action the user takes. For instance, to undo adding 10 to a particular number, you simply subtract 10. When a user deletes a word from a document, the inverse operation is to simply insert that same word back in.
Looking more closely at the requirements necessary to undo the deletion of a word, you can see that you need to know not only what the word was, but where the word was located in the document. At a lower level this location is simply the number of characters that preceed the deleted word.
For instance, imagine a document containing only the text “ice is blue”. Note that the word “blue” is preceded by a total of 7 characters. So to undo the deletion of the word “blue” from the document, we simply insert the word “blue” after the 7th character in the document.
Locations are complicated by document content that automatically updates itself. One example might be a timestamp. One second the stamp could read “Thursday 23:59”, the next, “Friday 00:00”. You can see that the stamp shrunk by 2 characters. Had our imaginary document in the previous paragraph contained a timestamp such as this one, the location we need to reinsert the word “blue” at to undo the deletion would have changed. To accommodate undo after a timestamp we need to be able to describe locations in the document like “the 7th character after the 2nd timestamp”.
Wouldn’t this just be accomplished by counting the number of characters in the field code instead of counting the result of the field code? (A question from an experienced by amateur programmer.)
For those who aren’t familiar with RTF, I should say that the “field code” is the term used by RTF to describe the data that tells the application what should be displayed for special bits of text. For example, the field code for a date/time stamp is “TIME”. The application is responsible for converting this field code into the actual date/time before displaying the decoded document. This actual display text is called the “field result”.
The reason you cannot count the number of characters in the field code has to do with the model used to store text for layout. Text that is layed out and displayed using Cocoa is stored in what is basically a big string (actually an attributed string). The text system accesses this string directly during layout, user editing, undo/redo operations, etc.
To leverage all the code Apple provides we must have the field result in the string during layout/editing/etc. But because the same string is also used for undo tracking, you’ve somehow got to be able to track changes in the string independant of changes to the field’s result.