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
@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
...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/
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:
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:
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
Copy link to clipboard
Copied
[...] 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.
Copy link to clipboard
Copied
[...] 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.
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
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Ok. Thanks.
Copy link to clipboard
Copied
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.
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
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.
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;
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 )
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
Copy link to clipboard
Copied
Currently I am stuck with generation of counters and applying a style to them.
By @shahidr100
What's the problem?
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.
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:
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');
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
@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.
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.
Copy link to clipboard
Copied
@Laubender I tried your method. It actually is faster than the method which I was using. Thanks.
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;
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);
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');
If you want to start not from "1", then you need to set Mode->Start At:
then switch back to Continue:
Copy link to clipboard
Copied
@Robert at ID-Tasker Thank you so much. It worked.