Skip to main content
Participating Frequently
March 17, 2023
Answered

Script to apply a style to a range of text frames or pages

  • March 17, 2023
  • 2 replies
  • 3001 views

Hi! I am  designing a book of 4 signatures, with text spanning the entirety of the book. I want to use a different paragraph style for each signature, but the text should remain continuous. What would a script look like that basically says:

  • For text frames 1-16, use Paragraph Style 1
  • For text frames 17-32, use Paragraph Style 2
  • For text frames 33-48, use Paragraph Style 3
  • For text frames 49-64, use Paragraph Style 4

 

Or some equivalent of the above. I cannot achieve this with paragraph styles or Next Style since text breaks to a new signature mostly mid-paragraph. Trying to do this manually with character styles isn’t feasible, since any minute adjustment will reflow the text and disrupt the setting on all subsequent pages.

Thanks in advance for any help!

This topic has been closed for replies.
Correct answer FRIdNGE
// by FRIdNGE, Michel Allio [18/03/2023]

// Place the Cursor in the Main Story!
var myStory = app.selection[0].parentStory,
myTFrames = myStory.textContainers,
T = myTFrames.length,  t;
//---------------------------------------------
// To Be Clearly Defined:
var myPagesRanges = [16, 32, 48, 64];
var myCStyles = ["Character Style 1", "Character Style 2", "Character Style 3", "Character Style 4"];
//---------------------------------------------
var myPagesRange = 0;
var myCStyle = 0;
for ( t = 0; t < T; t++ ) {
    try {
        if ( t >= myPagesRanges[myPagesRange] ) {
            myPagesRange++
            myCStyle++
        }
        myTFrames[t].texts[0].appliedCharacterStyle = app.activeDocument.characterStyles.item(myCStyles[myCStyle]);
    } catch(e) {}
}
alert( "Done! …" )

 

(^/)  The Jedi

2 replies

m1b
Community Expert
Community Expert
March 18, 2023

Hi @clw48, sorry if I've misunderstood your exact situation, but from what I do understand I would do it this way:

1. add a script label to the text frames that you want to set the character style (I've used the format characterStyle:<nameOfCharacterStyleHere>)

2. The script will search through all text frames and if that format is found, then set the text of that frame.

Let me know if that works in your case.

- Mark

 

 

/**
 * Sets text of specially-labeled text frame's to specified character style.
 * First put text into a multi-textFrame threaded story.
 * Then label the frames with "characterStyle:<insert Character Style name here>".
 * Then run script.
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/script-to-apply-a-style-to-a-range-of-text-frames-or-pages/m-p/13659632/thread-id/520047
 */
function main() {

    var doc = app.activeDocument,
        stories = doc.stories.everyItem().getElements(),
        matchLabel = /^characterStyle:(.+)/i;

    for (var i = 0; i < stories.length; i++) {
        var story = stories[i],
            frames = story.textContainers;

        for (var j = 0; j < frames.length; j++) {

            // examine the frame's script label
            var match = frames[j].label.match(matchLabel);
            if (
                match == null
                || match.length < 2
            )
                // no match
                continue;

            var charStyle = doc.characterStyles.itemByName(match[1]);
            if (!charStyle.isValid)
                // matched, but style not found
                continue;

            frames[j].texts[0].applyCharacterStyle(charStyle);

        }

    }

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Set Text Frame Character Styles');

 

Edit: added sample .indd. Run script with that first to check that it works as I expect it to.

clw48Author
Participating Frequently
March 18, 2023

Mark, I think this is the way. If I'm understanding it correctly this will involve hitting the script button every time text reflows, but that's simple and quick enough.

 

Do you have a basic paragraph style applied to all of the text frames first? Or none?

m1b
Community Expert
Community Expert
March 18, 2023

If I'm understanding it correctly this will involve hitting the script button every time text reflows

Yes. There is no way around this that I can think of.

 

Do you have a basic paragraph style applied to all of the text frames first? Or none?

Yes. I would expect that your paragraph style for all signatures would be the same, and would incorporate any properties that are shared between signatures, and that your character styles would only set the minimum number of properties required to achieve your desired result.

 

The method I showed is more work to set up—you have to add the script labels to each text frame—but this was what I chose to explore because I liked the deliberate certainty of knowing which text frames will be affected by the script each time it is run.

- Mark

Robert at ID-Tasker
Legend
March 18, 2023

Can you split it into 4x separate Threads / Stories? 

 

Or you really need to change formatting mid-paragraph - between TextFrames?? 

 

 

clw48Author
Participating Frequently
March 18, 2023

I really need to change the formatting between text frames.

 

I've been working with ChatGPT to try to come up with a solution. I've come close but can't get it quite right. It seems a script that applies character styles to page ranges will be the best bet. I have the following, but when I run it, all my text disappears and becomes overset beyond the text frames:

 

// Get the active document
var doc = app.activeDocument;

// Define the page range for each character style
var style1Pages = [1, 40];
var style2Pages = [41, 80];
var style3Pages = [81, 120];
var style4Pages = [121, 160];

// Apply character styles to each page range
for (var i = style1Pages[0]; i <= style1Pages[1]; i++) {
  var tf = doc.pages[i-1].textFrames.item(0);
  if (tf.isValid) {
    tf.parentStory.characters.everyItem().appliedCharacterStyle = doc.characterStyles.itemByName("Character Style 1");
  }
}
for (var i = style2Pages[0]; i <= style2Pages[1]; i++) {
  var tf = doc.pages[i-1].textFrames.item(0);
  if (tf.isValid) {
    tf.parentStory.characters.everyItem().appliedCharacterStyle = doc.characterStyles.itemByName("Character Style 2");
  }
}
for (var i = style3Pages[0]; i <= style3Pages[1]; i++) {
  var tf = doc.pages[i-1].textFrames.item(0);
  if (tf.isValid) {
    tf.parentStory.characters.everyItem().appliedCharacterStyle = doc.characterStyles.itemByName("Character Style 3");
  }
}
for (var i = style4Pages[0]; i <= style4Pages[1]; i++) {
  var tf = doc.pages[i-1].textFrames.item(0);
  if (tf.isValid) {
    tf.parentStory.characters.everyItem().appliedCharacterStyle = doc.characterStyles.itemByName("Character Style 4");
  }
}
rob day
Community Expert
Community Expert
March 18, 2023

I really need to change the formatting between text frames.

 

Hi @clw48 , A paragraph can’t have multiple Paragraph Styles applied, so if you were trying to that without a script you would have to override the Paragraph Style when it changes text frames. A script would have to handle the override, or use Character Styles as Mark is suggesting—seems like that would get messy.