Genii Weblog
Midas 101 - Chunk Definitions and Late Binding
Sat 2 Aug 2003, 12:17 PM
Tweetby Ben Langhinrichs
For those who have not used our Midas Rich Text LSX much, or have used it primarily from samples such as the Send It! sample, you might want to start by reading the first article in this series, Midas 101 - Chunk Definitions. Even for those familiar with chunk definitions, the current topic may come as a bit of a surprise.
To recap a bit, the Midas engine relies on a peculiar design methodology. The Notes Object Model, which basically maps a class to each discrete entity, such as a document, a view, a database, an item, etc. The Midas Object Model has very few classes, and primarily relies on a single class, the GeniiRTChunk class. This "chunk" represents a portion of the rich text in somewhat the way a view represents a portion of the document collection of a database.
In a view, there are selection criteria which determine which portion of the document collection to show. Within that selection, there is an order based on sorting. In the Midas Rich Text LSX, there is a chunk definition, which also determines which portion of the rich text to use. This may be a single element definition, such as "Button 2", or it my be a group of elements defined by a wildcard or range, such as "Section 2-5" or "Table *", or it may even be a portion of rich text bounded by one or more elements, such as "After Graphic 3". Finally, the portion of rich text can be narrowed down by drilling down in the definition, such as "Table *; Row 1", which is the first row of every table, or "Inside Section 3; Table 1; Row 1; Column 2-4", which is columns 2 through 4 of the first row of the first table inside the third section. Phew!
So far, anybody who has looked at chunk definitions in Midas before should be fairly comfortable. This definition language is powerful and used to great effect, since it allows you to describe a very specific part of the rich text and act on it. But the part that is often confusing is what happens after you act on it. This is due to the late binding nature of chunk definitions.
Late binding, by the way, usually refers in programming languages to type definitions. An early binding is when the type definitions can be checked at compile time. Late binding is when the type cannot be determined or checked until runtime, which makes error checking more difficult. The tradeoff is that late binding allows more flexibility, and that is the same tradeoff with the Midas chunk definition.
Consider a rich text field with a number of paragraphs of information including, scattered among the paragraphs, three graphics. If you wanted to use Midas to access each of these graphics and set its HTML name value, you would have code such as the following:
Set rtchunk = rtitem.DefineChunk("Graphic 1")
While rtchunk.Exists
Call rtchunk.SetTargetProperties("Graphic", "GraphicHTMLName=G" & Cstr(rtchunk.TargetNth))
rtchunk.GetNextTarget
Wend
The rtchunk.GetNextTarget call changes the definition from "Graphic 1" to "Graphic 2" and so on, so you cycle through the graphics in the rich text field. So far, so good. Now, what if instead of changing the property, you wanted to export the graphics and remove them. You might modify the above code to look like this:
Set rtchunk = rtitem.DefineChunk("Graphic 1")
While rtchunk.Exists
Call rtchunk.ExportGraphic("c:\temp\G" & Cstr(rtchunk.TargetNth) & ".gif")
Call rtchunk.Remove
rtchunk.GetNextTarget
Wend
The code looks good, but it skips every other graphic, leaving them in the rich text field and not exporting them. This is an easy mistake if you look at the chunk definitions as describing the original rich text. After all, you first export and remove Graphic 1, then you export and remove Graphic 2, then you export and remove Graphic 3. Right?
Well, not exactly. Let's look at the rich text after each step. First, you define a chunk called "Graphic 1". It points to the first graphic in the rich text field. Next, you export and remove that graphic. What does the chunk point to? Does it point to nothing, the way it would if you removed a NotesDocument object? No. It points to "the first graphic in the rich text field", just like before. Except that now, since the graphic that was there before has been removed, it points to what was the second graphic, but is now the first graphic. Therefore, the code should be more like:
Set rtchunk = rtitem.DefineChunk("Graphic 1")
While rtchunk.Exists
Call rtchunk.ExportGraphic("c:\temp\G" & Cstr(rtchunk.TargetNth) & ".gif")
Call rtchunk.Remove
'
Wend
This is late binding. You define a chunk and it is evaluated just as you call the method or check the property. If you call three methods against the same chunk, you may not be effecting the same rich text. Remember earlier when I mentioned the similarity to a view? If you remove a document, it is roughly the equivalent of doing the following:
Set view = db.GetView("Main")
Set doc = view.GetFirstDocument
doc.Remove
view.Refresh
Set doc = view.GetFirstDocument
Because the NotesDocument class has early binding, you have to refresh the view and get the first document again, but the "first" document in the view changes over time. With the chunk definition, the idea of "first" or any other relative definition changes all the time without a refresh or a redefinition of the chunk. The chunk is a definition, and the methods and properties act on the rich text through the definition, not on any specific rich text.
Copyright © 2003 Genii Software Ltd.
What has been said: