Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • EspaƱol
      • FranƧais
      • PortuguĆŖs
  • ę—„ęœ¬čŖžć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£
  • ķ•œźµ­ ģ»¤ė®¤ė‹ˆķ‹°
0

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

New Here ,
Mar 17, 2023 Mar 17, 2023

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!

TOPICS
Scripting
3.0K
Translate
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

Guide , Mar 18, 2023 Mar 18, 2023
// 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
...
Translate
LEGEND ,
Mar 17, 2023 Mar 17, 2023

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

 

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

 

 

Translate
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
New Here ,
Mar 17, 2023 Mar 17, 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");
  }
}
Translate
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 ,
Mar 18, 2023 Mar 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.

Translate
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
LEGEND ,
Mar 18, 2023 Mar 18, 2023

Very messy - especially when text reflows and script needs to be run again.. 

 

But the biggest drawback using CharStyles in this case - you can't use CharStyles anywhere - so it's rather needs to be local formatting / overriding.

 

Translate
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
New Here ,
Mar 18, 2023 Mar 18, 2023

Robert, I understand the drawback of essentially using character styles as one would normally use paragraph styles means that minute adjustments need to me made locally. I am okay with this compromise. Gotta do what I gotta do.

Translate
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
LEGEND ,
Mar 18, 2023 Mar 18, 2023

Can you show us a screenshot with an example of what you have and what you want to achieve? 

 

Because maybe we are just guessing - when it can be done differently šŸ˜‰ 

 

Translate
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
New Here ,
Mar 18, 2023 Mar 18, 2023

Hi Rob, this script uses character styles!

Translate
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 ,
Mar 17, 2023 Mar 17, 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

Story text frame character styles.gif

 

 

/**
 * 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.

Translate
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
LEGEND ,
Mar 18, 2023 Mar 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);

 

Translate
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
New Here ,
Mar 18, 2023 Mar 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?

Translate
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 ,
Mar 18, 2023 Mar 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

Translate
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 ,
Mar 19, 2023 Mar 19, 2023

The method I showed is more work to set up—you have to add the script labels to each text frame

 

Hi Mark, I’m wondering if you could check for the number of frames in the threaded text and use the modulus operator to make the change on every 4th frame? Something like this:

 

//a character style group with the 4 styles
var sg = app.activeDocument.characterStyleGroups.itemByName("Signature Styles").allCharacterStyles

function main(){
    var s = app.documents[0].selection;
    //check the selection
    if (s.length == 0 || !s[0].hasOwnProperty("parentStory")) {
        alert("Please Select a text frame or text")
        return
    } 
    //alert if the selection’s text frames do not = 16
    var tf = s[0].parentStory.textContainers;   
    if (tf.length != 16) {
        alert("The selected text has " + tf.length + " text frames")
    } 
    var c = 0;
    var as;
    for (var i = 0; i < tf.length; i++){
        // use % to get every 4th frame
        if (i % 4 == 0) {
            as = sg[c]
            c++
        } 
        tf[i].texts[0].appliedCharacterStyle = as;
    }; 
}

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

 

Here I’ve set up a Character Style group named Signature Styles containing the 4 styles in the order I what them applied:

 

Before:

Screen Shot 18.png

 

After:

 

Screen Shot 20.png

Translate
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 ,
Mar 19, 2023 Mar 19, 2023

Jusr reread @clw48’s OP and realized the document is 64 pages with 16 page signatures, so this adds a variable for the signature length:

 

 

 

//a character style group with the 4 styles
var sg = app.activeDocument.characterStyleGroups.itemByName("Signature Styles").allCharacterStyles

//the signature text frame count
var sigl = 16

function main(){
    var s = app.documents[0].selection;
    //check the selection
    if (s.length == 0 || !s[0].hasOwnProperty("parentStory")) {
        alert("Please Select a text frame or text")
        return
    } 
    //alert if the selection’s text frames do not = sig length *4
    var tf = s[0].parentStory.textContainers;   
    if (tf.length != sigl*4) {
        alert("The selected text has " + tf.length + " text frames")
    } 
    var c = 0;
    var as;
    for (var i = 0; i < tf.length; i++){
        // use % to get every nth frame
        if (i % sigl == 0) {
            as = sg[c]
            c++
        } 
        tf[i].texts[0].appliedCharacterStyle = as;
    }; 
}

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

 

 

 

Screen Shot 22.png

 

Translate
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
New Here ,
Apr 02, 2023 Apr 02, 2023

Thanks, all! I'll try this and let you know what happens.

Translate
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
New Here ,
Apr 02, 2023 Apr 02, 2023

I tried this, and the script runs, but all of my text disappears and is now overset. There was nothing but a Basic Paragraph style applied to the entire story.

Translate
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
Guide ,
Mar 18, 2023 Mar 18, 2023
// 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

Translate
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
New Here ,
Apr 02, 2023 Apr 02, 2023

Thanks for this script! I tried it, and it runs, but all of my text disappears and is now overset. There was nothing but a Basic Paragraph style applied to the entire story before running the script. Any ideas on why the error might be occurring?

Translate
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 ,
Apr 03, 2023 Apr 03, 2023

Can you share a sample document?

Translate
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
New Here ,
Apr 03, 2023 Apr 03, 2023

Sure. Here is the document I've been testing with. It's actually 160 pages (4 x 40 page signatures), but I modified the code in both yours and Jedi's scripts as follows:

 

//a character style group with the 4 styles
var sg =
  app.activeDocument.characterStyleGroups.itemByName(
    "Signature Styles"
  ).allCharacterStyles;

//the signature text frame count
var sigl = 40;

function main() {
  var s = app.documents[0].selection;
  //check the selection
  if (s.length == 0 || !s[0].hasOwnProperty("parentStory")) {
    alert("Please Select a text frame or text");
    return;
  }
  //alert if the selection’s text frames do not = sig length *4
  var tf = s[0].parentStory.textContainers;
  if (tf.length != sigl * 4) {
    alert("The selected text has " + tf.length + " text frames");
  }
  var c = 0;
  var as;
  for (var i = 0; i < tf.length; i++) {
    // use % to get every nth frame
    if (i % sigl == 0) {
      as = sg[c];
      c++;
    }
    tf[i].texts[0].appliedCharacterStyle = as;
  }
}

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

 

And:

 

// 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 = [40, 80, 120, 160];
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! …");

 

Translate
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
LEGEND ,
Apr 03, 2023 Apr 03, 2023

Because you have NoBreak set in your Character Style 1:

 

RobertTkaczyk_0-1680564129020.png

 

 

In your source document it's locally overriden - deactivated - but if you select your whole text and ClearOverrides BEFORE running script(s) - your text will be overset šŸ˜‰

 

The same is with 2nd, 3rd and 4th Char Style šŸ˜‰

 

In fact - ALL your CharStyles have the same problem ...

 

Translate
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
New Here ,
Apr 03, 2023 Apr 03, 2023
LATEST

That's it! I only found No Break in the first CharStyle, but switching it off solved the issue. Thanks, Robert!

Translate
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