Examples of AppleScript

From nswccWiki

Jump to: navigation, search

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.

Contents

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


Personal tools