Question regarding scripting support in OO3

Daniel Flatin dflatin at rcn.com
Thu May 6 15:31:45 PDT 2004


I want to preface my remarks by saying that I am no more than an
AppleScript dabbler.  I use it on occasion for simple to moderately
involved projects, but not on a daily basis.  That being said, I think
strong AppleScript capability is the key to raising OmniOutliner above
the ever growing pack of outliner tools in the MacOS X market.


Timothy J. Wood wrote:

>   One of the features we are working on for OO3 is 'unique identifier' 
>references in AppleScript.  This will allow you to make a reference to 
>a row and not have it broken if you (or the user in the UI) moves the 
>row in the hierarchy.

I see the unique identifier as a database-like property entirely
separate from the outline structure.

This identifying property for rows should:

   1) not be editable by the user, even in a script
   2) be unique within a document
   3) be assigned whenever a new row is created
   4) not have any ordered relationship to the structure of the document

Additionally, each document should not reuse deleted ids until all
available representations have been used.  If a 32 bit unsigned
integer is used as the id, there are 4 billion opportunities before an
id would have to be reused.

Transferring outline content between documents should cause the unique
identifiers to be reassigned in the new location.  This way each
document could be considered a separate database.

The entire discussion regarding managing hierarchy is a separate issue
involving the completely different property of outline structure.  In
fact, separating these two concepts is the key to capitalizing on the
identifier idea.

>   This introduces a little ugliness, though, depending on how we form 
>the reference.  The natural way to form the reference is 'row id 
>"some-id" of document...'.  The issue that this introduces is that this 
>form is equivalent to looking up the row with the given identifier in 
>the flattened rows of the document and this in turn introduces problems 
>interacting with hierarchical documents.

[snip]

>2) Add two new relationships on 'row', 'preceding siblings' and 
>'following siblings' (or equivalent terminology).  Then you could do:
>
>   move RowD to beginning of following siblings of RowB
>
>   this is clean, simple, robust, and uses no private API.  But, it is 
>rather wordy.  This option would also leave "move RowA to after RowB" 
>having an undefined meaning as far as indentation.  On the other hand, 
>this adds a new feature since you could easily get an array of all the 
>siblings before or after an row.

Why not use "first" or "last", e.g.

    move RowD after last child of RowA
or
    move RowD after last sibling of RowB

>   With this approach it might be best to make the flattened 'rows' 
>relationship read-only so that "move RowD after RowB" would be an error 
>(instead of getting undefined results).

Returning an error in this case is the right solution IMHO.

>3) Return an object specifier that is scoped to the 'children' 
>relationship but that uses a unique identifier so that you get 
>something like "row id 'xxx' of children of row id 'yyy' of children of 
>document ...".  This would preserve the hierarchy in the specifier so 
>that things like "after" and "before" would be scoped to the same array 
>as before, but it would have other problems -- consider if you move a 
>row so that it isn't under the same parent.  We could then either (a) 
>fail to resolve it (since there is no 'row id "xxx"' in the children of 
>the old parent or (b) magically find it in its new location.  This 
>seems like it could confuse folks, but it would be really easy to 
>implement.

This is an example of confusing the purpose of a unique identifier and
structural properties of the outline.  The child index is structural
and entirely different.

>4) Keep returning index based references but allow you explicitly make 
>a reference to a row by identifier.  This would also be easy, but it 
>loses some of the benefit of having unique identifiers since the 
>following would fail:
>
>   set MyRow to first child of MyParent
>   move MyRow to after SomeOtherRow
>   set topic of MyRow to "foo"  -- same old index-base reference breakage

I think a reference to MyRow should inherently carry the property of
row id.

>   and you'd need to do something like:
>
>   set MyID to id of first child of MyParent
>   move first child of MyParent to after SomeOtherRow
>   set topic of row id MyID of MyDoc to "foo"

Given

    set MyRow to first child of MyParent
    set MyID to id of first child of MyParent

these two should be equivalent:

    MyRow
    row id MyID
    
Similarly,

    id of MyRow
    MyID

should be equivalent.  In other words, MyRow should be a reference, a
pointer to the row object and properties such as the row id and
structural position in the outline should be retrievable from this
reference.  In a way, MyRow as a reference is just like the row id
except that MyRow is generated on the fly in the execution of the
script whereas the row id should be a persistent property of the
object in the document.

My $0.02,
Dan



More information about the OmniOutliner-Users mailing list