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

Script to find and select all text in a particular frame and set Grid Alignment to NONE

Contributor ,
Jul 12, 2023 Jul 12, 2023

Copy link to clipboard

Copied

Hi everyone,

I'm working on some documents that cotain text frames aligned to baseline grid where they are not supposed to be. They all have a specific fill color applied ("Akane red"). I managed to create a script which find and select all the text in the frame, but I'm stuck on the "Grid Alignment" part. The selected text should not be aligned to baseline grip. Could you please help me? Here's my code:

var doc = app.activeDocument;

var myDoc = app.activeDocument;

app.findObjectPreferences = null;
app.findObjectPreferences.fillColor = "Akane red";
var found = doc.findObject();
for(var i =0;i<found.length;i++)
{
    try{
        found[i].select();
     }catch(e){}
    }
app.findObjectPreferences = null;
   
try {
	app.selection[0].texts[0].select();
} catch (_)
{
   }

 
Thanks in advance,
Rogerio

TOPICS
How to , Scripting

Views

990

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 ,
Jul 12, 2023 Jul 12, 2023

Copy link to clipboard

Copied

Hi @Rogerio5C09, good to see you around. I had a look at your problem and I think it may be related to a bug I reported a while ago. The bug is that a fillColor (or strokeColor) cannot be supplied to the findObjectPreferences without throwing an error.

 

Anyway, here is a working script to do what you want I think. The actual property to turn off is "alignToBaseline".

- Mark

 

/**
 * Unsets "Align To Baseline" for all text in text frames filled with the target color.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/script-to-find-and-select-all-text-in-a-particular-frame-and-set-grid-alignment-to-none/m-p/13932423
 */
function main() {

    var doc = app.activeDocument,
        swatchName = 'Akane red';

    if (!doc.swatches.itemByName(swatchName).isValid) {
        alert('No swatch "' + swatchName + '" in document.');
        return;
    }

    app.findChangeObjectOptions.objectType = ObjectTypes.TEXT_FRAMES_TYPE;
    app.findObjectPreferences = NothingEnum.NOTHING;
    // this next line is just to work around this indesign bug: https://indesign.uservoice.com/forums/601180-adobe-indesign-bugs/suggestions/46404439--extendscript-app-findobjectpreferences-fillcolor
    app.changeTextPreferences.fillColor = swatchName;
    app.findObjectPreferences.fillColor = swatchName;

    var found = doc.findObject();

    for (var i = 0; i < found.length; i++)
        found[i].texts[0].alignToBaseline = false;

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Unapply Baseline Grid To Target 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
Contributor ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

Hi @m1b , likewise! 🙂 And thanks for the script! It worked just as expected.

I just realized there are some frames in "Akane red" color that Find/Change is not picking up. I found out that the swatch name is changing somehow by adding some random numbers at the end (see screenshot). This is the first time that I'm seeing it. Any thoughts? I guess that's why the script is not working on these particular frames.

Rogerio5C09_0-1689259788631.png


Anyway, I found a workaround by finding Inset Spacing instead - the text frames are set to 8,8,10,10 or 5,5,5,5 (Top, Bottom, Left, Right). I'm attaching some files for your reference here. See script below - Sorry, it dosn't look as great as yours and there might be some unnecessary lines hahah. So, I'm try to figure out how to make it work on multiple documents. For now, it works only on a single document and the rest remains the same. Could you please take a look?

for (var d=0; d<app.documents.length; d++)
{
    var doc = app.documents[d];

function main() {

    app.findChangeObjectOptions.objectType = ObjectTypes.TEXT_FRAMES_TYPE;
    app.findObjectPreferences = NothingEnum.NOTHING;
    
    app.changeObjectPreferences.insetSpacing = [ 8,10,8,10 ];
    app.findObjectPreferences.insetSpacing = [ 8,10,8,10 ];

    var found = doc.findObject();

    for (var i = 0; i < found.length; i++)
        found[i].texts[0].alignToBaseline = false;

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Unapply Baseline Grid To Target Frames');
}

 for (var d=0; d<app.documents.length; d++)
{
    var doc = app.documents[d];

function main() {

    app.findChangeObjectOptions.objectType = ObjectTypes.TEXT_FRAMES_TYPE;
    app.findObjectPreferences = NothingEnum.NOTHING;
    
    app.changeObjectPreferences.insetSpacing = [ 5,5,5,5 ];
    app.findObjectPreferences.insetSpacing = [ 5,5,5,5 ];

    var found = doc.findObject();

    for (var i = 0; i < found.length; i++)
        found[i].texts[0].alignToBaseline = false;
};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Unapply Baseline Grid To Target Frames');
}

 
Also, I noticed that some frames contain tables with text aligned to baseline grid and the script doesn't work on them. Would it be possible to turn off  "alignToBaseline" on tables as well?

Thanks in advance,
Rogerio

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 ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

Hi @Rogerio5C09, thanks for the test files—that was helpful. Here is a version of the script that searches for any swatch starting with "Akane red". - Mark

/**
 * Unsets "Align To Baseline" for all text in text frames filled with the target color.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/script-to-find-and-select-all-text-in-a-particular-frame-and-set-grid-alignment-to-none/m-p/13932423
 */
function main() {

    var doc = app.activeDocument,
        swatchNameMatcher = /^Akane Red/i,
        foundSwatches = getSwatches(doc, swatchNameMatcher);

    if (foundSwatches.length == 0) {
        alert('No swatches matching "' + swatchNameMatcher + '" in document.');
        return;
    }

    for (var s = 0; s < foundSwatches.length; s++) {

        app.findChangeObjectOptions.objectType = ObjectTypes.TEXT_FRAMES_TYPE;
        app.findObjectPreferences = NothingEnum.NOTHING;
        // this next line is just to work around this indesign bug: https://indesign.uservoice.com/forums/601180-adobe-indesign-bugs/suggestions/46404439--extendscript-app-findobjectpreferences-fillcolor
        app.changeTextPreferences.fillColor = foundSwatches[s].name;
        app.findObjectPreferences.fillColor = foundSwatches[s].name;

        var found = doc.findObject();

        for (var i = 0; i < found.length; i++) {
            found[i].texts[0].alignToBaseline = false;
            if (found[i].tables.length > 0)
                found[i].tables.everyItem().cells.everyItem().texts[0].alignToBaseline = false;
        }

    }

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Unapply Baseline Grid To Target Frames');


/**
 * Returns array of swatches with names
 * matching the `matcher` RegExp.
 * @author m1b
 * @version 2023-07-14
 * @param {Document} doc - an Indesign Document.
 * @param {RegExp} matcher - the regex to match the swatch name.
 */
function getSwatches(doc, matcher) {

    var found = [],
        swatches = doc.swatches;

    for (var i = 0; i < swatches.length; i++) {
        if (matcher.test(swatches[i].name))
            found.push(swatches[i]);
    }

    return found;

};

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
Contributor ,
Jul 14, 2023 Jul 14, 2023

Copy link to clipboard

Copied

Hi Mark, thanks so much! 🙂

I tested the script and it works perfectly. Would it be possible to make it work across multiple documents as well?

Regards,
Rogerio

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 ,
Jul 14, 2023 Jul 14, 2023

Copy link to clipboard

Copied

Hi @Rogerio5C09, glad it worked for you. It should have been really simple to make it work on all open documents, but ... when I simply put the whole thing in a loop over the documents it just did the active document and no others. I've never seen that behaviour before and I honestly don't know why it didn't work, but I would love to learn. Maybe doc.findObject() only works if doc is active? Anyway, I worked-around the problem by looping over the document names and setting them as the activeDocument.

- Mark

 

Here is the resulting script:

/**
 * Unsets "Align To Baseline" for all text in text frames filled with the target color in all open documents.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/script-to-find-and-select-all-text-in-a-particular-frame-and-set-grid-alignment-to-none/m-p/13932423
 */
function main() {

    var docNames = app.documents.everyItem().name,
        swatchNameMatcher = /^Akane Red/i;

    for (var d = 0; d < docNames.length; d++) {

        var doc = app.documents.itemByName(docNames[d]),
            foundSwatches = getSwatches(doc, swatchNameMatcher);

        if (foundSwatches.length == 0) {
            alert('No swatches matching "' + swatchNameMatcher + '" in document "' + doc.name + '".');
            continue;
        }

        app.activeDocument = doc;

        for (var s = 0; s < foundSwatches.length; s++) {

            app.findChangeObjectOptions.objectType = ObjectTypes.TEXT_FRAMES_TYPE;
            app.findObjectPreferences = NothingEnum.NOTHING;
            // this next line is just to work around this indesign bug: https://indesign.uservoice.com/forums/601180-adobe-indesign-bugs/suggestions/46404439--extendscript-app-findobjectpreferences-fillcolor
            app.changeTextPreferences.fillColor = foundSwatches[s].name;
            app.findObjectPreferences.fillColor = foundSwatches[s].name;

            var found = doc.findObject();

            for (var i = 0; i < found.length; i++) {
                found[i].texts[0].alignToBaseline = false;
                if (found[i].tables.length > 0)
                    found[i].tables.everyItem().cells.everyItem().texts[0].alignToBaseline = false;
            }

        }

    }

    // clean up
    app.activeDocument = app.documents.itemByName(docNames[0]);

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Unapply Baseline Grid To Target Frames');


/**
 * Returns array of swatches with names
 * matching the `matcher` RegExp.
 * @author m1b
 * @version 2023-07-14
 * @param {Document} doc - an Indesign Document.
 * @param {RegExp} matcher - the regex to match the swatch name.
 */
function getSwatches(doc, matcher) {

    var found = [],
        swatches = doc.swatches;

    for (var i = 0; i < swatches.length; i++) {
        if (matcher.test(swatches[i].name))
            found.push(swatches[i]);
    }

    return found;

};

 

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 ,
Jul 14, 2023 Jul 14, 2023

Copy link to clipboard

Copied

I'm no expert and i'm learning too - so just looking and lurking here...

Just wondering why docNames variable is assigned the value app.documents.everyItem().name

 

Just wondering why not like this - I haven't tried it. But just thinking.

 

function main() {
    var documents = app.documents,
        swatchNameMatcher = /^Akane Red/i;
    for (var d = 0; d < documents.length; d++) {
        var doc = documents[d],
            foundSwatches = getSwatches(doc, swatchNameMatcher);
        if (foundSwatches.length == 0) {
            alert('No swatches matching "' + swatchNameMatcher + '" in document "' + doc.name + '".');
            continue;
        }
        app.activeDocument = doc;

}

 

 

then at the end

 

    }

    // clean up
    app.activeDocument = documents[0];

}

 

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 ,
Jul 15, 2023 Jul 15, 2023

Copy link to clipboard

Copied

No, you have a good eye, @Eugene Tyson. I did this a strange way in an attempt to work around an apparent bug I found. It appears to be a problem with Document.findObject(). See this post I wrote, asking if anyone can reproduce the problem. If you have time, check out that post and see if you can reproduce the bug.

 

Buy yes, if there wasn't a bug (for me, at least) I would do it the way you described, except with no need to set the activeDocument.

- 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 Expert ,
Jul 15, 2023 Jul 15, 2023

Copy link to clipboard

Copied

Bit out of my paygrade ! Yikes !

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 ,
Jul 15, 2023 Jul 15, 2023

Copy link to clipboard

Copied

Perhaps I can explain what I did. First my aim was to loop over the documents and make each one the activeDocument. The problem with this is that as soon as you change the activeDocument, all the documents' indices change such that the activeDocument is always 0. So the normal loop won't work as the references will be wrong. Instead I collected the document names and looped over those, getting the document with app.documents.itemByName. The clean up bit is just to return the original activeDocument.

- 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
Contributor ,
Jul 15, 2023 Jul 15, 2023

Copy link to clipboard

Copied

Hi @m1b, yes, it might be a problem with doc.findObject() - I've been testing some other scripts and they only work if doc is active. Very weird. At least findText and findGrep didn't let me down hahaha

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 ,
Jul 15, 2023 Jul 15, 2023

Copy link to clipboard

Copied

LATEST

Yes we have confirmed there is a bug with Document.findObject().

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 ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

A better option would be to create an Object Style - and in the object style don't have it align to the baseline grid. 

Then the script could find the frames and apply the object style.

 

Then you can change the Object Style everytime you need to make a global change.

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 ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

I agree @Eugene Tyson but in this case I got the impression the documents were created elsewhere and weren't so tidy. Also the alignToBaseline would have to be turned off for every paragraph style in the document, and even then it would only work if they were neatly set up with an unoverridden paragraph style.

- 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 Expert ,
Jul 13, 2023 Jul 13, 2023

Copy link to clipboard

Copied

ah yes - I don't always remember things are setup as methodically as I would. 

 

Good point.

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