This page lists some utility subroutines that may be used by more than one tutorial:
These utilities are written to be as general as possible so then can be reused in different scripts. You can copy and paste the script code in the boxes on this page into your own scripts.
(* Activate GEDitCOM II (if needed) and verify a document is open. Return true or false if script can run. *) on CheckAvailable(sName) tell application "GEDitCOM II" activate if number of documents is 0 then user option title "The script '" & sName & ¬ "' requires a document to be open" ¬ message "Please open a document and try again." ¬ buttons {"OK"} return false end if end tell return true end CheckAvailable
Nearly all GEDitCOM II scripts will start by calling this subroutine to verify that a document is open (because most scripts work on data in one or more documents). You can optionally add other checks to this method before the script is allowed to run.
This subroutine returns true
if it passes all tests or returns false
if any test fails. Note that the script name is passed in the variable sName
. If needed, that name is displayed in a message window that explains the reason the script will not run.
Prior to GEDitCOM II, version 2.0, this subroutine would also check the version number and verify it was new enough for the current script. You should still check version number, but once you package the script in an extension, you can specify a minimum version number and that check will be done automatically before running the script.
-- set progress variables set {fractionStepSize, nextFraction} to {0.01, 0.01} -- main script loop tell application "GEDitCOM II" repeat with i from 1 to numTasks -- the script code -- time for progress set fractionDone to i / numFams if fractionDone > nextFraction then notify progress fraction fractionDone set nextFraction to nextFraction + fractionStepSize end if end repeat end tell
notify progress
CommandAppleScripting is a great tool, but it can get slow for large calculations in large files. For this reason, all good GEDitCOM II scripts should inform the user of the progress of the calculations. The code on the right gives the logic
At the beginning of the script you define two variables. The fractionStepSize
defines how often to inform the user of progress. There is no point in sending too many notifications since the progress is rounded to the nearest present. A good choice is usually to notify the user after each percent is completed and thus fractionStepSize
is set to 0.01. The nextFraction
variable defines the next time the notification should be sent to GEDitCOM II. It is initialized to the same value as fractionStepSize
to define the point for the first notification.
Periodically during the script, you should then calculate the fraction of the script that has finished. This sample code shows a script with a repeat loop that will execute numTasks
times. At the end the each pass through the loop, the fractionDone
is easily calculated to be i/numTasks
. If this fraction has passed a predetermined notification point (stored in nextFraction
), a notification is sent to GEDitCOM II using the notify progress
command and nextFraction
is advanced by the fractionStepSize
defined at the start of the script.
For other scripts, it may be harder to determine the fraction completed (such as a script searching for ancestors when you do not know how many ancestors will be found). For these scripts, you have two options. First, you can periodically guess the fraction done and send a notify progress
to GEDitCOM II. Second, you can post a message to the user with a second message argument to the notify progress
command; it can be any string. Third, you can do nothing. The scripting palette in GEDitCOM II will still show a spinning progress wheel to indicate the script is still running.
(* Convert two date SDNs to years from first date to second date *) on GetAgeSpan(beginDate, endDate) return (endDate - beginDate) / 365.25 end GetAgeSpan
This simple subrouting converts the time between two day numbers into the number of years. The time span is from the beginDate
to the endDate
.
(* Round number n to numDecimal digits *) on RoundNum(n, numDecimals) if numDecimals = 0 then return round n as string end if set x to 10 ^ numDecimals set nstr to ((((n * x) + 0.5) div 1) / x) as string set decPt to offset of "." in nstr if decPt = 0 then set nstr to nstr & "." set extra to numDecimals else set extra to numDecimals - (number of characters in nstr) + decPt end if repeat with i from 1 to extra set nstr to nstr ∓ "0" end repeat return nstr end RoundNum
When outputting decimal numbers to a report or to a text file, it is often useful to control the format of the output number. I don't know of a AppleScript method for the task, but this subroutine does some formatting. Given any number in n
, it will return a string representation of the number with numDecimals
digits after the decimal point. If fewer digits are needed, extra "0" digits will added to reach the desired number of digits.
For example:
RoundNum(43.81534,2) -> 43.82 RoundNum(72,3) -> 72.000 RoundNum(22.8144,1) -> 22.8 RoundNum(52.8144,0) -> 53
(* Change current selection to theText using paragraph properties in pstyle When done, move the selection point to the end of the inserted text. *) on TextToPages(theText, textStyle) tell application "Pages" tell front document set nc to count of characters set selection to theText & " " set endnc to count of characters if textStyle is not "" then set nc to nc + 1 tell characters nc thru endnc set properties to textStyle end tell end if select character endnc set selection to "" end tell end tell end TextToPages
Figuring out how to add style text to a Pages document is challenging. This utility subroutine solves the problem and may be all you need to write scripts to create Pages documents. The subroutine write the text in theText
to the current selection and then moves the insertion point to after the entered text. A series of calls to this subroutine can build any report by adding blocks of text to the document. WARNING: this Pages output option only works for Pages 4.x and older. Apple unfortunately decided to delete nearly all AppleScripting feature of Pages when they released Pages 5.0.
The textStyle
parameter lets you control the font and paragraph style for the inserted text. This parameter is an AppleScript record with any property allowed in the character
element defined in Pages' scripting dictionary. When inserting a series of text blocks, the textStyle
only needs to include properties that have changed from the previous text. If there are no changes, it can be an empty string ("")
The subroutine sets the current selection to the input text and adds a single blank character. If textStyle
is provided, it is used to set the properties of the recently inserted text. Finally, the last character of the inserted text is selected and deleted. This deleted character is the blank character inserted above. When done the selection point will be at the end of the document ready to insert the next text. The extra blank character was a trick that solved the problem of getting the selection to the end of the inserted text in all cases; there may be other solutions, but this one works.
(* Insert the text using changes in font in fontStyle and changes in paragraph style in paraStyle. Either can be "" to ignore. The new text replaces the current selection. *) on TextToWord(theText, fontStyle, paraStyle) tell application "Microsoft Word" tell selection if fontStyle is not "" then set properties of font object to fontStyle end if if paraStyle is not "" then set properties of paragraph format of text object to paraStyle end if type text text theText end tell end tell end TextToWord
The MS Word scripting dictionary is complex and verbose. It took some work to come up with a reliable method for inserting formatted text, but this method does the trick and turned out rather simple.
This subroutine will replace the current selection with theText
and format the new text using the font style in fontStyle
and the paragraph style in paraStyle
. These two style parameters should be an AppleScript record. They can contain any property allowed for the font object
or the paragraph format
elements, both of which are defined in MS Word's scripting dictionary. When inserting a series of text blocks, the style parameters only need to include properties that have changed from the previous text. If there are no changes, they can be empty strings ("")
When the method is done, the insertion point will be moved to the end of the new text. A series of calls to this method can build a report by inserting blocks of text with any style desired. The key AppleScript command was the type text
command. The philosophy of the MS Word scripting interface is more like "Macros" than background program. The scripting options are meant to duplicate all the ways a user can interact with MS Word. Here the type text
command is literally typing the text you provide into the document after setting the new font and paragraph styles.