Copy link to clipboard
Copied
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:
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!
// 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...
Copy link to clipboard
Copied
Can you split it into 4x separate Threads / Stories?
Or you really need to change formatting mid-paragraph - between TextFrames??
Copy link to clipboard
Copied
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");
}
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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 š
Copy link to clipboard
Copied
Hi Rob, this script uses character styles!
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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);
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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:
After:
Copy link to clipboard
Copied
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');
Copy link to clipboard
Copied
Thanks, all! I'll try this and let you know what happens.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
// 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
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
Can you share a sample document?
Copy link to clipboard
Copied
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! ā¦");
Copy link to clipboard
Copied
Because you have NoBreak set in your Character Style 1:
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 ...
Copy link to clipboard
Copied
That's it! I only found No Break in the first CharStyle, but switching it off solved the issue. Thanks, Robert!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now