I aplogize, I am very green when it comes to Applescript.
I am curious if the following scenario is possible using applescripting.
I make a lot of DVD trivia quizes, and often times I will have 100’s of questions that I make in photoshop. It is very tedious to say the least.
I would like to create a photoshop file that would serve as my trivia quiz template. This template would have a text layer for the question and a text layer for each answer option. There would also be a background image layer and forground image layer.
I would then like to create an excel file that has every question in one column and each answer posibillity in columns. Then there would be a column with background image, or the path to it and the last column with the foreground image.
Once I have completed my excel file, I would like a script that reads the data and assembles all of the questions and exports them as TGA image files.
I am hoping to create some trivia quizes with 1000’s of questions and I cant imagine doing it unless I can figure out how to write an automation script like I have described.
thanks so much for any help/advice that you might provide.
Ragfoo, welcome to the forum. I see no reason why your task could not be accomplished using AppleScript. Im not an Excel user so I can’t speak for how you could drive this from your database other than to save your data to list files. I have knocked together an example of how something like this can be worked in Photoshop from a few simple lists. My test file is constructed with text layers above a background layer and named like this:
The file is called “Question.psd” this should give you the basic idea of how to update the text content of layers, set the visibility options and save out a copy to file with renaming structure. Hope this helps get you going in the right direction.
tell application "Finder"
set MyTargas to make new folder at desktop with properties {name:"TARGA Images"}
end tell
set theFile to choose file with prompt "Where is the template file?"
--
set MyQuestions to {"What is the capital of France?", "What is the largest state in the US?", "In what continent is Brazil?", "What fruit is cider made from?", "In which month is Independence Day?", "What animal is the symbol of the WWF"}
set AnswerA to {"London", "Texas", "Europe", "Apple", "May", "Tiger"}
set AnswerB to {"Paris", "New York", "Africa", "Banana", "August", "Panda"}
set AnswerC to {"Madrid", "Florida", "North America", "Orange", "July", "Hippo"}
set AnswerD to {"Rome", "Kentucky", "South America", "Pear", "February", "Lion"}
set AnswerE to {"Lisbon", "California", "Asia", "Kiwi", "October", "Bear"}
--
repeat with i from 1 to count of MyQuestions
--
tell application "Adobe Photoshop CS"
activate
set display dialogs to never
set ruler units of settings to pixel units
open theFile
set docRef to the current document
set docName to name of docRef
set docBaseName to getBaseName(docName) of me
tell the current document
repeat with n from 1 to (count of layers) - 1
set properties of every layer to {visible:false}
set properties of background layer to {visible:true}
set properties of layer n to {visible:true}
set TextItemRef to text object of layer n
if name of layer n = "The_Question" then
set contents of contents of TextItemRef to (item i of MyQuestions)
end if
if name of layer n = "Answer_A" then
set contents of contents of TextItemRef to (item i of AnswerA)
end if
if name of layer n = "Answer_B" then
set contents of contents of TextItemRef to (item i of AnswerB)
end if
if name of layer n = "Answer_C" then
set contents of contents of TextItemRef to (item i of AnswerC)
end if
if name of layer n = "Answer_D" then
set contents of contents of TextItemRef to (item i of AnswerD)
end if
if name of layer n = "Answer_E" then
set contents of contents of TextItemRef to (item i of AnswerE)
end if
--
set x to name of layer n as string
set newFileName to (MyTargas as string) & docBaseName & "_" & i & "_" & x
save docRef in file newFileName as Targa with options ¬
{class:Targa save options, resolution:twenty four, RLE compression:true, save alpha channels:true} appending lowercase extension with copying
end repeat
end tell
close current document without saving
end tell
--
end repeat
--
-- Returns the document name without extension (if present)
on getBaseName(fName)
set baseName to fName
repeat with idx from 1 to (length of fName)
if (item idx of fName = ".") then
set baseName to (items 1 thru (idx - 1) of fName) as string
exit repeat
end if
end repeat
return baseName
end getBaseName
You are amazing. I wish I had discovered applscript earlier in my life so I could be an expert by now. If you have any more time you could donate, I would really like to understand how the script works. Reading through it I can see whats going on for the most part, but I am not familiar with applescript syntax, as simple as it my be.
The first thing I noticed about the script it exports a TGA file with only layer visible at a time, and it exports a TGA for each layer. I want the script to export 1 tga with both the question and answers visible so I changed the set all layers visibility from false to true. This didnt stop it from exporting a TGA for each layer, but now every 6th TGA is the fully composited question and answers.
Now Im stuck, at what is probably a very simple edit to have the script change all the layers before exporting a TGA. I thought by taking out the “end if” statement between all of the layer edits, and only have an end if after all the if statements would solve it, but I get an syntax error for the “end repeat” line.
How can I edit the loop to run through all of the if statements before exporting and repeating?
Also, I really like the list concept, I assume its possible to build lists, so am I right in thinking that I could read each field of a spreadsheet and append it to a list.
thank so much for helping me out,
ryan
***im making progress, i put the end repeat above the save file command, this plugs in every question and answer then exports the TGA - sweet
I cannot assist you with the Photoshop portion, but this script will extract the data from an Excel sheet that is already open:
set {master_data, dummy} to {{}, {}}
tell application "Microsoft Excel"
repeat with r from 1 to 2
repeat with c from 1 to 7
copy value of cell c of row r of active sheet to the end of dummy
end repeat
set end of master_data to dummy
set dummy to {}
end repeat
end tell
-->{{"Question A", "Ans 01", "Ans 02", "Ans 03", "Ans 04", "A Background", "A Foreground"}, {"Question B", "Ans 01", "Ans 02", "Ans 03", "Ans 04", "B Background", "B Foreground"}}
The questions are in column A, the responses are in columns B through E, and then the foreground and background data paths are in F and G. This script generates a master list of smaller lists of the question data, so looping through that should generate the data necessary to call up the Photoshop portion and speed things up nicely for you.
ryan, im no expert either and only started scripting some 6 months ago, a long time use of macs scripting has added a new dimension to the way I now work. If only I too had discovered it years ago then I could maybe claim to be a expert in the mean time just enjoying the learning. If I understand you correctly your requirements are simpler than I first thought, I didn’t know how your frames would interact. If you just want one file with all the Q&A visible we could get rid of the repeat in layers loop within the tell photoshop document and just set the text layer contents. Here is some updated syntax that should help you.
tell application "Finder"
set MyTargas to make new folder at desktop with properties {name:"TARGA Images"}
end tell
set theFile to choose file with prompt "Where is the template file?"
--
set MyQuestions to {"What is the capital of France?", "What is the largest state in the US?", "In what continent is Brazil?", "What fruit is cider made from?", "In which month is Independence Day?", "What animal is the symbol of the WWF"}
set AnswerA to {"London", "Texas", "Europe", "Apple", "May", "Tiger"}
set AnswerB to {"Paris", "New York", "Africa", "Banana", "August", "Panda"}
set AnswerC to {"Madrid", "Florida", "North America", "Orange", "July", "Hippo"}
set AnswerD to {"Rome", "Kentucky", "South America", "Pear", "February", "Lion"}
set AnswerE to {"Lisbon", "California", "Asia", "Kiwi", "October", "Bear"}
--
repeat with i from 1 to count of MyQuestions
--
tell application "Adobe Photoshop CS"
activate
set display dialogs to never
set ruler units of settings to pixel units
open theFile
set docRef to the current document
set docName to name of docRef
set docBaseName to getBaseName(docName) of me
tell the current document
set TextItemRefQ to text object of layer "The_Question"
set contents of contents of TextItemRefQ to (item i of MyQuestions)
set TextItemRefA to text object of layer "Answer_A"
set contents of contents of TextItemRefA to (item i of AnswerA)
set TextItemRefB to text object of layer "Answer_B"
set contents of contents of TextItemRefB to (item i of AnswerB)
set TextItemRefC to text object of layer "Answer_C"
set contents of contents of TextItemRefC to (item i of AnswerC)
set TextItemRefD to text object of layer "Answer_D"
set contents of contents of TextItemRefD to (item i of AnswerD)
set TextItemRefE to text object of layer "Answer_E"
set contents of contents of TextItemRefE to (item i of AnswerE)
--
set newFileName to (MyTargas as string) & docBaseName & "_" & i
save docRef in file newFileName as Targa with options ¬
{class:Targa save options, resolution:twenty four, RLE compression:true, save alpha channels:true} appending lowercase extension with copying
end tell
close current document without saving
end tell
--
end repeat
--
-- Returns the document name without extension (if present)
on getBaseName(fName)
set baseName to fName
repeat with idx from 1 to (length of fName)
if (item idx of fName = ".") then
set baseName to (items 1 thru (idx - 1) of fName) as string
exit repeat
end if
end repeat
return baseName
end getBaseName
hey guys, so here is where i stand with my script.
Ive modified the excel script so that it creates seperate lists that matches the list names of the first photoshop script. I couldnt figure out how to use a list of lists given what I had already.
So now what I have is a script that will read the first 5 columns of an already open excel spreadsheet. The number of rows to be read is defined in the script, I wasnt sure how I could have a popup ask how many rows to read down then plug that number into all of the list building commands, or even better automatically detect how many rows have information in them.
I dont know how to build the list of files paths to images then use that path in photoshop to paste an image into a layer. I dont know how to have a popup asking which excel file to open instead of need to open it before hand.
with out further ado, here is what I have.
tell application "Finder"
set MyTargas to make new folder at desktop with properties {name:"TARGA Images"}
end tell
set theFile to choose file with prompt "Where is the template file?"
--
set {MyQuestions} to {{}}
tell application "Microsoft Excel"
repeat with r from 1 to 20
copy value of cell 1 of row r of active sheet to the end of MyQuestions
end repeat
end tell
set {AnswerA} to {{}}
tell application "Microsoft Excel"
repeat with r from 1 to 20
copy value of cell 2 of row r of active sheet to the end of AnswerA
end repeat
end tell
set {AnswerB} to {{}}
tell application "Microsoft Excel"
repeat with r from 1 to 20
copy value of cell 3 of row r of active sheet to the end of AnswerB
end repeat
end tell
set {AnswerC} to {{}}
tell application "Microsoft Excel"
repeat with r from 1 to 20
copy value of cell 4 of row r of active sheet to the end of AnswerC
end repeat
end tell
set {AnswerD} to {{}}
tell application "Microsoft Excel"
repeat with r from 1 to 20
copy value of cell 5 of row r of active sheet to the end of AnswerD
end repeat
end tell
--
repeat with i from 1 to count of MyQuestions
--
tell application "Adobe Photoshop CS"
activate
set display dialogs to never
set ruler units of settings to pixel units
open theFile
set docRef to the current document
set docName to name of docRef
set docBaseName to getBaseName(docName) of me
tell the current document
repeat with n from 1 to (count of layers) - 1
set properties of every layer to {visible:true}
set properties of layer n to {visible:true}
set TextItemRef to text object of layer n
if name of layer n = "The_Question" then
set contents of contents of TextItemRef to (item i of MyQuestions)
end if
if name of layer n = "Answer_A" then
set contents of contents of TextItemRef to (item i of AnswerA)
end if
if name of layer n = "Answer_B" then
set contents of contents of TextItemRef to (item i of AnswerB)
end if
if name of layer n = "Answer_C" then
set contents of contents of TextItemRef to (item i of AnswerC)
end if
if name of layer n = "Answer_D" then
set contents of contents of TextItemRef to (item i of AnswerD)
end if
--
end repeat
set x to name of layer n as string
set newFileName to (MyTargas as string) & docBaseName & "_" & i & "_"
save docRef in file newFileName as Targa with options ¬
{class:Targa save options, resolution:twenty four, RLE compression:true, save alpha channels:true} appending lowercase extension with copying
end tell
close current document without saving
end tell
--
end repeat
--
-- Returns the document name without extension (if present)
on getBaseName(fName)
set baseName to fName
repeat with idx from 1 to (length of fName)
if (item idx of fName = ".") then
set baseName to (items 1 thru (idx - 1) of fName) as string
exit repeat
end if
end repeat
return baseName
end getBaseName
Ryan, had a bit more time to look at this. I have managed to create saved files “Questions.txt” “AnswerA.txt” etc and have the script read those which may be an option for you if others can’t help with the excel part. The text works great the only one im struggling with is providing file paths from a list its a “delimiter thing” and im not good at those. For some reason the first one works but then can’t find the second image to make alias. I have got it running with a choose folder of images just so you can see how to copy in another document to front layer then move it. I am presuming that you have run an action or script to size all of these files first otherwise some extra code would be needed to adjust this in each instance.
Below is my filepath text file if anybody could point out the obvious that I’ve overlooked. Many thanks
tell application "Finder"
set MyTargas to make new folder at desktop with properties {name:"TARGA Images"}
end tell
set theFile to choose file with prompt "Where is the template file?"
--
set theFileQ to alias choose file with prompt "Where are the Questions?" without invisibles
set MyQuestions to read (theFileQ) using delimiter {", "}
--
set theFileA to alias choose file with prompt "Where are the Answer A's?" without invisibles
set AnswerA to read (theFileA) using delimiter {", "}
--
set theFileB to alias choose file with prompt "Where are the Answer B's?" without invisibles
set AnswerB to read (theFileB) using delimiter {", "}
--
set theFileC to alias choose file with prompt "Where are the Answer C's?" without invisibles
set AnswerC to read (theFileC) using delimiter {", "}
--
set theFileD to alias choose file with prompt "Where are the Answer D's?" without invisibles
set AnswerD to read (theFileD) using delimiter {", "}
--
set theImages to alias choose folder with prompt "Where are the Image Files?"
--
repeat with i from 1 to count of MyQuestions
tell application "Finder"
set theFileB to (item i of theImages) as alias
end tell
--
tell application "Adobe Photoshop CS"
activate
set display dialogs to never
set ruler units of settings to pixel units
open theFile
set docRefA to the current document
set docName to name of docRefA
set docBaseName to getBaseName(docName) of me
--
open theFileB
set docRefB to the current document
delay 1
tell docRefB
duplicate layer "Background" to beginning of docRefA
end tell
close docRefB without saving
--
tell docRefA
set TextItemRefQ to text object of layer "The_Question"
set contents of contents of TextItemRefQ to (item i of MyQuestions)
set TextItemRefA to text object of layer "Answer_A"
set contents of contents of TextItemRefA to (item i of AnswerA)
set TextItemRefB to text object of layer "Answer_B"
set contents of contents of TextItemRefB to (item i of AnswerB)
set TextItemRefC to text object of layer "Answer_C"
set contents of contents of TextItemRefC to (item i of AnswerC)
set TextItemRefD to text object of layer "Answer_D"
set contents of contents of TextItemRefD to (item i of AnswerD)
--
translate layer 1 delta x 100
translate layer 1 delta y 200
--
set newFileName to (MyTargas as string) & docBaseName & "_" & i
save docRefA in file newFileName as Targa with options ¬
{class:Targa save options, resolution:twenty four, RLE compression:true, save alpha channels:true} appending lowercase extension with copying
end tell
close current document without saving
end tell
end repeat
--
-- Returns the document name without extension (if present)
on getBaseName(fName)
set baseName to fName
repeat with idx from 1 to (length of fName)
if (item idx of fName = ".") then
set baseName to (items 1 thru (idx - 1) of fName) as string
exit repeat
end if
end repeat
return baseName
end getBaseName
Found my stupid error and removed the spaces after comma in the list files. This now works as I wanted it to.
tell application "Finder"
set MyTargas to make new folder at desktop with properties {name:"TARGA Images"}
end tell
set theFile to choose file with prompt "Where is the template file?"
--
set theFileQ to alias choose file with prompt "Where are the Questions?" without invisibles
set MyQuestions to read (theFileQ) using delimiter {","}
--
set theFileA to alias choose file with prompt "Where are the Answer A's?" without invisibles
set AnswerA to read (theFileA) using delimiter {","}
--
set theFileB to alias choose file with prompt "Where are the Answer B's?" without invisibles
set AnswerB to read (theFileB) using delimiter {","}
--
set theFileC to alias choose file with prompt "Where are the Answer C's?" without invisibles
set AnswerC to read (theFileC) using delimiter {","}
--
set theFileD to alias choose file with prompt "Where are the Answer D's?" without invisibles
set AnswerD to read (theFileD) using delimiter {","}
--
set theImages to alias choose file with prompt "Where are the Image Files?" without invisibles
set thePaths to read (theImages) using delimiter {","}
--
repeat with i from 1 to count of MyQuestions
tell application "Finder"
set theFileB to (item i of thePaths) as alias
end tell
--
tell application "Adobe Photoshop CS"
activate
set display dialogs to never
set ruler units of settings to pixel units
open theFile
set docRefA to the current document
set docName to name of docRefA
set docBaseName to getBaseName(docName) of me
--
open theFileB
set docRefB to the current document
delay 1
tell docRefB
duplicate layer "Background" to beginning of docRefA
end tell
close docRefB without saving
--
tell docRefA
set TextItemRefQ to text object of layer "The_Question"
set contents of contents of TextItemRefQ to (item i of MyQuestions)
set TextItemRefA to text object of layer "Answer_A"
set contents of contents of TextItemRefA to (item i of AnswerA)
set TextItemRefB to text object of layer "Answer_B"
set contents of contents of TextItemRefB to (item i of AnswerB)
set TextItemRefC to text object of layer "Answer_C"
set contents of contents of TextItemRefC to (item i of AnswerC)
set TextItemRefD to text object of layer "Answer_D"
set contents of contents of TextItemRefD to (item i of AnswerD)
--
translate layer 1 delta x 100
translate layer 1 delta y 200
--
set newFileName to (MyTargas as string) & docBaseName & "_" & i
save docRefA in file newFileName as Targa with options ¬
{class:Targa save options, resolution:twenty four, RLE compression:true, save alpha channels:true} appending lowercase extension with copying
end tell
close current document without saving
end tell
end repeat
--
-- Returns the document name without extension (if present)
on getBaseName(fName)
set baseName to fName
repeat with idx from 1 to (length of fName)
if (item idx of fName = ".") then
set baseName to (items 1 thru (idx - 1) of fName) as string
exit repeat
end if
end repeat
return baseName
end getBaseName
This should clean up your Excel code a little bit:
set {MyQuestions, AnswerA, AnswerB, AnswerC, AnswerD} to {{}, {}, {}, {}, {}}
tell application "Microsoft Excel"
repeat with r from 1 to 20
copy value of cell 1 of row r of active sheet to the end of MyQuestions
copy value of cell 2 of row r of active sheet to the end of AnswerA
copy value of cell 3 of row r of active sheet to the end of AnswerB
copy value of cell 4 of row r of active sheet to the end of AnswerC
copy value of cell 5 of row r of active sheet to the end of AnswerD
end repeat
end tell
I think I can clean it up some more, just not tonight.