Re: Records
Re: Records
- Subject: Re: Records
- From: "Nigel Garvey" <email@hidden>
- Date: Tue, 27 Sep 2005 23:13:13 +0100
Martin Orpen wrote on Tue, 27 Sep 2005 13:56:49 +0100:
>On 27 Sep 2005, at 11:30, Nigel Garvey wrote:
>
>> You've forgotten not to try looping through a record and not to try
>> getting the property names of records as values in their own
>> right. :-)
>
>It might have been less cruel to mention what I'd *remembered* about
>records
Many apologies. :-)
>Am I going to have to do something kludgy like dumping the record out
>as an error and parse the result:
I wrote such a beast a couple of years ago, if it's of any interest. Its
main purpose was to get string representations of the top level labels in
a record (records within records being regarded as values), but it's easy
to splice these into a list with the values. I've checked it over for
Tiger compatibility and have changed the output to Unicode text, but
haven't had time to check it for style. :-)
(* Get a list of strings representing a record's labels *)
on listRecordLabels(r)
-- Get a string representation of the whole record
-- with the longest text values reduced to "".
considering case
set recStr to lrlGetString(r)
-- Assign some stuff to variables for speed in the parsing loop.
set triggers to ":,\"{}|"
-- set quote to "\"" -- quote is a constant with this value in Tiger
set escape to "\\"
set lBrace to "{"
set rBrace to "}"
set bar to "|"
set comma to ","
set colon to ":"
-- Parse the "record as string" and extract the "labels".
set labelList to {}
set textValue to false
set barredLabel to false
set arrayDepth to 0
set i to 1
repeat with j from 1 to (count recStr)
set c to recStr's character j
if (c is in triggers) then
if (textValue) then
if (c is quote) then set textValue to (recStr's character (j
- 1) is escape)
else if (barredLabel) then
if (c is bar) then set barredLabel to false
else if (c is lBrace) then
set arrayDepth to arrayDepth + 1
else if (c is quote) then
set textValue to true
else if (arrayDepth > 0) then
if (c is rBrace) then set arrayDepth to arrayDepth - 1
else if (c is bar) then
set barredLabel to true
else if (c is comma) then
set i to j + 2
else if (c is colon) then
set end of labelList to recStr's text i thru (j - 1)
end if
end if
end repeat
end considering
return labelList
end listRecordLabels
(* "Coerce" a record to string, with the longest text values reduced to
"". *)
on lrlGetString(r)
-- Get an error string that includes a text representation of the record
try
17th Tuesday of r
on error msg
set msg to msg as Unicode text
end try
set astid to AppleScript's text item delimiters
-- Get a list of the real record's text values (if any)
tell (r as list) to set txtList to its strings & its every Unicode text
-- Repeatedly remove text values from the "record string", so that
they don't
-- need to be parsed by the listRecordLabels handler. For safety,
removed text
-- shouldn't be a subset of anything else in the record string, so
it's not
-- removed if it's shorter than 100 characters (allowing that for
label names)
-- and removals occur in descending order of length.
repeat (count txtList) times
-- Locate the longest string in the list
set longest_idx to 1
set longest_len to (count txtList's item 1)
repeat with i from 2 to (count txtList)
tell (count txtList's item i)
if (it > longest_len) then
set longest_idx to i
set longest_len to it
end if
end tell
end repeat
-- If all the (remaining) text values are shorter than 100, remove
no more
if (longest_len < 100) then exit repeat
-- Get a string that includes a representation of this text value (!)
try
tell txtList's item longest_idx
if (its class is string) then
its 17th Tuesday
else -- Unicode
middle March of (it as record)'s «class ktxt»
end if
end tell
on error msg2
set msg2 to msg2 as Unicode text
end try
-- Replace this text in the list with a short "" to mark it done
set txtList's item longest_idx to ""
-- Extract the bit between the inverted commas and use it as
-- a delimiter to zap the same text from the record representation
set AppleScript's text item delimiters to "\""
set AppleScript's text item delimiters to msg2's text from text
item 2 to text item -2
set msg to msg's text items
set AppleScript's text item delimiters to ""
set msg to msg as Unicode text
end repeat
-- Trim the ends of the record string
set AppleScript's text item delimiters to "{"
set f to (count msg's first text item) + 2
set AppleScript's text item delimiters to ":"
set t to -1 - (count msg's last text item)
set AppleScript's text item delimiters to astid
return msg's text f thru t
end lrlGetString
tell application "Font Book"
activate
set b to typeface 1
set r to typeface additional info of b
end tell
set labelList to listRecordLabels(r)
set valueList to r as list
set myList to {}
repeat with i from 1 to (count labelList)
set end of myList to item i of labelList
set end of myList to item i of valueList
end repeat
myList
NG
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Applescript-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden