• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

With CS5, some things have changed

LEGEND ,
Apr 12, 2010 Apr 12, 2010

Copy link to clipboard

Copied

This discussion is for changes to the scripting DOM which can affect legacy scripts.

Please use this discussion for discussing new scripting features in CS5.

Please keep in mind that all changes are specific to version 7 DOM. InDesign supports versioning, so you should be able to use legacy scripts in CS5 without issues. Versioning can be done in two ways:

1) Place the script in a folder named: "Version 6.0 Scripts" (or 5.0, 4.0, 3.0). The folder must be named exactly as specified.

2) Set the script version preferences at the start of your script. (i.e. app.scriptPreferences.version = 6), but it's highly recommended to reset the scripting version at the end of the script, and even to enclose the script in a try/catch/finally block to ensure that the script preferences are reset correctly.

Here's quick links to issues brought up in this thread:

  1. PageItem.parent
  2. PageItem.itemByName()
  3. PageItem.cornerOption and PageItem.cornerRadius
  4. Text values returned as Strings instead of Numbers
  5. PointType.LINE_TYPE was changed to PointType.PLAIN
  6. PasteBoardPreference.minimumSpaceAboveAndBelow was removed.

Harbs

TOPICS
Scripting

Views

58.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 04, 2011 Mar 04, 2011

Copy link to clipboard

Copied

Hi all,

we just tracked down a bug to the E4X implementation in ExtendScript. Fixed in CS5, but unfortunately that project is still CS4.

First, be assured that below syntax is no typo - for details see the XML section in the JavaScript Tools Guide. The code implements different approaches to initialize a simple XML object (the ExtendScript brew, not InDesign's XMLElement) with a single element and text content. The curly brackets within the embedded XML literal are a way to pass on JavaScript expressions.

The only problem here - some kind of conversion is taking place under the hood. Speaking in InDesign character codes, the paragraph end character (13) is silently converted into a forced line break (10). Not good if this XML is later returned into InDesign ...

Dirk

( function () {   var aCRbLFc = "a\rb\nc";   $.writeln(aCRbLFc.charCodeAt(1),"/",aCRbLFc.charCodeAt(3));   // => 13,10   // first attempt / redundant XML wrapping.   var xml = new XML(<tag>{aCRbLFc}</tag>);   var hmm = xml.child(0).toString();   $.writeln(hmm.charCodeAt(1),"/",hmm.charCodeAt(3));   // => 10,10   // second attempt / straight XML literal   var xml = <tag>{aCRbLFc}</tag>;   var hmm = xml.child(0).toString();   $.writeln(hmm.charCodeAt(1),"/",hmm.charCodeAt(3));   // => 10,10   // inconsequent, but works:   var xml = new XML(<tag/>);   xml.appendChild(aCRbLFc);   var hmm = xml.child(0).toString();   $.writeln(hmm.charCodeAt(1),"/",hmm.charCodeAt(3));   // => 13,10 } )();

Edit: formatting attempt

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Mar 08, 2011 Mar 08, 2011

Copy link to clipboard

Copied

In case anyone's interested: In the VB object model (not sure of anything else) the idTextWrapTypes was changed to idTextWrapModes.

Not sure why, but there 'tis.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 10, 2011 Mar 10, 2011

Copy link to clipboard

Copied

A couple of other things I've noticed:

1. The Book.exportFile() parameters have changed (which bring them more in line with Document.exportFile()), so:

CS4: myBook.exportFile(myPdfFile, false)

CS5: myBook.exportFile(ExportFormat.PDF_TYPE, myPdfFile)

2. The regular expression engine seems to have been changed slightly, in CS5 you now have to escape pipes.

Consider the expression:

$.writeln('test'.replace(/|/g, '|'));

CS4: 'test'

CS5: '|t|e|s|t'

You have to escape the pipe like this:

$.writeln('test'.replace(/\|/g, '|'));

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 10, 2011 Mar 10, 2011

Copy link to clipboard

Copied

Hi Ben,

Nice to see you here!

Yes there are definitely things that changed with the RegExp engine. One important thing to know is that for regex that will be used more than once it's important to create a RegExp object and invoke it by referencing it rather than using a regex literal which the engine has to reconstruct each tme it's used. This makes a huge difference in performance in CS5...

Harbs

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 28, 2011 Sep 28, 2011

Copy link to clipboard

Copied

Can anyone point me to a CS5 VB script reference? Having trouble locating one.

Thank you,

Mike

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 28, 2011 Sep 28, 2011

Copy link to clipboard

Copied

You won't find it - because it doesn't exist ...

Try this:

http://www.jongware.com/idjshelp.html

It's for JS - but should be helpful.

Or if you have M$ Office - you can add reference to "Resources for Visual Basic.tlb" file and use built-in Visual Basic Editor.

robin

www.adobescripts.com

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 04, 2011 Oct 04, 2011

Copy link to clipboard

Copied

I have noticed that in the situation of a two page spread, the left and right pages in CS2 will have different parent IDs, while in CS5 they will have the same parent IDs. I am trying to add pages to a document after a page of my choosing, and have the new page come in next.

This is my CS2 code:

X = .Parent.ID

With idDoc.Pages.Add(at:=idAfter, reference:=idDoc.Pages.ItemByID(X))

I am wondering if there is a way to set the "reference:" to place a new page by page .ParentPage, since the .Parent.ID is ambiguous?

Mike

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 04, 2011 Oct 04, 2011

Copy link to clipboard

Copied

I am wondering if there is a way to set the "reference:" to place a new page by page .ParentPage, since the .Parent.ID is ambiguous?

According to VB Reference Guide:

Function Add([At As idLocationOptions = idUnknown], [Reference]) As Page

    Member of InDesign.Pages

    Creates a new page.

    Return value: The new page/.

    At: The location of the new page relative to the reference object or within the document or spread. .

    Reference: eference object. Note: Required when the at parameter value specifies before or after. Type: Page, Spread, MasterSpread or Document

So your reference can be just the page. If you know the page after which you want to add new page - just use it - without reffering to Pages collection of the Document:

With idDoc.Pages.Add(at:=idAfter, reference:=myPage)

Beside, X = .Parent.ID will give you ID of the - so you can't use it as reference in PAGES collection.

Unless by X = .Parent.ID you are trying to get ID of the parent page for the Object on that page, but still - if you know the page you are on - if you have reference to that page - you can use it directly in .Pages.Add().

If I'm wrong - please show us more of your code.

robin

www.adobescripts.com

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 04, 2011 Oct 04, 2011

Copy link to clipboard

Copied

Mike wrote: "With idDoc.Pages.Add(at:=idAfter, reference:=idDoc.Pages.ItemByID(X))"

As far ask I know, using labeled parameters (e.g., "at:" or "reference:" in the above) in VBScript/VB method calls has never worked (or has never worked reliably) in InDesign scripting. I think I even wrote a note about it in the documentation somewhere, though I have no idea if it's still there. Just provide the parameters in order, omitting optional parameters that you don't need. In this case, something like this should work (untested, off the top of my head):

Rem Given a page item "X" in a document "idDoc"...

idDoc.pages.add(idLocationOptions.idAfter, idDoc.pages.itemByID(X.parentPage.id))

Thanks,

Ole

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 13, 2011 Oct 13, 2011

Copy link to clipboard

Copied

This is wonderful! Thank you! Everything is working now.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 18, 2011 Apr 18, 2011

Copy link to clipboard

Copied

So far, I've slept through all the CS5 activity because our customers have been using CS3 and CS4, but now, some of them are putting their toes into the CS5 water and so I'm finally paying attention to what is now the release before last (ah well).

According to the CS5 OMV, Text.contents returns either a String or a SpecialCharacters enumerator. But this code is failing on me:

var txtSample = oSetText.contents.replace(/\t/g,"[Tab]");

because contents is returning an array.
Here's what the JS Console has to say:
oSetText.contents
Result: Linda [stroke survivor]
“If you don’t have a proper wheelchair, that is when you really feel that you are disabled. But if you have a proper wheelchair, which meets your needs and suits you, you can forget about your disability.”
Faustina [person with paraplegia]
oSetText.contents.constructor.name
Result: Array
oSetText.contents.length
Result: 1
oSetText
Result: [object Text]
Anbody else seen this? Or am I suffering from a third-party plug-in induced weirdness?
Dave

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 18, 2011 Apr 18, 2011

Copy link to clipboard

Copied

I think I see the cause. I typed:

This is a test.

into a text frame, and selected it.

app.selection[0]

Result: [object Paragraph]

app.selection[0].texts[0]

Result: [object Text]

app.selection[0].texts[0].contents

Result: This is some text.

app.selection[0].texts[0].contents.constructor.name

Result: String

app.selection[0].parentStory.characters.itemByRange(0,-1).texts[0]

Result: [object Text]

app.selection[0].parentStory.characters.itemByRange(0,-1).texts[0].contents

Result: This is some text.

app.selection[0].parentStory.characters.itemByRange(0,-1).texts[0].contents.constructor.name

Result: Array

It appears that using itemByRange across a range of text is at the root of the issue here because this second construction is akin to what I had done in the other script.
To be blunt, this looks like a bug to me, but as long as it is consistent, I can work with it.
Dave

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 18, 2011 Apr 18, 2011

Copy link to clipboard

Copied

The solution (which works in at least CS4 and CS5) is to use getElements():

app.selection[0].parentStory.characters.itemByRange(0,-1).texts[0].getElements()[0].contents.constructor.name

String

However, in CS4 and earlier, the use of getElements here was not necessary.

Dave


Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 19, 2011 Apr 19, 2011

Copy link to clipboard

Copied

Not actually a bug. This is a side-effect of a request that (wait for it, wait for it) I made two and a half years ago. At the time, I was bemoaning the fact that when you used everyItem() it didn't always return a collection (if there were only one of the items in question). Well, now it does and so does itemByRange.

Thinking back to an earlier time, it always had struck me as rather mysterious that:

myText.characters.itemByRange(m, n).texts[0]

returned a singular text reference. Well, now it doesn't. It returns a collection of one text object. So:

myText.characters.itemByRange(m, n).texts[0].getElements()[0]

gives you that text object, which isn't such a big price to pay for consistency elsewhere.

Dave

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Apr 19, 2011 Apr 19, 2011

Copy link to clipboard

Copied

Thanks Dave for pointing out these hidden pitfalls.

The itemByRange() method has always seemed unpredictable to me, especially with text objects. For example:

app.selection[0].parentStory.words.itemByRange(0,-1).characters[0].contents

returns only the first character of the first word (in CS4 and CS5), while:

app.selection[0].parentStory.words.everyItem().characters[0].contents

returns —as expected— an array that collects the 1st character of each word. Thus, itemByRange() may integrate the 'range' as a single block of data and does not produce, in that case, a collective specifier.

In addition, the texts collection is really mysterious. In your example, the specifier:

var spec = app.selection[0].parentStory.characters.itemByRange(0,-1).texts[0];

should finally be resolved as a range of characters. Indeed, both ID CS4 and CS5 return a character-to-character path when you test this:

alert( resolve(spec.toSpecifier()).toSpecifier() );

However —as you have discovered— spec is treated as a collective specifier in CS5, so spec.contents produces an array of one string, while spec is a singular specifier in CS4. So it's sure that something has changed in the implementation of the .texts method, and we probably will find other side effects...

A final note: technically we cannot say that myText.characters.itemByRange(m, n).texts[0] returns a 'collection'. The returned value is actually a Text specifier (versus a Texts collection). What you found is that, in CS5, this can be a collective specifier, in that any underlying property is returned through an array although the DOM object has in fact a single receiver.

@+

Marc

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 20, 2011 Apr 20, 2011

Copy link to clipboard

Copied

Thanks Marc.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 29, 2011 Apr 29, 2011

Copy link to clipboard

Copied

Just found another really unfortunate change in CS5. It is no longer safe to issue:

myTextFrame.lines[-1].baseline

even when the text frame is known to contain at least one line because if that line contains a partial table that is not completely set (i.e., the story goes overset before the end of the table) you'll get "Invalid request in the current state".

Possibly worse, if the table is completely set, rather than get the bottom coordinate of the part of the table in the text frame, you instead get the baseline of the actual bottom of the last row of the table no matter which text frame it might actually be in on whichever page.

A really sad state of affairs that wipes out my script that does vertical justification of tables.

Dave

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
May 03, 2011 May 03, 2011

Copy link to clipboard

Copied

Apologies for cross posting this to both mailing list and forums, I'm not sure what most people are using.

Just starting to look at moving the company from CS3 to CS5/5.5 and updating the scripts has been, well, interesting.  The inability to directly refer to page items via their Label has been quite a challenge as EVERYTHING we do names frames and subsequently refers to them by that name.

One thing that has me stuck is why the following doesn't throw an error in a try block if the frame doesn't exist.

set myFrame to item 1 of all page items whose label is "kim"

I simply end up with an undefined variable. I would have thought if it didn't exist and myFrame was undefined an error should be returned.

Am I missing something here or is this expected behaviour?

I've just found another issue regarding restoration of styles to a frame. In CS3 we used to simply get the parent story properties from the frame, place the new text and then reapply the properties to restore the style. In CS5 this breaks as it simply applies the default paragraph style despite the properties holding all the individual style elements. I'm thinking this will necessitate applying individual properties (font, leading, tracking, kerning, etc etc) and that's gonna be horrible. If someone has a workaround for this I would appreciate it.

It's been a long time since I wrote these scripts and there's a LOT of work in updating them to follow the new syntax - this is going to be a far more substantial task than I was expecting.

cheers

'k

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 03, 2011 May 03, 2011

Copy link to clipboard

Copied

It's been a long time since I wrote these scripts and there's a LOT of work in updating them to follow the new syntax - this is going to be a far more substantial task than I was expecting.

Perhaps you should consider using:

--Set to 5.0 scripting object model
set version of script preferences to 5.0

until such time as you need to make serious use of CS5 features?

One thing that has me stuck is why the following doesn't throw an error in a try block if the frame doesn't exist.

set myFrame to item 1 of all page items whose label is "kim"

I simply end up with an undefined variable. I would have thought if it didn't exist and myFrame was undefined an error should be returned.

Am I missing something here or is this expected behaviour?

It is indeed expected!

A "whose" filter in AppleScript is permitted to return a null list. Errors are only supposed to be thrown in fairly serious errors. Depending on how you try to use the myFrame it might generate an error later though...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
May 03, 2011 May 03, 2011

Copy link to clipboard

Copied

Well it's certainly returning an error when used later

And there's the rub, in the CS3 version there was no problem simply checking to see if the frame existed but with the variable assignment failing without error the existence check naturally fails as well. I have coded a (fairly clunky) workaround which I think will be reliable but I still think returning an error when trying to assign a non-existent object to a variable makes sense.

With regards using the v5 Scripting, I figure I may as well just bite the bullet and get it done. We're probably a few months away from upgrading (and I'm the one who decides so it can be further postponed) so it's just a matter of getting it all done.

I like fiddling around but when I haven't looked at the scripts in probably 5 years it can take a while to get back into the swing of things

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 07, 2011 Sep 07, 2011

Copy link to clipboard

Copied

John Hawkinson suggested that changing the version in the script preferences could give one the ability to use properties the way we used to (i.e., set the properties of object A to the properties of object B). Sadly, this isn't the case in CS5 and CS5.5--it's one of those changes that defies versioning--so you're reduced to using other means. I should revise that a bit--*some* properties will transfer; it's important stuff like fill and stroke options won't.

I wish I'd caught this while I was still at Adobe, but I was working on other stuff during CS5. I can't believe that this big a mistake was made without someone else inside the company noticing.

Thanks,

Ole

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 07, 2011 Sep 07, 2011

Copy link to clipboard

Copied

Ole,

I'm not sure I'm following, but if I understand the issue correctly, deleting the "style" property from the proerties object should solve the issue.

Harbs

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 07, 2011 Sep 07, 2011

Copy link to clipboard

Copied

Hi Harbs,

My point was that you were once able to quickly apply all of the formatting of one object to another object, and now you can't--without further work, anyway. Yes, it's almost certainly a problem of the sequence in which items in the properties record are applied. But it shouldn't have changed.

I do have an example of a change that can be overcome with script versioning--the stacking order of items on a layer. It's possible to end up with mulitple page items with the same index(!)--I think it's a problem that's to do with documents coming from old versions of InDesign, or documents with pasted Illustrator paths--I'm not sure. Whatever causes it, it's something that survives export to IDML and back. When you iterate over the page items in a layer with this problem in CS5/CS5.5, you'll see something like this (this is reverse iteration--counter is counting down from layer.pageItems.length):

Counter: 62 Index: 60 ID: 4679
Counter: 61 Index: 59 ID: 4682

...

Counter: 3 Index: 1 ID: 4761
Counter: 2 Index: 0 ID: 4762
Counter: 1 Index: 1 ID: 4919
Counter: 0 Index: 0 ID: 4680

Isn't that crazy? The counter and the index are out of synch. What's more, ID: 4680 and ID:4919 are at the *back*--they should be at the start of the list. If you're trying to rebuild the stacking order of the objects in some other place (like, in a custom FXG or SVG export, in my case--both formats where stacking order depends on output order), this can drive you insane.

But...switch back to version 6.0 (CS4) before doing the iteration, and you get the items back in the correct back-to-front stacking order:

Counter: 62 Index: 1 ID: 4919
Counter: 61 Index: 60 ID: 4679
Counter: 60 Index: 0 ID: 4680
Counter: 59 Index: 59 ID: 4682

....

Counter: 3 Index: 3 ID: 4759
Counter: 2 Index: 2 ID: 4760
Counter: 1 Index: 1 ID: 4761
Counter: 0 Index: 0 ID: 4762

...even though the indices are clearly messed up. I'm not sure anyone else will ever face this particular problem, but it's cost me enough lost sleep that I thought I'd better mention it here!

Thanks,

Ole

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 07, 2011 Sep 07, 2011

Copy link to clipboard

Copied

Wow!

What a mess!

I assume you filed this bug...

Harbs

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 08, 2011 Sep 08, 2011

Copy link to clipboard

Copied

Ole:

John Hawkinson suggested that changing the version in the script preferences could give one the ability to use properties the way we used to (i.e., set the properties of object A to the properties of object B). Sadly, this isn't the case in CS5 and CS5.5--it's one of those changes that defies versioning--so you're reduced to using other means. I should revise that a bit--*some* properties will transfer; it's important stuff like fill and stroke options won't.

My claim was intended to be much more narrow, and I'm a bit confused how you thought I was referring to property transfer. I was really just talking about the ability to index objects by their script label.

That is, given a TextFrame labelled "foo", in CS5:

app.activeDocument.textFrames.item("foo").contents
Error: Object is invalid

However, if one sets the version preferences:

app.scriptPreferences.version=6.0
Result: 6
app.activeDocument.textFrames.item("foo").contents
Result: Foobar

So that does seem to work.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines