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

Thread Frames through script

Enthusiast ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

I have some circled textframes which I want to thread together using script and in each text frame I would like to place a counter of my choice. The counter is a number which I want to give manually.

 

Some examples of the counter is:

ex1: A-2234 onwards ...eg A-2235, A2236, A-2237 respectively in separate text frames.

ex2: B-0001 onwards...eg B-0002, B-0003, B-0004 respectively in separate text frames.

 

I have written a script to thread the frames but its threading hapazardly.

I have attached a screenshot with before and after run of the script. Also when the script ends, it gives an error.

 

Here is the script. It just threads. Once threading is perfect, I will place the counters using a variable.

 

frames = app.selection;
//alert(frames.length);
for(i=0;i<frames.length;i++){
frames[i].nextTextFrame = frames[i+1];
}

 

 

Currently the matter is in one page. It may run through multiple pages.

 

What mistake am I doing ?

 

Thanks

TOPICS
How to , Scripting

Views

912

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

correct answers 1 Correct answer

Community Expert , May 09, 2024 May 09, 2024
quote

@Robert at ID-Tasker I have come up with the following script where I have followed process mentioned by @Laubender and assigned the story to frame by the process suggested by you, but still it shows only 1 \n char in first frame only. I have tried with 5 textframes only for testing. Screenshot of the output is attached.

var output = String('\n', 5);

 

By @shahidr100

 

Looks like this doesn't work as per example I've found on some website, sorry.

And you should use '\r' rather than '\n'.

 

Thi

...

Votes

Translate

Translate
Community Expert ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

You can create a "grid" using InDesign - and all TextFrames will be threaded automatically:

https://creativepro.com/tip-week-gridify-magic/

 

 

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 ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

Hi @shahidr100 , The error is happening because your loop is from 0 to the frames.length—it should be 0 to frames.length-1:

 

frames = app.selection;
//alert(frames.length);
for(i=0;i<frames.length-1;i++){
    frames[i].nextTextFrame = frames[i+1];
}

 

This works with the IDML you shared:

 

Screen Shot 11.png

 

But note that your loop is threading via the text frame index (your i variable), and the index is determined by the order the frames were added to the page. So, if I cut and paste the center circle its index becomes 0 and i get this:

 

Screen Shot 12.png

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
Enthusiast ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

First of all thank you so much for the correction.

Secondly, I know about the gridify feature.  Actually I am making one circle then applying object style. Then I am using gridify feature to create the grid of circles. Then I will run the script to thread the frame and then the last step would be to populate the circles with the counters.

 

I made the corrections and it worked. However, one thing is bothering me. When I select the circle one by one and then run the script, it threads perfectly. But when I do a select all OR select it by using the mouse drag, the threading again acts weirdly.

 

What modification do I need to do so that if I do a select all or select using mouse drag, the threading is perfect.

 

If I want to thread by order of creation, what modification do I need to do ?

Thanks

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 ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

quote

[...] Actually I am making one circle then applying object style. Then I am using gridify feature to create the grid of circles.

[...] 

 

By @shahidr100

 

Make your circle as a TextFrame - not a Graphic Object - InDesign will automatically thread them together. 

 

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 ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

quote

[...] If I want to thread by order of creation, what modification do I need to do ?


By @shahidr100

 

You don't want to thread by creation order - but rather by location - if all objects are on the same Page / Spread - you need to build an Array or Collection with PosX, PosY, ID - then sort it by PosX+PosY or PosY+PosX - depends if you need to thread top-to-bottom or left-to-right.

 

If objects are on multiple spreads - then you need to add PageIndex in front. 

 

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
Enthusiast ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

Thanks for the answer.

 

I am stuck at the following:

frames = app.selection;
var counter="A-";
var counterPart=2250;

for(i=0;i<frames.length-1;i++){
	frames[i].contents=counter+counterPart+SpecialCharacters.FRAME_BREAK;
	frames[i].nextTextFrame = frames[i+1];
	counterPart++;
}

 

Ideally the circles should be populated with A-2250, A-2251, A-2252 etc...but for some reason that is not happening and only first circle is getting populated with the value "2251" which is wrong. It  should start with  "2250". Also I am giving a frame break but instead I am getting some value. I dont know from where it is getting that value. Also I am getting an override. I have tested by selecting 3 circles only.

 

I have attached a screenshot.

 

Thanks

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 ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

@shahidr100

 

As those TFs are threaded - you shouldn't refer to each one - you should either build whole string and set to the parent story's contents - or refer to last insertionPoint of the parentStory. 

 

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
Enthusiast ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

Ok. Thanks.

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 ,
May 02, 2024 May 02, 2024

Copy link to clipboard

Copied

quote

Ok. Thanks.


By @shahidr100

 

You are welcome. 

 

If you apply ParaStyle - before or after - to the whole Story - you don't have to insert Frame Breaks - you can set "start in next frame" in Keep Options of ParaStyle definition.

 

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
Enthusiast ,
May 08, 2024 May 08, 2024

Copy link to clipboard

Copied

@Robert at ID-Tasker Thanks. Actually I am stuck at generation the counter and applying it to the circles which I have created.

Thanks

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 ,
May 08, 2024 May 08, 2024

Copy link to clipboard

Copied

quote

@Robert at ID-Tasker Thanks. Actually I am stuck at generation the counter and applying it to the circles which I have created.


By @shahidr100

 

You can do it the "easy way" - build a string with required number of new line characters, create ParaStyle with numbering - set prefix and "start at" - set this string as contents of the story, then apply this ParaStyle to the Story.

Also, set this ParaStyle to start in the next TextFrame - keep option.

 

var output = String('\n', 200);

myStory.contents = output;

 

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 ,
May 03, 2024 May 03, 2024

Copy link to clipboard

Copied

Hi @shahidr100 ,

if you are working with a selection of text frames your script will work in the order you have selected the frames.

So, if you want the order from left to right and top to bottom select the frames one by one in that order using the Shift key with click.

 

FWIW: performance is no issue with a couple of text frames.

But in case you want to accelerate your script's performance use property previousTextFrame instead of nextTextFrame.

var textFramesSelected = app.selection;

for( n=1; n<textFramesSelected.length; n++ )
{
	textFramesSelected[n].previousTextFrame = 
	textFramesSelected[n-1];
};

 

Regards,
Uwe Laubender
( Adobe Community Expert )

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
Enthusiast ,
May 08, 2024 May 08, 2024

Copy link to clipboard

Copied

@Laubender Thanks.  I am using few text frames with only a counter that would run from 1 to 200 or A-0001 to A-0200.

I will try your method of previousTextFrame also. Currently I am stuck with generation of counters and applying a style to them.

Thanks

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 ,
May 08, 2024 May 08, 2024

Copy link to clipboard

Copied

quote

Currently I am stuck with generation of counters and applying a style to them.


By @shahidr100

 

What's the problem? 

 

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
Enthusiast ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

The problem is that I am not able to generate the counters and attach to the parent story of the threaded frame

as suggested by you  earlier.

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 ,
May 08, 2024 May 08, 2024

Copy link to clipboard

Copied

Hi @shahidr100 , I think you will have to add the Frame Break character after you insert the counter string, something like this:

 

Screen Shot 11.png


function threadFrames(){
    var frames = app.selection;
    var counter="A-";
    var counterPart=2250;
    
    for(i=0;i<frames.length-1;i++){
        frames[i].contents =  counter+counterPart;
        frames[i].insertionPoints.lastItem().contents =  SpecialCharacters.FRAME_BREAK
        frames[i].nextTextFrame = frames[i+1];
        counterPart++;
    }
    frames[frames.length-1].contents=  counter+counterPart;
}

app.doScript(threadFrames, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Thread Frames');

 

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 ,
May 08, 2024 May 08, 2024

Copy link to clipboard

Copied

@rob day

 

With all due respect, but this approach is so wrong on so many levels?

 

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
Enthusiast ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

@rob day Wow. This is actually what I wanted. Thanks so much.

@Robert at ID-Tasker mentioned that this process is wrong at many level. I would like to know what are the drawbacks of this process. Thanks

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 ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

quote

 

@Robert at ID-Tasker mentioned that this process is wrong at many level. I would like to know what are the drawbacks of this process. Thanks


By @shahidr100

 

It will work only in certain circumstances - when order of the TFs in the selection is correct. 

 

Then, it's quicker to build string and set it as contents of the Story - than constantly referencing to new TFs. 

 

And as @Laubender mentioned - "in case you want to accelerate your script's performance use property previousTextFrame instead of nextTextFrame.". 

 

You've more control over the text - contents of the Story - when there are no "manual" breaks - and you set Keep Option of the ParaStyle.

 

And if you use Bullets & Numbering in the ParaStyle definition - you don't have to build your string - just use String('\n', 200). 

 

Then, in case those TFs are not created manually by the user - you could create them yourself, in your script - so you've better control over the proces. 

 

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 ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

Wow. This is actually what I wanted. Thanks so much.

 

I wasn’t trying to re write or develop your script, but with the code you provided setting the contents to include a frame break didn’t seem to be working, All I did was ensure that it was added at the last insertion point of the frame you were threading. Also the IDML you provided seems to be setting the text RTL, so you might have to consider that.

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
Enthusiast ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

@Laubender I tried your method. It actually is faster than the method which I was using. Thanks.

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
Enthusiast ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

@Robert at ID-Tasker I have come up with the following script where I have followed process mentioned by @Laubender and assigned the story to frame by the process suggested by you, but still it shows only 1 \n char in first frame only. I have tried with 5 textframes only for testing. Screenshot of the output is attached.

 

 

var output = String('\n', 5);
var textFramesSelected = app.selection;
for( n=1; n<textFramesSelected.length; n++ )
{
textFramesSelected[n].previousTextFrame = textFramesSelected[n-1];
};
textFramesSelected[0].contents=output;

 

 

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 ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

quote

@Robert at ID-Tasker I have come up with the following script where I have followed process mentioned by @Laubender and assigned the story to frame by the process suggested by you, but still it shows only 1 \n char in first frame only. I have tried with 5 textframes only for testing. Screenshot of the output is attached.

var output = String('\n', 5);

 

By @shahidr100

 

Looks like this doesn't work as per example I've found on some website, sorry.

And you should use '\r' rather than '\n'.

 

This should work:

 

 

var output = new Array(5).join('\r');
var textFramesSelected = app.selection;
for( n=1; n<textFramesSelected.length; n++ )
{
textFramesSelected[n].previousTextFrame = textFramesSelected[n-1];
};

app.selection[0].contents = output;
app.selection[0].parentStory.appliedParagraphStyle = app.activeDocument.paragraphStyles.item('qqq');

 

 

 

RobertatIDTasker_1-1715272383609.png

 

RobertatIDTasker_0-1715272367941.png

 

 

If you want to start not from "1", then you need to set Mode->Start At:

RobertatIDTasker_4-1715272686075.png

 

then switch back to Continue:

RobertatIDTasker_5-1715272705707.png

 

 

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
Enthusiast ,
May 09, 2024 May 09, 2024

Copy link to clipboard

Copied

@Robert at ID-Tasker Thank you so much. It worked.

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