home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / Development Tools & Languages / Macintosh Common Lisp Related / AppleScript-from-lisp / AppleScript.lisp < prev    next >
Encoding:
Text File  |  1994-09-14  |  17.9 KB  |  437 lines  |  [TEXT/CCL2]

  1. ;;;-*- Mode: Lisp; Package: cl-user -*-
  2.  
  3. (in-package :cl-user)
  4.  
  5. ;;  applescript.lisp
  6.  
  7. ;;    Author T. Bonura, 1994
  8. ;;    ©Apple Computer
  9. ;;____________________________________________________________
  10. ;;    Documentation:
  11. ;;  Revisions from the first version
  12. ;;
  13. (require :aestuff)
  14. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  15. ;;;  AppleScript.lisp - T. Bonura 2/3/94
  16. ;;;
  17. ;;;  Note that this is © Apple Computer, Inc.  1994.  All rights reserved.
  18. ;;;  Class definitions for creating applescript CLOS instances.
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20. ;;;  Changes:
  21. ;;  Fri, Mar 11, 1994  3:02 PM Changed EXECUTE-APPLESCRIPT to check for an open
  22. ;;  component and also a compiled script id.
  23. ;;  Fri, Mar 11, 1994  3:02 PM Changed EXTRACT-THE-RESULT so that it extracts
  24. ;;  the right thing now - which seems to be an id of 1+ the compiled-script-id.
  25. ;;;  Fri, Mar 25, 1994  2:30 PM  Added recordability to the  functionality of the ASO. 
  26. ;;  9/12/94
  27. ;;  Nathan Wilson - changed the extract result method to be a bit more general. 
  28. ;;  It now extracts the result into a descriptor record of (wild type).  The
  29. ;;  user is then obliged to dispose of it properly.  Now types other than chars
  30. ;;  can be gotten from an application.  See the method show-result-as-string to
  31. ;;  see how to coerce from wild type to a string.
  32. ;;  9/12/94 Put everything in the cl-user package.
  33. ;; 9/12/94 Think memory leak is fixed - see CLEANUP.
  34. ;;  New:
  35. ;;  According to Inside Mac IAC Chapter 10, an application can maintain several
  36. ;;  connections to a single scripting component or it can have connections to
  37. ;;  several components at the same time.  Since AppleScript can only execute a
  38. ;;  single script at a time per component instance, a multithreaded application
  39. ;;  has to provide a seperate component instance for each script that it
  40. ;;  compiles or executes while it is simultaneously executing other scripts. But
  41. ;;  MCL is not multi threaded so,   I have defined a global called
  42. ;;  *multiple-component-instances* which is initialized to NIL.  If NIL 
  43. ;;  there will only be a single scripting component bound to the variable
  44. ;;  *current-scripting-component*.  When an instance of an AppleScript
  45. ;;   object is created, if *multiple-component-instances* is NIL (the
  46. ;;   default) then the value of the component slot will be set to the VALUE of
  47. ;;   the global *current-scripting-component*. Otherwise the applescript
  48. ;;   object will get its own instance of a scripting component.  There is more
  49. ;;   overhead with creating multiple instances of the scripting component,
  50. ;;   though and they all must be appropriately cleaned up.
  51.  
  52. ;;  When lisp is shut down or when the value of *multiple-component-instances*
  53. ;;  is reset via (use-multiple-component-instances-p) then the
  54. ;;  *current-scripting-component* is disposed.
  55. ;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  56. ;;  changes:
  57. ;;  • stop-recording - fixed bug where if there was a compiled script id, it would
  58. ;;  immediately return without recording. TB 9/14
  59. ;;  • stop-recording - check for a component before calling open-component TB 9/14
  60. ;;  • applescript-object class def - initialize the slot returned-value to NIL TB
  61. ;;  9/14 
  62. ;;  •  cleanup - call dispose method on aedesc reather than the trap. TB 9/14
  63.  
  64. ;;  Bugs:
  65.  
  66.  
  67. (DEFVAR *multiple-component-instances* NIL "Allows for multiple instances of a
  68. scripting component.  Set this using the function (use-multiple-component-instances-p t) ")
  69.  
  70. (DEFPARAMETER *current-scripting-component* NIL "A pointer to the current
  71. scripting component if the application is only using a single component instance"
  72.   )
  73.  
  74.  
  75. (DEFCONSTANT $AppleScript :|ascr| "The applescript scripting component")
  76. (DEFCONSTANT $GeneralScriptingComponent :|cscr| "The general scripting component")
  77. (DEFCONSTANT $HyperTalk :|htlk| "The hypertalk scripting component")
  78.  
  79. (DEFUN CLOSE-SCRIPTING-COMPONENT ()
  80.   (if (pointerp *current-scripting-component*)
  81.            (#_closeComponent *current-scripting-component*)))
  82.  
  83. (pushnew #'close-scripting-component *lisp-cleanup-functions*)
  84.  
  85. (DEFUN USE-MULTIPLE-COMPONENT-INSTANCES-P (boolean)
  86.   (cond (boolean
  87.          (setf *multiple-component-instances* t
  88.                *current-scripting-component* nil)
  89.          (if (pointerp *current-scripting-component*)
  90.            (#_closeComponent *current-scripting-component*)))
  91.         ))
  92.  
  93. (DEFUN NULL-AEDESC ()
  94.    (let ((result (make-record :aedesc)))
  95.       (rset result :aedesc.descriptorType #$typeNull)
  96.       (rset result :aedesc.dataHandle (%null-ptr))
  97.       result))
  98.  
  99. (DEFUN AEDESC-P (thing)
  100.   "Returns T if thing if it is an aesedc, otherwise NIL"
  101.   (eq (class-of thing)
  102.       (find-class 'aedesc)))
  103.  
  104. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  105. ;;;    Class:  APPLESCRIPT-OBJECT
  106. ;;;   OPEN-COMPONENT ((ASO APPLESCRIPT-OBJECT)) "opens a scripting component
  107. ;;;    and sets the value of the component slot to a pointer
  108. ;;;   COMPILE-APPLESCRIPT ((ASO APPLESCRIPT-OBJECT)) "compiles the script
  109. ;;;    which is in the script slot"
  110. ;;;   EXECUTE-APPLESCRIPT ((ASO APPLESCRIPT-OBJECT)) "What do you think?"
  111. ;;;   EDIT-SCRIPT ((ASO APPLESCRIPT-OBJECT))
  112. ;;;   CLEANUP ((ASO APPLESCRIPT-OBJECT)) 
  113. ;;;   DISPOSE-SCRIPT ((ASO APPLESCRIPT-OBJECT))
  114. ;;;   DISPLAY-RESULT ((ASO APPLESCRIPT-OBJECT))  - elided - TB 9/12
  115. ;;;   EXTRACT-THE-RESULT ((ASO APPLESCRIPT-OBJECT))
  116. ;;;    ******  Recording *****
  117. ;;;   START-RECORDING ((ASO APPLESCRIPT-OBJECT))
  118. ;;;   STOP-RECORDING ((ASO APPLESCRIPT-OBJECT)) "When we 
  119. ;;;   stop recording, we add the decompiled script to the script slot"
  120. ;;;   DECOMPILE-SCRIPT ((ASO APPLESCRIPT-OBJECT))
  121. ;;;    ** ASO = AppleScriptObject **
  122. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  123.  
  124. (DEFCLASS APPLESCRIPT-OBJECT (standard-object)
  125.   ((script :initform NIL :initarg :script :accessor script)
  126.    (application-name :initform NIL :initarg :application-name :accessor
  127.                      application-name) 
  128.    (scripting.component.type :initform NIL :initarg :scripting-component-type
  129.                              :accessor scripting-component-type)
  130.    ;;  NOTE:  the as.target slot is not currently used
  131.    (as.target :initform NIL :initarg :target :accessor as-target)
  132.    (break.on.error :initarg :break-on-error :accessor break-on-error)
  133.    (compiled.script :initform NIL :initarg NIL :accessor compiled-script)
  134.    (compiled.script.id :initform NIL :initarg NIL :accessor compiled-script-id) 
  135.    (component :initform nil :initarg :component :accessor component)
  136.    (returned.value :initarg :returned-value :accessor returned-value)
  137.    )
  138.   (:default-initargs
  139.     :scripting-component-type $AppleScript
  140.     :break-on-error t
  141.     :returned-value NIL)
  142.   )
  143. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  144.  
  145. (DEFGENERIC OPEN-COMPONENT (APPLESCRIPT-OBJECT)
  146.   (:documentation "Opens a scripting component.  We only open a new scripting
  147. component if the global *multiple-component-instances* is t.  Otherwise all the
  148. scripts use the same scripting component.")
  149.   )
  150.  
  151. (DEFMETHOD OPEN-COMPONENT ((ASO APPLESCRIPT-OBJECT))
  152.   ;;  changed to deal with either a single or multiple components
  153.   (cond (*multiple-component-instances*
  154.          (setf (component ASO)
  155.                (#_OpenDefaultComponent #$kOSAComponentType 
  156.                 (scripting-component-type ASO))))
  157.         ((or (null *current-scripting-component*)
  158.              (%null-ptr-p *current-scripting-component*))
  159.          (setf *current-scripting-component* 
  160.                (#_OpenDefaultComponent #$kOSAComponentType 
  161.                 (scripting-component-type ASO)))
  162.          (setf (component ASO) *current-scripting-component*))
  163.         (t (setf (component ASO) *current-scripting-component*))))
  164.  
  165. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  166. (DEFGENERIC COMPILE-APPLESCRIPT (APPLESCRIPT-OBJECT)
  167.   (:documentation "Compile the applescript")
  168.   )
  169.  
  170. (DEFMETHOD COMPILE-APPLESCRIPT ((ASO APPLESCRIPT-OBJECT))
  171.   (unless (component aso)
  172.     (open-component aso))
  173.   (with-pointers ((as (component ASO)))
  174.     (let ((text (script ASO)))
  175.       (with-aedescs (source)
  176.         (let ((size (length text)))
  177.           (%vstack-block (buff size)
  178.             (dotimes (i size)
  179.               (%put-byte buff (char-code (char text i)) i))
  180.             (#_AECreateDesc #$typeChar buff size source)))
  181.         (rlet ((id :OSAID))
  182.           (%put-long id #$kOSANullScript)
  183.           (let ((err (#_OSACompile as source 0 id)))
  184.             (cond ((zerop err)
  185.                    ;;(format t "OK Seems to compile")
  186.                    (setf (compiled-script aso) t)
  187.                    (setf (compiled-script-id ASO) (%get-long id)))
  188.                   (t
  189.                    (if (break-on-error ASO)
  190.                      (error (script-error as)))
  191.                    (values nil err))))))
  192.       )
  193.     )
  194.   )
  195. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  196. (DEFGENERIC EXECUTE-APPLESCRIPT (APPLESCRIPT-OBJECT)
  197.   (:documentation "Execute the script on the target")
  198.   )
  199.  
  200. ;;; Typically returns an AEDesc that the user must dispose.  May return a
  201. ;;; string or nil if bad things happen.  The AEDESC is put in the returned-value
  202. ;;; slot of the object
  203. (DEFMETHOD EXECUTE-APPLESCRIPT ((ASO APPLESCRIPT-OBJECT))
  204.   ;;  in case we try to execute without having an open scripting component
  205.   (unless (component ASO)
  206.       (open-component ASO))
  207.   ;;  whenever the script is edited in the script editor, the value of
  208.   ;;  compiled-script is set to nil 
  209.   (unless (compiled-script aso)
  210.     (compile-applescript ASO))
  211.   (let ((id (compiled-script-id ASO))
  212.           (err nil)
  213.           (result nil)
  214.           (as (component ASO)))
  215.      (rlet ((result-id :OSAID #$typeChar))
  216.         (setq err (#_OSAExecute as id 0 0 result-id))
  217.         (cond
  218.           ((zerop err)
  219.             (unwind-protect
  220.                (setq result (extract-the-result aso (%get-long result-id)))
  221.                (#_OSADispose as (%get-long result-id)))
  222.             result)
  223.           (t
  224.             (if (break-on-error ASO)
  225.                (error (script-error as)))
  226.             (values nil err))))))
  227.  
  228. (DEFMETHOD EXTRACT-STRING ((aso applescript-object) result-id)
  229.    (with-aedescs (source)
  230.        (let ((err (#_OSADisplay (component aso) result-id #$typeChar 0 source)))
  231.           (cond ((zerop err)
  232.                      (setf (returned-value aso)
  233.                               (as-get-string (rref source AEDesc.dataHandle))))
  234.                    (t (values nil err))))))
  235.  
  236. ;;; Returns either a string or an AEDesc object.  If the latter, the user is responsible for
  237. ;;; calling dispose on it.
  238. (DEFMETHOD EXTRACT-THE-RESULT ((aso applescript-object) result-id)
  239.    (let ((as (component aso)))
  240.       (with-aedescs (resultDesc)
  241.           (let ((err (#_OSACoerceToDesc as result-id #$typeWildCard #$kOSAModeNull resultDesc)))
  242.              (cond
  243.                ((zerop err)
  244.                  (let ((final-result (null-aedesc)))
  245.                     (setq err (#_AEDuplicateDesc resultDesc final-result))
  246.                     (cond
  247.                       ((zerop err) (setf (returned-value aso)
  248.                              (make-instance 'AEDesc :descRecPtr final-result)))
  249.                       (t (unless (eql final-result (%null-ptr))
  250.                              (#_AEDisposeDesc final-result))
  251.                           (extract-string aso result-id)))))
  252.                ;;; If OSACoerceToDesc fails then try to return a string
  253.                (t (extract-string aso result-id)))))))
  254.  
  255.  
  256. ;; Extract the result creates a descriptor record containing the data (of any
  257. ;; type).  THis data might be a pict or just about anything that the target
  258. ;; sends back.  The following shows how to deal with coercing the descriptor to
  259. ;; type char so that we can show it as a string.
  260.  
  261. (DEFMETHOD SHOW-RESULT-AS-STRING ((aso applescript-object))
  262.   (with-aedescs (coerced.desc)
  263.           (let ((err (#_AECoerceDesc (getDescRecPtr (returned-value aso))
  264.                       #$typechar coerced.desc)))
  265.              (cond
  266.                ((zerop err)
  267.                 (as-get-string (rref coerced.desc AEDesc.dataHandle)))))))
  268.  
  269. (DEFMETHOD DISPOSE-SCRIPT ((ASO APPLESCRIPT-OBJECT))
  270.   (let ((as (component ASO))
  271.         (id (compiled-script-id ASO)))
  272.   (when (and as id)
  273.     (assert (zerop (#_OSADispose as id))))
  274.   )
  275.   )
  276.  
  277. (DEFMETHOD CLEANUP ((ASO APPLESCRIPT-OBJECT))
  278.   (dispose-script ASO)
  279.   (let ((returned.value (returned-value aso)))
  280.     (cond (returned.value
  281.            (setf (returned-value aso) nil)
  282.            (if (aedesc-p returned.value)
  283.              (dispose returned.value))))
  284.     (cond (*multiple-component-instances*
  285.            (#_CloseComponent (component aso))
  286.            (setf (component aso) nil)
  287.            )
  288.           )
  289.     )
  290.   )
  291.  
  292. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  293. (DEFGENERIC EDIT-SCRIPT (APPLESCRIPT-OBJECT)
  294.   (:documentation "Bring up a script editor on the script")
  295.   )
  296.  
  297.  
  298. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  299. ;;  Methods for dealing with error conditions
  300. ;;
  301. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  302.  
  303.  
  304. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  305. ;;;
  306. ;;;
  307. ;;;        Recording From Recordable Applications
  308. ;;;  The following allows for recording to be turned on. 
  309. ;;;  Actions are recorded to the compiled script in the
  310. ;;;  applescript object.
  311. ;;;
  312. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  313. (DEFMETHOD START-RECORDING ((aso APPLESCRIPT-OBJECT))
  314.   ;;  tell the applescript object to start recording
  315.   ;;  tell the object to open a scripting component
  316.   (unless (component aso)
  317.     (open-component aso))
  318.   (with-pointers ((as (component aso)))
  319.     (rlet ((id :OSAID))
  320.       (%put-long id #$KOSANullScript)
  321.       (let ((oserr (#_OSAStartRecording as id)))
  322.         (if (zerop oserr)
  323.           (progn
  324.             (format t "Recording is on.~%")
  325.             (setf (compiled-script-id aso) (%get-long id)))
  326.           (if (break-on-error ASO)
  327.             (error (script-error as))))))))
  328.  
  329.  
  330. (DEFMETHOD STOP-RECORDING ((aso APPLESCRIPT-OBJECT))
  331.   (with-pointers ((as (component aso)))
  332.     (let ((oserr (#_OSAStopRecording as (compiled-script-id aso))))
  333.       
  334.       (cond ((zerop oserr)
  335.              (decompile-script aso)
  336.              (format t "Recording is off.~%"))
  337.             (t
  338.              (if (break-on-error ASO)
  339.                (error (script-error as))))))))
  340.  
  341.  
  342. (DEFMETHOD DECOMPILE-SCRIPT ((aso applescript-object))
  343.   ;;  extract the script from the compiled script.  Most
  344.   ;;  useful when doing recording
  345.   (with-pointers ((as (component aso)))
  346.     (let* ((descObj (make-instance 'aedesc :type #$TypeChar))
  347.            (id (compiled-script-id aso))
  348.            (err (#_OSAGetSource as id #$typeChar
  349.                    (getDescRecPtr descObj))))
  350.       (cond ((zerop err)
  351.              ;;  extract the text from the descriptor, then
  352.              ;;  add the script to the script slot of the
  353.              ;;  object and inform the object that the
  354.              ;;  script has changed
  355.              (setf (script aso)
  356.                    (as-get-string (rref (getDescRecPtr descObj)
  357.                         AEDesc.dataHandle))
  358.                    (compiled-script aso) t))
  359.             (t (if (break-on-error ASO)
  360.                      (error (script-error as)))
  361.                )
  362.             )
  363.       )
  364.     )
  365.   )
  366.  
  367. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  368. ;;  Utilities
  369. ;;
  370. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  371.  
  372. (DEFUN EXTRACT-SCRIPT-TEXT (text)
  373.   "Remove any tabs and linefeeds from the text if the script should be of short
  374. form, otherwise if the script is of the type 'tell, end tell' just return the
  375. whole thing"
  376.   ;;  see if the last word of the text is "tell"
  377.   (if (string= "tell" (reverse (string-downcase (subseq (reverse text) 0 4))))
  378.     text
  379.     (strip-lf&tab text)))
  380.  
  381. (DEFUN STRIP-LF&TAB (string)
  382.   "Removes linefeeds and tabs from a copy of string"
  383.   (substitute-if #\space #'(lambda (char)
  384.                  (or (char= char #\return)
  385.                      (char= char #\tab)))
  386.              string))
  387.  
  388.  
  389. (DEFUN AS-GET-STRING (data)
  390.   (let* ((size (#_GetHandleSize data))
  391.             (text (make-string size)))
  392.      (dotimes (i size)
  393.         (setf (char text i) (code-char (%hget-byte data i))))
  394.      text))
  395.  
  396. (DEFUN SCRIPT-ERROR (as)
  397.   (with-aedescs (err)
  398.     (if (/= (#_OSAScriptError as #$kOSAErrorMessage #$typeChar err) #$noErr)
  399.       ""
  400.       (as-get-string (rref err AEDesc.dataHandle)))))
  401.  
  402.  
  403. (provide :appleScript)
  404.  
  405.  
  406. #|
  407.  
  408. (setf ttest (make-instance 'applescript-object))
  409. (start-recording ttest)
  410. (inspect ttest)
  411. (execute-applescript ttest)
  412. (cleanup ttest2)
  413. (decompile-script ttest)
  414.  
  415.  
  416. (setf astest (make-instance 'APPLESCRIPT-OBJECT
  417.                :script "tell \"Scriptable Text Editor\" to set the size of word 1 of window 1 of application \"Scriptable Text Editor\" to 48"
  418.                ))
  419. (open-component astest)
  420. (compile-applescript astest)
  421. (execute-applescript astest)
  422. (edit-script astest)
  423. (cleanup astest)
  424. Here are some scripts which seem to work:
  425. "tell application \"Eudora2.0.2a1d-2.1994\" to make new Message at the end of Mailbox \"out\" of Mail Folder \"\""
  426. "tell application \"Eudora2.0.2a1d-2.1994\" to Connect with send and check"
  427. "tell application \"Eudora2.0.2a1d-2.1994\" to Reply Message 4 of Mailbox \"In\" of Mail Folder \"\""
  428. "tell application \"Eudora2.0.2a1d-2.1994\" to Redirect the last Message of Mailbox \"In\" of Mail Folder \"\""
  429. "tell application \"Eudora2.0.2a1d-2.1994\" to get the Field \"to\" of the last Message of Mailbox \"In\" of Mail Folder \"\""
  430. "tell application \"Eudora2.0.2a1d-2.1994\" to get the number of Message of Mailbox \"In\" of Mail Folder \"\""
  431. "tell application \"Eudora2.0.2a1d-2.1994\" to Connect without Send"
  432.  
  433. ;; here's one for :|quil|
  434. "tell \"Scriptable Text Editor\" to set the size of word 1 of window 1 of application \"Scriptable Text Editor\" to 48"
  435.  
  436. |#
  437.