Automatically create shapes from a file/script

I have a project where I want to fiddle with relative layout of blocks. What I’d like to do is have a text file which specifies the width, height, and label of each shape, and have all the shapes automatically created so I can try different layouts.

Is there any easy way to do this? TIA

This isn’t exactly what you’re doing, but I happened to write this AppleScript for my own use today. You might be able to iterate off of it?
In my case, I used a verbose format to define each shape because that’s the format Xcode’s debugger prints a CGRect in. But I think the parsing is generic enough that you could simply define each shape by 4 numbers (x, y, width, height) in order, such as

0 258 254 2

instead of writing out “(origin =” etc. for each one.

(* copy/paste your Xcode output into rectText, then run this script on an OmniGraffle document with scale set to points.*)
set rectText to "
(origin = (x = 0, y = 258), size = (width = 254, height = 2))
(origin = (x = 0, y = 514), size = (width = 254, height = 2))
(origin = (x = 0, y = -510), size = (width = 254, height = 2))
"

set theDelims to items of "(),= abcdefghijklmnopqrstuvwxyz"
repeat with thisRect in paragraphs of rectText
	set maybeNumberList to my multiDelimSplit(thisRect, theDelims)
	display dialog maybeNumberList as text
	set numberList to {}
	repeat with maybeNumber in maybeNumberList
		if length of maybeNumber is greater than 0 then
			try
				set numberList to numberList & (maybeNumber as number)
			on error
				--			display dialog maybeNumber
			end try
		end if
	end repeat
	display dialog numberList as text
	if (length of numberList is equal to 4) then
		tell application id "com.omnigroup.OmniGraffle7"
			tell canvas of front window
				make new shape at end of graphics with properties {draws shadow:false, size:{item 3 of numberList, item 4 of numberList}, origin:{item 1 of numberList, item 2 of numberList}}
			end tell
		end tell
	end if
end repeat

(* The following method is copied from http://macscripter.net/viewtopic.php?id=24725 *)
on multiDelimSplit(theString, theDelims)
	set oldDelim to AppleScript's text item delimiters
	set theList to {theString}
	repeat with aDelim in theDelims
		set AppleScript's text item delimiters to aDelim
		set newList to {}
		repeat with anItem in theList
			set newList to newList & text items of anItem
		end repeat
		set theList to newList
	end repeat
	set AppleScript's text item delimiters to oldDelim
	return theList
end multiDelimSplit

Re-reading your question, you’ll definitely need to customize it, because my code is explicitly throwing away all alpha characters, and you’ll want to use those for your labels…

  • Remove a…z from theDelims
  • write each shape out with four numbers, then a space, then your label
  • add a line to grab the 5th element of maybeNumberList and stash it in a variable such as thisLabel
  • in the ‘make new shape…’ line, add some text formatting info, something like…
    text: {size: 16, alignment: center, color: {0.000000, 0.000000, 0.000000}, font: “HelveticaNeue”, text: thisLabel

Success! After some hacking I successful got the script to work. My script ended up as:

(* copy/paste your Xcode output into rectText, then run this script on an OmniGraffle document with scale set to points.*)
set rectText to "
0,258,128,128,Rect1
0,514,64,64,Rect2
0,-510,96,256,Rect3
"

set theDelims to items of “,”
repeat with thisRect in paragraphs of rectText
set numberList to my multiDelimSplit(thisRect, theDelims)
if (length of numberList is equal to 5) then
display dialog numberList as text
tell application id “com.omnigroup.OmniGraffle7.MacAppStore”
tell canvas of front window
set textItem to item 5 of numberList
make new shape at end of graphics with properties {draws shadow:false, size:{item 3 of numberList, item 4 of numberList}, origin:{item 1 of numberList, item 2 of numberList}, text:{size:16, alignment:center, text:textItem}}
end tell
end tell
end if
end repeat

(* The following method is copied from http://macscripter.net/viewtopic.php?id=24725 *)
on multiDelimSplit(theString, theDelims)
set oldDelim to AppleScript’s text item delimiters
set theList to {theString}
repeat with aDelim in theDelims
set AppleScript’s text item delimiters to aDelim
set newList to {}
repeat with anItem in theList
set newList to newList & text items of anItem
end repeat
set theList to newList
end repeat
set AppleScript’s text item delimiters to oldDelim
return theList
end multiDelimSplit

1 Like