Des actualités personnelles sous un style impersonnel, et inversement.
Follow @Thomas_Jannaud
Le langage AppleScript est un peu au Mac ce que le VBA est à Windows : une syntaxe simple que l'on utilise pour développer rapidement de petites applications. S'il reste loin derrière Python ou Bash, sa grande force réside dans sa capacité à communiquer simplement avec d'autres applications, comme iTunes ou le Finder. Un débutant aura peut être plus envie de commencer avec AppleScript. Il y a aussi possibilité dans nos programmes Cocoa / Objective-C de laisser des endroits qui rendront notre application scriptable.
AppleScript est somme toute assez limité en vitesse et je conseille donc de n'utiliser AppleScript que pour faire des scripts qui communiquent, automatiser des tâches avec Automator, ...
Exemple : je télécharge 100 chansons de Claude François, numérotées 01 - Si j'avais un marteau, 02 - Belles belles belles, 03 - ...
alors que moi j'aime bien avoir Claude François - Si j'avais un marteau, Claude François - Belles belles belles, ...
Au lieu de renommer à la main 100 fichiers je lance un petit script !
Il vous faut au départ un ordinateur Mac. Vous pouvez ensuite utiliser XCode ou 'Editeur de scripts'.
Je vous conseille d'utiliser le premier pour les applications un petit peu poussées, avec une interface graphique (i.e une ou plusieurs fenêtres,
des boutons, des onglets, ...) et le deuxième pour débuter et apprendre à maîtriser le langage.
J'utilise souvent 'Editeur de scripts' pour tester juste une partie du code, rapidement, que je tape dans XCode, pour ne pas avoir à relancer tout un projet à chaque fois, ou pour tester l'utilisation d'une commande quand je la vois sur un site (que je note ensuite dans un doc texte, d'où l'idée de ce site). Il ne faut pas avoir peur de tester dans l'Editeur toutes les choses sur lesquelles on n'est pas sur. C'est le meilleur moyen de progresser.
Dans codes sources vous accéderez à deux tutoriels Applescript plus que généreux sur les explications (mais aussi plus longs à lire), ainsi qu'à mes codes. Vous trouverez dans le dossier Developer de votre Mac un dossier 'Examples' avec beaucoup d'exemples dans beaucoup de langages, y compris Applescript.
Les éditions O'Reilly sont réputées pour leurs livres de qualité, je ne saurais que trop les recommander aussi.
D'autre part, par expérience, vous verrez qu'un site internet ne remplacera jamais un livre papier.
Cette version est en français.
Rappel : [n] désigne que n est un paramètre optionnel
global x
property x : 5
set x to 2
set l to {3, "bonjour", {"une", "sous", "liste"}, 17}
if ... then
...
else if ... then
...
else
...
end if
try
...
on error [message erreur, n° d'erreur]
...
end try
repeat n times
...
end repeat
ou
repeat while condition
...
end repeat
ou
repeat with i from 1 to 5 [by 2]
...
end repeat
ou
repeat with i in liste -- équivalent du For Each en Visual Basic ; i va itérer tous les éléments de la liste, un à un.
...
end repeat
on mafonction(a, b, c)
...
return a+b+c
end mafonction
tell app "Finder"... end tell
, alors il faudra faire
my f(x)
pour accéder à la fonction f définie au sein de votre script.
Vous aurez sinon l'erreur "impossible de poursuivre avec f".tell application "Finder" to close front window
ou bien
tell application "..."
...
end tell
tell application "iCal"
tell application "iCal"
set a to first item of calendars
set b to events of a
set c to first item of b
set dd to summary of c
end tell
Avec les listes (plus loin) vous saurez lister tous les événements très simplement.
Dans 'Editeur de Scripts' vous pouvez faire Fichier->Ouvrir Dictionnaire. Selectionnez alors une application, et vous voyez alors la liste des attributs et méthodes de celle-ci. AppleScript est donc un peu l'avatar de VB sur Mac : vous pouvez contrôler d'autres applications depuis vos scripts, mais seulement ici vous n'avez pas à chercher sur Internet les méthodes d'une dll : tout est explicite !
set a to "bonjour"
length of a
word n of a
set chaine to liste as String
chaine1 & chaine2
item ou character 4 of "bonjour"
set liste to every character of "bonjour"
set souschaine to text 6 to 9 of "bonjour, comment ça va ?"
set findechaine to text 10 to end of "bonjour, comment ça va ?"
set AppleScript’s text item delimiters to " "
texte begins with ou start with, ends with, comes before, comes after
(pour ordre alphabétique, même si < et > fonctionnent quand même),
is in, contains
ignoring case ou considering case (end ignoring et end considering)
Il n'y a aucune différence en Applescript entre l'un et l'autre, ce qui peut être déroutant au début. Mais alors direz vous, cela ralentit considérablement l'exécution des programmes d'utiliser des tableaux en Applescript, puisque l'accès à un élément est en temps O(n) dans une liste.
Et bien non. La raison (pas officielle, mais celle que je me suis faite) est que les listes sont implémentées en interne (en Applescript en tout cas) par des tableaux : quand on crée une liste, AppleScript crée un tableau beaucoup plus grand, avec un pointeur sur le début et un autre sur la fin de la liste. C'est pour ça qu'il va très vite à calculer la taille de la liste, à ajouter un élément à la fin, ou à accéder au nième élément de la liste. C'est d'ailleurs un bon exercice que d'implémenter les listes de cette manière, dans n'importe quel langage que ce soit.
Au final, c'est très agréable à utiliser puisque l'on a l'accès aux éléments comme dans un tableau, ainsi que l'ajout d'un élément en tête ou queue de liste.
set l to {3, "bonjour", {"une", "sous", "liste"}, 17}
item n of maliste
copy "toto" to the end of maliste
copy "toto" to the beginning of maliste
item 1 <-> [the] first item <-> 1st item
last item of maliste
rest list
liste1 & liste2
set item n of maliste to "toto"
items 2 through (ou thru) 5 of maliste
reverse
count of ou length of
some item of maliste
Les objets internes d'Applescript utilisent beaucoup cette structure. Ça sert à définir les propriétés d'un objet.
set enregi to {age : 20, taille : 180}
count of enregi = nombre de champs
-- information totalement inutile puisqu'il n'y a pas de commande pour connaitre le noms de champs
if enregi contains {couleur : "verte"} then ...
Le résultat d'une boite de dialogue est un enregistrement, avec les champs 'button returned', et 'text returned' si c'est une inputbox.
En faisant clic droit dans l'Editeur de scripts, puis Dialogs, on peut créer facilement n'importe quel type de boite.
display dialog texteprincipal [default answer ""] [buttons {"ok", "annuler", "stop", ...}] [default button "ok" ou default button n]
choose from list {"1- Saisir une personne", "2- Voir les personnes"} cancel button name "Quitter"
set age to (text returned of the result) as integer
AppleScript donne la possibilité de créer des objets-scripts (je ne m'en suis encore jamais servi pour être honnête)
script monPremierObjet
property age : 100
property nom : "Thomas"
on dire_mon_nom()
display dialog nom
end dire_mon_nom
end script
set Personne to monPremierObjet
tell Personne to dire_mon_nom()
ou
the dire_mon_nom() of Personne
Il faut souvent faire tell app "Finder" ... end tell
pour pouvoir utiliser les choses ci-dessous. Attention, pour
appeler une fonction de votre script dans un tell app...
, il faut faire my mafonction(x)
.
tell app "TextEdit"
set doc to open "Ordinateur:Users:Thomas:..."
set letexte to text of doc
close doc
end tell
ou
set thepath to "Ordinateur:Users:Thomas:Desktop:toto.txt" as alias
open for access thepath with write permission
write "au revoir" to thepath
ou bien
set contenu to read thepath
close access thepath
set thepath to a reference to "Ordinateur:Users:Thomas:..."
set thepath to alias "Ordinateur:Users:Thomas:..."
choose folder ["choisissez un .."]
open folder, file
path to desktop as text = ordinateur:users:thomas:desktop
tell application "Finder"
set thepath to "Ordinateur:Users:Thomas:NouveauDossier"
set a to exists thepath
if not a then make new folder at folder "Ordinateur:Users:Thomas" with properties {name:"NouveauDossier"}
end if
set maison to a reference to home
set dossierCalendriers to folder "Calendars" of folder "Library" of maison
repeat with dossier in dossierCalendriers -- boucle sur les dossiers
repeat with fichier in folder "Events" of dossier -- boucle sur les fichiers
...
end repeat
end repeat
empty the trash
close the front window
the name of the front window
open the startup disk
the second file of folder(2) of startup disk
AppleScript permet d'appeler des scripts automators simplement.
Si en Applescript on est sensé pouvoir faire des choses comme : (je cherche à imprimer une page web)
keystroke "p" using {command down}
delay 2
click menu button "PDF" of sheet 1
click menu item "Save as PDF…" of menu 1 of menu button "PDF" of sheet 1
ça ne marche pas toujours. Utiliser Automator peut être une solution.
Il faut créer un processus ("workflow") Automator et l'enregistrer comme application, et non comme processus. Pour l'appeler :
tell application "MacBook:Users:Thomas:Desktop:nomautomator.app:Contents:MacOS:nomautomator" to launch
Quelques précisions :
La gestion d'événements est intimement liée à l'existence d'une interface graphique. Pour ce faire, ouvrez XCode, créez une application Applescript, (la première proposée dans la liste des nouveaux projets), et ouvrez dans les "NIB Files" le fichier .nib. L'interface Builder se lance tout seul. Il est assez bien fait, même si je trouve que Visual Studio surpasse Xcode (de loin). Prenez alors autant d'éléments que vous voulez dans la "library" (dans le menu Tools) et faites les glisser sur la fenetre. Ouvrez ensuite la fenetre des propriétés (Tools, Inspector) pour régler... les propriétés des objets que vous venez de mettre.
Pour gérer les événements associés à ces objets, dans le dernier onglet des propriétés d'un objet, sélectionnez Applescript, et votre script. Donnez alors un nom à l'objet. (Ne donnez pas 2 noms pareils à 2 objets !). Vous pouvez alors cliquer sur les événements qui vous intéressent (comme clicked, ...).Attention, vous devez également cocher Applescript et donner un nom à tous les éléments qui contiennent l'objet en question En clair, si vous avez un bouton dans un onglet, nommez la fenetre, les onglets, l'onglet en question, et le bouton. Vous allez comprendre pourquoi dans un instant.
Contrairement à Visual Basic où les événements sont biens distincts les uns des autres, ici tout est regroupé : tous les événements "clic" sont regroupés dans la procédure on clicked theObject(). Heureusement, pour savoir quel bouton a été cliqué, on peut tester le paramètre 'theObject'.
Ex :
on clicked theObject
if the name of theObject is "boutonbonjour" then
display dialog "bonjour"
else if the name of theObject is "boutonaurevoir" then
direaurevoir()
end if
Ceci est bien sur valable pour n'importe quel événement...
Pour agir sur l'environnement graphique (sur les objets), par exemple en affichant des informations dans une zone texte, il faut faire :
set content of text field "txtnom" of window "fenetreprincipale" to "vous vous appelez Thomas"
Je pense que c'est le principal défaut d'AppleScript : c'est que c'est ultra chiant (pardonnez moi l'expression) pour accéder aux objets,
vous pouvez vous en rendre compte par vous même. (idem on peut faire set x to content of text field ... pour récupérer la valeur d'un champ,
d'une case à cocher, ...)
Une autre difficulté est que... il faut connaitre quel est le nom des propriétés des objets. De temps en temps, c'est title of, ou content of (pour savoir ce qui est écrit dans un contrôle), mais cela peut varier. Je vous conseille de vous référer à ce site d'apple pour de plus amples informations ou à Guide des Objets AppleScript si vous préférez le français.
on idle
on idle display dialog "bonjour" end idle
. Pour obtenir idle,sélectionner
File Owner (dans l'espèce de fenetre Finder qui n'en est pas une, où l'on voit le menu, ...), cocher Applescript, ... et sélectionner on idle.on awake from nib
Voici cependant quelques informations utiles : vous pouvez vous en inspirer pour deviner comment régler la propriété voulue d'un de vos objets.
label of tab view item "..."
on will select
ou on should select
set current tab view item to tab view item "tab2"
set mot to content of text field "txtbox" of tab view item "onglettoto" of tab view "tabs" of window "fenetreprincipale"
make new combo box item at end of combo box items of combo box "macombo" of window "main" with data "du texte"
contents of text field "...."
editable of text field "..."
Une espèce de tableur, assez pratique pour afficher certains types de données.
set l to {....}
set content of table view "tabviewtrain" of scroll view "scrstattrain" of window "main" to l
-- un commentaire sur une ligne
(* un commentaire
sur plusieurs lignes *)
beep [n] (n bips sinon un seul)
say "lecture d'un texte à vive voix" [using "Zarvox" ou "Trinoids" ou "Cellos" ou "Fred" ou "Victoria" ou ...]
class of valeur
load script "toto.applescript"
current date
weekday of, day of , ...
set a to (current date + 5 * days)
weeks, hours, minutes
.set aire to 5 as square kilometers ; aire as square feet
(pour la conversion)random number
tell application "System Events" to tell process "Safari"
keystroke "q" using command down
end tell
tell app iTu-nes to pause
(Rappel : ouvrir le dictionnaire des applications pour connaître toutes les commandes
possibles)delay 2
shell script "open -a Firefox http://www.google.com"
activate
activate
permet de donner la main à l'application lancée par le script (même si le script continuera de tourner en
fond). tell app xxx ... activate... end tell
Vous pouvez toujours aller voir la rubrique codes sources pour télécharger quelques scripts tout faits, notamment imprimer automatiquement des pages web (AppleScript + Automator) ou lire des événements de iCal par 2 manières différentes (lecture des fichiers, ou appel de iCal)
Laissez un commentaire !
Pas besoin de vous connecter, commencez à taper votre nom et une case "invité" apparaîtra.