Examples of AppleScript
From nswccWiki
In each of the examples given, what you are about to read is EXECUTABLE CODE ON A MACINTOSH COMPUTER. This is not documentation of executable code or PseudoCode. It is the code! Copy each one into your AppleScript Script Editor and run it.
| MacScripter is good source of information on Apple scripting. Download a free .pdf copy of the definitive AppleScript Language Guide from Apple (version 2.0). This is very easy to read with excellent examples of how to write and use core Applescript.
AppleScripting - Part II shows how to implement a simple state machine in AppleScript.
Scriptable Applications
Many applications on the Mac are scriptable. They can be driven by a script with the full power of AppleScript, including able to automate the process of transferring huge amounts of information between applications such as Microsoft Excel and FileMaker Pro and iCal. AppleScript is a one off programming language. It has features programmers both dread and almost die for. It is one of the few truly extensible programming languages. This is not lip service to the idea. Scriptable Applications act like "plug-ins" to the language adding syntax and behaviour. I know of no other language that even remotely behaves this way as yet.
Add-ins like .dll's are possible on a Mac. They are called OSAXen.
AppleScripting - Finder
AppleScripting -Finder is a simple AppleScript that automatically finds all mounted volumes (ejectable disk images), and then proceeds to eject them one by one.
AppleScripting - SerialPort
AppleScripting -SerialPort AppleScripts to use a serial port. The first is a front end "data logger" for up to 4 temperature sensors. The second is code for a tri-axial (X,Y,Z) accelerometer. It measure both static and dynamic acceleration simultaneously.
AppleScripting - what's the point of it all?
AppleScript (Apple Events) will be recognised as one of the most far-sighted software engineering projects ever undertaken. If we were limited to ONE sentence about it that recognises this, the sentence would be something like: AppleScript clearly bridges the gap between what is written and what is spoken. Think about that for a moment. Apple are now focussing on bridging the gap between what is gestured and what is seen. Stay tuned to see how this will be integrated with AppleScript. The result would be nothing short of amazing!
There have been many reported instances of: "AppleScript is very easy to read but very difficult to write". True, I say. But to counterbalance that I would say almost every other computer language is difficult to read and difficult to write. Now here's the clincher. Add to the mix, speech! Now do you see the point of it all!. Most computer languages are even more difficult to speak than klingon with a mouth full of spaghetti noodles.
As soon as I saw some AppleScript, I knew immediately it was different; very different. I investigated it's beginnings and came to realise that it had a very difficult birth, an even more difficult infancy and has almost gone into hiding in its childhood. It is one of a very few that were incubated in a commercial environment rather than an academic environment, although its "DNA" is clearly from academia. It will mature. It will become a dominant mode of communicating with computer technology.
The designers tried something spectacularly daring: build a very small core of fundamental English-like language on top of a very lean communication protocol. Embed it at the core of the operating system. Make it able to communicate with the OS and applications, by exposing some of the objects(nouns) of the applications and their methods(verbs). Bind this all together as though it was written in English. Now provide each application with the ability to extend the core by carrying a vocabulary that can be used, in context, by AppleScript. And just to really make it difficult, try this between two computers connected via a network. Really think hard about that for two moments. This is where some of the modern internet protocols, such as SOAP were born.
OK it has not worked so well for a number of reasons. But the intention is there, and many application developers could have made better use of linguists. AppleScript does work but only if you forgive its rough edges.
So, does its communication model extend to an area that you might not expect? Yes. It has been used to "do geometry" linguistically and graphically. Here is a simple example:
-- Ian W. Parker 2008-07-01, last updated 2008-07-01
-- Geometry-01 - find perpendicular bisector of a line segment
-- requires Satimage Geometry OSAX installed
-- these results can be calculated algebraically...
-- however, using AppleScript, we have a kind-of linguistic bridge!!!
-- ---------------------------------------------------------------------------------------------
property degrees : 360 / (2 * pi) -- conversion factor between radians and degree
set point_1 to {0, 0} -- the start point {x1,y1}
set point_2 to {100, 100} -- the end point {x2,y2}
set x to line from {point_1, point_2} -- find starting point and angle
set a to (angle of x) * degrees -- convert to degrees
-- find perpendicular bisector line starting point and angle
set y to perpendicular bisector of {point_1, point_2}
set b to (angle of y) * degrees -- convert to degrees
-- report the result: start point, end point,
-- bisector point, parallel angle of segment, normal angle of bisector (= 360 - parallel angle)
set z to {point_1, point_2, {bis_point:point of y, par_angle:{a, "°"}, nor_angle:{b, "°"}}}
--result is {{0, 0}, {100, 100}, {bis_point:{50.0, 50.0}, par_angle:{45.0, "°"}, nor_angle:{135.0, "°"}}}
AppleScripting-Much a do about object oriented programming style(OOPs)
The polemics of the object oriented paradigm vs the- well, other way of doing things- debate has all but abated and OOPs it seems is the 'one true way' to write good programs. But what could this really mean, especially for someone who cares little about the merits of C++ vs C. Firstly I am not a strong advocate of OOPs, except where the language positively encourages you to write OOP. You may not consider AppleScript to be an OOPs language. But you'd be wrong. AppleScript is a language that positively encourages OOPs.
Here is a script that clearly demonstrates the value of OOPs. The script contains an object building script "define_device" to construct objects modelling the control set of a very cheap 10 MHz oscilloscope from Dick Smith Electronics. The control set is generic and may easily be applied to other oscilloscopes. It may also be extended using the patterns in the object properties and methods. The concepts here obviously go to the heart of the OOP paradigm.
The first executable line defines or "cookie cuts" an object, and gives it an actual name, by instantiating the myName property of the object called Oscilloscope_1. The myName property value, and the name of the object are different here but could be the same. The next 6 lines, bounded by the < tell Oscilloscope_1 ... end tell > exercise the properties and 2 methods of the object.
tell Oscilloscope_1 to]_ report on its settings is an example of reflection where the object dumps its settings in the form of a record of, well, its settings. You have to be careful here because AppleScript can be made to look awfully like English-which it really is not. We can be more specific with the target by using a form of __property of settings__, such as __tell Oscilloscope_2 to report on the intensity of its settings__. If you read the script a number of time you will appreciate the power of AppleScript. A hint is to take what you read at face value - it does what you think it does! Better still, copy it into the Script Editor (for AppleScript), click-on run and see the result. You should see "Mid". Next comment out the lines from -- now cut another object to -- ----------------------------- end of runnable code -------------------------- and observe the result. Look carefully for any changes! make some changes, observe the result!
Clearly there is scope for developing some very interesting OOPs here.
-- 2008 Ian W. Parker, demonstration of AppleScript's OOP features
-- define characteristics of instrument: oscilloscope, take model as DSE Q1803
-- first worked on: 2000-06-30 last worked on 2008-05-02
-- cut an object, tell it to do some things
set Oscilloscope_1 to define_device({myname:"Oscilloscope-" & "DSE-Q1803"})
tell Oscilloscope_1
setup() -- adjust the controls to startup condition
set Focus of its settings to "Fully Left" -- adjust one control
set VertAmp of its settings to "2V/Div" -- adjust another control
report on its settings -- uses prepositional form of parameters
end tell
-- now cut another object
set Oscilloscope_2 to define_device({myname:"Oscilloscope-" & "DSE-Q1803"})
-- tell the second object to do something specific
tell Oscilloscope_2 to report on the intensity of its settings -- will set result to "Mid"
-- ----------------------------- end of runnable code --------------------------
on define_device(aname)
script buildDevice
-- properties
property settings_1 : {AC_GND_DC:"GND", ON_OFF:"OFF", Focus:"Mid"}
property settings_2 : {intensity:"Mid", VertShift:"Mid"}
property settings_3 : {VertAmp:"1V/Div", HorizShift:"Mid"}
property settings_4 : {Trigger_Level:"CounterClockwise", TriggerSelect:"Auto"}
property settings_5 : {TimeBase:"20 ms", Time_Base_Vernier:"Fully Right"}
property settings : settings_1 & settings_2 & settings_3 & settings_4 & settings_5
property myname : aname
-- methods
to setup() -- reconstruct basic parameters and initial situation
local settings
set AC_GND_DC of my settings to "GND"
set ON_OFF of my settings to "OFF"
set Focus of my settings to "Mid Position"
set intensity of my settings to "Fully Right"
set VertShift of my settings to "Mid"
set VertAmp of my settings to "1V/Div"
set HorizShift of my settings to "Mid"
set Trigger_Level of my settings to "Fully right"
set TriggerSelect of my settings to "Auto, internal(+ve)"
set TimeBase of my settings to "20 ms"
set Time_Base_Vernier of my settings to "Fully Right"
end setup
-- syntax when used: report on [<aSetting> of] its settings
to report on aSetting
return aSetting
end report
end script
end define_device
AppleScripting - Interrogating current print queue status for a Macintosh
The current print queue status of all print queues on a Macintosh can be interrogated using this short AppleScript. It quickly reports the name, type and current status of every active print queue. This could prove very useful for a system administrator wanting to check workstations on a local network. On the other hand if you have Apple Remote Desktop, then you do not need this script.
-- Ian Parker 2008 first worked on 2007-01-09, last worked on 2008-01-23
-- get a list of all print queues on this machine, with current status
tell application "Printer Setup Utility"
activate
-- the printer queue details on this machine are returned as a list
set {printerDetails, fullDetails} to {"", {}}
set printerlist to every printer -- to get details of every print queue
-- extract details and compose message
repeat with nextprinter in printerlist
set printer_details to properties of nextprinter
set printerDetails to {name:name of nextprinter, Type:kind of nextprinter}
set printerStatus to status of nextprinter
set fullDetails to fullDetails & {InstalledPrinter:printerDetails, Currently:printerStatus}
end repeat
-- fullDetails is a list, each item describes a print queue with sample result of ...
-- {InstalledPrinter:{name:"HP Color LaserJet 2600n", Type:"HP Color LaserJet 2600n"}, Currently:<idle> | <printing>}
-- <printing> indicates the printer is processing at least one job, or stalled queue
-- <idle> indicates the printer has cleared every job is in the queue
end tell
This script shows how easy it is to enumerate and collect information about aspects of the machine using the Printer Setup Utility application. There is also a large number of system properties that may be interrogated using System Profiler. However extracting specific items from System Profiler can be tedious.
AppleScripting - Auto select Printer and Internet Access for Laptop
This next example makes it easy for a novice user (eg visitor to site) to configure the network settings and printer settings for a laptop. The idea is that they need to change the printer and network settings according to where they are working: some place on site, or at home. This reduces the task to selecting from a pick list that only refers to the location. of course you will need to customise it for your own situation.
-- V 1.1.0 MANAGE PRINTER ACCESS for Apple Macintosh MacOS 10.4.x on Intranet
--
-- Copy (saved as app) to each machine in apps folder. Set as the last "startup" item for user
-- ------------------------------------------------------------------------------------------------------
-- © Ian Parker 2005, First worked on: 18 Apr 2005, last worked on: 29 Sep 2005
-- WHAT IT DOES:
-- 1. get list of all known printers on this machine (eg. network printers)
-- does not auto discover any printers but gets list of INSTALLED PRINTERS
-- 2. get workstation name, truncate, leaving first 3 characters as location ID
-- 3. loads a reference list of printers that can be altered (see 'printer_list' below)
-- 4. scans 'printer_list', looking for a match of the 3 char workstation abbrev.
-- also builds 'have-printer' list (in 'known_printers' AND 2nd entry of 'printer_list')
-- OPTIONAL
-- 5. if successful match to 3 char workstation abbrev. assigns current printer
-- 6. user can accept default or choose printer - 5 second timeout
-- this can be used to act as an available printer filter
-- 7. give the user a pick list based on info strings (here rooms)
-- 8. set user picked printer
-- --------------------------------------------------------------------------------------------------------
-- 'standard printer list'. Note the necessary double curly quotes
-- triad is: 3 char prelude abbrev. of workstation (eg "D14" from "D14-05", "Gan" from "Gandalf")
-- name of printer (eg. "10.x.y.z" - assigned when using Printer Setup Utility)
-- user info string (you set here- will be presented to the user)
set printer_list to {}
set printer_list to printer_list & {{"B03", "10.x.y.z", "in Room B03"}} -- printer in B03
set printer_list to printer_list & {{"ScS", "10.x.y.z", "in Room Science Staff"}}
set printer_list to printer_list & {{"Gan", "HP Color LaserJet 2600n", "at home"}}
-- --------------- no need to alter anything below this line --------------------------
tell application "Printer Setup Utility" to set known_printers to every printer's name -- get all installed printers
set Workstation to computer name of (system info) -- extract name from info record of this machine
set myWorklocation to (characters 1 thru 3 of Workstation) as string -- key on first 3 characters
set have_printers to {}
-- select default printer based on workgroup prefix
repeat with next_printer in printer_list
set {place_locn, printer_name, user_info} to next_printer --as list -- split and assign variables
if printer_name is in known_printers then set have_printers to have_printers & user_info
-- assign printer
if place_locn is myWorklocation then tell application "Printer Setup Utility" to set current printer to printer printer_name
end repeat
-- tell user. has 5 seconds to decide to change...
display dialog "Assigned printer and location: " & user_info with icon caution buttons {"OK", "Choose"} giving up after 5
--
-- OPTIONAL --- if removed clicking on either button will have no effect
if button returned of result is "Choose" then
-- base selection on location. A location field for printers but no access to it in AppleScript
set user_selected to choose from list have_printers with prompt "Where are you working?"
repeat with next_printer in printer_list -- walk the list
set {place_locn, printer_name, user_info} to next_printer as list -- split list and assign
-- compare user picked name with current name
if user_info is in user_selected then -- we have a match so...
tell application "Printer Setup Utility" to set current printer to printer printer_name
end if
end repeat
end if
-- END OF OPTIONAL -------------------------------------------------
tell application "Printer Setup Utility" to quit
-- from an Apple UI Element Script -Set Network Location-3 Jul 2005
tell application "System Events"
-- assumes Enable Access for assistive devices in Universal Access pane of Sys Prefs ticked
-- got to be a "kludge"
try
if printer_name is "HP Color LaserJet 2600n" then
-- I am at home and so...
click menu item "Home-Telstra" of menu "Location" of menu item "Location" of menu "Apple" of menu bar 1 of process "Finder"
else
-- I am at work and so...
click menu item "Work-Ethernet" of menu "Location" of menu item "Location" of menu "Apple" of menu bar 1 of process "Finder"
end if
on error
display dialog "Location not changed-please open System Preferences>Universal Access. Click \"Enable Access for assistive devices\" " with icon caution buttons {"OK"}
end try
end tell
AppleScripting - iCal-1
A simple AppleScript to create an event for iCal, providing the following fields: Title, url, a note, and assigns 3 attendees to the event. Because this example assigns to the standard “Home” calendar, with the start date and end date both on 6th Jan 2007 (well in the past) it should do no harm to an operational setup. There is no error checking of date-time ordering.
-- ---------------------------------------------------------------------------------
-- Example for iCal Sample Entry, Ian W. Parker 2007
-- ---------------------------------------------------------------------------------
set full_day to false -- a flag to indicate not an all day event
set attendeeList to {"First Person", "Second Person", "Third Person"}
set theCal to "Home" -- sample standard calendar name
-- ---------------------------------------------------------------------------------
tell application "iCal"
-- assign event properties, should check and ensure start < end
set theSday to date "Saturday, 6 January 2007 12:00:00 PM" -- start event
set theEday to date "Saturday, 6 January 2007 2:00:00 PM" -- end event
set the_text to "Title for new Event"
set assoc_url to "http://server/folder/page.htm"
set loc_n to "The event location" -- where the event will take place
set event_notes to "the notes for the event"
-- build properties record and make before we assign attendees
set the_info to {allday event:full_day, summary:the_text, description:event_notes}
set the_info to the_info & {location:loc_n, url:assoc_url}
set the_info to the_info & {start date:theSday, end date:theEday}
set newEvent to make new event at end of events of calendar theCal with properties the_info
-- -------- ----------[ process attendee list ]------------------------------
repeat with nextitem in attendeeList
make new attendee at end of newEvent
set (display name of last attendee) of newEvent to nextitem
end repeat
reload calendars -- make sure the display is up to date
switch view to month view -- subs 'week' or 'day' as desired
end tell
-- ---------------------------------------------------------------------------------
AppleScripting - iCal-2
A simple AppleScript to create a calendar and a predefined set of events. This would be useful for establishing a project workgroup calendar which can then be modified. Could also be distributed across a LAN as a RUN-ONLY executable. As always there are many ways to achieve a result.
-- Ian W. Parker, 2008, first worked on: 2007-04-19 last worked on 2008-02-22
-- loads iCal with a NEW calendar and predefined set of events (for a project)
-- initialise a workgroup calendar, becomes part of iCal and editable from iCal
-- could be easily distributed across a network as a run-only application
-- -------------------------------------------------------------------------------------------------------
-- format of event list
-- {"<event-title>", "<date-time>","<url>",<alarm-days-prior>, <alarm-hours-prior>}
set event1 to {"Year 07", "Staff Room", date "Tuesday, 29 May 2007 12:15:00 PM", "http://host/faculty/page-01.htm", 2, 2}
set event2 to {"Year 08", "Common Room", date "Tuesday, 29 May 2007 2:20:00 PM", "http://host/faculty/page-02.htm", 2, 2}
set eventList to {event1, event2} -- accumulate events into a list
-- format of schedule call:
-- Schedule("<calendar-title>","<calendar-description>", event list}
Schedule("Review", "Assessment", eventList)
-- --------------------------------------------------------------------------------------------------------
on Schedule(ProjectName, ProjectArea, eventList)
tell application "iCal"
activate
if (calendar ProjectName exists) then -- delete an existing project "Review" calendar
delete calendar ProjectName
end if
-- create new project calendar
set theCal to make new calendar at ¬
end of calendars with properties {title:ProjectName, description:ProjectArea}
tell theCal -- ie target the new calendar
repeat with nextitem in eventList
set eventInfo to item 1 of nextitem -- name of event
set RevueLocn to item 2 of nextitem -- meeting location
set sDate to item 3 of nextitem -- start date (or time)
set eDate to sDate + 60 * minutes -- end date (ie. + start_time + 1 hour)
set urlInfo to item 4 of nextitem -- url page reference for more info
set trigger01 to item 5 of nextitem -- alarm trigger 1 (days before)
set trigger02 to item 6 of nextitem -- alarm trigger 2 (same day)
-- target the new event of the new calendar
tell (make new event at end of events ¬
with properties {start date:sDate, end date:eDate, summary:eventInfo, location:RevueLocn, allday event:false, url:urlInfo})
-- trigger interval is in minutes: ( -60*24) = 1 day before
make new display alarm at ¬
end of display alarms with properties {trigger interval:-60 * 24 * trigger01}
-- trigger interval is in minutes: ( -60) = 1 hour before
make new sound alarm at end of sound alarms ¬
with properties {trigger interval:-60 * trigger02, sound name:"sousumi"}
end tell
end repeat
end tell
-- reconcile display with database
reload calendars
end tell
-- to signal successful completion ...
beep 3
end Schedule
AppleScripting - Skim
“Skim” is a PDF Reader that all teachers using Macs should have. It can be downloaded from http://skim-app.sourceforge.net . As a simple example, I have been asked on at least one occasion to refer to “key verbs” in “dot points” of NSW syllabuses. This AppleScript scans the NSW Physics Syllabus document located on your desktop for occurrences of two words: “formulate” and “investigation”. It then creates an index list shown below the program. How fast: on a PPC mac Mini it takes a few seconds to do the two scans! The list, of course, could be used for further processing such as embedding in a web ontology document. “Skim” has other features like writing notes into a PDF document and add and edit bookmarks.
-- Ian W Parker, First worked on 2007-10-06 Last worked on 2007-10-06
-- Scan a PDF document using "Skim" looking for key words and make a list
-- {"keyword", page no1, page no2, ...}
-- capable of finding multiple words, using multiple passes
-- uses native AppleScript to search a string containing text from a single page
-- rather than "Skim"'s find command
-- in this example we skim the NSW physics syllabus for "formulate"
-- and "investigation"
-- ------------------------------------------------------------------------
set pageList to {"formulate", "investigation"} -- could be extended
set {pageList1, pageList2} to {{}, {}} -- set up emply lists
tell application "Skim"
set myPath to path to desktop as string -- assumes on your desktop
open (myPath & "physics_stg6_syl.pdf") -- open the file to scan
tell document 1
set view settings to {display mode:single page} -- one up
set all_pages to count of pages -- so we only calculate it once
repeat with nextitem in pageList -- pull out a key word at a time
set pageList1 to {} -- clear the list for this pass
repeat with i from 1 to all_pages --
go to page i -- only to see it in action, comment out to speed up (a little)
set y to (get text for page i) -- suck up the text into a string!
ignoring hyphens
set y to (every word of y) as list -- tokenise!
end ignoring
if y contains nextitem then -- record page number if word on page
set pageList1 to pageList1 & "," & {i - 1}
end if
end repeat
set pageList2 to pageList2 & {nextitem & pageList1} -- concat list
end repeat
end tell
end tell
set x to pageList2 -- to show up in the Script Editor Event Recorder
-------------------------------------------------------------------------------------------------------
RESULT: {"formulate,20,40", "investigation,8,13,16,17,18,19,22,23,24,25,27,28,29,31,32,37,38,39,41,42,44,46,47,48,49,50,51,52,53,54,55,56,57,60,61,62,63,64,66,68,71,73,75"}
--------------------------------------------------------------------------------------------
AppleScripting - Journler
This next script requires | Journler to be installed. The script automatically builds a generic work environment suitable for a high school teacher. The purpose is to show how ‘real’ scripts are built from code snippets and the AppleScript Dictionary entries found in AppleScrpit enabled applications. This script tries to find a folder called “@Trak 2007” in your Documents folder but will revert back to asking you where it is- any folder can be a link target. “@Track 2007” is a work folder I use the folder as a location for my current work files. The script does not alter the folder or contents in any way.
-- ----------------------------------------------------------------------------------
-- Example, Journler Setup for use by a high school teacher, 2007 Ian W. Parker
-- Can be installed in the Journler Menu as a pull-down item
-- Several lines have been split to make the listing flow in the Wiki
-- ---------------------------------------------------------------------------------
set myCategories to {"Lesson", "Task"}
set myName to "<name>" -- obviously substitute actual name here
set targetUrl to "http://localhost/welcome.php" -- can be ANY valid url
set ClassList to {"Class-01", "Class-02", "Class-03", "Class-04", "Class-04"}
set ClassList to ClassList & {"Class-05", "Class-06"}
set myCollections to {"School", "Faculty-01", "Faculty-02"} & ClassList
-- next two lines should be on one line
choose from list myCollections with title "Choose from list..." with prompt ¬
"Entry for..." OK button name "OK" cancel button name "Cancel" default items "School"
set myTitle to the result
--set myTitle to item 1 of myCollections and construct a picklist of categories...
-- next three lines should be on one line as a single instruction!
set myCategory to (choose from list myCategories with title ¬
"Choose from list..." with prompt "Link entry to..." OK button name ¬
"OK" cancel button name "Cancel" default items "Lesson") as string
--
set today to current date -- capture today right NOW!
set workDate to today -- copy date
set workfolder to "@Trak " & year of workDate -- -- eg. @Trak 2007
set myOutline to "" -- clear by default
-- ------------------------------------------------------------
-- LESSON SCAFFOLD V0.2 -editable, this is how it compiles...
-- ------------------------------------------------------------
if myCategory is "Lesson" then set myOutline to "
---------------[ Lesson Plan ]------------
Preparation
Ordered Equipment
Materials
Do
-------------[ Delivered: ] ------
1. Phase I - context
2. Phase II - construction
3. Phase III - consolidation
______________________________________
Review"
set myPrompt to ("Started:" & today & myOutline) as text
-- ----------------------------------------------------------------------
tell application "Journler"
activate
set selected date to current date -- show current date information
open journal viewer
repeat with nextCollection in myCollections --to (re-)construct work collection folder set
if not (folder nextCollection exists) then --(re-)build default context item
set newFolder to make new folder
set name of newFolder to nextCollection
end if
end repeat
-- construct a new entry
set categories to myCategories --redefine list of collections
-- make new entry with predefined properties, join record like this for short lines
-- default pending is for 2 days time
set entryProperties to {name:myTitle, date created:current date, date due:today + 2 * days}
set entryProperties to entryProperties & {rich text:myPrompt, category:myCategory, tags:myTitle, mark:flagged}
set theEntry to make new entry with properties entryProperties
-- add a link directly to first folder in myCollections list
set resourceProperties to {name:myName, type:website, owner:theEntry, url:targetUrl}
set theResource to make new resource with properties resourceProperties
tell application "Finder"
try -- to get at the @Trak files
set the aFile to (folder workfolder of folder "Documents" of home) as alias
on error -- folder does not exist yet so...
activate
set aFile to choose folder
end try
end tell
--make new resource if user did not abort selection
if the result is not false then
set resourceProperties to {owner:theEntry, type:media, original path:aFile, aliased:yes}
set aResource to make new resource with properties resourceProperties
end if
-- ----------------------------------------------------------
-- finally update the Journler database and display
-- ----------------------------------------------------------
save changes
activate
end tell
-- ------------------------------------------------------------------------------
AppleScripting - Voice Recognition (activation)
Voice recognition of commands comes "straight out of the box" with MacOS X 10.4. This next example requires voice recognition to be activated in the speech pane of System Preferences. It allows you to activate iCal by voice command. The obvious use in education is for disabled students...but ... Interestingly, I've experimented with a set of commands {Calendar, Diary, Daybook} and voice activation is FASTER and MORE ACCURATE. I can't wait to have a conservation with my computer. I kid you not!
Of course there must be a microphone connected. Any application could be substituted, with an appropriate prompt...
-- Sample speech Recognition-01 ©2007 Ian W. Parker
-- requires a connected and activated microphone
tell application "SpeechRecognitionServer"
try
set spoken to listen continuously for {"Yes"} with identifier "1" with prompt "Open Calendar"
on error number -32766
stop listening for identifier "1"
say "I don't have a sound input device connected "
end try
end tell
try
if "Yes" is spoken then tell application "iCal" to activate
on error
say "I could not find iCal, " with waiting until completion
end try
say " OK"
This second script implements the {Calendar, Diary, Daybook} with voice activation.
-- Speech Recognition - 02
-- © 2009 Ian W. Parker, First Worked on 2007-04-15 last Worked on 2009-07-25
-- requires a connected and activated microphone
-- first check Speech control panel
-- the listening key should be <exc>
-- to use this application: press and hold down <esc> key
-- then speak (respond) "Diary" or speak "Calendar" or speak "Register"
--(assuming the current year is 2009 and the folder exists)
set workfolder to ((path to documents folder from user domain) as string) ¬
& "@Trak " & year of (current date)
-- these are files in: < User>/Documents/@Trak 2009
set DiaryFile to "Daybook.FP5"
set MarkBookFile to "Register.xls"
--
tell application "SpeechRecognitionServer"
try
set spoken to listen continuously for {"Diary", "Calendar", "Register"} ¬
with identifier "1" with prompt "Diary, Calendar, or Register"
-- Diary
if "Diary" is spoken then
tell application "Finder"
set current_location to (folder workfolder of folder "Documents" of home)
set current_location to ((current_location as string) & DiaryFile) as alias
open current_location
end tell
end if
-- Calendar
if "Calendar" is spoken then tell application "iCal" to activate
-- Register
if "Register" is spoken then
tell application "Finder"
set current_location to (folder workfolder of folder "Documents" of home)
set current_location to ((current_location as string) & MarkBookFile) as alias
open current_location
end tell
end if
on error
say "No microphone connected. Please connect a microphone."
stop listening for identifier "1"
end try
end tell
AppleScripting - Constructing a Term Roll for a class
This one has taken me about 6 years to develop! It has some interesting nuances. Try running it and responding only with a <return> where appropriate. Then with Excel still open run it again but respond with what you expect to be reasonable data. Dates should be in the format dd/mm/yy if you can't supply it in any other format. The resulting template can be directly transferred to a PC running Excel. It has been tested!
-- FORMAT EXCEL SPREADSHEET AS CLASS ROLL by Ian Parker © 2001-2007
-- first worked on 01-07-21 --last worked on 07-08-28
-- requires recent version of MS Excel (up to v.X but not beyond!!) to be installed
-- make sure there is only ONE copy of ONE version!
-- does NOT work on MS Excel 2004+ (significantly altered syntax)
-- creates template for a class roll with automatic
-- counted coded entries ['a' - absent, 'x' - lack of effort ]
-- ['e' - excellent, 's' - behaviour infringement]
-- you just place a code letter in the appropriate cell, it will be counted at end
-- you to export the resulting template to other Macs AND PCs running Excel
-- contains some good examples of AppleScript driving Excel
global endCellC, beginCellR, beginCellC, endCellR, lastCellC
set {theStartDay, weeksInTerm, myclass} to {date string of (current date), 10, "xyzxyz"}
set columnOffset to 5 -- columnOffset -> begin calendar
set startRow to 3 -- offset
set endRow to startRow + 30 -- no of students
---------------------------------------------------------------------------
-- the date embedded in Excel is AppleScript full date format (NOT DISPLAYED DATE FORMAT)
display dialog "Enter Date to begin Sequence" default answer theStartDay
-- get text version of the date, and default to today!
set theStartDay to date (text returned of the result)
-- ask user for term information
display dialog "Enter Term Number {1, 2, 3, 4}" default answer 1
set termNumber to (text returned of the result) as number
-- ask user for how many weeks; we also accept a final date
display dialog "Enter number of weeks in term or last Date" default answer weeksInTerm
try
-- a properly formatted date will produce an error when coercing to a number
set weeksInTerm to (text returned of the result) as number
on error
-- so assume that we can't coerce into a date and return weeksInTerm as a number
set theEndDay to date (text returned of the result)
set weeksInTerm to ((((theEndDay - theStartDay) / weeks) div 1) + 1)
end try
-- ask user for name of the class
-- -----------------------------------------------------------------------------
display dialog "Enter name of Class" default answer myclass
set myclass to text returned of the result
-- the heavy work routine - drive excel to do the work
-- -----------------------------------------------------------------------------
tell application "Microsoft Excel"
Activate
try
Create New Sheet After last Sheet
Select last Sheet
-- assume Excel ready: compose the class name {location, size and orientation}
on error
--if Excel is open but not currently selected....
Create New Workbook
end try
-- ---------- a bit of auto magic for the lazy ------------------
repeat
try
set Name of last Sheet to " Attendance Term " & termNumber
Select last Sheet
exit repeat
on error
set termNumber to termNumber + 1
end try
end repeat
Select Cell ("R" & startRow - 2 & "C1")
set Selection to "Term: " & termNumber
-- Excel constants, 90°orientation, Verdana, 18 pt., centred...plant name of class
Select Cell ("R" & startRow & "C1")
set Orientation of Selection to 90
set {Name of Font of Selection, Size of Font of Selection} to {"Verdana", 18}
set {HorizontalAlignment of Selection, FormulaR1C1 of Selection} to ¬
{xlCenter, myclass}
-- plant the roll group label ---------------------------------
Select Cell ("R" & startRow & "C3")
set {HorizontalAlignment of Selection, Orientation of Selection} to ¬
{xlCenter, xlUpward}
set ColumnWidth of Selection to 4 -- slightly wider to accomodate 3 chars.
-- an insertable block
set Selection to "Roll Group"
-- ---------------------------------------------------
-- added 29/12/04
Select Cell ("R" & startRow & "C4")
set {HorizontalAlignment of Selection, Orientation of Selection} to ¬
{xlCenter, xlUpward}
set ColumnWidth of Selection to 4 -- slightly wider to accomodate 3 chars.
set Selection to "Textbook No."
-- find the number of days to loop -- corrected 07-07-22
set endIndex to (weeksInTerm * 7)
-- -----------------------------------------------------------------------
-- the grand loop
repeat with myIndex from 0 to endIndex
-- set up cell reference
set colRef to myIndex + columnOffset
-- take care of the begining and ending columns...
if myIndex = 0 then set {beginCellR, beginCellC} to {startRow, colRef}
if myIndex = endIndex then set {endCellR, endCellC} to {endRow, colRef}
Select Cell ("R" & startRow & "C" & colRef)
-- format the columns
set {Orientation of Selection, NumberFormat of Selection} to ¬
{xlUpward, "dd-mmm-yy"}
-- note "days" is a conversion unit built-in later version (1.4+) of AppleScript
-- set days to 7 -- if next line causes a fault uncomment this line
set mydate to theStartDay + myIndex * days
---------------------------------------------------------------------
-- extract the string to put in the cell
set currentColumn to weekday of mydate as string
-- -------------------------------------------------------------------
-- is it a weekend -fill
if ({"Saturday", "Sunday"} contains currentColumn) then
--------------------------------------------------------------
-- set up the cell reference... (to a single cell !)
Select Range ¬
("R" & startRow & "C" & colRef & ":R" & endRow & "C" & colRef)
---------------------------------------------------------------
-- colour fill, canary yellow= colour 36, width to 1 unit (weekends)
-- amended
set Pattern of Interior of Selection to xlSolid
----------------------------------------------------------
set ColorIndex of Interior of Selection to 15
set {ActiveCell, ColumnWidth of Selection} to {"", 1}
else
-- what we do if a work day. Plant the week label at Wednesday
-- week label is relative offest from the date row
-- ------------------------------------------------------------------
if currentColumn is "Wednesday" then
-- plant the week number
Select Range ¬
("R" & startRow - 1 & "C" & colRef & ":R" & startRow - 1 & "2C" & colRef)
-- find the integer value of myIndex then add 1 (index begins with week 1)
set ActiveCell to "Week: " & ((myIndex div 7) + 1)
end if
-- ---------------------------
-- weekday widths are set to 3
Select Range ("R" & startRow & "C" & colRef & ":R" & endRow & "C" & colRef)
-- -------------------------------------------------------------
-- active cell is the anchor cell in a range!
set {ActiveCell, ColumnWidth of Selection} to {mydate, 3}
-- ---------------------------
-- colour fill with transparent
set {Pattern of Interior of Selection, ColorIndex of Interior of Selection} to {xlSolid, 0}
end if
end repeat
-- --------------------------------------------------
-- end of sheet work (last column), plant the days absent counters in the spreadsheet
end tell
set lastCellC to endCellC -- tag the last entry column
set endCellC to endCellC + 1
create_counter_for("a", "Days Absent") -- absent
create_counter_for("e", "Special Effort") -- effort award
create_counter_for("x", "Lack of Effort") -- lack of effort note
create_counter_for("s", "Student Referral Slip") -- SRS handed out
plant_task_headers(4) -- plant generic task headers
-- split panes and set columns
tell application "Microsoft Excel"
set ScrollColumn of ActiveWindow to 1
set SplitColumn of ActiveWindow to 2
end tell
-- -------------------------------------------------------------------------------------------------------
-- --------[ Helper Routines] ---------------
-- --------------------------------------------------------------------------------------------------------
on plant_task_headers(header_qty)
tell application "Microsoft Excel"
-- Assessment template Appends
set endCellC to endCellC + 2
repeat with k from 0 to 3
repeat with j from 1 to header_qty
Select Cell ("R" & beginCellR & "C" & endCellC + j - 1)
set ActiveCell to "Task " & j
set {Orientation of Selection, ColumnWidth of Selection} to {xlUpward, 3}
set Bold of Font of Selection to true
end repeat
set endCellC to endCellC + 5
end repeat
end tell
end plant_task_headers
-- ----------------------------------------------------------------------------------------------------------
on create_counter_for(entry_type, reasonCode)
tell application "Microsoft Excel"
-- -------------------------------------------------------------------------------------------------
-- completed on 23/04/02 -relative cell references (A1 format), original used absolute R1C1
-- revised 07-07-22 - made into a subroutine
-- in order to use scripted indexing we first use RxCx format then convert
Select Cell ("R" & beginCellR & "C" & endCellC + 1)
set ActiveCell to reasonCode -- plant reasson code
set {Orientation of Selection, ColumnWidth of Selection} to {xlUpward, 3}
set Bold of Font of Selection to true
set cellRangeX to "R" & beginCellR + 1 & "C"
set cellRangeX to cellRangeX & beginCellC & ":R" & beginCellR + 1 & "C" & lastCellC
set cellRangeX to (Address Range cellRangeX ReferenceStyle xlA1 ¬
without ColumnAbsolute and RowAbsolute) -- make excel do the work!
-- ------------------------------------------------------------------------------------------------
-- insert a formula to count the number of entries in a row
set daysAbsentTemplate_01 to "=IF(COUNTIF(" -- range of cells
set daysAbsentTemplate_02 to ", \"" & entry_type & "\"), COUNTIF(" -- range of cells
set daysAbsentTemplate_03 to ", \"" & entry_type & "\"), \" \" )" -- close the function
set daysAbsent to daysAbsentTemplate_01 & cellRangeX
set daysAbsent to ¬
daysAbsent & daysAbsentTemplate_02 & cellRangeX & daysAbsentTemplate_03
Select Cell ("R" & beginCellR + 1 & "C" & endCellC + 1) -- select the begin cell
-- ----------------------------------------------------------------------------------------------
-- make Excel do the work, relative fill down the formula
-- this saved a huge amount of iteration code
set Formula of Selection to daysAbsent -- the compiled formula
Select Range ¬
("R" & beginCellR + 1 & "C" & endCellC + 1 & ":R" & endCellR + 1 & "C" & endCellC + 1)
FillDown Selection
set HorizontalAlignment of Selection to xlCenter
set endCellC to endCellC + 1
end tell
end create_counter_for
