harges
November 2, 2007, 4:09pm
#1
I’m having trouble with the script below. It almost works. Here’s what it’s supposed to do:
For a given InDesign CS3 document:
Get a list of every graphic frame on a given page.
Filter out any frames that are not of a specified size.
Sort the the filtered list so that frame are listed from page top to bottom, left to right (essentially sorting first by the X coordinate and then by the Y coordinate).
The result is close but a few frames are out of place. It’s a pretty simple script and I can’t figure out where I went wrong. Can anyone spot my mistake?
–Open this script in a new Script Editor window.
set theRightSize to {width :0.875, height :1.0}
set List2 to {}
set List3 to {}
set tempList to {}
set finalList to {}
set CoordRefList to {1, 4, 5}
tell application “Adobe InDesign CS3”
tell active document
set List1 to (object reference of every item of all page items of page 1 whose content type is graphic type )
–the following repeat loop tests each List1 item to make sure it matches specified dimensions
repeat with i from 1 to count of items in List1
set theBounds to geometric bounds of item i of List1
–a rounding handler is called
if my [color=green]GetSize/color = theRightSize then
copy item i of List1 to the end of List2
end if
end repeat
--[i][color=olive]a third list is built to hold a record with the object reference and the bounds of each item[/color][/i]
[b][color=blue]repeat[/color][/b] [b][color=blue]with[/color][/b] [color=green]n[/color] [b][color=blue]from[/color][/b] 1 [b][color=blue]to[/color][/b] [color=blue]count[/color] [b][color=blue]of[/color][/b] [color=green]List2[/color]
[b][color=blue]set[/color][/b] [color=green]holder[/color] [b][color=blue]to[/color][/b] [color=blue]geometric bounds[/color] [b][color=blue]of[/color][/b] [color=blue]item[/color] [color=green]n[/color] [b][color=blue]of[/color][/b] [color=green]List2[/color]
[b][color=blue]set[/color][/b] [color=green]temp_Rec[/color] [b][color=blue]to[/color][/b] {[color=green]frame[/color]:[color=blue]item[/color] [color=green]n[/color] [b][color=blue]of[/color][/b] [color=green]List2[/color], [color=green]bounds_Y1[/color]:[color=blue]item[/color] 1 [b][color=blue]of[/color][/b] [color=green]holder[/color], [color=green]bounds_x1[/color]:[color=blue]item[/color] 2 [b][color=blue]of[/color][/b] [color=green]holder[/color], [color=green]bounds_y2[/color]:[color=blue]item[/color] 3 [b][color=blue]of[/color][/b] [color=green]holder[/color], [color=green]bounds_x2[/color]:[color=blue]item[/color] 4 [b][color=blue]of[/color][/b] [color=green]holder[/color]}
[b][color=blue]copy[/color][/b] [color=green]temp_Rec[/color] [b][color=blue]to[/color][/b] [b][color=blue]end[/color][/b] [b][color=blue]of[/color][/b] [color=green]List3[/color]
[b][color=blue]end[/color][/b] [b][color=blue]repeat[/color][/b]
--[i][color=olive]list three is sorted by X1 values[/color][/i]
[b][color=blue]set[/color][/b] [color=green]List3[/color] [b][color=blue]to[/color][/b] [b][color=blue]my[/color][/b] [color=green]bubbleSort1[/color]([color=green]List3[/color])
--[i][color=olive]this should create short lists containing only those items with the same X1 value, the short list is then sorted by Y1 and pasted into a final list; the result should be a list sorted first by x1 values and then by Y1 values[/color][/i]
[b][color=blue]repeat[/color][/b] [b][color=blue]with[/color][/b] [color=green]m[/color] [b][color=blue]from[/color][/b] 1 [b][color=blue]to[/color][/b] [b][color=blue]the[/color][/b] [color=blue]count[/color] [b][color=blue]of[/color][/b] [color=blue]items[/color] [b][color=blue]in[/color][/b] [color=green]CoordRefList[/color]
[b][color=blue]repeat[/color][/b] [b][color=blue]with[/color][/b] [color=green]j[/color] [b][color=blue]from[/color][/b] 1 [b][color=blue]to[/color][/b] [color=blue]count[/color] [b][color=blue]of[/color][/b] [color=blue]items[/color] [b][color=blue]in[/color][/b] [color=green]List3[/color]
[b][color=blue]set[/color][/b] [color=green]testhandler[/color] [b][color=blue]to[/color][/b] [b][color=blue]my[/color][/b] [color=green]roundThis[/color](([color=green]bounds_x1[/color] [b][color=blue]of[/color][/b] [color=blue]item[/color] [color=green]j[/color] [b][color=blue]of[/color][/b] [color=green]List3[/color]), 0)
[b][color=blue]if[/color][/b] [color=green]testhandler[/color] [b][color=blue]as[/color][/b] [color=blue]integer[/color] = ([color=blue]item[/color] [color=green]m[/color] [b][color=blue]of[/color][/b] [color=green]CoordRefList[/color] [b][color=blue]as[/color][/b] [color=blue]integer[/color]) [b][color=blue]then[/color][/b]
[b][color=blue]copy[/color][/b] [color=blue]item[/color] [color=green]j[/color] [b][color=blue]of[/color][/b] [color=green]List3[/color] [b][color=blue]to[/color][/b] [b][color=blue]end[/color][/b] [b][color=blue]of[/color][/b] [color=green]tempList[/color]
[b][color=blue]end[/color][/b] [b][color=blue]if[/color][/b]
[b][color=blue]end[/color][/b] [b][color=blue]repeat[/color][/b]
--[i][color=olive]this handler sorts the short list so that it is sorted by Y1 values when it's pasted into the final list[/color][/i]
[b][color=blue]set[/color][/b] [color=green]tempList[/color] [b][color=blue]to[/color][/b] [b][color=blue]my[/color][/b] [color=green]bubbleSort2[/color]([color=green]tempList[/color])
[b][color=blue]copy[/color][/b] [color=green]tempList[/color] [b][color=blue]to[/color][/b] [b][color=blue]end[/color][/b] [b][color=blue]of[/color][/b] [color=green]finalList[/color]
[b][color=blue]end[/color][/b] [b][color=blue]repeat[/color][/b]
[b][color=blue]return[/color][/b] [color=green]finalList[/color]
[b][color=blue]end[/color][/b] [b][color=blue]tell[/color][/b]
end tell
–-------- H A N D L E R S -----------
on roundThis (n , numDecimals )
set x to 10 ^ numDecimals
(((n * x ) + 0.5) div 1) / x
end roundThis
on [color=green]bubbleSort1/color
– sorts by X1
script bs
property alist : theList
end script
set theCount to length of bs ’s alist
if theCount < 2 then return bs ’s alist
repeat with indexA from theCount to 1 by -1
repeat with indexB from 1 to indexA - 1
if bounds_x1 of item indexB of bs ’s alist > bounds_x1 of item (indexB + 1) of bs ’s alist then
set temp to item indexB of bs ’s alist
set item indexB of bs ’s alist to item (indexB + 1) of bs ’s alist
set item (indexB + 1) of bs ’s alist to temp
end if
end repeat
end repeat
return bs ’s alist
end bubbleSort1
on [color=green]bubbleSort2/color
– sorts by Y1
script bs
property alist : theList
end script
set theCount to length of bs ’s alist
if theCount < 2 then return bs ’s alist
repeat with indexA from theCount to 1 by -1
repeat with indexB from 1 to indexA - 1
if bounds_Y1 of item indexB of bs ’s alist > bounds_Y1 of item (indexB + 1) of bs ’s alist then
set temp to item indexB of bs ’s alist
set item indexB of bs ’s alist to item (indexB + 1) of bs ’s alist
set item (indexB + 1) of bs ’s alist to temp
end if
end repeat
end repeat
return bs ’s alist
end bubbleSort2
–this handler uses the bounds to determine the frame width and height
on [color=green]GetSize/color
set theWidth to (((item 4 of theBounds ) - (item 2 of theBounds )))
set theWidth to my roundThis (theWidth , 3)
set theHeight to (((item 3 of theBounds ) - (item 1 of theBounds )))
set theHeight to my roundThis (theHeight , 3)
set the theSize to {width :theWidth , height :theHeight }
return theSize
end GetSize
[This script was automatically tagged for color coded syntax by Convert Script to Markup Code ]
This is complicated enough that I don’t believe it can easily be resolved without access to your test file. It’s not a glaring error, but I suspect that the rounding may be at issue - e.g., if the following is received as a result of the dimension check, your handler will round to 3, but not necessarily the expected match:
set x to 10 ^ 3
(((0.8755 * x) + 0.5) div 1) / x
This may or may not be the problem; as I said, it’s hard to test just by reading. You may want to see all the bounds after they’ve been processed through GetSize - you could test it by temporarily adding in a dialog to display the result.
harges
November 3, 2007, 6:13pm
#3
Thanks for your reply. I figured out my problem, when copying the tempList to ther finalList. I was not accounting for the fact that the templist was a list of lists, not a simple list of items. What I needed to do was copy it one item at a time to the finalList. So this:
set tempList to my bubbleSort2(tempList)
copy tempList to end of finalList
became ths:
set tempList to my bubbleSort2(tempList)
repeat with z from 1 to count of items in tempList
copy item z of tempList to end of finalList
end repeat
and that fixed the problem. My only problem now is that the script slows down considerably as it iterated through pages in the doc. I’ve added a repeat loop to have it sort boxes on all pages in the doc one page at a time. It starts off moving pretty quickly but slows to a crawl after the first cople paes. Not sure why as it should be repeating the exact same actions on each page. I would think that each page should take the same amount of processing time (provided of course that the pages contain the same number of frames, which they do).