Script to merge data from Numbers into Pages, export as PDF and email

Hi,

I am wondering if it would be possible to achieve the following with an applescript:

  1. Merge Names from Numbers into a multi-page Pages document.
  2. Export each page of the resulting document as a PDF
  3. Attach each of these PDFs to an email with specific text in the body of the email, setting the subject, the ‘from’ email address, as well as the ‘to’ email address from a field in the Numbers document.
  4. Optionally send the emails automatically.

I would be glad to know if this is possible before I embark on trying to write such a script, and for any advice/script that would help me on my way.

Thanks,

Nick

As far as I know, the 1st step is complicated and I’m not sure that it may be achieved.
There is no provision to drive this feature thru plain AppleScript.
Everything would be driven by GUIScripting.
As I’m curious, I will try to do the trick.

For other steps I have all the tools allowing to do the trick.

(a) two ways to split the result of the merge task in separate PDFs.

(b) script to create mails with embedded attachment. (I will have to retrieve this one).

First way to split.

This one use plain AppleScript.
To achieve this goal, it duplicate the Pages document created by the merge feature,
remove every sections minus one,
save the one section file in a PDF.


--{code}
--[SCRIPT splitMergedFile]
(*
Enregistrer le script en tant que Script : splitMergedFile.scpt
déplacer le fichier ainsi créé dans le dossier
<VolumeDeDémarrage>:Users:<votreCompte>:Library:Scripts:Applications:Pages:
Il vous faudra peut-être créer le dossier Pages et peut-être même le dossier Applications.

Ouvrir le document Mise en pages résultant d'une fusion de données
menu Scripts > Pages > splitMergedFile
crée un fichier PDF pour chaque section du document.

--=====

L'aide du Finder explique:
L'Utilitaire AppleScript permet d'activer le Menu des scripts :
Ouvrez l'Utilitaire AppleScript situé dans le dossier Applications/AppleScript.
Cochez la case "Afficher le menu des scripts dans la barre de menus".

--=====

Save the script as a Script: splitMergedFile.scpt

Move the newly created file into the folder:
<startup Volume>:Users:<yourAccount>:Library:Scripts:Applications:Pages:
Maybe you would have to create the folder Pages and even the folder Applications by yourself.

Open the Layout document build by a Merge session.
menu Scripts > Pages > splitMergedFile
create a PDF for every embedded section.

--=====

The Finder's Help explains:
To make the Script menu appear:
Open the AppleScript utility located in Applications/AppleScript.
Select the "Show Script Menu in menu bar" checkbox.

--=====

Yvan KOENIG (VALLAURIS, France)
2010/05/11
*)
--=====
(*
Some global constants
*)

property targetFolderName : "Merged pages or sections"

property folderOnDesktop : true
(*
true = stores the PDFs in a folder on the Desktop
false = stores the PDFs in a subfolder of the Documents folder
*)
property useDateStamp : false
(*
true = inserts a dateTimeStamp in the names of PDFs
false = doesn't insert a dateTimeStamp in the names of PDFs
*)

--=====

on run
	
	tell application "Pages"
		set dName to name of document 1
		tell document 1
			set maybe to (get body text) is missing value
		end tell
	end tell -- Pages
	
	
	if not maybe then
		if my parleAnglais() then
			error "The document "" & dName & "" is not a Layout one !"
		else
			error """ & dName & "" n'est pas un document Mise en page !"
		end if -- parleAnglais.
	end if -- not maybe.
	(*
	Build some constants
(1) Prepare a folder to store the PDF reports 
*)
	if folderOnDesktop then
		set p2d to path to desktop folder as text
	else
		set p2d to path to documents folder as text
	end if
	
	set targetFolder to p2d & targetFolderName & ":"
	tell application "System Events"
		if not (exists folder targetFolder) then make new folder at end of folder p2d with properties {name:targetFolderName}
	end tell -- System Events
	(*
(2) Grabs the path to the source spreadsheet
*)
	tell application "Pages" to set thePath to path of document dName (* an Unix path *)
	tell application "System Events" to set thePath to (path of disk item thePath) as text
	(*
(3) Build the name and the path of the temporary Pages document
*)
	set tempFolderHFS to path to temporary items
	set tempDoc to (tempFolderHFS as text) & dName
	tell application "System Events"
		if exists disk item tempDoc then delete disk item tempDoc
	end tell
	tell application "Pages" to tell document dName
		set nbSections to count of sections
	end tell -- Pages
	(*
*************************
* Here we enter the main loop 
*************************
*)
	repeat with i from 1 to nbSections
		
		set sectionID to i
		(*
Grabs datas to build the name of the PDF then
save the document with the temporary sheet in the temporary folder
*)
		tell application "System Events" to make new file at end of tempFolderHFS with properties {name:dName}
		set fullName to dName & "_section#" & text -5 thru -1 of ("00000" & sectionID)
		tell application "Pages"
			save document dName in (tempDoc as alias)
		end tell -- Pages
		(*
Now, the displayed document is the one stored in the temporary items folder.
		
Builds the name and the pathname of the student's PDF.
*)
		if useDateStamp then
			set pdfName to fullName & my dateTimeStamp() & ".pdf"
		else
			set pdfName to fullName & ".pdf"
		end if -- useDateStamp
		set pdfPath to targetFolder & pdfName
		(*
Create the PDF file
*)
		tell application "System Events" to make new file at end of folder targetFolder with properties {name:pdfName}
		
		tell application "Pages"
			tell document dName
				if sectionID < nbSections then
					repeat with s from nbSections to (sectionID + 1) by -1
						delete section s
					end repeat
				end if
				if sectionID > 1 then
					repeat with s from 1 to (sectionID - 1)
						delete section s
					end repeat
				end if
			end tell -- temporary document 
			save document dName as "SLDocumentTypePDF" in (pdfPath as alias)
			close document dName without saving
		end tell -- Pages
		tell application "System Events" to delete disk item tempDoc
		
		tell application "Pages"
			open (thePath as alias)
			repeat until exists document dName
				delay 0.2
			end repeat
		end tell -- Pages
		
	end repeat -- for next section
	
end run

--=====

on parleAnglais()
	local z
	try
		tell application "Pages" to set z to localized string "Cancel"
	on error
		set z to "Cancel"
	end try
	return (z is not "Annuler")
end parleAnglais

--=====

on dateTimeStamp()
	return (do shell script "date +_%Y%m%d-%H%M%S")
end dateTimeStamp

--=====
--[/SCRIPT]
--{code}

Second way to split.

Open the link : http://www.cs.cmu.edu/~benhdj/Mac/unix.html#splitPDF
to grab the Python file Split.py whose name describe what it is designed to achieve : split a PDF file.

Store the downloaded file at the root of your startup volume, say :
Macintosh HD:splitPDF.py
Exec this three lines Applescript (enabler.scpt):


--{code}
set splitter to (path to startup disk as text) & "splitPDF.py"
set splitter to quoted form of POSIX path of splitter
do shell script "chmod a+x " & splitter
--{code}

to get an executable command.

Trigger the terminal man command to get its way of use :

#!/usr/bin/python

“”“Splits an input pdf file into several given a list of split-
ting points (page numbers). “””

author = ‘benhdj@cs.cmu.edu (Benjamin Han)’

import sys import os

from CoreGraphics import *

def Usage ():
print “”" Usage: splitPDF.py inputFN splitPageNum1 splitPa-
geNum2 …

  • inputFN: the path to the input pdf file.

  • splitPageNum1, …: each one is a positive integer; the num-
    bers
    must not exceed the number of pages of the input file, and
    the
    entire sequence must be strictly increasing.

Example: splitPDF.py input.pdf 3 5

This will split file input.pdf into 3 files (assuming input.pdf
is 10 pages long):

  • input.part1.1_3.pdf contains page 1-3;

  • input.part2.4_5.pdf contains page 4-5;

  • input.part3.6_10.pdf contains page 6-10.

“”"

if len(sys.argv) < 3:
Usage()
sys.exit(1) else:
inputFN = sys.argv[1]
inputDoc = CGPDFDocumentCreateWithProvider( CGDat-
aProviderCreateWithFilename(inputFN))

if inputDoc:
maxPages = inputDoc.getNumberOfPages()
print ‘%s has %d pages’ % (inputFN, maxPages)
else:
sys.exit(2)

try:
splitPageNums = map(int, sys.argv[2:])
except:
print ‘Error: invalid split page number(s).’

for i, splitPageNum in enumerate(splitPageNums):
if splitPageNum < 1 or splitPageNum > maxPages:
print ‘Error: a split page number must be >= 1 and <= %d.’
% maxPages
sys.exit(3)
elif i and splitPageNums[i - 1] >= splitPageNum:
print ‘Error: split page numbers must be increasing.’
sys.exit(4)

baseFN = os.path.splitext(os.path.basename(inputFN))[0] pageRect
= CGRectMake (0, 0, 612, 792)

if splitPageNums[-1] < maxPages:
splitPageNums.append(maxPages)

Use this other script to split the PDF built thru Export the meted Pages document in a PDF.


--{code}
--[SCRIPT découpe_PDFs.scpt]
--=====
(*
utilisation décrite dans aVosMac n°108

Yvan KOENIG (VALLAURIS, France)
2010/06/12
2010/06/13 - ajouté le déplacement dans le dossier Documents:PDFs_découpés.
2011/08/23 - add ability to define the count of pages of splitted PDFs
*)
--=====

property nom_dossier : "PDFs_découpés"

--=====
(*
Point d'entrée utilisé lorsqu'on double clique l'icône 
du script enregistré comme progiciel (application sous 10.6.x).
Si on l'a enregistré en tant que fichier script on peut l'exécuter
dans l'éditeur de scripts ou depuis le menu Scripts.
*)
on run
	set un_fichier to choose file of type {"com.adobe.pdf"} without invisibles
	
	my commun(un_fichier)
end run

--=====
(*
Point d'entrée utilisé lorsqu'on glisse & dépose l'icône d'un fichier PDF
sur celle du script enregistré en tant que progiciel (application sous 10.6.x).
*)
on open sel
	my commun(item 1 of sel)
end open

--=====

on commun(le_fichier)
	local p2startup, dossier_Documents
	local dossier_de_stockage, dossier_de_stockage_unix, Date_Heure
	local le_script, message_d_erreur, nbPages, _
	local ancien_contenu, nouveau_contenu, un_fichier, nom_du_fichier, nouveau_nom
	
	set p2startup to (path to startup disk) as text
	(*
Define the count of pages of splitted PDFs to create.
1, 4, 8, 12 are commun values *)
	repeat
		set pages_per_PDF to text returned of (display dialog "How many pages per splitted PDFs" default answer "8")
		try
			pages_per_PDF * 1
			exit repeat
		on error
			beep 1
		end try
	end repeat
	
	set dossier_Documents to (path to documents folder) as text
	(*
ATTENTION : ne pas omettre le caractère deux points à la fin de dossier_de_stockage !
*)
	set dossier_de_stockage to dossier_Documents & nom_dossier
	if dossier_de_stockage does not end with ":" then set dossier_de_stockage to dossier_de_stockage & ":"
	set dossier_de_stockage_unix to quoted form of POSIX path of dossier_de_stockage
	
	tell application "System Events"
		if not (exists folder dossier_de_stockage) then
			make new folder at end of folder dossier_Documents ¬
				with properties {name:nom_dossier}
		end if
	end tell -- System Events
	
	set Date_Heure to do shell script "date +_%Y%m%d-%H%M%S_"
	
	if type identifier of (info for le_fichier) is "com.adobe.pdf" then
		set le_script to "/splitPDF.py " & quoted form of POSIX path of le_fichier & space
		try
			(*
requête incongrue vouée à l'échec
*)
			do shell script le_script & "0 0"
		on error message_d_erreur
			(*
Récupère la liste des fichiers existants à la racine du disque de démarrage
*)
			tell application "System Events"
				set ancien_contenu to path of every file of folder p2startup
			end tell
			
			set nbPages to last word of message_d_erreur
			set _ to {}
			repeat with i from pages_per_PDF to nbPages by pages_per_PDF
				copy i to end of _
			end repeat
			my recolle(_, space)
			(*
On peut enfin appeler correctement le script Python !
*)
			do shell script le_script & result
			(*
Récupère la liste des fichiers existant maintenant à la racine du disque de démarrage
*)
			tell application "System Events"
				set nouveau_contenu to path of every file of folder p2startup
			end tell
			
			repeat with un_fichier in nouveau_contenu
				if (un_fichier is not in ancien_contenu) and ¬
					type identifier of (info for file un_fichier) is "com.adobe.pdf" then
					(*
C'est un fichier PDF nouvellement créé, il faut le déplacer.
Préfèrant ne pas utiliser le Finder en raison de sa lenteur exaspérante,
il faut gérer la présence éventuelle d'un fichier homonyme dans le dossier destination.
Dans ce cas une chaine date_heure est placée au début du nom de fichier.
Ainsi il n'y aura pas de doublon et les fichiers d'une même opération seront contigus.
*)
					tell application "System Events"
						set nom_du_fichier to name of file un_fichier
						if exists file (dossier_de_stockage & nom_du_fichier) then
							set nouveau_nom to Date_Heure & nom_du_fichier
							set name of file un_fichier to nouveau_nom
							set un_fichier to p2startup & nouveau_nom
						end if -- exists file.
					end tell -- System Events
					do shell script "mv -n " & quoted form of POSIX path of un_fichier & ¬
						space & dossier_de_stockage_unix
				end if -- (un_fichier is not.
			end repeat -- with un_fichier.
		end try
	end if -- type identifier of (info for.
	
end commun

--=====

on recolle(l, d)
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

--=====
--[/SCRIPT]
--{code}


You may play with these codes.
Now, I will
(1) try to retrieve the script creating the mails
(2) drive the Merge feature.

CAUTION : I wrote these codes when I used Snow Leopard. I never ran them under Lion.

Yvan KOENIG (VALLAURIS, France) vendredi 2 janvier 2011 10:59:17

It appears that the splitPDF.py code is not compatible with Lion.

When I run it, I get the report :

do shell script “/splitPDF.py ‘/private/var/folders/16/dth32kv50459qlvqdfn90z000000gn/T/TemporaryItems/_20111202_181815.pdf’ 8 16 20”
→ error “Dec 2 18:18:16 Macintosh.local python[3908] : CGDataConsumerCreateWithFilename: failed to open /_20111202_181815.part1.1_8.pdf' for writing: Permission denied. deflateEnd: error -3: (null). Dec 2 18:18:16 Macintosh.local python[3908] <Error>: CGPDFContextCreate: failed to create PDF context delegate. Dec 2 18:18:16 Macintosh.local python[3908] <Error>: The function CGPDFDocumentGetMediaBox’ is obsolete and will be removed in an upcoming update. Unfortunately, this application, or a library it uses, is using this obsolete function, and is thereby contributing to an overall degradation of system performance. Please use `CGPDFPageGetBoxRect’ instead.
Traceback (most recent call last):
File "/splitPDF.py", line 86, in
writeContext.beginPage(mediaBox)
AttributeError: ‘NoneType’ object has no attribute ‘beginPage’” number 1

I ignore all about Python but maybe someone here would be able to update this code.

At this time, I have a script which apply the merge task and export the resulting Pages document in a PDF.

As I’m not sure to get a new version of the script Python, I will try to apply the alternate scheme.

Yvan KOENIG (VALLAURIS, France) vendredi 2 janvier 2011 18:35:00

Oops, I don’t know why my first message is duplicated. I will try to remove this duplicate.

Bingo, I deleted it.

Here is a script achieving the entire goal.

I just use a fake instruction to get the recipient’s mail address.


property pour_tester : true
(*
true = we test the script
false = we want to send the mails
*)
property targetFolderName : "Merged pages or sections"

tell application "Pages" to activate
tell application "System Events" to tell process "Pages"
	(*
Get name of current document *)
	set sourceName to name of first window whose subrole is "AXStandardWindow"
	(*
Prepare the loop which would close the sheet "Your document has been changed. " *)
	set nbw to count of (every window whose subrole is "AXStandardWindow")
	
	tell menu bar 1 to tell menu bar item 4 to tell menu 1 to click menu item 20
	
	repeat 5 times
		if exists first sheet of window sourceName then
			click first button of first sheet of window sourceName
			exit repeat
		end if
	end repeat
	repeat while nbw = (count of (every window whose subrole is "AXStandardWindow"))
		--
	end repeat
end tell -- System Events
(*
Here, merge is achieved
*)

set tempFolderHFS to path to temporary items (* from local domain *)

set p2d to path to documents folder as text

set targetFolder to p2d & targetFolderName & ":"
tell application "System Events"
	if not (exists folder targetFolder) then make new folder at end of folder p2d with properties {name:targetFolderName}
end tell -- System Events

set |fusionné| to my dateTimeStamp() & ".pages"

tell application "Pages"
	set nbSections to count of sections of document 1
	set name of document 1 to |fusionné|
	
	set thePath to p2d & |fusionné|
	save document |fusionné| in thePath
	close document 1 without saving
	open file thePath
end tell -- Pages

(*
Build the name and the path of the temporary Pages document
*)
set tempDoc to (tempFolderHFS as text) & |fusionné|
tell application "System Events"
	if exists disk item tempDoc then delete disk item tempDoc
end tell
(*
*************************
* Here we enter the main loop 
*************************
*)
repeat with i from 1 to nbSections
	
	set sectionID to i
	(*
Grabs datas to build the name of the PDF then
save the merged document in the temporary folder
*)
	tell application "System Events" to make new file at end of tempFolderHFS with properties {name:|fusionné|}
	
	tell application "Pages"
		save document |fusionné| in (tempDoc as alias)
	end tell -- Pages
	(*
Now, the displayed document is the one stored in the temporary items folder.
		
Builds the name and the pathname of the individual PDF.
*)
	set pdfName to |fusionné| & "_section#" & text -5 thru -1 of ("00000" & sectionID) & my dateTimeStamp() & ".pdf"
	
	set pdfPath to targetFolder & pdfName
	(*
Create the PDF file
*)
	tell application "System Events" to make new file at end of folder targetFolder with properties {name:pdfName}
	
	tell application "Pages"
		tell document |fusionné|
			if sectionID < nbSections then
				repeat with s from nbSections to (sectionID + 1) by -1
					delete section s
				end repeat
			end if
			if sectionID > 1 then
				repeat with s from (sectionID - 1) to 1 by -1
					delete section s
				end repeat
			end if
		end tell -- temporary document 
		save document |fusionné| as "SLDocumentTypePDF" in (pdfPath as alias)
		close document |fusionné| without saving
	end tell -- Pages
	tell application "System Events" to delete disk item tempDoc
	(*
Add code to extract the mail_address of the correspondant from the Spreadsheet. 
Here I use a fake one *)
	set destinataire to "trucmuche." & sectionID & "@em.com"
	my build_a_mail(pdfPath as alias, destinataire)
	
	tell application "Pages"
		open (thePath as alias)
		repeat until exists document |fusionné|
			delay 0.2
		end repeat
	end tell -- Pages
	
end repeat -- for next section

--=====

on dateTimeStamp()
	return (do shell script "date +_%Y%m%d-%H%M%S")
end dateTimeStamp

--=====

on build_a_mail(un_pdf, le_destinataire)
	local le_sujet, le_corps
	set le_sujet to "Coucou"
	set le_corps to "Veuillez étudier le PDF joint."
	
	tell application "Mail"
		set nouveau_message to make new outgoing message ¬
			with properties {subject:le_sujet, content:le_corps, visible:true}
		tell nouveau_message
			make new to recipient at end of to recipients with properties {address:le_destinataire}
			repeat 3 times
				make new paragraph at end of content with data linefeed
			end repeat
			make new attachment at end of last paragraph of content with properties {file name:un_pdf}
			if not pour_tester then
				send
				close without saving
			end if
		end tell
	end tell -- Mail
end build_a_mail

--=====

Yvan KOENIG (VALLAURIS, France) vendredi 2 janvier 2011 23:12:27

Hi Yvan,

Thanks very much for this script. Does the last version of the script actually do the merging as well as the generating of PDF attachments, and, if so, from what file does the script get the names to merge into the Pages document, as I can’t see a Numbers file referred to in the script? My hope was that the script could pull the name and the email address from a Numbers table.

Best Wishes,

Nick

Here is a new version.

The Pages document in which we merge is supposed to be open at front.
At this time I am unable to extract the path to the the Numbers file from the Merge dialog so I can’t automate the extraction of mail addresses from it.

So, I defined an other scheme:

I use a paragraph in the Pages document ending with :
mail :

This way it’s easy to grab the address from the merged Pages document.

Here is the script.


--{code}
--[SCRIPT merge-to-PDFs#2]
(*
Enregistrer le script en tant que Script : merge-to-PDFs#2.scpt
déplacer le fichier ainsi créé dans le dossier
<VolumeDeDémarrage>:Utilisateurs:<votreCompte>:Bibliothèque:Scripts:Applications:Pages:
Il vous faudra peut-être créer le dossier Pages et peut-être même le dossier Applications.

Ouvrir le document Pages dans lequel sera effectuée la fusion.
Un paragraphe est censé se terminer par :
"mail : <champ adresse mail>"
Aller au menu Scripts , choisir Pages puis choisir "merge-to-PDFs#2"
Le script
exécute la fusion
découpe le document généré en documents individuels d'où il extrait l'adresse mail du destinataire
enregistre chaque document individuel en PDF
crée un mail contenant le PDF en pièce jointe.
Si la property pour_tester a la valeur false, les mails sont automatiquement expédiés.

--=====

L'aide du Finder explique:
L'Utilitaire AppleScript permet d'activer le Menu des scripts :
Ouvrez l'Utilitaire AppleScript situé dans le dossier Applications/AppleScript.
Cochez la case "Afficher le menu des scripts dans la barre de menus".
Sous 10.6.x,
aller dans le panneau "Général" du dialogue Préférences de l'Éditeur Applescript
puis cocher la case "Afficher le menu des scripts dans la barre des menus".

--=====

Save the script as a Script: merge-to-PDFs#2.scpt

Move the newly created file into the folder:
<startup Volume>:Users:<yourAccount>:Library:Scripts:Applications:Pages:
Maybe you would have to create the folder Pages and even the folder Applications by yourself.

Open the Pages document in which we will merge.
A paragraph is supposed to end with :
"mail : <merge field mailto>"
Go to the Scripts Menu, choose Pages, then choose "merge-to-PDFs#2"
The script
execute the merge task
split the resulting document in individual ones from which it extracts the target mail address
save each individual document as PDF
create a mail embedding a PDF as attachment.
If the value of the property pour_tester is false, the mails are automatically sent.

--=====

The Finder's Help explains:
To make the Script menu appear:
Open the AppleScript utility located in Applications/AppleScript.
Select the "Show Script Menu in menu bar" checkbox.
Under 10.6.x,
go to the General panel of AppleScript Editor's Preferences dialog box
and check the "Show Script menu in menu bar" option.

--=====

Yvan KOENIG (VALLAURIS, France)
2011/12/03
*)
--=====

property pour_tester : true
(*
true = we test the script
false = we want to send the mails
*)

on run
	local nomSource, nbw, p2d, |fusionné|, nbSections, |chemin_du_fusionné|
	local Pages_temporaire, sectionID, chemin_des_PDFs, |texte_personnalisé|, destinataire
	tell application "Pages" to activate
	tell application "System Events" to tell process "Pages"
		(*
Get name of current document *)
		set nomSource to name of first window whose subrole is "AXStandardWindow"
		(*
Prepare the loop which would close the sheet "Your document has been changed. " *)
		set nbw to count of (every window whose subrole is "AXStandardWindow")
		
		tell menu bar 1 to tell menu bar item 4 to tell menu 1 to click menu item 20
		
		repeat 5 times
			if exists first sheet of window nomSource then
				click first button of first sheet of window nomSource
				exit repeat
			end if
		end repeat
		repeat while nbw = (count of (every window whose subrole is "AXStandardWindow"))
			--
		end repeat
	end tell -- System Events
	(*
Here, merge is achieved
*)
	(*
Builds an unique name for the merged Pages document *)
	if nomSource ends with ".pages" then
		set |fusionné_court| to (text 1 thru -7 of nomSource) & my dateTimeStamp()
	else
		set |fusionné_court| to nomSource & my dateTimeStamp()
	end if
	set |fusionné| to |fusionné_court| & ".pages"
	
	set p2d to path to documents folder as text
	set |chemin_du_fusionné| to p2d & |fusionné|
	set chemin_des_PDFs to p2d & |fusionné_court| & ".pdf"
	
	tell application "Pages"
		set nbSections to count of sections of document 1
		set name of document 1 to |fusionné|
		save document |fusionné| in |chemin_du_fusionné|
		close document 1
	end tell -- Pages
	(*
Builds the path of the temporary Pages document
*)
	set Pages_temporaire to (path to temporary items as text) & |fusionné|
	tell application "System Events"
		if exists disk item Pages_temporaire then delete disk item Pages_temporaire
	end tell
	(*
*************************
* Here we enter the main loop 
*************************
*)
	repeat with sectionID from 1 to nbSections
		(*
Create a temporary duplicate of the merged file
*)
		do shell script "cp -R " & quoted form of POSIX path of |chemin_du_fusionné| & " " & quoted form of POSIX path of Pages_temporaire
		(*
Open the temporary file *)
		tell application "Pages"
			open Pages_temporaire
			tell document 1
				(*
Remove sections after *)
				if sectionID < nbSections then
					repeat (nbSections - sectionID) times
						delete last section
					end repeat
				end if
				(*
Remove sections before *)
				if sectionID > 1 then
					repeat (sectionID - 1) times
						delete first section
					end repeat
				end if
				(*
Extracts the text content to grab the target mail address *)
				set |texte_personnalisé| to body text
			end tell -- temporary document 
			(*
Save the section file as PDF *)
			save document 1 in chemin_des_PDFs
			(*
Close the Pages section document *)
			close document 1
		end tell -- Pages
		(*
Delete the temporary Pages document *)
		tell application "System Events"
			delete disk item Pages_temporaire
		end tell
		(*
In the original Pages document,  we are supposed to find a paragraph ending with the string
"mail : " just before the merge field receiving the dest mail address. *)
		set destinataire to contents of first paragraph of item 2 of my decoupe(|texte_personnalisé|, "mail : ")
		(*
Build a mail with the attached PDF *)
		my build_a_mail(chemin_des_PDFs as alias, destinataire)
	end repeat -- for next section
	
	tell application "Pages"
		open |chemin_du_fusionné|
	end tell -- Pages
	(*
I don't understand why System Events doesn't delete the PDF 	
*)
	(*
	tell application "System Events"
		delete disk item chemin_des_PDFs
	end tell
	*)
	(*
so, I uses do Shell Script *)
	do shell script "rm " & quoted form of POSIX path of chemin_des_PDFs
end run

--=====

on dateTimeStamp()
	return (do shell script "date +_%Y%m%d-%H%M%S")
end dateTimeStamp

--=====

on decoupe(t, d)
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

--=====

on build_a_mail(un_pdf, le_destinataire)
	local le_sujet, le_corps, nouveau_message
	(*
Requires the property pour_tester	
*)
	set le_sujet to "Coucou"
	set le_corps to "Veuillez étudier le PDF joint."
	tell application "Mail"
		set nouveau_message to make new outgoing message ¬
			with properties {subject:le_sujet, content:le_corps, visible:true}
		tell nouveau_message
			make new to recipient at end of to recipients with properties {address:le_destinataire}
			
			repeat 3 times
				make new paragraph at end of content with data linefeed
			end repeat
			
			make new attachment at end of last paragraph of content with properties {file name:un_pdf}
			if not pour_tester then
				send
				close without saving
			end if
		end tell -- nouveau_message
	end tell -- Mail
end build_a_mail

--=====
--[/SCRIPT]
--{code}

My test document contain these lines:

Nom
adresse
mail : mailto

Nom is a merge field
adresse is a merge field
mailto is a merge field.

The script behave flawlessly under Lion.

If you want, go to my iDisk :
<http://public.me.com/koenigyvan>
Download :
merge-inPDFs-2-mails.sparsebundle.zip

Expand the archive.
The disk image contain :
the script
the Pages and the Numbers documents which I used for tests.
As these two documents are in a disk image, the link between them will be preserved.

Yvan KOENIG (VALLAURIS, France)  samedi 3 janvier 2011 18:54:38


Hello

(1) I enhanced the main script.
(2) I found a way to get the path to the Spreadsheet used for the merge task.
I wrote the code extracting the list of mail addresses. The unique requirement is that they are stored in a column whose header name is “mailto” in table #1 of Sheet #1.


--{code}
--[SCRIPT merge-to-PDFs#2]
(*
Enregistrer le script en tant que Script : merge-to-PDFs#2.scpt
déplacer le fichier ainsi créé dans le dossier
<VolumeDeDémarrage>:Utilisateurs:<votreCompte>:Bibliothèque:Scripts:Applications:Pages:
Il vous faudra peut-être créer le dossier Pages et peut-être même le dossier Applications.

Ouvrir le document Pages dans lequel sera effectuée la fusion.
Un paragraphe est censé se terminer par :
"mail : <champ adresse mail>"
Appliquer la couleur de texte "Blanc" si vous ne voulez pas que ces informations soient visibles dans les PDFs.
Aller au menu Scripts , choisir Pages puis choisir "merge-to-PDFs#2"
Le script
exécute la fusion
découpe le document généré en documents individuels d'où il extrait l'adresse mail du destinataire
enregistre chaque document individuel en PDF
crée un mail contenant le PDF en pièce jointe.
Si la property pour_tester a la valeur false, les mails sont automatiquement expédiés.

--=====

L'aide du Finder explique:
L'Utilitaire AppleScript permet d'activer le Menu des scripts :
Ouvrez l'Utilitaire AppleScript situé dans le dossier Applications/AppleScript.
Cochez la case "Afficher le menu des scripts dans la barre de menus".
Sous 10.6.x,
aller dans le panneau "Général" du dialogue Préférences de l'Éditeur Applescript
puis cocher la case "Afficher le menu des scripts dans la barre des menus".

--=====

Save the script as a Script: merge-to-PDFs#2.scpt

Move the newly created file into the folder:
<startup Volume>:Users:<yourAccount>:Library:Scripts:Applications:Pages:
Maybe you would have to create the folder Pages and even the folder Applications by yourself.

Open the Pages document in which we will merge.
A paragraph is supposed to end with :
"mail : <merge field mailto>"
Apply text color White if you don't want to see these infos in the PDFs.
Go to the Scripts Menu, choose Pages, then choose "merge-to-PDFs#2"
The script
execute the merge task
split the resulting document in individual ones from which it extracts the target mail address
save each individual document as PDF
create a mail embedding a PDF as attachment.
If the value of the property pour_tester is false, the mails are automatically sent.

--=====

The Finder's Help explains:
To make the Script menu appear:
Open the AppleScript utility located in Applications/AppleScript.
Select the "Show Script Menu in menu bar" checkbox.
Under 10.6.x,
go to the General panel of AppleScript Editor's Preferences dialog box
and check the "Show Script menu in menu bar" option.

--=====

Yvan KOENIG (VALLAURIS, France)
2011/12/03
2011/12/04 added code allowing to extract some infos from a text file
*)
--=====

property pour_tester : true
(*
true = we test the script
false = we want to send the mails
*)
property lire_dans_fichier : false
(*
true = grab leSujet and leCorps from a text file
false = define them in the script itself
*)
--=====

on run
	local sujet_corps, leSujet, leCorps, nomSource, nbw, p2d, |fusionné|, nbSections, |chemin_du_fusionné|
	local Pages_temporaire, sectionID, chemin_des_PDFs, |texte_personnalisé|, leDestinataire
	(*
I moved the definition of these two items here so it would be easy to edit the script if you want to grab them from a text file *)
	if lire_dans_fichier then
		tell application "System Events"
			set mon_dossier to path of container of disk item (path to me as text)
		end tell
		if my parleAnglais() then
			"Select the text file embedding mail's subject and body"
		else
			"Sélectionner le fichier texte contenant le sujet et le corps des mails"
		end if
		choose file with prompt result of type {"public.plain-text"} default location mon_dossier as alias without invisibles
		set sujet_corps to paragraphs of (read result as «class utf8»)
		set leSujet to item 1 of sujet_corps
		set leCorps to my recolle(items 2 thru -1 of sujet_corps, return)
	else
		set leSujet to "Coucou"
		set leCorps to "Veuillez étudier le PDF joint.
N'oubliez pas de répondre."
	end if
	tell application "Pages" to activate
	tell application "System Events" to tell application process "Pages"
		(*
Get name of current document *)
		set nomSource to name of first window whose subrole is "AXStandardWindow"
		(*
Prepare the loop which would close the sheet "Your document has been changed. " *)
		set nbw to count of (every window whose subrole is "AXStandardWindow")
		
		tell menu bar 1 to tell menu bar item 4 to tell menu 1 to click menu item 20
		
		repeat 5 times
			if exists first sheet of window nomSource then
				click first button of first sheet of window nomSource
				exit repeat
			end if
		end repeat
		(*
Wait while the merge feature apply *)
		repeat while nbw = (count of (every window whose subrole is "AXStandardWindow"))
			--
		end repeat
	end tell -- System Events
	(*
Here, merge is achieved
*)
	(*
Builds an unique name for the merged Pages document *)
	if nomSource ends with ".pages" then
		set |fusionné_court| to (text 1 thru -7 of nomSource) & my dateTimeStamp()
	else
		set |fusionné_court| to nomSource & my dateTimeStamp()
	end if
	set |fusionné| to |fusionné_court| & ".pages"
	
	set p2d to path to documents folder as text
	set |chemin_du_fusionné| to p2d & |fusionné|
	set chemin_des_PDFs to p2d & |fusionné_court| & ".pdf"
	
	tell application "Pages"
		set nbSections to count of sections of document 1
		set name of document 1 to |fusionné|
		save document |fusionné| in |chemin_du_fusionné|
		close document 1
	end tell -- Pages
	(*
Builds the path of the temporary Pages document
*)
	set Pages_temporaire to (path to temporary items as text) & |fusionné|
	tell application "System Events"
		if exists disk item Pages_temporaire then delete disk item Pages_temporaire
	end tell
	(*
*************************
* Here we enter the main loop 
*************************
*)
	repeat with sectionID from 1 to nbSections
		(*
Create a temporary duplicate of the merged file
*)
		do shell script "cp -R " & quoted form of POSIX path of |chemin_du_fusionné| & " " & quoted form of POSIX path of Pages_temporaire
		(*
Open the temporary file *)
		tell application "Pages"
			open Pages_temporaire
			tell document 1
				(*
Remove sections after the one to keep *)
				if sectionID < nbSections then
					repeat (nbSections - sectionID) times
						delete last section
					end repeat
				end if
				(*
Remove sections before the one to keep *)
				if sectionID > 1 then
					repeat (sectionID - 1) times
						delete first section
					end repeat
				end if
				(*
Extracts the text content to grab the target mail address *)
				set |texte_personnalisé| to body text
			end tell -- temporary document 
			(*
Save the section file as PDF *)
			save document 1 in chemin_des_PDFs
			(*
Close the Pages section document *)
			close document 1
		end tell -- Pages
		(*
Delete the temporary Pages document *)
		tell application "System Events"
			delete disk item Pages_temporaire
		end tell
		(*
In the original Pages document,  we are supposed to find a paragraph ending with the string
"mail : " just before the merge field receiving the dest mail address. *)
		set leDestinataire to contents of first paragraph of item 2 of my decoupe(|texte_personnalisé|, "mail : ")
		(*
Build a mail with the attached PDF *)
		my build_a_mail(chemin_des_PDFs as alias, leSujet, leCorps, leDestinataire)
		(*
Some providers don't like that we send many mails in a single task.
Pause from time to time to get rid of that. 
Here it pause 30 seconds every 20 mails.
Maybe you will have to edit according to your provider's requirements *)
		if (sectionID / 20) = sectionID div 20 then delay 30
	end repeat -- for next section
	(*
Here, all mails are built (maybe sent).

Open the merged file so you will be easily reach the file in the Documents folder if you want to delete it. *)
	tell application "Pages"
		open |chemin_du_fusionné|
	end tell -- Pages
	(*
I don't understand why System Events doesn't delete the PDF 	
*)
	(*
	tell application "System Events"
		delete disk item chemin_des_PDFs
	end tell
	*)
	(*
so, I uses do Shell Script *)
	do shell script "rm " & quoted form of POSIX path of chemin_des_PDFs
end run

--=====

on dateTimeStamp()
	return (do shell script "date +_%Y%m%d-%H%M%S")
end dateTimeStamp

--=====

on parleAnglais()
	local z
	try
		tell application "Pages" to set z to localized string "Cancel"
	on error
		set z to "Cancel"
	end try
	return (z is not "Annuler")
end parleAnglais

--=====

on recolle(l, d)
	local oTIDs, t
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

--=====

on decoupe(t, d)
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

--=====

on build_a_mail(un_pdf, le_sujet, le_corps, le_destinataire)
	local nouveau_message
	(*
Requires the property pour_tester	
*)
	tell application "Mail"
		set nouveau_message to make new outgoing message ¬
			with properties {subject:le_sujet, content:le_corps, visible:true}
		tell nouveau_message
			make new to recipient at end of to recipients with properties {address:le_destinataire}
			
			repeat 3 times
				make new paragraph at end of content with data linefeed
			end repeat
			
			make new attachment at end of last paragraph of content with properties {file name:un_pdf}
			if not pour_tester then
				send
				close without saving
			end if
		end tell -- nouveau_message
	end tell -- Mail
end build_a_mail

--=====
--[/SCRIPT]
--{code}


--[SCRIPT extract-mailAddresses-for-merge]
(*
Yvan KOENIG (VALLAURIS, France)
2011/12/04
*)

on run
	local pathUnix, cheminHFS, le_nom, la_classe, Pages_temporaire, chemin_index, numbers_path, les_entetes, c, maybe, les_adresses
	(*
Get some properties of the Pages document in which we are supposed to merge *)
	tell application "Pages" to set pathUnix to path of document 1
	tell application "System Events" to tell disk item pathUnix
		set cheminHFS to path
		set le_nom to name
		set la_classe to class as text
	end tell
	(*
Copy the original file to the temporary folder *)
	set Pages_temporaire to (path to temporary items as text) & le_nom
	do shell script "cp -R " & quoted form of pathUnix & " " & quoted form of POSIX path of Pages_temporaire
	(*
If the file is a flat one, expand it *)
	if la_classe is not "file package" then
		tell application "System Events" to set name of disk item Pages_temporaire to (le_nom & ".zip")
		do shell script "unzip " & quoted form of POSIX path of (Pages_temporaire & ".zip")
	end if
	(*
If the index.xml file is gzipped, ungzip it *)
	set chemin_index to Pages_temporaire & ":index.xml"
	tell application "System Events"
		exists disk item (chemin_index & ".gz")
	end tell
	if result then
		do shell script "gunzip " & quoted form of POSIX path of (chemin_index & ".gz")
	end if
	(*
Now we have a readable index.xml file. Extract the Unix path to the Numbers source file. *)
	read file chemin_index
	item 2 of my decoupe(result, "<sl:SFWPMailMergeNumbersFilenameProperty>")
	item 1 of my decoupe(result, quote & "/>")
	item 2 of my decoupe(result, "<sl:string sfa:string=" & quote)
	(*
Try to convert the Unix path in a HFS one. If it fails it means that the link between the two documents is broken *)
	try
		tell application "System Events"
			set numbers_path to path of disk item result
		end tell
	on error errMsg number errNum
		if my parleAnglais() then
			error "The link between" & return & """ & cheminHFS & """ & return & "and the Numbers source file is broken." & return & "Please, rebuild it."
		else
			error "Le lien entre" & return & "« " & cheminHFS & " »" & return & "et le tableur source est brisé. Veuillez le reconstruire."
		end if
	end try
	(*
Open the spreadsheet *)
	tell application "Numbers"
		open numbers_path
		tell document 1 to tell sheet 1 to tell table 1
			set les_entetes to value of cells of row 1
			repeat with c from 1 to count of les_entetes
				set maybe to item c of les_entetes = "mailto "
				if maybe then exit repeat
			end repeat
			(*
If there is no "mailto" column header, exit. Can't get mail addresses *)
			if not maybe then
				if not my parleAnglais() then
					error "The spreadsheet" & return & """ & numbers_path & """ & return & "doesn't embed a header named "mailto" !"
				else
					error "Le tableur" & return & "« " & numbers_path & " »" & return & "ne contient pas d'en tête de colonne « mailto » !"
				end if
			end if
			(*
Extract the addresses *)
			tell column c to set les_adresses to value of cells 2 thru -1
		end tell -- document 1
	end tell -- Numbers
	(*
Drop values from empty bottom rows *)
	repeat while item -1 of les_adresses is 0.0
		set les_adresses to items 1 thru -2 of les_adresses
	end repeat
	
	les_adresses
end run

--=====

on parleAnglais()
	local z
	try
		tell application "Pages" to set z to localized string "Cancel"
	on error
		set z to "Cancel"
	end try
	return (z is not "Annuler")
end parleAnglais

--=====

on decoupe(t, d)
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

--=====

I hope that with the embedded comments it would be easy to understand the scripts behavior and possibly to merge both.

I will upload the entire kit to my iDisk soon.
Now it’s time for dinner :wink:

Yvan KOENIG (VALLAURIS, France) dimanche 4 janvier 2011 19:23:05

Here is a version extracting the target addresses from the Numbers spreadsheet ‘linked’ to the Pages document for merge.


--{code}
--[SCRIPT merge-to-PDFs#3]
(*
Enregistrer le script en tant que Script : merge-to-PDFs#2.scpt
déplacer le fichier ainsi créé dans le dossier
<VolumeDeDémarrage>:Utilisateurs:<votreCompte>:Bibliothèque:Scripts:Applications:Pages:
Il vous faudra peut-être créer le dossier Pages et peut-être même le dossier Applications.

Ouvrir le document Pages dans lequel sera effectuée la fusion.
Aller au menu Scripts , choisir Pages puis choisir "merge-to-PDFs#3"
Le script
extrait la liste des destinataires du tableur Numbers lié au document Pages
exécute la fusion
découpe le document généré en documents individuels
enregistre chaque document individuel en PDF
crée un mail contenant le PDF en pièce jointe.
Si la property pour_tester a la valeur false, les mails sont automatiquement expédiés.

--=====

L'aide du Finder explique:
L'Utilitaire AppleScript permet d'activer le Menu des scripts :
Ouvrez l'Utilitaire AppleScript situé dans le dossier Applications/AppleScript.
Cochez la case "Afficher le menu des scripts dans la barre de menus".
Sous 10.6.x,
aller dans le panneau "Général" du dialogue Préférences de l'Éditeur Applescript
puis cocher la case "Afficher le menu des scripts dans la barre des menus".

--=====

Save the script as a Script: merge-to-PDFs#3.scpt

Move the newly created file into the folder:
<startup Volume>:Users:<yourAccount>:Library:Scripts:Applications:Pages:
Maybe you would have to create the folder Pages and even the folder Applications by yourself.

Open the Pages document in which we will merge.
Go to the Scripts Menu, choose Pages, then choose "merge-to-PDFs#3"
The script
extract the list of target address from the Numbers spreadsheet linked to the Pages document
execute the merge task
split the resulting document in individual ones
save each individual document as PDF
create a mail embedding a PDF as attachment.
If the value of the property pour_tester is false, the mails are automatically sent.

--=====

The Finder's Help explains:
To make the Script menu appear:
Open the AppleScript utility located in Applications/AppleScript.
Select the "Show Script Menu in menu bar" checkbox.
Under 10.6.x,
go to the General panel of AppleScript Editor's Preferences dialog box
and check the "Show Script menu in menu bar" option.

--=====

Yvan KOENIG (VALLAURIS, France)
2011/12/03
2011/12/04 added code allowing to extract some infos from a text file
2011/12/08 added code extracting addresses from the Numbers spreadsheet used to merge
*)
--=====

property pour_tester : true
(*
true = we test the script
false = we want to send the mails
*)
property lire_dans_fichier : false
(*
true = grab leSujet and leCorps from a text file
false = define them in the script itself
*)
--=====

on run
	local sujet_corps, leSujet, leCorps, nomSource, nbw, p2d, |fusionné|, nbSections, |chemin_du_fusionné|
	local Pages_temporaire, sectionID, chemin_des_PDFs, |texte_personnalisé|, leDestinataire
	(*
I moved the definition of these two items here so it would be easy to edit the script if you want to grab them from a text file *)
	if lire_dans_fichier then
		tell application "System Events"
			set mon_dossier to path of container of disk item (path to me as text)
		end tell
		if my parleAnglais() then
			"Select the text file embedding mail's subject and body"
		else
			"Sélectionner le fichier texte contenant le sujet et le corps des mails"
		end if
		choose file with prompt result of type {"public.plain-text"} default location mon_dossier as alias without invisibles
		set sujet_corps to paragraphs of (read result as «class utf8»)
		set leSujet to item 1 of sujet_corps
		set leCorps to my recolle(items 2 thru -1 of sujet_corps, return)
	else
		set leSujet to "Coucou"
		set leCorps to "Veuillez étudier le PDF joint.
N'oubliez pas de répondre."
	end if
	(*
Extract target addresses from the Numbers document linked to the Pages one *)
	set destinataires to my getAddresses()
	
	tell application "Pages" to activate
	tell application "System Events" to tell application process "Pages"
		(*
Get name of current document *)
		set nomSource to name of first window whose subrole is "AXStandardWindow"
		(*
Prepare the loop which would close the sheet "Your document has been changed. " *)
		set nbw to count of (every window whose subrole is "AXStandardWindow")
		
		tell menu bar 1 to tell menu bar item 4 to tell menu 1 to click menu item 20
		
		repeat 5 times
			if exists first sheet of window nomSource then
				click first button of first sheet of window nomSource
				exit repeat
			end if
		end repeat
		(*
Wait while the merge feature apply *)
		repeat while nbw = (count of (every window whose subrole is "AXStandardWindow"))
			--
		end repeat
	end tell -- System Events
	(*
Here, merge is achieved
*)
	(*
Builds an unique name for the merged Pages document *)
	if nomSource ends with ".pages" then
		set |fusionné_court| to (text 1 thru -7 of nomSource) & my dateTimeStamp()
	else
		set |fusionné_court| to nomSource & my dateTimeStamp()
	end if
	set |fusionné| to |fusionné_court| & ".pages"
	
	set p2d to path to documents folder as text
	set |chemin_du_fusionné| to p2d & |fusionné|
	set chemin_des_PDFs to p2d & |fusionné_court| & ".pdf"
	
	tell application "Pages"
		set nbSections to count of sections of document 1
		set name of document 1 to |fusionné|
		save document |fusionné| in |chemin_du_fusionné|
		close document 1
	end tell -- Pages
	(*
Builds the path of the temporary Pages document
*)
	set Pages_temporaire to (path to temporary items as text) & |fusionné|
	tell application "System Events"
		if exists disk item Pages_temporaire then delete disk item Pages_temporaire
	end tell
	(*
*************************
* Here we enter the main loop 
*************************
*)
	repeat with sectionID from 1 to nbSections
		(*
Create a temporary duplicate of the merged file
*)
		do shell script "cp -R " & quoted form of POSIX path of |chemin_du_fusionné| & " " & quoted form of POSIX path of Pages_temporaire
		(*
Open the temporary file *)
		tell application "Pages"
			open Pages_temporaire
			tell document 1
				(*
Remove sections after the one to keep *)
				if sectionID < nbSections then
					repeat (nbSections - sectionID) times
						delete last section
					end repeat
				end if
				(*
Remove sections before the one to keep *)
				if sectionID > 1 then
					repeat (sectionID - 1) times
						delete first section
					end repeat
				end if
			end tell -- temporary document 
			(*
Save the section file as PDF *)
			save document 1 in chemin_des_PDFs
			(*
Close the Pages section document *)
			close document 1
		end tell -- Pages
		(*
Delete the temporary Pages document *)
		tell application "System Events"
			delete disk item Pages_temporaire
		end tell
		(*
Grab the target address from the list extracted from the Spreadsheet *)
		set leDestinataire to item sectionID of destinataires
		(*
Build a mail with the attached PDF *)
		my build_a_mail(chemin_des_PDFs as alias, leSujet, leCorps, leDestinataire)
		(*
Some providers don't like that we send many mails in a single task.
Pause from time to time to get rid of that. 
Here it pause 30 seconds every 20 mails.
Maybe you will have to edit according to your provider's requirements *)
		if (sectionID / 20) = sectionID div 20 then delay 30
	end repeat -- for next section
	(*
Here, all mails are built (maybe sent).

Open the merged file so you will be easily reach the file in the Documents folder if you want to delete it. *)
	tell application "Pages"
		open |chemin_du_fusionné|
	end tell -- Pages
	(*
I don't understand why System Events doesn't delete the PDF 	
*)
	(*
	tell application "System Events"
		delete disk item chemin_des_PDFs
	end tell
	*)
	(*
so, I uses do Shell Script *)
	do shell script "rm " & quoted form of POSIX path of chemin_des_PDFs
end run

--=====

on getAddresses()
	local pathUnix, cheminHFS, le_nom, la_classe, Pages_temporaire, chemin_index, numbers_path, les_entetes, c, maybe, les_adresses
	(*
Get some properties of the Pages document in which we are supposed to merge *)
	tell application "Pages" to set pathUnix to path of document 1
	tell application "System Events" to tell disk item pathUnix
		set cheminHFS to path
		set le_nom to name
		set la_classe to class as text
	end tell
	(*
Copy the original file to the temporary folder *)
	set Pages_temporaire to (path to temporary items as text) & le_nom
	do shell script "cp -R " & quoted form of pathUnix & " " & quoted form of POSIX path of Pages_temporaire
	(*
If the file is a flat one, expand it *)
	if la_classe is not "file package" then
		tell application "System Events" to set name of disk item Pages_temporaire to (le_nom & ".zip")
		do shell script "unzip " & quoted form of POSIX path of (Pages_temporaire & ".zip")
	end if
	(*
If the index.xml file is gzipped, ungzip it *)
	set chemin_index to Pages_temporaire & ":index.xml"
	tell application "System Events"
		exists disk item (chemin_index & ".gz")
	end tell
	if result then
		do shell script "gunzip " & quoted form of POSIX path of (chemin_index & ".gz")
	end if
	(*
Now we have a readable index.xml file. Extract the Unix path to the Numbers source file. *)
	read file chemin_index
	item 2 of my decoupe(result, "<sl:SFWPMailMergeNumbersFilenameProperty>")
	item 1 of my decoupe(result, quote & "/>")
	item 2 of my decoupe(result, "<sl:string sfa:string=" & quote)
	(*
Try to convert the Unix path in a HFS one. If it fails it means that the link between the two documents is broken *)
	try
		tell application "System Events"
			set numbers_path to path of disk item result
		end tell
	on error errMsg number errNum
		if my parleAnglais() then
			error "The link between" & return & """ & cheminHFS & """ & return & "and the Numbers source file is broken." & return & "Please, rebuild it."
		else
			error "Le lien entre" & return & "« " & cheminHFS & " »" & return & "et le tableur source est brisé. Veuillez le reconstruire."
		end if
	end try
	(*
Open the spreadsheet *)
	tell application "Numbers"
		open numbers_path
		tell document 1 to tell sheet 1 to tell table 1
			set les_entetes to value of cells of row 1
			repeat with c from 1 to count of les_entetes
				set maybe to item c of les_entetes = "mailto"
				if maybe then exit repeat
			end repeat
			(*
If there is no "mailto" column header, exit. Can't get mail addresses *)
			if not maybe then
				if not my parleAnglais() then
					error "The spreadsheet" & return & """ & numbers_path & """ & return & "doesn't embed a header named "mailto" !"
				else
					error "Le tableur" & return & "« " & numbers_path & " »" & return & "ne contient pas d'en tête de colonne « mailto » !"
				end if
			end if
			(*
Extract the addresses *)
			tell column c to set les_adresses to value of cells 2 thru -1
		end tell -- document 1
	end tell -- Numbers
	(*
Drop values from empty bottom rows *)
	repeat while item -1 of les_adresses is 0.0
		set les_adresses to items 1 thru -2 of les_adresses
	end repeat
	return les_adresses
end getAddresses

--=====

on dateTimeStamp()
	return (do shell script "date +_%Y%m%d-%H%M%S")
end dateTimeStamp

--=====

on parleAnglais()
	local z
	try
		tell application "Pages" to set z to localized string "Cancel"
	on error
		set z to "Cancel"
	end try
	return (z is not "Annuler")
end parleAnglais

--=====

on recolle(l, d)
	local oTIDs, t
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

--=====

on decoupe(t, d)
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

--=====

on build_a_mail(un_pdf, le_sujet, le_corps, le_destinataire)
	local nouveau_message
	(*
Requires the property pour_tester	
*)
	tell application "Mail"
		set nouveau_message to make new outgoing message ¬
			with properties {subject:le_sujet, content:le_corps, visible:true}
		tell nouveau_message
			make new to recipient at end of to recipients with properties {address:le_destinataire}
			
			repeat 3 times
				make new paragraph at end of content with data linefeed
			end repeat
			
			make new attachment at end of last paragraph of content with properties {file name:un_pdf}
			if not pour_tester then
				send
				close without saving
			end if
		end tell -- nouveau_message
	end tell -- Mail
end build_a_mail

--=====
--[/SCRIPT]
--{code}

Yvan KOENIG (VALLAURIS, France)  jeudi 8 décembre 2011 18:50:28