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

[JS][CS4] - Create outlines of all textFrames in document

Explorer ,
Nov 17, 2011 Nov 17, 2011

Hello,

I realize this is an absolutely terrible step to have in your workflow. I am working hard to change it in my organization; however, for now I have to incorporate this function into my script.  I have tried the following snippets without much luck.

var doc = app.activeDocument;

for (i=doc.stories.length-1; i>=0; i--){

doc.stories.createOutlines();

}

This approach has been the most successful but depending on the file I'll get a few different errors:

1. NoPathCreated - I seem to get this on files that have one textFrame filled with text and a second textFrame that has a table in it.

2. can't perform function due to bad data - I think I'm getting this error when the file has textFrames within textFrames (which I can rememdy by telling people not to do that) but is there another reason I might get this error?

I've also tried:

var doc = app.activeDocument;

var textFrames = doc.textFrames;

with(doc) {

while (textFrames.length !=0){

textFrames[0].createOutlines();

}

}

This approach seems to loop forever without ever completing the script because INDD gets hung up and eventually has to be force quit.

Also tried:

var doc = app.activeDocument;

with(doc){

for (var i= textFrames.length-1; i> =0; i--){

textFrames.createOutlines();

}

}

This approach appears to do nothing but I also don't get any errors.

Any help is greatly appreciated.

Thanks,

Lindsay

TOPICS
Scripting
4.3K
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
Advocate ,
Nov 18, 2011 Nov 18, 2011

Hi Lindsay,

Can you please try the below JS code is convert to all the text frame texts and tables(cells) texts to create outlines creation.

Below i am using the try{}catch{} because i escape the dummy text frames and cells, i.e, no characters in this text frame and cells, so i used try{}catch{}.

var myDoc = app.activeDocument;

var myStory = myDoc.stories.everyItem();

var myTable = myStory.tables.everyItem().cells.everyItem();

try{

    myTable.createOutlines();

    }catch(e){};

try{

        myStory.createOutlines();

}catch(e){};

alert("Done!");

thx

csm_phil

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
Explorer ,
Nov 18, 2011 Nov 18, 2011

Hi Phil,

I really appreciate your help.  Did you try the script and get it to work?  I've tried it on a few files and it doesn't seem to be working fully. The table text is outlined but the regular textFrames are not. Any reason that might happen? That's the same result I was getting when I was trying

var doc = app.activeDocument;
var textFrames = doc.textFrames;

with(doc) {
while (textFrames.length !=0){
textFrames[0].createOutlines();
}
}

but INDD would get held up and eventually timeout without completely executing the script.

Thanks for your help!

Lindsay

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
Engaged ,
Nov 18, 2011 Nov 18, 2011

hi,

try this js code here.

var doc = app.activeDocument;

var textFrames = doc.textFrames.everyItem().getElements();

for (var i=0; i< textFrames.length; i++) {

        textFrames.createOutlines();   

    }

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
Engaged ,
Nov 18, 2011 Nov 18, 2011

This can be done with just a single JS code:

app.activeDocument.textFrames.everyItem().createOutlines();

Shonky

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
Advocate ,
Nov 19, 2011 Nov 19, 2011

Hi Shonky,

Your code very short nice, however document have any empty textframe that would be throw the error right. So i changed try catch.

However but the table text frame not converted only coverted the cells texts only.

try{

    app.activeDocument.textFrames.everyItem().createOutlines();

    }catch(e){};

thx

csm_phil

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
Explorer ,
Dec 13, 2018 Dec 13, 2018

hi, is it possible to convert to outline only the selected text box and not everyItem on the page?

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 ,
Dec 13, 2018 Dec 13, 2018

Hi Briann,

Try the following

try

{

    app.selection[0].createOutlines();

}catch(e){};

-Manan

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
Explorer ,
Dec 13, 2018 Dec 13, 2018

Thank you Manan! I can go to sleep now.

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 ,
Dec 13, 2018 Dec 13, 2018

If the selection has more than one items then the code above can be modified to the following, so that all the textframes in the selection are outlined

try

{

     var sel = app.selection

     for(var i = 0; i < sel.length; i++)

          sel.createOutlines();

}catch(e){};

-Manan

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 ,
Dec 14, 2018 Dec 14, 2018

Hi Manan,

I wonder why Brian needs a script to create outlines on a selection when a menu command with a keyboard shortcut is also available in the UI of InDesign.

Regards,
Uwe

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
Explorer ,
Dec 14, 2018 Dec 14, 2018

Hi Uwe, it's the last step in one script to perform a series of tasks on a text box.

Manan, the loop is very useful too, save me the trouble of hacking it. Learning, albeit slowly.

Thank you all!

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
Explorer ,
Dec 14, 2018 Dec 14, 2018

Sorry to trouble you guys again. I got it to work the way i want it, just missing the final step, which is to move the duplicated text box—turned into an outline, into a different layer.

I tried diff combo of codes i found in the forum. It runs but doesn't move the new outline into a diff layer.

Can this be done within the same loop?

try

{

     var sel = app.selection;

     for(var i = 0; i < sel.length; i++)  {

        sel.duplicate();

        sel.doOtherThings();

        sel.createOutlines();

      //sel.move().layers.itemByName("differentLayerName");

        }

}catch(e){};

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
Contributor ,
Dec 14, 2018 Dec 14, 2018

Hi briann,

the variable sel contains a textframe. After converting the textframe to outlines that textframe is gone. That breaks the script. So the solution would be changing the order of the operations

- move the textframe to another layer first

- then convert to outlines.

moving an object to a different layer:

sel.itemLayer = "differentLayerName";

Greetings

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
Explorer ,
Dec 14, 2018 Dec 14, 2018

I thought so too, but i didn't know the correct code and syntax.

I need to learn to read the DOM.

Thank you so much!

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 ,
Dec 16, 2018 Dec 16, 2018

Hi Brian,

if you do createOutlines() check what's returned by using the method.

If it's a group or a single object you can set the itemLink for that.

If it's an array of objects you could loop the array and set the itemLink for every item of the array.

Of course it could be more elegant to set the itemLink before using createOutlines(), but you would not be able to do this if the text frame is anchored or otherwise be part of a nested structure like a group.

Regards,
Uwe

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
Explorer ,
Dec 15, 2018 Dec 15, 2018

hi, after duplicating the frame. can i offset the text frame-moving it down- it doesn't matter by how much, cause i am going to use the distribute space later.

try

{

     var sel = app.selection;

     for(var i = 0; i < sel.length; i++)  {

        sel.duplicate();

    >>>    sel.offset the duplicated item... <<<<

        sel.createOutlines();

      //sel.move().layers.itemByName("differentLayerName");

        }

}catch(e){};

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 ,
Dec 15, 2018 Dec 15, 2018

Use the following

sel.move( undefined , [ 0 , "1pt" ] );

This will move the object in sel down by 1pt, if you want to move it in x direction you could change the 0 value to the desired value. You can use any other unit like moving by .5 inches would be done by using the value ".5in"

-Manan

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
Explorer ,
Dec 15, 2018 Dec 15, 2018

hi Manan, thanks again!

it works as intended. yay!

however, when i select the text frame and the outline character in indesign 2019 and hit distribute vertical spacing (zero space) in the Properties window, it placed the outlined character on top instead of bottom. 

Can the outlined character be set to aligned to the bottom of the text frame within the script?

It's not a big deal if it can't i can always move it manually, before hitting the distribute vertical spacing, which brings me to the next question....  (or another workaround would be to offset the outlined character enough vertically so that it clears the text frame. Then selected them both manually, before hitting align.)

Do you know if the "distribute vertical spacing, use spacing: zero" can be scripted or accessed with a custom shortcut key? i can't find it in the Keyboard shortcuts. It seems to be only accessible thru the Properties menu, 1 level down. It's not even in the quick apply.

Thank you for any insights.

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
Contributor ,
Dec 16, 2018 Dec 16, 2018

Hi Brian,

try this to distribute your objects

var doc = app.activeDocument;

try

{

var sel = app.selection;

for(var i = 0; i < sel.length; i++)

    {

        //duplicate textframe and move it down 10mm in one go

        var tf_duplicate = sel.duplicate(undefined, [0, "10mm"]);

       

        //distribute original and textframe copy vertically

        doc.distribute([sel, tf_duplicate], DistributeOptions.VERTICAL_SPACE, undefined,true, 0);

       

        //convert the duplicate to outlines

        tf_duplicate.createOutlines();

    }

}catch(e){};

Greetings

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
Explorer ,
Dec 16, 2018 Dec 16, 2018
LATEST

Hi fragmichnicht,

Thanks for the distribute objects script! I know enough that i can hack it to suit my needs. The house is being built brick-by-brick.

HI Uwe,

the duplicate&outlined is a single object, which is used to spacing. I'll look into itemLink method, although by now you know i am an novice.

Thank you all for the help!

My hat's off to all of you!

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