Highlighted

Thread Text Frames Across Document by Object Style Name

Community Beginner ,
May 21, 2020

Copy link to clipboard

Copied

Hi all, hope everyone is well!
Would appreciate some help fixing this script. I have a document with many text frames with object styles. I’m looking for a script that will thread text frames that have the same object style name. When new pages are added to the document then the script could be run to link the newly created frames. (So I guess it would have to activate master page items too?)
The following script was pieced together from 2 different scripts I found online. It works in finding the frames and in threading them but the sequence of the frames is not correct.
The sequence works fine if the objects are on the same page and neatly stacked on top of each other.. But if not then it produces 1,3,5,2,4,6 and even 6,5,4,3,2,1 when on different pages.
Would appreciate help with fixing this, Thanks!
Capture1.PNG
(PS. I'm not a programmer or that familiar with scripting so it is highly possible that parts of the frankenstein srcipt may not be necessary!)
(PSS. Just want to give credit to Jongware for the orginal script. It was made by combining (or butchering) 2 scripts he wrote. (Though he may not know it!)
 
 

__________________

 

 
 

 

 

 

 

for(p=0; p<app.activeDocument.pages.length; p++){
var combineMe = new Array;
app.findObjectPreferences = null;
app.findObjectPreferences.appliedObjectStyles = "Style";
found_list = app.activeDocument.findObject(true);
for (a=0; a<found_list.length; a++)
{
if (found_list[a] instanceof TextFrame)
combineMe.push(found_list[a]);
}
combineMe.sort (function (a,b) { return (a.geometricBounds[0] < b.geometricBounds[0]) || (a.geometricBounds[0] == b.geometricBounds[0] && a.geometricBounds[1] < b.geometricBounds[1]) ? -1 : 1; } );
for (i=0; i<combineMe.length-1; i++)
{
if (combineMe[i].nextTextFrame == null)
{
nextFree = i+1;
while (nextFree < combineMe.length && combineMe[nextFree].previousTextFrame != null)
nextFree++;
combineMe[i].nextTextFrame = combineMe[nextFree];
}
}
}

 

 

 

 

Adobe Community Professional
Correct answer by brianp311 | Adobe Community Professional

When you're calling 

 

found_list = app.activeDocument.findObject(true);

 

even though you think you're working by page, you're actually finding all matched objects throughout the document and adding them to the array. There's probably more efficient ways of going about this, but I would just search the whole document once, rather than iterating through pages. The following adds to the sort method a check to see if they are are on a previous page, then just relinks everything: 

 

var sortFrames = function (arr) {
    arr.sort(function (a, b) {
        if (a.parentPage.documentOffset < b.parentPage.documentOffset) {
            return -1;
        }
        else if (a.parentPage.documentOffset > b.parentPage.documentOffset) {
            return 1;
        }
        else {
            if (a.geometricBounds[0] < b.geometricBounds[0]) {
                return -1;
            }
            else if (a.geometricBounds[0] > b.geometricBounds[0]) {
                return 1;
            }
            else {
                if (a.geometricBounds[1] < b.geometricBounds[1]) {
                    return -1;
                }
                else if (a.geometricBounds[1] > b.geometricBounds[1]) {
                    return 1;
                }
                return 0;
            }
        }
    });

};

var combineMe = new Array;
app.findObjectPreferences = null;
app.findObjectPreferences.appliedObjectStyles = "Style";
found_list = app.activeDocument.findObject();
for (a=0; a<found_list.length; a++) {
    if (found_list[a] instanceof TextFrame) {
        combineMe.push(found_list[a]);
    }
}

sortFrames(combineMe);

for (var c = 0; c < combineMe.length - 1; c++) {
    try {
        combineMe[c+1].previousTextFrame = null;
        combineMe[c].nextTextFrame = combineMe[c + 1];
    } catch(e) {}
}

 

 

 

Now with testing 🙂

Topics

Scripting

Views

626

Likes

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

Thread Text Frames Across Document by Object Style Name

Community Beginner ,
May 21, 2020

Copy link to clipboard

Copied

Hi all, hope everyone is well!
Would appreciate some help fixing this script. I have a document with many text frames with object styles. I’m looking for a script that will thread text frames that have the same object style name. When new pages are added to the document then the script could be run to link the newly created frames. (So I guess it would have to activate master page items too?)
The following script was pieced together from 2 different scripts I found online. It works in finding the frames and in threading them but the sequence of the frames is not correct.
The sequence works fine if the objects are on the same page and neatly stacked on top of each other.. But if not then it produces 1,3,5,2,4,6 and even 6,5,4,3,2,1 when on different pages.
Would appreciate help with fixing this, Thanks!
Capture1.PNG
(PS. I'm not a programmer or that familiar with scripting so it is highly possible that parts of the frankenstein srcipt may not be necessary!)
(PSS. Just want to give credit to Jongware for the orginal script. It was made by combining (or butchering) 2 scripts he wrote. (Though he may not know it!)
 
 

__________________

 

 
 

 

 

 

 

for(p=0; p<app.activeDocument.pages.length; p++){
var combineMe = new Array;
app.findObjectPreferences = null;
app.findObjectPreferences.appliedObjectStyles = "Style";
found_list = app.activeDocument.findObject(true);
for (a=0; a<found_list.length; a++)
{
if (found_list[a] instanceof TextFrame)
combineMe.push(found_list[a]);
}
combineMe.sort (function (a,b) { return (a.geometricBounds[0] < b.geometricBounds[0]) || (a.geometricBounds[0] == b.geometricBounds[0] && a.geometricBounds[1] < b.geometricBounds[1]) ? -1 : 1; } );
for (i=0; i<combineMe.length-1; i++)
{
if (combineMe[i].nextTextFrame == null)
{
nextFree = i+1;
while (nextFree < combineMe.length && combineMe[nextFree].previousTextFrame != null)
nextFree++;
combineMe[i].nextTextFrame = combineMe[nextFree];
}
}
}

 

 

 

 

Adobe Community Professional
Correct answer by brianp311 | Adobe Community Professional

When you're calling 

 

found_list = app.activeDocument.findObject(true);

 

even though you think you're working by page, you're actually finding all matched objects throughout the document and adding them to the array. There's probably more efficient ways of going about this, but I would just search the whole document once, rather than iterating through pages. The following adds to the sort method a check to see if they are are on a previous page, then just relinks everything: 

 

var sortFrames = function (arr) {
    arr.sort(function (a, b) {
        if (a.parentPage.documentOffset < b.parentPage.documentOffset) {
            return -1;
        }
        else if (a.parentPage.documentOffset > b.parentPage.documentOffset) {
            return 1;
        }
        else {
            if (a.geometricBounds[0] < b.geometricBounds[0]) {
                return -1;
            }
            else if (a.geometricBounds[0] > b.geometricBounds[0]) {
                return 1;
            }
            else {
                if (a.geometricBounds[1] < b.geometricBounds[1]) {
                    return -1;
                }
                else if (a.geometricBounds[1] > b.geometricBounds[1]) {
                    return 1;
                }
                return 0;
            }
        }
    });

};

var combineMe = new Array;
app.findObjectPreferences = null;
app.findObjectPreferences.appliedObjectStyles = "Style";
found_list = app.activeDocument.findObject();
for (a=0; a<found_list.length; a++) {
    if (found_list[a] instanceof TextFrame) {
        combineMe.push(found_list[a]);
    }
}

sortFrames(combineMe);

for (var c = 0; c < combineMe.length - 1; c++) {
    try {
        combineMe[c+1].previousTextFrame = null;
        combineMe[c].nextTextFrame = combineMe[c + 1];
    } catch(e) {}
}

 

 

 

Now with testing 🙂

Topics

Scripting

Views

627

Likes

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
Adobe Community Professional ,
May 22, 2020

Copy link to clipboard

Copied

When you're calling 

 

found_list = app.activeDocument.findObject(true);

 

even though you think you're working by page, you're actually finding all matched objects throughout the document and adding them to the array. There's probably more efficient ways of going about this, but I would just search the whole document once, rather than iterating through pages. The following adds to the sort method a check to see if they are are on a previous page, then just relinks everything: 

 

var sortFrames = function (arr) {
    arr.sort(function (a, b) {
        if (a.parentPage.documentOffset < b.parentPage.documentOffset) {
            return -1;
        }
        else if (a.parentPage.documentOffset > b.parentPage.documentOffset) {
            return 1;
        }
        else {
            if (a.geometricBounds[0] < b.geometricBounds[0]) {
                return -1;
            }
            else if (a.geometricBounds[0] > b.geometricBounds[0]) {
                return 1;
            }
            else {
                if (a.geometricBounds[1] < b.geometricBounds[1]) {
                    return -1;
                }
                else if (a.geometricBounds[1] > b.geometricBounds[1]) {
                    return 1;
                }
                return 0;
            }
        }
    });

};

var combineMe = new Array;
app.findObjectPreferences = null;
app.findObjectPreferences.appliedObjectStyles = "Style";
found_list = app.activeDocument.findObject();
for (a=0; a<found_list.length; a++) {
    if (found_list[a] instanceof TextFrame) {
        combineMe.push(found_list[a]);
    }
}

sortFrames(combineMe);

for (var c = 0; c < combineMe.length - 1; c++) {
    try {
        combineMe[c+1].previousTextFrame = null;
        combineMe[c].nextTextFrame = combineMe[c + 1];
    } catch(e) {}
}

 

 

 

Now with testing 🙂

Likes

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
Reply
Loading...
Community Beginner ,
May 22, 2020

Copy link to clipboard

Copied

Hi Brian!
Thank you very much! It seems to work perfectly. I've tested in LTR & RTL documents.👌🏼


 

 

Likes

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
Reply
Loading...
Adobe Community Professional ,
May 23, 2020

Copy link to clipboard

Copied

Great. FYI, this might break if any text frames are on the pasteboard. 

Likes

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
Reply
Loading...
Adobe Community Professional ,
May 25, 2020

Copy link to clipboard

Copied

Hi Brian,

this will break if any text frames are found on the pasteboard.

In that case parentPage will return null instead of a page object.

 

Also note:

If a text frame is found on a master page, parentPage.documentOffset will return -1.

 

Regards,
Uwe Laubender

( ACP )

Likes

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
Reply
Loading...