[Python-checkins] python/dist/src/Doc/mac libaetools.tex,NONE,1.1 libgensuitemodule.tex,NONE,1.1 scripting.tex,NONE,1.1 libaepack.tex,1.2,1.3 libaetypes.tex,1.1,1.2 mac.tex,1.10,1.11 using.tex,1.7,1.8

jackjansen@users.sourceforge.net jackjansen@users.sourceforge.net
Fri, 11 Apr 2003 08:35:32 -0700


Update of /cvsroot/python/python/dist/src/Doc/mac
In directory sc8-pr-cvs1:/tmp/cvs-serv30924/mac

Modified Files:
	libaepack.tex libaetypes.tex mac.tex using.tex 
Added Files:
	libaetools.tex libgensuitemodule.tex scripting.tex 
Log Message:
Moved all the scripting stuff to a separate section, added all the
missing bits (well, all the bits I could think of) and updated the
rest.


--- NEW FILE: libaetools.tex ---
\section{\module{aetools} ---
         OSA client support}

\declaremodule{standard}{aetools}
  \platform{Mac}
%\moduleauthor{Jack Jansen?}{email}
\modulesynopsis{Basic support for sending Apple Events}
\sectionauthor{Jack Jansen}{Jack.Jansen@cwi.nl}


The \module{aetools} module contains the basic functionality
on which Python AppleScript client support is built. It also
imports and re-exports the core functionality of the
\module{aetypes} and \module{aepack} modules. The stub packages
generated by \module{gensuitemodule} import the relevant
portions of \module{aetools}, so usually you do not need to
import it yourself. The exception to this is when you
cannot use a generated suite package and need lower-level
access to scripting.

The \module{aetools} module itself uses the AppleEvent support
provided by the \module{Carbon.AE} module. This has one drawback:
you need access to the window manager, see section \ref{osx-gui-scripts}
for details. This restriction may be lifted in future releases.


The \module{aetools} module defines the following functions:

\begin{funcdesc}{packevent}{ae, parameters, attributes}
Stores parameters and attributes in a pre-created \code{Carbon.AE.AEDesc}
object. \code{parameters} and \code{attributes} are 
dictionaries mapping 4-character OSA parameter keys to Python objects. The
objects are packed using \code{aepack.pack()}.
\end{funcdesc}

\begin{funcdesc}{unpackevent}{ae\optional{, formodulename}}
Recursively unpacks a \code{Carbon.AE.AEDesc} event to Python objects.
The function returns the parameter dictionary and the attribute dictionary.
The \code{formodulename} argument is used by generated stub packages to
control where AppleScript classes are looked up.
\end{funcdesc}

\begin{funcdesc}{keysubst}{arguments, keydict}
Converts a Python keyword argument dictionary \code{arguments} to
the format required by \code{packevent} by replacing the keys,
which are Python identifiers, by the four-character OSA keys according
to the mapping specified in \code{keydict}. Used by the generated suite
packages.
\end{funcdesc}

\begin{funcdesc}{enumsubst}{arguments, key, edict}
If the \code{arguments} dictionary contains an entry for \code{key}
convert the value for that entry according to dictionary \code{edict}.
This converts human-readable Python enumeration names to the OSA 4-character
codes.
Used by the generated suite
packages.
\end{funcdesc}

The \module{aetools} module defines the following class:

\begin{classdesc}{TalkTo}{\optional{signature=None, start=0, timeout=0}}

Base class for the proxy used to talk to an application. \code{signature}
overrides the class attribute \code{_signature} (which is usually set by subclasses)
and is the 4-char creator code defining the application to talk to.
\code{start} can be set to true to enable running the application on
class instantiation. \code{timeout} can be specified to change the
default timeout used while waiting for an AppleEvent reply.
\end{classdesc}

\begin{methoddesc}{_start}{}
Test whether the application is running, and attempt to start it if not.
\end{methoddesc}

\begin{methoddesc}{send}{code, subcode\optional{, parameters, attributes}}
Create the AppleEvent \code{Carbon.AE.AEDesc} for the verb with
the OSA designation \code{code, subcode} (which are the usual 4-character
strings), pack the \code{parameters} and \code{attributes} into it, send it
to the target application, wait for the reply, unpack the reply with
\code{unpackevent} and return the reply appleevent, the unpacked return values
as a dictionary and the return attributes.
\end{methoddesc}

--- NEW FILE: libgensuitemodule.tex ---
\section{\module{gensuitemodule} ---
         Generate OSA stub packages}

\declaremodule{standard}{gensuitemodule}
  \platform{Mac}
%\moduleauthor{Jack Jansen?}{email}
\modulesynopsis{Create a stub package from an OSA dictionary}
\sectionauthor{Jack Jansen}{Jack.Jansen@cwi.nl}

The \module{gensuitemodule} module creates a Python package implementing
stub code for the AppleScript suites that are implemented by a specific
application, according to its AppleScript dictionary.

It is usually invoked by the user through the \program{PythonIDE}, but
it can also be run as a script from the command line (pass \code{--help}
for help on the options) or imported from Python code. For an example of
its use see \file{Mac/scripts/genallsuites.py} in a source distribution,
which generates the stub packages that are included in the standard
library.

It defines the following public functions:

\begin{funcdesc}{is_scriptable}{application}
Returns true if \code{application}, which should be passed as a pathname,
appears to be scriptable. Take the return value with a grain of salt:
\program{Internet Explorer} appears not to be scriptable but definitely is.
\end{funcdesc}

\begin{funcdesc}{processfile}{application\optional{, output, basepkgname, 
        edit_modnames, creatorsignature, dump, verbose}}
Create a stub package for \code{application}, which should be passed as
a full pathname. For a \file{.app} bundle this is the pathname to the
bundle, not to the executable inside the bundle; for an unbundled CFM
application you pass the filename of the application binary.

This function asks the application for its OSA terminology resources,
decodes these resources and uses the resultant data to create the Python
code for the package implementing the client stubs.

\code{output} is the pathname where the resulting package is stored, if
not specified a standard "save file as" dialog is presented to
the user. \code{basepkgname} is the base package on which this package
will build, and defaults to \module{StdSuites}. Only when generating
\module{StdSuites} itself do you need to specify this.
\code{edit_modnames} is a dictionary that can be used to change
modulenames that are too ugly after name mangling.
\code{creator_signature} can be used to override the 4-char creator
code, which is normally obtained from the \file{PkgInfo} file in the
package or from the CFM file creator signature. When \code{dump} is
given it should refer to a file object, and \code{processfile} will stop
after decoding the resources and dump the Python representation of the
terminology resources to this file. \code{verbose} should also be a file
object, and specifying it will cause \code{processfile} to tell you what
it is doing.
\end{funcdesc}

\begin{funcdesc}{processfile_fromresource}{application\optional{, output, 
	basepkgname, edit_modnames, creatorsignature, dump, verbose}}
This function does the same as \code{processfile}, except that it uses a
different method to get the terminology resources. It opens \code{application}
as a resource file and reads all \code{"aete"} and \code{"aeut"} resources
from this file.
\end{funcdesc}


--- NEW FILE: scripting.tex ---
\chapter{MacPython OSA Modules \label{scripting}}

Python has a fairly complete implementation of the Open Scripting
Architecure (OSA, also commonly referred to as AppleScript), allowing
you to control scriptable applications from your Python program,
and with a fairly pythonic interface. 

For a description of the various components of AppleScript and OSA, and
to get an understanding of the architecture and terminology, you should
read Apple's documentation. The "Applescript Language Guide" explains
the conceptual model and the terminology, and documents the standard
suite. The "Open Scripting Architecture" document explains how to use
OSA from an application programmers point of view. In the Apple Help
Viewer these book sare located in the Developer Documentation, Core
Technologies section.


As an example of scripting an application, the following piece of
AppleScript will get the name of the frontmost \program{Finder} window
and print it:
	
\begin{verbatim}
tell application "Finder"
    get name of window 1
end tell
\end{verbatim}

In Python, the following code fragment will do the same:

\begin{verbatim}
import Finder

f = Finder.Finder()
print f.get(Finder.window(1).name)
\end{verbatim}

As distributed the Python library includes packages that implement the
standard suites, plus packages that interface to a small number of
common applications.

To send AppleEvents to an application you must first create the Python
package interfacing to the terminology of the application (what
\program{Script Editor} calls the "Dictionary"). This can be done from
within the \program{PythonIDE} or by running the
\file{gensuitemodule.py} module as a standalone program from the command
line.

The generated output is a package with a number of modules, one for
every suite used in the program plus an \module{__init__} module to glue
it all together. The Python inheritance graph follows the AppleScript
inheritance graph, so if a programs dictionary specifies that it
includes support for the Standard Suite, but extends one or two verbs
with extra arguments then the output suite will contain a module
\module{Standard_Suite} that imports and re-exports everything from
\module{StdSuites.Standard_Suite} but overrides the methods that have
extra functionality. The output of \module{gensuitemodule} is pretty
readable, and contains the documentation that was in the original
AppleScript dictionary in Python docstrings, so reading it is a good
source of documentation.

The output package implements a main class with the same name as the
package which contains all the AppleScript verbs as methods, with the
direct object as the first argument and all optional parameters as
keyword arguments. AppleScript classes are also implemented as Python
classes, as are comparisons and all the other thingies.

Note that in the current release there is no coupling between the main
Python class implementing the verbs and the Python classes implementing
the AppleScript classes. Hence, in the example above we need to use
\code{f.get(Finder.window(1).name)} in stead of the more Pythonic
\code{f.window(1).name.get()}.


If an AppleScript identifier is not a Python identifier the name is
mangled according to a small number of rules:
\begin{itemize}
    \item spaces are replaced with underscores
    \item other non-alphanumeric characters are replaced with
    \code{_xx_} where \code{xx} is the hexadecimal character value
    \item any Python reserved word gets an underscore appended
\end{itemize}

Python also has support for creating scriptable applications
in Python, but
The following modules are relevant to MacPython AppleScript support:

\localmoduletable

In addition, support modules have been pre-generated for
\module{Finder}, \module{Terminal}, \module{Explorer},
\module{Netscape}, \module{CodeWarrior}, \module{SystemEvents} and
\module{StdSuites}.

\input{libgensuitemodule}
\input{libaetools}
\input{libaepack}
\input{libaetypes}
\input{libminiae}

Index: libaepack.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/mac/libaepack.tex,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** libaepack.tex	12 Feb 2003 09:58:33 -0000	1.2
--- libaepack.tex	11 Apr 2003 15:35:26 -0000	1.3
***************
*** 46,50 ****
  \end{funcdesc}
  
! \begin{funcdesc}{unpack}{x}
    \var{x} must be an object of type \class{AEDesc}. This function
    returns a Python object representation of the data in the Apple
--- 46,50 ----
  \end{funcdesc}
  
! \begin{funcdesc}{unpack}{x\optional{, formodulename}}
    \var{x} must be an object of type \class{AEDesc}. This function
    returns a Python object representation of the data in the Apple
***************
*** 54,67 ****
    elements are recursively unpacked.  Object references
    (ex. \code{line 3 of document 1}) are returned as instances of
!   \class{aetypes.ObjectSpecifier}.  AppleEvent descriptors with
    descriptor type typeFSS are returned as \class{FSSpec}
    objects.  AppleEvent record descriptors are returned as Python
!   dictionaries, with keys of type \class{?} and elements recursively
    unpacked.
  \end{funcdesc}
  
  
  \begin{seealso}
!   \seemodule{AE}{Built-in access to Apple Event Manager routines.}
    \seemodule{aetypes}{Python definitions of codes for Apple Event
                        descriptor types.}
--- 54,77 ----
    elements are recursively unpacked.  Object references
    (ex. \code{line 3 of document 1}) are returned as instances of
!   \class{aetypes.ObjectSpecifier}, unless \code{formodulename}
!   is specified.  AppleEvent descriptors with
    descriptor type typeFSS are returned as \class{FSSpec}
    objects.  AppleEvent record descriptors are returned as Python
!   dictionaries, with 4-character string keys and elements recursively
    unpacked.
+   
+   The optional \code{formodulename} argument is used by the stub packages
+   generated by \module{gensuitemodule}, and ensures that the OSA classes
+   for object specifiers are looked up in the correct module. This ensures
+   that if, say, the Finder returns an object specifier for a window
+   you get an instance of \code{Finder.Window} and not a generic
+   \code{aetypes.Window}. The former knows about all the properties
+   and elements a window has in the Finder, while the latter knows
+   no such things.
  \end{funcdesc}
  
  
  \begin{seealso}
!   \seemodule{Carbon.AE}{Built-in access to Apple Event Manager routines.}
    \seemodule{aetypes}{Python definitions of codes for Apple Event
                        descriptor types.}

Index: libaetypes.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/mac/libaetypes.tex,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** libaetypes.tex	14 Oct 2000 05:06:24 -0000	1.1
--- libaetypes.tex	11 Apr 2003 15:35:27 -0000	1.2
***************
*** 9,39 ****
  
  
! The \module{aetypes} defines classes used to represent Apple Event
! object specifiers. An object specifier is essentially an address of an
! object implemented in a Apple Event server. An Apple Event specifier
! is used as the direct object for an Apple Event or as the argument of
! an optional parameter. In AppleScript an object specifier is
! represented by a phrase such as:
! \code{character 23 of document "Semprini"}. The classes defined in
! this module allow this specifier to be represented by a Python object
! which is initialized as follows:
! \code{res = Document(1).Character(23)}
  
  
! The \module{AEObjects} module defines the following class:
  
! \begin{classdesc}{ObjectSpecifier}{want, form, seld, from}
!   This is the base class for representing object specifiers and is
!   generally not constructed directly by the user. Its important
!   functionality is to define an \function{__aepack__()} function,
!   which returns the Apple Event descriptor containing the object
!   specifier.  Its data members, set directly from the constructor
!   arguments, are:
  \end{classdesc}
  
- \begin{memberdesc}{want}
-   A four character string representing the class code of the
-   object. These class codes are specified in Apple Event Suites; for
-   example the standard code for a character object is the 4 bytes
-   \samp{char}.
- \end{memberdesc}
--- 9,135 ----
  
  
! The \module{aetypes} defines classes used to represent Apple Event data
! descriptors and Apple Event object specifiers.
  
+ Apple Event data is is contained in descriptors, and these descriptors
+ are typed. For many descriptors the Python representation is simply the
+ corresponding Python type: \code{typeText} in OSA is a Python string,
+ \code{typeFloat} is a float, etc. For OSA types that have no direct
+ Python counterpart this module declares classes. Packing and unpacking
+ instances of these classes is handled automatically by \module{aepack}.
  
! An object specifier is essentially an address of an object implemented
! in a Apple Event server. An Apple Event specifier is used as the direct
! object for an Apple Event or as the argument of an optional parameter.
! The \module{aetypes} module contains the base classes for OSA classes
! and properties, which are used by the packages generated by
! \module{gensuitemodule} to populate the classes and properties in a
! given suite.
  
! For reasons of backward compatibility, and for cases where you need to
! script an application for which you have not generated the stub package
! this module also contains object specifiers for a number of common OSA
! classes such as \code{Document}, \code{Window}, \code{Character}, etc.
! 
! 
! 
! The \module{AEObjects} module defines the following classes to represent
! Apple Event descriptor data:
! 
! \begin{classdesc}{Unknown}{type, data}
! The representation of OSA descriptor data for which the \module{aepack}
! and \module{aetypes} modules have no support, i.e. anything that is not
! represented by the other classes here and that is not equivalent to a
! simple Python value.
! \end{classdesc}
! 
! \begin{classdesc}{Enum}{enum}
! An enumeration value with the given 4-character string value.
! \end{classdesc}
! 
! \begin{classdesc}{InsertionLoc}{of, pos}
! Position \code{pos} in object \code{of}.
! \end{classdesc}
! 
! \begin{classdesc}{Boolean}{bool}
! A boolean.
! \end{classdesc}
! 
! \begin{classdesc}{StyledText}{style, text}
! Text with style information (font, face, etc) included.
! \end{classdesc}
! 
! \begin{classdesc}{AEText}{script, style, text}
! Text with script system and style information included.
! \end{classdesc}
! 
! \begin{classdesc}{IntlText}{script, language, text}
! Text with script system and language information included.
! \end{classdesc}
! 
! \begin{classdesc}{IntlWritingCode}{script, language}
! Script system and language information.
! \end{classdesc}
! 
! \begin{classdesc}{QDPoint}{v, h}
! A quickdraw point.
! \end{classdesc}
! 
! \begin{classdesc}{QDRectangle}{v0, h0, v1, h1}
! A quickdraw rectangle.
! \end{classdesc}
! 
! \begin{classdesc}{RGBColor}{r, g, b}
! A color.
! \end{classdesc}
! 
! \begin{classdesc}{Type}{type}
! An OSA type value with the given 4-character name.
! \end{classdesc}
! 
! \begin{classdesc}{Keyword}{name}
! An OSA keyword with the given 4-character name.
! \end{classdesc}
! 
! \begin{classdesc}{Range}{start, stop}
! A range.
! \end{classdesc}
! 
! \begin{classdesc}{Ordinal}{abso}
! Non-numeric absolute positions, such as \code{"firs"}, first, or \code{"midd"},
! middle.
! \end{classdesc}
! 
! \begin{classdesc}{Logical}{logc, term}
! The logical expression of applying operator \code{logc} to
! \code{term}.
! \end{classdesc}
! 
! \begin{classdesc}{Comparison}{obj1, relo, obj2}
! The comparison \code{relo} of \code{obj1} to \code{obj2}.
! \end{classdesc}
! 
! The following classes are used as base classes by the generated stub
! packages to represent AppleScript classes and properties in Python:
! 
! \begin{classdesc}{ComponentItem}{which\optional{, fr}}
! Abstract baseclass for an OSA class. The subclass should set the class
! attribute \code{want} to the 4-character OSA class code. Instances of
! subclasses of this class are equivalent to AppleScript Object
! Specifiers. Upon instantiation you should pass a selector in
! \code{which}, and optionally a parent object in \code{fr}.
! \end{classdesc}
! 
! \begin{classdesc}{NProperty}{fr}
! Abstract basclass for an OSA property. The subclass should set the class
! attributes \code{want} and \code{which} to designate which property we
! are talking about. Instances of subclasses of this class are Object
! Specifiers.
! \end{classdesc}
! 
! \begin{classdesc}{ObjectSpecifier}{want, form, seld\optional{, fr}}
! Base class of \code{ComponentItem} and \code{NProperty}, a general
! OSA Object Specifier. See the Apple Open Scripting Architecture
! documentation for the parameters. Note that this class is not abstract.
  \end{classdesc}
  

Index: mac.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/mac/mac.tex,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** mac.tex	12 Feb 2003 09:58:33 -0000	1.10
--- mac.tex	11 Apr 2003 15:35:27 -0000	1.11
***************
*** 58,64 ****
  \input{libmacui}
  \input{libframework}
! \input{libminiae}
! \input{libaepack}
! \input{libaetypes}
  
  \input{toolbox}                         % MacOS Toolbox Modules
--- 58,63 ----
  \input{libmacui}
  \input{libframework}
! 
! \input{scripting}
  
  \input{toolbox}                         % MacOS Toolbox Modules

Index: using.tex
===================================================================
RCS file: /cvsroot/python/python/dist/src/Doc/mac/using.tex,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** using.tex	9 Apr 2003 15:12:38 -0000	1.7
--- using.tex	11 Apr 2003 15:35:28 -0000	1.8
***************
*** 68,75 ****
  \file{/usr/local/bin} is in your shell search path before \file{/usr/bin},
  where the Apple-supplied Python lives (which is version 2.2, as of Mac OS X
! 10.2.4). There is one Mac OS X quirk that you need to be aware of: programs
! that talk to the window manager (in other words, anything that has a GUI)
! need to be run in a special way. Use \program{pythonw} in stead of \program{python}
! to start such scripts.
  
  To run your script from the Finder you have two options:
--- 68,72 ----
  \file{/usr/local/bin} is in your shell search path before \file{/usr/bin},
  where the Apple-supplied Python lives (which is version 2.2, as of Mac OS X
! 10.2.4). 
  
  To run your script from the Finder you have two options:
***************
*** 84,87 ****
--- 81,91 ----
  Option-dragging allows you to change these for one invocation, or use its
  Preferences menu to change things globally.
+ 
+ \subsection{Running scripts with a GUI \label{osx-gui-scripts}}
+ 
+ There is one Mac OS X quirk that you need to be aware of: programs
+ that talk to the Aqua window manager (in other words, anything that has a GUI)
+ need to be run in a special way. Use \program{pythonw} in stead of \program{python}
+ to start such scripts.
  
  \subsection{configuration}