
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.
# Verify GEDitCOM II is running and a document is open.
# Return 1 or 0 if script can run or not.
def CheckAvailable(gedit,sName)
if gedit.documents().count()<1
errMsg = "The script '"+sName+"' requires requires a document to be"\
+ " open\nPlease open a document and try again."
puts errMsg
return 0
end
return 1
end
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 1 if it passes all tests or returns 0 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.
notifyProgressFraction_message_() Command
# set progress variables
fractionStepSize = nextFraction = 0.01
# main script loop
for i in 1...numTasks
# the script code
# time for progress
fractionDone = Float(i)/Float(numTasks)
if fractionDone > nextFraction:
gdoc.notifyProgressFraction_message_(fractionDone,nil)
nextFraction = nextFraction + fractionStepSize
end
end
Scripting of GEDitCOM II 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 percent. 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 (converted to floating point). If this fraction has passed a predetermined notification point (stored in nextFraction), a notification is sent to a document (here it is assumed gdoc references a document) using the notifyProgressFraction_message_() 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 three options. First, you can periodically guess the fraction done and send a notifyProgressFraction_message_() to a document. Second, you can post a message to the user with the second argument to the notifyProgressFraction_message_(); 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. For Ruby scripts, that palette will also have an abort button (with an "X") that can be clicked to stop any script.
# Convert two date SDNs to years from first date to second date
def GetAgeSpan(beginDate, endDate)
return (endDate - beginDate) / 365.25
end
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.
# convert string to AppleScript enumerated constant
def GCConstant(uniqueStr)
if uniqueStr=="chart"
byteForm = 0x74724348 # trCH
elsif uniqueStr=="outline"
byteForm = 0x74724F55 # trOU
elsif uniqueStr=="the children"
byteForm = 0x736B4348 # skCH
elsif uniqueStr=="the events"
byteForm = 0x736B4556 # skEV
elsif uniqueStr=="the spouses"
byteForm = 0x736B5350 # skSP
elsif uniqueStr=="char_MacOS"
byteForm = 0x784F7031 # xOp1
elsif uniqueStr=="char_ANSEL"
byteForm = 0x784F7032 # xOp2
elsif uniqueStr=="char_UTF8"
byteForm = 0x784F7033 # xOp3
elsif uniqueStr=="char_UTF16"
byteForm = 0x784F7034 # xOp4
elsif uniqueStr=="char_Windows"
byteForm = 0x784F7035 # xOp5
elsif uniqueStr=="lines_LF"
byteForm = 0x784F7036 # xOp6
elsif uniqueStr=="lines_CR"
byteForm = 0x784F7037 # xOp7
elsif uniqueStr=="lines_CRLF"
byteForm = 0x784F7038 # xOp8
elsif uniqueStr=="mm_GEDitCOM"
byteForm = 0x784F7039 # xOp9
elsif uniqueStr=="mm_Embed"
byteForm = 0x784F7041 # xOpA
elsif uniqueStr=="mm_PhpGedView"
byteForm = 0x784F7042 # xOpB
elsif uniqueStr=="logs_Include"
byteForm = 0x784F7043 # xOpC
elsif uniqueStr=="logs_Omit"
byteForm = 0x784F7044 # xOpD
elsif uniqueStr=="places_Include"
byteForm = 0x784F7045 # xOpE
elsif uniqueStr=="places_Omit"
byteForm = 0x784F7046 # xOpF
elsif uniqueStr=="books_Include"
byteForm = 0x784F7047 # xOpG
elsif uniqueStr=="books_Omit"
byteForm = 0x784F7048 # xOpH
elsif uniqueStr=="settings_Embed"
byteForm = 0x784F7049 # xOpI
elsif uniqueStr=="settings_Omit"
byteForm = 0x784F7050 # xOpJ
elsif uniqueStr=="thumbnails_Embed"
byteForm = 0x784F7051 # xOpK
elsif uniqueStr=="thumbnails_Omit"
byteForm = 0x784F7052 # xOpL
elsif uniqueStr=="locked"
byteForm = 0x724C636B # rLck
elsif uniqueStr=="privacy"
byteForm = 0x72507276 # rPrv
elsif uniqueStr=="unlocked"
byteForm = 0x72556E6C # rUnl
else
byteForm = 0
end
return byteForm
end
Some commands take arguments that select among two or more defined constants (such as chart and outline for family trees). Similarly, the restriction property of individual records returns a defined constant (amoung unlocked, locked, and privacy). These constants are used in AppleScript by their name, but in Ruby scripts, you have to use the underlying numeric codes instead. The GCConstant() subroutine solves this problem by translating any constant to its numeric value. The constant's name is passed as the subroutine's single argument as a string variable. For example. GCConstant("chart") will return the numeric value for the chart constant.