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

Threading all textFrame in document skips second frame in page

Community Beginner ,
Jun 05, 2023 Jun 05, 2023

Copy link to clipboard

Copied

I've this script that links all Document textFrame with specific frame name.

It works well, only if I've one box per page.

When I've two textFrames in one page, it links only one.

var ps = app.activeDocument.pages;
var ct, nt;
for (var i = 0; i < ps.length - 1; i++) {
    ct = ps[i].textFrames.itemByName("<Numbers>");
	secondTextFrame = ct.nextTextFrame
    nt = ps[i+1].textFrames.itemByName("<Numbers>");
	ct.nextTextFrame = nt;    
}

 Thanks

TOPICS
How to , Scripting

Views

211

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 , Jun 05, 2023 Jun 05, 2023

Hi @lux65, here's some code that might help you with your project. It will thread any text frame that has the script label "NUMBERS". If you prefer using the name you can change that—either is fine. Text frames will be sorted by page order, then Y coordinate, then X coordinate.

- Mark

Screenshot 2023-06-06 at 08.30.06.png

 

 

 

 

/**
 * Thread text frames labelled "NUMBERS"
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/threading-all-textframe-in-document-skips-second-frame-in-page/m-p/13842736
 *
...

Votes

Translate

Translate
Community Expert ,
Jun 05, 2023 Jun 05, 2023

Copy link to clipboard

Copied

If you have two text frames named <Numbers> on a page, then yes, this would not work. ItemByName only returns the first item it finds. You would need to either change how you name your frames and adjust the script to account for that, or loop through ps[i].allPageItems, and find all text frames named <Numbers>. Of course, in that case, how would the script know which is the first and which is the second? Alternatively, you could link the frames on the page before executing the script. 

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 Beginner ,
Jun 05, 2023 Jun 05, 2023

Copy link to clipboard

Copied

I changed second frame name, it works but only if all frames are unthreaded.

var ps = app.activeDocument.pages;
var ct, nt, ct2;
for (var i = 0; i < ps.length - 1; i++) {
    ct = ps[i].textFrames.itemByName("<Number>");
	ct2 = ps[i].textFrames.itemByName("Number2");
    nt = ps[i+1].textFrames.itemByName("<Number>");
  //  ct.nextTextFrame = nt;

  if(ct2.isValid ){
ct.nextTextFrame = ct2;
ct2.nextTextFrame = nt;
}
else{
ct.nextTextFrame = nt
}

}

 

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 ,
Jun 05, 2023 Jun 05, 2023

Copy link to clipboard

Copied

Hi @lux65, here's some code that might help you with your project. It will thread any text frame that has the script label "NUMBERS". If you prefer using the name you can change that—either is fine. Text frames will be sorted by page order, then Y coordinate, then X coordinate.

- Mark

Screenshot 2023-06-06 at 08.30.06.png

 

 

 

 

/**
 * Thread text frames labelled "NUMBERS"
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/threading-all-textframe-in-document-skips-second-frame-in-page/m-p/13842736
 */

var targetScriptLabel = "NUMBERS";

function main() {

    var doc = app.activeDocument,
        allTextFrames = doc.textFrames,
        targetFrames = [];

    // we only want the text frames
    // with target script label
    for (var i = 0; i < allTextFrames.length; i++)
        if (allTextFrames[i].label == targetScriptLabel)
            targetFrames.push(allTextFrames[i]);

    //sort in page order
    targetFrames.sort(sortFrames);

    // now we thread the frames, by only if
    // they aren't already threaded properly
    for (var i = 0; i < targetFrames.length - 1; i++)
        if (targetFrames[i].nextTextFrame != targetFrames[i + 1])
            targetFrames[i].nextTextFrame = targetFrames[i + 1];

}

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Thread "' + targetScriptLabel + '" Frames');


/**
 * Sorts text frames based on page, then left position, then top position.
 * @param {TextFrame} a - the TextFrame to sort.
 * @param {TextFrame} b - the TextFrame to sort.
 */
function sortFrames(a, b) {

    // by page number
    if (a.parentPage.documentOffset < b.parentPage.documentOffset) return -1;
    else if (a.parentPage.documentOffset > b.parentPage.documentOffset) return 1;
    // by top-bottom
    else if (round(a.geometricBounds[0]) < round(b.geometricBounds[0])) return -1;
    else if (round(a.geometricBounds[0]) > round(b.geometricBounds[0])) return 1;
    // by left-right
    else if (round(a.geometricBounds[1]) < round(b.geometricBounds[1])) return -1;
    else if (round(a.geometricBounds[1]) > round(b.geometricBounds[1])) return 1;
    // same
    else return 0;

    function round(a) { return (Math.round(a * 1000) / 1000) };
};

 

 

Edit 2023-06-07: added sorting function so the layer order doesn't matter.

Edit 2023-06-17: changed sorting order to prefer left-right.

Edit 2023-06-18: changed sorting order to prefer top-bottom.

Edit 2023-06-18: improved sorting so that tiny Extendscript rounding errors are ignored.

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 Beginner ,
Jun 06, 2023 Jun 06, 2023

Copy link to clipboard

Copied

Hi m1b

strange behaviour, still ignoring second frame and links page 3 before page 2

 

Schermata 2023-06-06 alle 09.50.47.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
Community Expert ,
Jun 06, 2023 Jun 06, 2023

Copy link to clipboard

Copied

Interesting! Can you check if the frames are in the correct order on the spread? Maybe the page 3 frame is above the page 2 frame?

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 Beginner ,
Jun 06, 2023 Jun 06, 2023

Copy link to clipboard

Copied

Seems it links Frames randomly

Schermata 2023-06-06 alle 20.58.29.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
Community Expert ,
Jun 06, 2023 Jun 06, 2023

Copy link to clipboard

Copied

Hi @lux65, the way the script works currently is to link them in page order, and then layer order. So which ever text frame is topmost in the Layers Panel will be first. It isn't random.

 

However, it isn't hard for me to put some useful logic in the script so I will update the above code with a sorting function that sorts each text frame by page, then by Y location, then by X location. That should make it simpler.

- Mark

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 Beginner ,
Jun 17, 2023 Jun 17, 2023

Copy link to clipboard

Copied

Thank you m1bI didn't see you added sort code.

I just need a little change to get left-right priority then top down.

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 ,
Jun 17, 2023 Jun 17, 2023

Copy link to clipboard

Copied

Hi @lux65, I changed the sorting function above to do left-right before top-bottom. That should do it.

- Mark

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 Beginner ,
Jun 17, 2023 Jun 17, 2023

Copy link to clipboard

Copied

Maybe the flow I need is too complicated.

Schermata 2023-06-17 alle 15.50.34.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
Community Expert ,
Jun 17, 2023 Jun 17, 2023

Copy link to clipboard

Copied

It looks fine to me. (But I have to revert the last change I made to the script—must be top-bottom first then left-right.)  When I test it threads in the correct order. Remember that it sorts top to bottom first, so even though the frames look like they are lining up to our eye, check the numbers! Even if a right-ward frame is 0.001 higher than the other, it will be threaded first. - Mark

Screenshot 2023-06-18 at 07.29.23.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
Community Beginner ,
Jun 18, 2023 Jun 18, 2023

Copy link to clipboard

Copied

Thank you m1b,

Perfect!

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 Beginner ,
Jun 18, 2023 Jun 18, 2023

Copy link to clipboard

Copied

 

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 ,
Jun 18, 2023 Jun 18, 2023

Copy link to clipboard

Copied

LATEST

Hi @lux65, thanks for the sample document—that helped a lot! The problem was because even though in Indesign two frames say the same top value, eg. 36, the actual number of some of them is 35.9999999. The UI shows 36 for both. I easily fixed this problem by changing the sorting function to round the numbers off to 3 decimal places. Try the updated script.

- Mark

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