Need Pages Script to set paper size to 8.5x11, Batch process on folder

I have a folder of several hundred Pages files and I need a script to set the page size of the documents to 8.5 x 11 page size. (this is in preparation of a batch pdf run)

Hello

Good news. I discovered that the ability to set the paper size thru clean code is at last available.


tell application "Pages"
	# CAUTION, the paper name is localized !
	set _8_5x13settings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:936.0, width:612.0}, paper name:"8,5 x 13", class:page setup, scale:1.0, orientation:portrait}
	set A4settings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:842.0, width:595.0}, paper name:"A4", class:page setup, scale:1.0, orientation:portrait}
	set A5settings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:595.0, width:420.0}, paper name:"A5", class:page setup, scale:1.0, orientation:portrait}
	set AdministratifSettings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:756.0, width:522.0}, paper name:"Administratif", class:page setup, scale:1.0, orientation:portrait}
	set enveloppeC5settings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:649.0, width:459.0}, paper name:"Enveloppe C5", class:page setup, scale:1.0, orientation:portrait}
	set enveloppeDLsettings to {printer margins:{top margin:17.289978027344, left margin:11.619999885559, right margin:11.619995117188, bottom margin:17.289978027344}, paper size:{height:624.0, width:312.0}, paper name:"Enveloppe DL", class:page setup, scale:1.0, orientation:portrait}
	set enveloppeMonarchSettings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:540.0, width:279.0}, paper name:"Enveloppe Monarch", class:page setup, scale:1.0, orientation:portrait}
	set enveloppe10settings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:684.0, width:297.0}, paper name:"Enveloppe nº 10", class:page setup, scale:1.0, orientation:portrait}
	set jisB5settings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:729.0, width:516.0}, paper name:"JIS B5", class:page setup, scale:1.0, orientation:portrait}
	set letterUSsettings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:792.0, width:612.0}, paper name:"Lettre US", class:page setup, scale:1.0, orientation:portrait}
	set legalUSsettings to {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:1008.0, width:612.0}, paper name:"Légal US", class:page setup, scale:1.0, orientation:portrait}
	
	tell document 1 to tell page attributes
		properties
		--> {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:1008.0, width:612.0}, paper name:"Légal US", class:page setup, scale:1.0, orientation:portrait}
		paper size of A4settings
		set paper size to result
		paper name of A4settings
		set paper name to result
		properties
		--> {printer margins:{top margin:11.619995117188, left margin:11.619999885559, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:842.0, width:595.0}, paper name:"A4", class:page setup, scale:1.0, orientation:portrait}
	end tell
end tell

Yvan KOENIG (VALLAURIS, France) mercredi 24 octobre 2012 11:08:36

Just to add that the numbers involved appear to be “points”, ie. multiples of 1/72 of an inch.

Works great! I’ll put it in a “batch loop” and my hundreds of docs will be re-set in no time. THANKS!

I say thank you too because the last time I tried to use this feature (months ago) I got no result.
It’s why I responded at first that GUI Scripting would be required.
Happily I thought that maybe I missed an enhancement introduced by one of the application revisions (or maybe by the system changes) and Bingo, it works.

Now, I will make tests with the print settings properties.

Alas, no chage.


tell application "Pages"
	print document 1 with properties {copies:1, starting page:1, ending page:2, pages across:2}
end tell

continue to print every pages of the current document with a single page per sheet of paper.
Problem reported for years which is not treated.

Yvan KOENIG (VALLAURIS, France) mercredi 24 octobre 2012 17:39:52

This has taken too long to work out to be any good to jump55, but I post it because it may be of interest. It works on the Pages files directly without involving Pages itself and is quite fast ” although if I knew how to do the repeat within a single shell script, it might turn out to be faster yet.

-- The input values can be numbers representing inches, or inches coercions, or centimeters coercions
on setPagesDocSizes to {w:w, h:h}
	tell application "System Events" to set PagesOpen to (application process "Pages" exists)
	if (PagesOpen) then tell application (path to frontmost application as text) to display dialog "Make sure that none of the Pages documents you want to change are open before continuing!" buttons {"Cancel", "Continue"} default button 2 with icon caution with title "Set Page Sizes of Pages Documents"
	
	-- Get the path to the folder containing the Pages documents and derive the paths to the XML files which will exist in it temporarily.
	set dirPath to POSIX path of (choose folder with prompt "Select a folder containing Pages documents")
	set qdirPath to quoted form of dirPath
	set qindexPath to quoted form of (dirPath & "index.xml")
	set qindex2Path to quoted form of (dirPath & "index2.xml")
	-- Also precalculate the point sizes for the page dimensions.
	set wp to (w as inches as number) * 72.0
	set hp to (h as inches as number) * 72.0
	
	-- Insert the paths and figures into the editing shell script string so that there's less to do during the repeat.
	-- A Pages document is a ZIP archive containing, amongst other things, a file called "index.xml", which defines nearly everything about the document. The shell script extracts and reads this and substitutes the new page dimensions for the existing ones. The edited data are written to a new XML file, which is then renamed to replace the original. (Writing straight back to the original seems merely to empty the file.) The file is then zipped back into the Pages document.
	-- The four figures to be changed occur near the beginning of the file and the four individual "sed" substitutions save having to search right through to the end of it and conceivably clashing with something in the document's text.
	set part1 to "unzip -oqq " -- Current Pages path inserted here.
	set part2 to " 'index.xml' -d " & qdirPath & ";  sed -E 's/(print-info [^>]*sl:page-width=\")[0-9.]+/\\1" & wp & "/ ; s/(print-info [^>]*sl:page-height=\")[0-9.]+/\\1" & hp & "/ ; s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:w=\")[0-9.]+/\\1" & wp & "/  ; s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:h=\")[0-9.]+/\\1" & hp & "/ ;' <" & qindexPath & " >" & qindex2Path & " ; mv -f " & qindex2Path & " " & qindexPath & "; zip -jq " -- Current Pages path inserted here.
	set part3 to " " & qindexPath
	
	-- Get the paths to the individual Pages document files and run the editing shell script on each of them.
	set PagesPaths to paragraphs of (do shell script "find -f " & quoted form of dirPath & " \\( -maxdepth 1 -type f -name '*.pages' \\)")
	repeat with i from 1 to (count PagesPaths)
		set thisPagesPath to quoted form of item i of PagesPaths
		do shell script part1 & thisPagesPath & part2 & thisPagesPath & part3
	end repeat
	
	-- Delete the remaining XML file and beep to announce the finish.
	do shell script "rm " & qindexPath
	beep
end setPagesDocSizes

setPagesDocSizes to {w:8.5 as inches, h:11 as inches}

Hello.

I hope this isn’t inappropriate. but you can open the bash manual in terminal window. If you there search by hitting “/” you can enter “loop” then hit enter and you’ll see your options. Many times when search the bash manual, you’ll have to search for synonyms or similar terms in order to get the desired results.

If you press “h” you’ll get a simple help screen. You can use regexp to search with. Less was the first computer program I really loved. My first encounter with it was on my Atari ST :).

I think the way you have organized your script is good, and much more readable.

Thanks, McUsr.

I’ve always found the Terminal to be a useless pile of junk, especially for reading man pages; but a quick trial of your keystroke tips looks hopeful! I already have the bash manual in PDF format thanks to a script developed from this thread, so one way or another, it should be easy to find what what I need.

I too used to have an Atari ST!

I have tried all the options too. :slight_smile: I settled for the Terminal You can also set marks.

By the way more often than not, xargs proves to be t the most efficient loop, both regarding speed, and robustness, when it comes to iterating over files; then it is just so many arguments that a for loop can take for instance. (It is also much easier to code this in a do shell script.) :slight_smile:

Just thought it was well worth mentioning.

Nigel… your update was of much interest to me… I’ll try it… Perhaps I wasn’t implementing your original idea correctly but I found that it gave me a problem. When I ran it on “statement” size page setup docs the result was that the displayed Pages doc did indeed show as a portrait 8.5x11 but when converted to pdf the result was a landscape pdf. I went back and looked at the 8.5x11 displayed doc and looked at page setup. It was showing a page setup of “landscape” even though when looking at the doc it was clearly portrait!

So, being somewhat of a novice…
If I read correctly… I zip the individual Pages documents and then simply run this script as is with the containing folder having been selected… Correct? Is there anything I need to “set” or “define” in the script itself?

It’s because Nigel failed to edit the property NSOrientation according to the passed values.

  <sl:NSOrientation>
    <sl:number sfa:number="0" sfa:type="i"/>
  </sl:NSOrientation>

if width < height the number value must be “0”

if width > height, the number value must be “1”

Yvan KOENIG (VALLAURIS, France) jeudi 25 octobre 2012 17:04:41

(1) A Pages document may be a packed file but it’s not always one.

(2) I don’t understand your script behavior

It execute this command :
do shell script “unzip -oqq ‘/Users/userAccount/Desktop/dossier sans titre//testNigelSkript.pages’ ‘index.xml’ -d ‘/Users/userAccount/Desktop/dossier sans titre/’; sed -E ‘s/(print-info [^>]*sl:page-width=")[0-9.]+/\1612,0/ ; s/(print-info [^>]*sl:page-height=")[0-9.]+/\1792,0/ ; s/(NSPaperSize>sl:value<sfa:size [^>]*sfa:w=")[0-9.]+/\1612,0/ ; s/(NSPaperSize>sl:value<sfa:size [^>]*sfa:h=")[0-9.]+/\1792,0/ ;’ <‘/Users/userAccount/Desktop/dossier sans titre/index.xml’ >‘/Users/userAccount/Desktop/dossier sans titre/index2.xml’ ; mv -f ‘/Users/userAccount/Desktop/dossier sans titre/index2.xml’ ‘/Users/userAccount/Desktop/dossier sans titre/index.xml’; zip -jq ‘/Users/userAccount/Desktop/dossier sans titre//testNigelSkript.pages’ ‘/Users/userAccount/Desktop/dossier sans titre/index.xml’”

I have no idea about what is a path with two consecutive slashs.

Altough being unable to understand that, I made a huge crime : I splitted the shell script into four components which may be used separately.


-- The input values can be numbers representing inches, or inches coercions, or centimeters coercions
on setPagesDocSizes to {w:w, h:h}
	tell application "System Events" to set PagesOpen to (application process "Pages" exists)
	if (PagesOpen) then tell application (path to frontmost application as text) to display dialog "Make sure that none of the Pages documents you want to change are open before continuing!" buttons {"Cancel", "Continue"} default button 2 with icon caution with title "Set Page Sizes of Pages Documents"
	
	-- Get the path to the folder containing the Pages documents and derive the paths to the XML files which will exist in it temporarily.
	set dirPath to POSIX path of (choose folder with prompt "Select a folder containing Pages documents")
	set qdirPath to quoted form of dirPath
	set qindexPath to quoted form of (dirPath & "index.xml")
	set qindex2Path to quoted form of (dirPath & "index2.xml")
	-- Also precalculate the point sizes for the page dimensions.
	set wp to (w as inches as number) * 72.0
	set hp to (h as inches as number) * 72.0
	
	-- Insert the paths and figures into the editing shell script string so that there's less to do during the repeat.
	-- A Pages document is a ZIP archive containing, amongst other things, a file called "index.xml", which defines nearly everything about the document. The shell script extracts and reads this and substitutes the new page dimensions for the existing ones. The edited data are written to a new XML file, which is then renamed to replace the original. (Writing straight back to the original seems merely to empty the file.) The file is then zipped back into the Pages document.
	-- The four figures to be changed occur near the beginning of the file and the four individual "sed" substitutions save having to search right through to the end of it and conceivably clashing with something in the document's text.
	set part1 to "unzip -oqq " -- Current Pages path inserted here.
	set part2_1 to " 'index.xml' -d " & qdirPath
	set part2_2 to "sed -E 's/(print-info [^>]*sl:page-width=\")[0-9.]+/\\1" & wp & "/ ; s/(print-info [^>]*sl:page-height=\")[0-9.]+/\\1" & hp & "/ ; s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:w=\")[0-9.]+/\\1" & wp & "/  ; s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:h=\")[0-9.]+/\\1" & hp & "/ ;' <" & qindexPath & " >" & qindex2Path
	set part2_3 to "mv -f " & qindex2Path & " " & qindexPath
	set part2_4 to "zip -jq " -- Current Pages path inserted here.
	set part3 to " " & qindexPath
	
	-- Get the paths to the individual Pages document files and run the editing shell script on each of them.
	set PagesPaths to paragraphs of (do shell script "find -f " & quoted form of dirPath & " \\( -maxdepth 1 -type f -name '*.pages' \\)")
	
	repeat with i from 1 to (count PagesPaths)
		set thisPagesPath to quoted form of item i of PagesPaths
		do shell script part1 & thisPagesPath & part2_1
		do shell script part2_2
		do shell script part2_3
		do shell script part2_4 & thisPagesPath & part3
	end repeat
	
	-- Delete the remaining XML file and beep to announce the finish.
	do shell script "rm " & qindexPath
	beep
end setPagesDocSizes

setPagesDocSizes to {w:8.5 as inches, h:11 as inches}

It works this way.
It’s fine because with that I may edit an index the way I want and reinsert it in the flatfile.

Of course, I would be interested by explanations about the double slash embedded in the path.

I guess that Nigel will play with the sed piece of code to edit the orientation property which he forgot :wink:

Yvan KOENIG (VALLAURIS, France) jeudi 25 octobre 2012 17:13:58

I’ve no idea what “statement” size is. It’s not one of the sizes offered in my “Page Size” menu. (Consults Wikipedia.) Hmmm. Alias “Half Letter” size. Was the printing orientation Landscape before you ran the script?

The individual Pages documents are already ZIP archives, but with “.pages” name extensions instead of “.zip”. (At least, all the ones on my machines are ZIP archives. Yvan says they needn’t necessarily be so.)

I didn’t “fail” or “forget” anything in this respect. :slight_smile: There was simply nothing in the original post to give me cause to consider it. And now I do consider it, I’d say the paper orientation is a separate issue which depends on the paper size of the printer concerned. I can’t possibly guess that, but orientation could be made another parameter for the script.

It’s simply an artifact of the “find” command. The POSIX path to the root folder is provided by AppleScript and ends with a slash. But “find” assumes there isn’t one and prepends a slash to whatever it adds on to it. Thus there are two slashes at that point in each returned path. It turns out these make no difference at all to the interpretation of the paths in shell scripts, so I usually ignore them.

Thank you both for the feedback and additional information. I’ll incorporate them into the script when I get a moment.

Well… looking at the code above… this is running way over my head and abilities. I was hoping for something quick and easy. And I’ve amended my original request somewhat too. Here is what I’m looking for though I’m not sure it’s in the scope of this conversation any longer…

“Regardless of original document size (which I may not even know, having hundreds of docs), set the document page setup to 8.5x11 (US Letter), portrait orientation, and also set the top, left, right, and bottom DOCUMENT margins to one inch (72 pts.)”

I have hundreds of docs to process, some in .pages and others in .doc format which I process and save (all) as Pages doc. I then run a script which converts to pdf. I’ve already converted hundreds that were all 8.5x11 setup and now I am running into docs that have some custom pages sizes.

All the docs are simple text docs with no images or complex layout. Pretty much simply flowing text paragraphs.

I think this does all that, but it’s only known to work with files which have not been saved “as packages”. (See under “Saving” in Pages’s “General” Preferences.) I’ve not yet got round to investigating the ramifications of saving as packages. Edit: Also, the dimensions of the documents’ windows are not changed.

Whole-number values are now entered into the XML files without “.0” on the end, as happens when Pages itself enters them, and I’ve removed the long explanatory comment about the long shell script until the action’s confirmed as finalised.

Edit: To humour Yvan, the “sed” script can now handle “formatted” XML code too!
Edit: I’ve now posted another version (see post #19 below) which can handle Pages documents saved as packages too.

-- The input values can be numbers representing inches, or inches coercions, or centimeters coercions
on setPagesDocSizes to {w:w, h:h, orientation:o, |doc margins|:{t:tm, l:lm, b:bm, r:rm}}
	tell application "System Events" to set PagesOpen to (application process "Pages" exists)
	if (PagesOpen) then tell application (path to frontmost application as text) to display dialog "Make sure that none of the Pages documents you want to change are open before continuing!" buttons {"Cancel", "Continue"} default button 2 with icon caution with title "Set Page Sizes of Pages Documents"
	
	-- Get the path to the folder containing the Pages documents and derive the paths to the XML files which will exist in it temporarily.
	set dirPath to POSIX path of (choose folder with prompt "Select a folder containing Pages documents")
	set qdirPath to quoted form of dirPath
	set qindexPath to quoted form of (dirPath & "index.xml")
	set qindex2Path to quoted form of (dirPath & "index2.xml")
	-- Also precalculate the point sizes for the page dimensions.
	set wPts to pts(w)
	set hPts to pts(h)
	set oNum to ((o is "Landscape") as integer) as text
	
	-- Insert the paths and figures into the editing shell script string so that there's less to do during the repeat.
	set part1 to "unzip -oqq " -- Current Pages path inserted here.
	set part2 to " 'index.xml' -d " & qdirPath & ";
sed -E '2 {
	/<sl:version-history>/ {
		s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:w=\")[0-9.]+/\\1" & wPts & "/ ;
		s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:h=\")[0-9.]+/\\1" & hPts & "/ ;
		s/<sl:NSOrientation><sl:number sfa:number=\"[0-1]\"/<sl:NSOrientation><sl:number sfa:number=\"" & oNum & "\"/ ;
	} ;
} ;
4,$ {
	/<sl:NSPaperSize>/,/<[/]sl:value>/ {
		s/(<sfa:size [^>]*sfa:w=\")[0-9.]+/\\1" & wPts & "/ ;
		s/(<sfa:size [^>]*sfa:h=\")[0-9.]+/\\1" & hPts & "/ ;
	};
	/<sl:NSOrientation>/,/<[/]sl:NSOrientation>/ s/sfa:number=\"[0-1]\"/sfa:number=\"" & oNum & "\"/ ;
} ;
/sl:slprint-info/ {
	s/(slprint-info [^>]*sl:page-width=\")[0-9.]+/\\1" & wPts & "/ ;
	s/(slprint-info [^>]*sl:page-height=\")[0-9.]+/\\1" & hPts & "/ ;
} ;
/sf:page-margins/ {
	s/(page-margins [^>]*top=\")[0-9.]+/\\1" & pts(tm) & "/ ;
	s/(page-margins [^>]*left=\")[0-9.]+/\\1" & pts(lm) & "/ ;
	s/(page-margins [^>]*bottom=\")[0-9.]+/\\1" & pts(bm) & "/ ;
	s/(page-margins [^>]*right=\")[0-9.]+/\\1" & pts(rm) & "/ ; 
} ;' <" & qindexPath & " >" & qindex2Path & " ;
mv -f " & qindex2Path & " " & qindexPath & ";
zip -jq " -- Current Pages path inserted here.
	set part3 to " " & qindexPath
	
	-- Get the paths to the individual Pages document files and run the editing shell script on each of them.
	set PagesPaths to paragraphs of (do shell script "find -f " & quoted form of dirPath & " \\( -maxdepth 1 -type f -name '*.pages' \\)")
	repeat with i from 1 to (count PagesPaths)
		set thisPagesPath to quoted form of item i of PagesPaths
		do shell script part1 & thisPagesPath & part2 & thisPagesPath & part3
	end repeat
	
	-- Delete the remaining XML file and beep to announce the finish.
	do shell script "rm " & qindexPath
	beep
end setPagesDocSizes

on pts(input)
	set p to (input as inches as number) * 72
	if (p mod 1 is 0) then set p to p as integer
	set p to p as text
	set o to (offset of "," in p)
	if (o > 0) then set p to text 1 thru (o - 1) of p & "." & text (o + 1) thru -1 of p
	
	return p
end pts

setPagesDocSizes to {w:8.5 as inches, h:11 as inches, orientation:"Portrait", |doc margins|:{t:1, l:1, b:1, r:1}}

Thanks for the explanation about puzzling double slashes.

I posted a detailed message about the structure of iWork (and iBooks Author) documents in an other thread :
http://macscripter.net/viewtopic.php?pid=156967#p156967

About Orientation, I apologize but there is a link with the size values and it.
Here are extracts from the index.xml file of the same document in portrait mode and in landscape one.

Portrait mode :

<sl:slprint-info sl:page-width=“595” sl:page-height=“842” sl:page-scale=“1”>
<sf:page-margins sf:top=“56.692916870117188” sf:left=“56.692916870117188” sf:bottom=“56.692916870117188” sf:right=“56.692916870117188” sf:header=“35.433071136474609” sf:footer=“42.519683837890625”/>
sl:print-info
sl:NSJobDisposition
<sl:string sfa:string=“NSPrintSpoolJob”/>
</sl:NSJobDisposition>
sl:NSPaperSize
sl:value
<sfa:size sfa:w=“595” sfa:h=“842”/>
</sl:value>
</sl:NSPaperSize>

  <sl:NSPaperName>
    <sl:string sfa:string="iso-a4"/>
  </sl:NSPaperName>

  <sl:NSOrientation>
    <sl:number sfa:number="0" sfa:type="i"/>
  </sl:NSOrientation>
</sl:print-info>

</sl:slprint-info>

Landscape mode :

<sl:slprint-info sl:page-width=“842” sl:page-height=“595” sl:page-scale=“1”>
<sf:page-margins sf:top=“56.692916870117188” sf:left=“56.692916870117188” sf:bottom=“56.692916870117188” sf:right=“56.692916870117188” sf:header=“35.433071136474609” sf:footer=“42.519683837890625”/>
sl:print-info
sl:NSJobDisposition
<sl:string sfa:string=“NSPrintSpoolJob”/>
</sl:NSJobDisposition>
sl:NSPaperSize
sl:value
<sfa:size sfa:w=“842” sfa:h=“595”/>
</sl:value>
</sl:NSPaperSize>

  <sl:NSPaperName>
    <sl:string sfa:string="iso-a4"/>
  </sl:NSPaperName>

  <sl:NSOrientation>
    <sl:number sfa:number="1" sfa:type="i"/>
  </sl:NSOrientation>
</sl:print-info>

</sl:slprint-info>

The width is supposed to be the horizontal dimension and the height is supposed to be the vertical one according to the orientation.

Portrait means :
orientation number = 0
width = smaller dimension
height = greater dimension

Landscape means :
orientation number = 1
width = greater dimension
height = smaller dimension

It’s because the trio width, height, orientation value was not consistent that jump55 got an odd behavior.
It’s why I took care, in my script to include the entire set of properties of page attributes .

For A4 paper in landscape mode with the default settings they are :
{printer margins:{top margin:11.619995117188, left margin:11.619995117188, right margin:11.619995117188, bottom margin:11.619995117188}, paper size:{height:595.0, width:842.0}, paper name:“A4”, class:page setup, scale:1.0, orientation:landscape}

As you may see, Consistency is not the rule when AppleScript is involved. The paper orientation is described in English but the paper names are given in the local language.

Yvan KOENIG (VALLAURIS, France) vendredi 26 octobre 2012 15:57:36

Thanks Nigel :wink:

Now I must try to understand the behavior of this fine script.

If I have spare time, tomorrow I will try to build a version applying to packages.
In fact, I guess that it will not be too difficult.

The true problem is that, if my memory is OK, the app is unhappy when we unpack the index.xml.gz embedded file, edit it the gzip it.
But maybe it’s simply what you described with flat files.
I will duplicate the index.xml.gz file in the temporary folder and will do the trich in this location.
Then move it back to the package.

I will also try to add some instructions allowing the scripts to apply to Keynote documents because they don’t use index.xml files but Index.apxl ones.
This name was defined when Keynote was a lonely application.
When the first iWork combo was introduced, Pages used index.xml so when Numbers appeared I was afraid to discover a third name and a fourth one when iBooks Author surfaced.

Oops, If I understand well, I found an error in your late script.
I guess that it’s because you never used iWork in French.
When we use metric system (happily, Apple is on the road to use it) the conversion into points give decimal values which must be kept.

Rounding width and height was good idea but margins are supposed to accept decimal value (conflict between inches and centimeters).

So, I guess that you will have to use my ugly piece of code:


# if values are centimeter
set w to 21
set h to 29.7
set lm to 1

set wp to my setRoundPtsValues(w * 0.393700787402)
set hp to my setRoundPtsValues(h * 0.393700787402)

set lmp to my setDecimalPtsValues(lm * 0.393700787402)
{wp, hp, lmp}

on setDecimalPtsValues(x)
	set xp to ((x as inches as number) * 72.0) as text
	if text 2 of (0.5 as text) is "," then
		set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ","}
		set xp to text items of xp
		set AppleScript's text item delimiters to "."
		set xp to xp as text
		set AppleScript's text item delimiters to oTIDs
	end if
	return xp
end setDecimalPtsValues

on setRoundPtsValues(x)
	return round ((x as inches as number) * 72.0)
end setRoundPtsValues

Yvan KOENIG (VALLAURIS, France) vendredi 26 octobre 2012 22:56:26

Here’s a version which ” so far as I’ve been able to test it ” can handle Pages documents saved as packages as well as as compressed files. As above, it doesn’t mind if the contained XML files are “formatted” or not.

Yvan’s been telling me off-list about a group of other settings which need to be changed in the process. But although setting them would be a trivial matter, I’m not able to see or to understand what they represent and thus to what values they need to be set. If and when the penny drops, I’ll amend the script. Meanwhile, it does everything I’m expecting.

-- The input values can be numbers representing inches, or inches coercions, or centimeters coercions
on setPagesDocSizes to {w:w, h:h, orientation:o, |doc margins|:{t:tm, l:lm, b:bm, r:rm}}
	tell application "System Events" to set PagesOpen to (application process "Pages" exists)
	if (PagesOpen) then tell application (path to frontmost application as text) to display dialog "Make sure that none of the Pages documents you want to change are open before continuing!" buttons {"Cancel", "Continue"} default button 2 with icon caution with title "Set Page Sizes of Pages Documents"
	
	-- Get the path to the folder containing the Pages documents and derive the path to the XML file which will exist in it temporarily.
	set dirPath to POSIX path of (choose folder with prompt "Select a folder containing Pages documents")
	set qdirPath to quoted form of dirPath
	set qXMLPath to quoted form of (dirPath & "index.xml")
	-- Also precalculate the point sizes for the page dimensions.
	set wPts to pts(w)
	set hPts to pts(h)
	set oNum to ((o is "Landscape") as integer) as text
	
	-- Insert the paths and figures into the parts of the editing shell script so that there's less to do during the repeat. Different versions of parts 1 and 3 fetch and return XML data according to whether the documents were saved as compressed files or as packages. Part 2 edits the data.
	set part1fl to {"unzip -oqq ", missing value, " 'index.xml' -d " & qdirPath & " ; edited=$(<" & qXMLPath & " "}
	set part1pkg to {"edited=$(gunzip -c ", missing value, " | "}
	set part2 to "sed -E '2 {
	/<sl:version-history>/ {
		s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:w=\")[0-9.]+/\\1" & wPts & "/ ;
		s/(NSPaperSize><sl:value><sfa:size [^>]*sfa:h=\")[0-9.]+/\\1" & hPts & "/ ;
		s/<sl:NSOrientation><sl:number sfa:number=\"[0-1]\"/<sl:NSOrientation><sl:number sfa:number=\"" & oNum & "\"/ ;
	} ;
} ;
4,$ {
	/<sl:NSPaperSize>/,/<[/]sl:value>/ {
		s/(<sfa:size [^>]*sfa:w=\")[0-9.]+/\\1" & wPts & "/ ;
		s/(<sfa:size [^>]*sfa:h=\")[0-9.]+/\\1" & hPts & "/ ;
	};
	/<sl:NSOrientation>/,/<[/]sl:NSOrientation>/ s/sfa:number=\"[0-1]\"/sfa:number=\"" & oNum & "\"/ ;
} ;
/sl:slprint-info/ {
	s/(slprint-info [^>]*sl:page-width=\")[0-9.]+/\\1" & wPts & "/ ;
	s/(slprint-info [^>]*sl:page-height=\")[0-9.]+/\\1" & hPts & "/ ;
} ;
/sf:page-margins/ {
	s/(page-margins [^>]*top=\")[0-9.]+/\\1" & pts(tm) & "/ ;
	s/(page-margins [^>]*left=\")[0-9.]+/\\1" & pts(lm) & "/ ;
	s/(page-margins [^>]*bottom=\")[0-9.]+/\\1" & pts(bm) & "/ ;
	s/(page-margins [^>]*right=\")[0-9.]+/\\1" & pts(rm) & "/ ; 
} ;' "
	set part3fl to {") ; echo \"$edited\" >" & qXMLPath & " ; zip -jq ", missing value, " " & qXMLPath & " ;"}
	set part3pkg to {") ; echo \"$edited\" | gzip >", missing value, " ;"}
	
	-- Get the paths to Pages document files or gzipped XML files in Pages document packages and run the editing shell script with each of them.
	set relevantPaths to paragraphs of (do shell script "find -f " & quoted form of dirPath & " \\( -depth 1 -type f -name '*.pages' \\) -or \\( -depth 2 -type f -path '*.pages/index.xml.gz' \\) ")
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to ""
	repeat with i from 1 to (count relevantPaths)
		set thisPath to quoted form of item i of relevantPaths
		if (thisPath ends with ".pages'") then
			set part1 to part1fl
			set part3 to part3fl
		else
			set part1 to part1pkg
			set part3 to part3pkg
		end if
		set item 2 of part1 to thisPath
		set item 2 of part3 to thisPath
		do shell script ((part1 as text) & part2 & part3)
	end repeat
	set AppleScript's text item delimiters to astid
	
	-- Delete the remaining XML file and beep to announce the finish.
	do shell script ("rm -f " & qXMLPath)
	beep
end setPagesDocSizes

on pts(input)
	set p to (input as inches as number) * 72
	if (p mod 1 is 0) then set p to p as integer
	set p to p as text
	set o to (offset of "," in p)
	if (o > 0) then set p to text 1 thru (o - 1) of p & "." & text (o + 1) thru -1 of p
	
	return p
end pts

setPagesDocSizes to {w:8.5 as inches, h:11 as inches, orientation:"Portrait", |doc margins|:{t:1, l:1, b:1, r:1}}

Edit: Fixed a bug in the “package” code which caused “formatted” XML files to end up with no content! Also tightened up the “find” search expression. Thanks to Yvan for pointing these out to me.