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

Cloning text frames to a new layer with different specs ?

Community Beginner ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

Hello everyone, I am searching for a script that could allow me to take all the text frames from a document (a manga, or comic book style), and create a new identical one (size and position) on a new layer, but with a different style based on my default frame type.

Does that exists or is it a hopeless quest ? 🙂

TOPICS
Feature request , Scripting

Views

328

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

correct answers 1 Correct answer

Community Expert , Feb 23, 2024 Feb 23, 2024

Using transform() would be easier. Try this:

 

//the amount to scale the frame
var s = 1.3
var d = app.activeDocument;
//change as object style name to to yours
var os = d.objectStyles.itemByName("YourStyle")
var tf = d.textFrames.everyItem().getElements();
var dl = makeLayer(d, "TextCopy");
var tm = app.transformationMatrices.add({horizontalScaleFactor:s, verticalScaleFactor:s})
var df;
for (var i = 0; i < tf.length; i++){
    df = tf[i].duplicate();
    df.transform(CoordinateSpaces.innerCoor
...

Votes

Translate

Translate
Community Expert ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

Do you really need a script? You can achieve what you need without any script:

  1. Be sure that the text frames are on a dedicated layer 
  2. In the layer panel, duplicate the layer
  3. Create a new object style with the appropriate paragraph style you need
  4. Lock the original layer
  5. Run a find change (object tab) and apply this new object style to all the text frames of the duplicated layer

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 Beginner ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

the original frames are from a japanese file, and I cannot transform them into latin frames (because of the orientation of the characters). That's why I need to create new ones based on my default frames but with the position of the original ones. If I could make the frame bigger, that would be a great bonus ! 

 

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 ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

and I cannot transform them into latin frames (because of the orientation of the characters). That's why I need to create new ones

Do you work with a japanese version? What happens if you apply a new paragraph style and apply any latin language to this style?

 

 

If I could make the frame bigger, that would be a great bonus ! 

In the object style, just enable “Auto-size” and the frame size will change according to the new text size. 

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 ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

Hi @Olivier5E38 , Try this:

 

var d = app.activeDocument;
//change as object style name to to yours
var os = d.objectStyles.itemByName("YourObjectStyle")
var dl = makeLayer(d, "TextCopy");
var tf = d.textFrames.everyItem().getElements();

var df;
for (var i = 0; i < tf.length; i++){
    df = tf[i].duplicate();
    df.itemLayer = dl
    df.appliedObjectStyle = os
};   


/**
* Makes a new named Layer 
* @ param the document to add the layer 
* @ param layer name 
* @ return the new layer 
*/

function makeLayer(d, n){
    if (d.layers.itemByName(n).isValid) {
        return d.layers.itemByName(n);
    } else {
        return d.layers.add({name:n});
    }
}

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 ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

Rob, your script does exactly what Olivier is asking for in the OP, but in Olivier's second post, I see that the new frames on the new layer are meant to be horizontal text frames for Latin script, not vertical text frames for Japanese. That can't be done with an object style in a non-CJK install of InDesign. In fact, it can't even be done with a script, in a non-CJK install of InDesign.

 

So my solution was to revise your for loop, grabbing only the source text frame .geometricBounds and .contents:

 

 

var d = app.activeDocument;
//change as object style name to to yours
var os = d.objectStyles.itemByName("vertical text frame")
var dl = makeLayer(d, "TextCopy");
var tf = d.textFrames.everyItem().getElements();

for (var i = 0; i < tf.length; i++){
    pf = tf[i].geometricBounds;
    cf = tf[i].contents;
    var df = d.textFrames.add();
    df.properties = {
        geometricBounds : pf,
        contents : cf
    }
    df.itemLayer = dl
    df.appliedObjectStyle = os
};   


/**
* Makes a new named Layer 
* @ param the document to add the layer 
* @ param layer name 
* @ return the new layer 
*/

function makeLayer(d, n){
    if (d.layers.itemByName(n).isValid) {
        return d.layers.itemByName(n);
    } else {
        return d.layers.add({name:n});
    }
}

 

 

Given some time, I'm sure that I could eventually whip up a little bit of arithmetic to reach @Olivier5E38 's stretch goal of slightly increased geometric bounds to account for text expansion in translation from Japanese to English... but my brain is reaching for contemporary JS stuff that won't work in ExtendScript, like arrow functions, or map(). 

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 ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

Not sure I’m following, think I need to see an example. In the altered script you are adding new text frames without indicating what page they should be on. So I get this with text frames on the 2-3 spread—all the new frames get added to page 1:

 

Screen Shot 12.png

 

Screen Shot 13.png

 

duplicate() clones the textFrame on top of the original using the same bounds, so the bounds of the cloned frames could be changed—this swaps their width and height:

 

var d = app.activeDocument;
//change as object style name to to yours
var os = d.objectStyles.itemByName("YourStyle")
var tf = d.textFrames.everyItem().getElements();
var dl = makeLayer(d, "TextCopy");
var df, b;
for (var i = 0; i < tf.length; i++){
    df = tf[i].duplicate();
    b = df.geometricBounds;
    //swaps the width and height
    df.geometricBounds = [b[0], b[1], b[0]+(b[3]-b[1]), b[1]+(b[2]-b[0])]
    df.itemLayer = dl
    df.appliedObjectStyle = os
};   


/**
* Makes a new named Layer 
* @ param the document to add the layer 
* @ param layer name 
* @ return the new layer 
*/

function makeLayer(d, n){
    if (d.layers.itemByName(n).isValid) {
        return d.layers.itemByName(n);
    } else {
        return d.layers.add({name:n});
    }
}

 

Screen Shot 16.png

 

Screen Shot 17.png

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 ,
Feb 19, 2024 Feb 19, 2024

Copy link to clipboard

Copied

Yeah, that absolutely makes sense now. I was only testing it on a single-page document. The reason that Olivier can't use .duplicate() here is that Olivier wants to change a property of a frame that our installs of InDesign don't have. The one-pager I'm using is a Trad Chinese template that DIane Burns first distributed many years ago; currently she has it up at http://www.transpacificdigital.com/downloads/. 

 

Here's what it looks like in action:

robbb.gif

 

So, we can't use .duplicate, that will just dupe the frame with the vertical property unchanged. In my attempt I tried using .contents() but now I see that it only captures the raw text of the frame. I suppose that looping through app.activeDocument.textFrames.texts would work better, I'll give that a shot. 

 

(If Olivier is using a CJK install of InDesign, then we could write a script that would address only storyOrientation. That's the only reason that I'm chasing this idea of creating new text frames with the contents of the old 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
Community Beginner ,
Feb 20, 2024 Feb 20, 2024

Copy link to clipboard

Copied

I don't use a CJK inDesign. But I noticed something interesting : if I take the japanese frames layer, clone it into my regular latin file, then empty the text frames, change the content from texte to image and back to text, the japanese specs disappear. So I have a latin frame with the desired position.

 

So the procedure would be : select a layer / empty every frame on it / switch content from txt to image /switch back from img to txt/ (and bonus points for enlarge frames by 30% 😉

 

One newbie question, how do use the coding you shared ? I usually download script from the internet and save them in the indesign script folder, I don't know how to take the code and save it as a .js or .jsx.

Thank you !

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 ,
Feb 20, 2024 Feb 20, 2024

Copy link to clipboard

Copied

So the procedure would be : select a layer / empty every frame on it / switch content from txt to image /switch back from img to txt/ (and bonus points for enlarge frames by 30%

 

So you want the duplicate text frame to be empty? The script could convert the duplicate to a graphic frame and back to a text frame, which would remove its contents. To test the script copy the code into a plain text editor (e.g. Notepad), save with a .jsx extension and save into your scripts folder:

 

var d = app.activeDocument;
//change as object style name to to yours
var os = d.objectStyles.itemByName("YourStyle")
var tf = d.textFrames.everyItem().getElements();
var dl = makeLayer(d, "TextCopy");
var df, b;
for (var i = 0; i < tf.length; i++){
    df = tf[i].duplicate();
    b = df.geometricBounds;
    //swaps the width and height
    //df.geometricBounds = [b[0], b[1], b[0]+(b[3]-b[1]), b[1]+(b[2]-b[0])]
    //increases the frame width by 30%
    df.geometricBounds = [b[0], b[1], b[2], b[1]+((b[3]-b[1])*1.3)];
    df.itemLayer = dl;
    df.appliedObjectStyle = os;
    df.contents = ""
    df.contentType = ContentType.GRAPHIC_TYPE;
    df.contentType = ContentType.TEXT_TYPE;
};   


/**
* Makes a new named Layer 
* @ param the document to add the layer 
* @ param layer name 
* @ return the new layer 
*/

function makeLayer(d, n){
    if (d.layers.itemByName(n).isValid) {
        return d.layers.itemByName(n);
    } else {
        return d.layers.add({name:n});
    }
}

 

Screen Shot 18.png

 

Screen Shot 19.png

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 ,
Feb 20, 2024 Feb 20, 2024

Copy link to clipboard

Copied

empty every frame on it

 

Also, do you really want to make copies of the text frames or do you just need to clear the existing text frame’s content and make the frame wider? If that’s the case the script could be this:

 

var d = app.activeDocument;
//change as object style name to to yours
var os = d.objectStyles.itemByName("YourStyle")
var tf = d.textFrames.everyItem().getElements();
var b;
for (var i = 0; i < tf.length; i++){
    b = tf[i].geometricBounds;
    tf[i].geometricBounds = [b[0], b[1], b[2], b[1]+((b[3]-b[1])*1.3)];
    tf[i].appliedObjectStyle = os;
    tf[i].parentStory.contents = ""
    tf[i].contentType = ContentType.GRAPHIC_TYPE;
    tf[i].contentType = ContentType.TEXT_TYPE;
};

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 ,
Feb 20, 2024 Feb 20, 2024

Copy link to clipboard

Copied

@Olivier5E38 

 

You can duplicate WHOLE layer with one click:

 

RobertTkaczyk_0-1708474013397.png

 

Then - it would be just a case of iterating through the collection of TextFrames, checking if they are on the new layer - increasing size and performing change of contentType...

 

▒► ID-Tasker / ID-Tasker Server - work smart not hard ◄▒

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 ,
Feb 21, 2024 Feb 21, 2024

Copy link to clipboard

Copied

Hi @Robert Tkaczyk that is exactly what I wrote at the beginning of this thread.

@rob day In this case, I wonder if a script is necessary since a few clicks can easily do the job

  • Duplicate the layer
  • Lock the original one
  • Run a find change to delete the whole text
  • Run another find change to transform the text frames to image frames
  • Run a last find change to transform the frames back to text frames and apply an object style.

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 ,
Feb 21, 2024 Feb 21, 2024

Copy link to clipboard

Copied

Maybe if the text frames are really on their own layer independent of the art? And then @Olivier5E38 wants to change the frames’ bounds.

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 ,
Feb 20, 2024 Feb 20, 2024

Copy link to clipboard

Copied

So, we can't use .duplicate

 

I don‘t have anything to test, but @Olivier5E38 ’s switch from text to graphic back to text can be scripted

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 ,
Feb 20, 2024 Feb 20, 2024

Copy link to clipboard

Copied

Seems to work perfectly:

 

BBBB.gif

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 Beginner ,
Feb 21, 2024 Feb 21, 2024

Copy link to clipboard

Copied

I can't make it work, I am on mac and don't have notepad. So I tried to use text edit, but I have this error message when I try to use it. I really have no knowledge of programming, sorry.Capture d’écran 2024-02-21 à 23.59.54.png

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 ,
Feb 21, 2024 Feb 21, 2024

Copy link to clipboard

Copied

TextEdit saves in RTF format by default, not raw text. The last time I needed to save raw text on a Mac, I opened the script in TextEdit and found "Make Plain Text" in the Format menu. You might be able to do the same thing by using Save As, and choosing a plain-text or raw-text format. You might have something like BBEdit installed, be which will also allow saving as plain text IIRC.

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 ,
Feb 22, 2024 Feb 22, 2024

Copy link to clipboard

Copied

As Joel suggests you need to format the text as Plain Text—you can also make Plain text the default in Text Edit’s preferences:

 

Screen Shot 24.png

 

Screen Shot 21.png

 

 

Also, edit the object style name to yours on line 2, and make sure the extension is .jsx when you save (not .jsx.txt)

 

 

Screen Shot 22.png

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 Beginner ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

thank you very much for your time, it works ! I have one small problem, even though my reference point is the middle one, the script enlarges the frames to the right.

I managed to understand the enlargment ratio *1.3, if I want higher I could got to *2 or more, but didn't get how to adjust the reference point in the code.

 

 

ratio Capture d’écran 2024-02-23 à 16.59.21.pngCapture d’écran 2024-02-23 à 17.00.07.png

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 ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

@Olivier5E38

 

For GeometricBounds, InDesign expects (top, left, bottom, right) arguments.

 

Or you can move() TF left - after resizing. 

 

▒► ID-Tasker / ID-Tasker Server - work smart not hard ◄▒

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 Beginner ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

going from this, to this.

Capture d’écran 2024-02-23 à 17.11.39.png

Capture d’écran 2024-02-23 à 17.11.53.png

  

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 ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

Using transform() would be easier. Try this:

 

//the amount to scale the frame
var s = 1.3
var d = app.activeDocument;
//change as object style name to to yours
var os = d.objectStyles.itemByName("YourStyle")
var tf = d.textFrames.everyItem().getElements();
var dl = makeLayer(d, "TextCopy");
var tm = app.transformationMatrices.add({horizontalScaleFactor:s, verticalScaleFactor:s})
var df;
for (var i = 0; i < tf.length; i++){
    df = tf[i].duplicate();
    df.transform(CoordinateSpaces.innerCoordinates, AnchorPoint.CENTER_ANCHOR, tm);
    df.itemLayer = dl;
    df.appliedObjectStyle = os;
    df.contents = ""
    df.contentType = ContentType.GRAPHIC_TYPE;
    df.contentType = ContentType.TEXT_TYPE;
};   


/**
* Makes a new named Layer 
* @ param the document to add the layer 
* @ param layer name 
* @ return the new layer 
*/

function makeLayer(d, n){
    if (d.layers.itemByName(n).isValid) {
        return d.layers.itemByName(n);
    } else {
        return d.layers.add({name:n});
    }
}

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 ,
Feb 23, 2024 Feb 23, 2024

Copy link to clipboard

Copied

quote

Using transform() would be easier. Try this:



By @rob day

 

Why? 

 

It's just a case of a different params for:

 

tf[i].geometricBounds = [b[0], b[1], b[2], b[1]+((b[3]-b[1])*1.3)];

 

▒► ID-Tasker / ID-Tasker Server - work smart not hard ◄▒

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 Beginner ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

LATEST

Hi everyone, I had lots of project to finalise before getting into this action again, and it works like a charm! A huge thank you to everyone who helped. This is a great community !

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