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.

Robert at ID-Tasker
Legend
March 18, 2023

As it's a single story - and ranges are simple - I was thinking about using itemByRange? With 1st Char of 1st TextFrame till last Char of 16th TextFrame? And so on. 

Kind of one-line-solution 😉 

 

Pseudo code - or maybe it will work straight away:

 

myStory.characters.itemByRange(myStory.textFrames.item(1).characters.item(1),myStory.textFrames.item(16).characters.item(-1)).item(1).applyCharacterStyle(name1);

 

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.