version 1.1.0, dernière mise à jour le 19 octobre 2018.
À chaque fois qu'un processus implique la réalisation d'une tâche répétitive, élémentaire ou non, il faut s'interroger sur la pertinence de développer un script qui permettrait de l'automatiser et ainsi de s'affranchir des erreurs humaines (erreur de clic, faute de frappe…). En règle générale, si une tâche doi têtre réalisée plus de deux ou trois fois, il convient de l'automatiser au maximum. Pour ce faire, plusieurs langages permettent de contrôler InDesign
Le logiciel InDesign peut, à l'instar des autres produits Adobe, être automatisé par le biais de scripts. Il est possible d'utiliser plusieurs langages :
si le fichier est amené à n'être utilisé que des utilisateurs sous Mac, un script au format AppleScript
si le fichier est amené à n'être utilisé que des utilisateurs sous Windows, un script au format VBScript
enfin, si le fichier peut être utilisé indifféremment sous Windows ou Mac, un script au langage JavaScript
Dans le cadre de ce cours, nous nous limiterons à JavaScript.
Les scripts peuvent être trouvés via l'interface du logiciel, dans le menu (en français) Fenêtre→Utilitaires→Scripts.
Les scripts contenus dans le répertoire Application sont stockés dans le répertoire d'installation d'InDesign et à moins d'avoir les droits administrateur, il n'est pas possible de les modifier ou, a fortiori, d'en supprimer. Les scripts dans le répertoire Utilisateur peuvent être modifiés, et on peut en ajouter. Pour accéder au répertoire en question, il faut faire un clic droit puis « Faire apparaître dans l'Explorateur » (sous Windows) ou « Faire apparaître dans Finder » (sous Mac) :
Les scripts doivent être placés dans un des deux répertoires mentionnés précédemment. On peut ensuite les modifier avec un éditeur de texte normal, ou bien dans le logiciel ExtendScript Toolkit accessible via un clic droit quand un script est sélectionné. Le fichier doit être sauvegardé avec l'extension .jsx.
Voici un exemple de base de script :
var monDoc = app.documents.add() ;
var monBlocTexte = monDoc.pages.item(0).textFrames.add() ;
monBlocTexte.geometricBounds = ["6p", "6p", "30p", "30p"] ;
monBlocTexte.contents = "Bonjour à tous!" ;
Ce script peut être lancé simplement en double-cliquant dessus dans la fenêtre permettant d'explorer les scripts.
La première ligne déclare une variable, nommée monDoc
, qui va servir à désigner le document sur lequel on travaille. Pour cela, on ajoute à l'application (app
) un nouveau document.
La deuxième ligne déclare une nouvelle variable, nommée monBlocTexte
, qui va désigner un « bloc de texte » (text frame dans la version anglaise du logiciel) que l'on ajoute à la première page du document : monDoc.pages
permet de parcourir toutes les pages du document, items(0)
désigne la première page (et donc, items(2)
désignerait la troisième page, la numérotation des pages commençant à 0).
On spécifie ensuite les limites géométriques du bloc de texte en utilisant un tableau : les deux premières chaînes de caractères donnent les coordonnées du point en haut à gauche (dans l'ordre y, puis x), les deux suivantes les coordonnées du point en bas à droite (de même). On utilise ici le pica.
Enfin, on déclare que le contenu du bloc de texte doit être « Bonjour à tous! ».
Un commentaire, en programmation, est une annotation laissée par le programmeur mais qui n'est pas interprétée lors de l'exécution du script. Cela permet par exemple d'expliquer un morceau de code.
Quand le commentaire s'étend sur une seule ligne, on peut commencer cette ligne par //
.
Quand le commentaire doit s'étendre sur plusieurs lignes, il doit commencer par /*
et se terminer par */
.
//Une ligne
/*Deux
lignes*/
Un type de donnée désigne la nature des valeurs que peut prendre une donnée, stockée pour Javascript dans une variable. Il existe de multiples types de données en JavaScript (moins toutefois que dans la plupart des langages de programmation). On distingue :
la chaîne de caractères. Une chaîne de caractères est délimitée par des "
ou '
. Par exemple, a="Ceci est une chaîne" ;
. Si l'on doit utiliser des apostrophes ou des guillemets imbriqués, on peut faire appel à l'autre forme : "C'est une chaîne"
, voire « échapper » les caractères : 'Le duc déclara : "C\'est une affaire d\'honneur".'
Il existe d'autres caractères échappés : \b
correspond au retour arrière, \f
au saut de page, \n
au saut de ligne, \r
au retour chariot, \t
à la tabulation horizontale et finalement \\
au caractère \
lui-même.
On peut obtenir la longueur d'une chaîne de caractères avec la « propriété » length
(nous reviendrons sur cette notion de propriété plus loin.) Par exemple, si on a écrit var chaine = "Ma chaîne";
, alors chaine.length
vaut 9, soit le nombre de caractères de la chaîne.
les nombres. Il s'agit soit d'un nombre entier (par exemple 3, -456 ou 78900001), soit d'un nombre à virgule flottante (comme 3.1415 ou -745.6). Les nombres sont compris entre 224-1 et -(224), ce qui correspond à environ 10308. Certaines constantes correspondent à des valeurs particulières. Ce sont´:
les booléens, avec le type boolean
. Les variables de type booléen ne peuvent prendre que deux valeurs possibles : « vrai » (true
) ou « faux » (false)
.
JavaScript
permet de changer le type d'une variable, avec les fonctions suivantes :
parseInt()
et parseFloat()
permettent de convertir une chaîne de caractères en nombre (respectivement entier ou à virgule flottante). Si par exemple la variable x
contient la chaîne de caractères "34.7"
, parseInt(x)
renvoie 34, et parseFloat(x)
renvoie 34,7.
Number()
transforme un objet en nombre à la manière de parseFloat()
pour les chaînes de caractères.
string()
transforme un objet en chaîne de caractères.
Les variables permettent de contenir une valeur. Nous en avons déjà vu deux dans le premier exemple de script. Le nom d'une variable ne peut pas contenir de signe de ponctuation ou d'espace. Il ne peut pas commencer par un chiffre. Attention, les noms des variables (comme JavaScript dans son ensemble) sont sensibles à la casse : maVariable
et mavariable
désignent deux variables différentes. Il est recommandé d'utiliser des noms explicites pour les variables, afin que la personne programmant puisse identifier plus rapidement ce qu'elles désignent.
Un tableau permet de déclarer une variable qui doit se présenter comme une collection de valeurs. On numérote alors ces valeurs à partir de 0. Par exemple,
//Déclaration d'un tableau de 4 éléments :
var tableau1 = new Array(4) ;
//Déclaration d'un tableau dont le nombre d'éléments est a priori inconnu :
var tableau2 = new Array() ;
Pour affecter des valeurs à un tableau, plusieurs possibilités sont disponibles :
On peut affecter les valeurs l'une après l'autre :
var tableau1 = new Array(4) ;
tableau1[0]="Beurre" ;
tableau1[1]="Confiture" ;
tableau1[2]="Pain" ;
tableau1[3]="Jus de fruit" ;
On peut affecter les valeurs en une seule ligne :
var tableau1 = new Array(4) ;
tableau1=["Beurre", "Confiture", "Pain", "Jus de fruit"] ;
On peut déclarer et définir le tableau simultanément :
var tableau1 = new Array('Beurre', 'Confiture', 'Pain', 'Jus de fruit') ;
La propriété length
d'un tableau renvoie son nombre d'éléments. Par exemple...
var tableau1 = new Array('Beurre', 'Confiture', 'Pain', 'Jus de fruit') ;
alert(tableau1.length) ;
… renvoie 4.
Les opérateurs binaires sont ceux qui effectuent une opération sur deux variables ou données. Ces opérateurs sont :
-
permet de faire la soustraction de deux nombres. JavaScript
gère les conversions de types à la volée dans ce cas, et "7"-2
renvoie 5
*
permet de faire la multiplication de deux nombres. 9*2
renvoie donc 18
. JavaScript
gère aussi les conversions de types à la volée dans ce cas, et "9"*2
renvoie aussi 18
.
/
permet de faire la division du premier nombre par le second. 9/2
renvoie donc 4.5
. JavaScript
gère aussi les conversions de types à la volée dans ce cas, et "7"/2
renvoie 3.5
.
+
permet dans le cas de deux nombres leur addition, et dans le cas de deux chaînes de caractères leur concaténation. Par exemple, 2+3
renvoie 5, mais "2"+"3"
renvoie "23"
. Si cet opérateur agit sur une chaîne et un nombre, alors ce dernier est transformé en chaîne : "un"+2
renvoie donc "un2"
et 2+"3"
renvoie "23"
.
%
renvoie le reste de la division euclidienne de deux nombres. Par exemple, 9 % 2
renvoie 1
. JavaScript
opère la conversion de type aussi dans ce sens : "9" % 2
renvoie aussi 1
. Cette opérateur fonctionne aussi avec les nombres à virgule flottante : 20.4%4.8
renvoie 1.2
(ou plutôt 1.1999999999999993
selon les arrondis de calcul).
<
permet de tester si le premier nombre est strictement inférieur au second : 1<2
renvoie true
, mais 1<1
. renvoie false
.
<=
permet de tester si le premier nombre est inférieur ou égal au second : 1<=2
renvoie true
ainsi que 1<=1
.
>
permet de tester si le premier nombre est strictement supérieur au second : 1>2
renvoie false
.
>=
permet de tester si le premier nombre est supérieur ou égal au second : 1>=2
renvoie false
.
==
permet de tester l'égalité de deux nombres : 1==2
renvoie false
. JavaScript
gère la conversion de type et 1=="1"
renvoie true
.
!=
permet de tester si deux nombres sont différents : 1!=2
renvoie true
.
Ces opérateurs renvoient aussi des booléens, et opèrent sur des booléens.
&&
est le "et logique", et renvoie true
quand les deux quantités sur laquelle il opère valent true
. Par exemple, (1<2) && (chaine == "a")
renvoie true
si la variable chaine
vaut "a"
, et false
dans le cas contraire.
||
est le "ou logique", et renvoie true
quand au moins une des deux quantités sur laquelle il opèrent vaut true
. Par exemple, (1<2) && (chaine == "a")
renvoie true
dans tous les cas, car 1<2
est toujours vrai.
!
est l'opérateur logique de négation. Ainsi, !(1<2)
renvoie false
.
Une boucle permet de réaliser une suite d'instructions un nombre déterminé de fois. Par exemple…
var tab = new Array(3) ;
for (i=0;i<3;i++)
{
tab[i]=i ;
}
Vous noterez que la numérotation commence à 0. La syntaxe générale de la parenthèse après le mot-clef for
est
instruction de départ ;
condition de fin ;
instruction à exécuter à chaque fin d'itération.
La dernière instruction est souvent limitée à une incrémentation, mais lorsque la boucle ne comporte qu'une seule instruction, il est possible de l'y placer. L'exemple précédent se simplifie donc en…
var tab = new Array(3) ;
for (i=0;i<3;tab[i++]=i) ;
Les tests logiques permettent de réaliser des opérations en fonction des conditions dans lesquelles le code s'exécute. Par exemple, si l'utilisateur a entré un prénom féminin en guise d'identifiant, on peut envisager d'accorder les participes passés en fonction de ce choix.
L'instruction if
est la plus simple possible. Elle permet de tester une condition unique. Par exemple,
if (choix==1)
{
alert("Vous avez fait le premier choix") ;
}
Elle peut être complétée par l'instruction else
, qui permet d'indiquer le code à exécuter si la condition n'est pas remplie :
if (choix==1)
{
alert("Vous avez fait le premier choix") ;
}
else
{
alert("Vous n'avez pas fait le premier choix") ;
}
Parfois, il est nécessaire de répéter de mêmes portions de codes. Par exemple, on peut souhaiter afficher un résultat donné sous une certaine forme, ou bien faire un calcul répétitif. Dans ce cas, au lieu de réécrire plusieurs fois cette même portion de code, on définit ce que l’on appelle des fonctions. Ces fonctions peuvent accepter des paramètres, ou arguments, pour leur permettre de réaliser l’action désirée. Par exemple…
function
ajoute2(x) {
return x+2 ;
}
Si dans un code, on écrit var maVariable = ajoute2(28)
, cela équivaudra à affecter la valeur 28+2, soit 30, à la variable maVariable
.
Un document InDesign peut se penser comme constitué de couches successives: les paragraphes s'insèrent dans des blocs de texte, eux-même inclus dans des pages (pouvant d'ailleurs contenir rectangles, ellipses…), constituant elles-mêmes des documents. Cette structure constituées en couches imbriquées successives est le modèle objet d'InDesign ; c'est cette structure qui se retrouve quand on manipule un document avec JavaScript.
Un objet est une entité caractérisée par des propriétés. Par exemple, les propriétés d'un segment de texte incluent la police, sa couleur, sa taille… On peut consulter la valeur d'une propriété, ou la modifier, à l'aide de méthodes. Par exemple, une méthode pourrait changer la police d'un segment de texte.
En programmation orientée objet, on écrit tout d'abord l'objet, puis un point, ensuite la propriété ou la méthode. Par exemple, si maChaine
désigne une chaîne de caractères, on peut accéder à sa propriété de longueur en écrivant maChaine.length
. Nous avons déjà rencontré de telles propriétés par exemple la propriété geometricBounds des blocs de texte. Nous avons aussi déjà rencontré des méthodes, quand nous ajoutions des blocs de texte à un document existant : onBlocTexte = monDoc.pages.item(0).textFrames.add()
.
Dans ExtendScript Toolkit, il est possible à tout moment d'obtenir toutes les informations sur un objet, ses propriétés et ses méthodes en ouvrant l'« outil de visualisation d'Object Model », puis en sélectionnant le modèle objet de la version d'InDesign en cours d'utilisation.
On peut ensuite explorer tous les objets disponibles, avoir un aperçu de l'ensemble de leur propriétés et méthodes, et des détails sur chacune d'entre elles
Toutes les options disponibles dans la mise en forme d'un bloc de texte peuvent être réglées avec le script. Cependant, les changements de style ne peuvent pas être appliqués directement au bloc de texte, mais au(x) paragraphe(s) qu'il contient. De même que pour les pages et les blocs de texte, étant donné un bloc de texte donné nommé blocTexte
, on a accès au premier paragraphe en écrivant monPara=blocTexte.paragraphs.item(0)
. C'est à monPara
que le style peut être appliqué.
Modifier le style d'un paragraphe est utile, mais si ce style doit être appliqué à plusieurs paragraphes, voire un document entier cela peut être fastidieux. InDesign offre la possibilité de nommer des styles pour les appliquer à des paragraphes : monStyle = monDoc.paragraphStyles.add("NouveauStyle");
On peut ensuite appliquer ce style à un paragraphe (identifié par exemple par p1
), en écrivant p1.applyParagraphStyle(monStyle, true);
Cette création est mise à disposition par Gilles Chagnon sous un contrat Creative Commons.