hello all you smart guys.
I get a big complex files from another designers every month for further processing. Among other not-so-good habits, they usually do not use layers.
To make layout a bit more organized, I move text to its own layer - simple task, have script for it. But it does the job straightforward - exactly 'as advertised' (Jongware's expression - I like it so
)
Unfortunately, those designers didn't bother much with 'frame content' option. They can draw a frame with a text tool, fill it with color and use it as a background for some artwork or whatever...
my script 'text frames to separate layer' creates a mess on such pages, and locate it - not always is an easy task. Document usually has over 200 pages...
So, I'm dreaming about some magic script, which is able to "prepare" text for moving, I mean, to find and process:
case1: empty text frame with no fill/outline - remove (delete)
case2: empty text frame with any fill/outline - convert to 'unassigned'
case3: text frame with the same color applied to text and the frame itself (yes, it happens!) - well, maybe just 'select and stop'? I'm afraid it's too complicated to remove text from such a frame and then treat the frame as 'case2'?
any suggestions would be greatly appreciated...
thank you for your reply, I see my fault now - I didn't mention, I'm on PC, ID 7.5.2 (CS5.5), so java is preferable...
anyway, this one
http://forums.adobe.com/message/2291359#2291359
is closer to my needs, but in both threads guys are talking about "deleting empty text frames" - that's not the biggest part for me...
my main problem is, that not all frames, which content marked as "text", are really text.
What I really need is proper content marking.
Let's say, you draw a box with text tool, fill it with a some color, maybe even tap spacebar inside that frame inadvertently... and use that "text frame" as a background for your artwork.
Later you send me that file for further processing, and:
1) if I run script "remove empty text frames", I loose your "background" (if you didnt tap spacebar or whatever in it)
or
2) if I run script "move text frames to layer" - I get your "text frame" (a.k.a. "background") all over the artwork and maybe real text frames...
You keep your text layer above images, didn't you?
It's a mess...
use this script it will help to remove only the empty text frame
var myDocument = app.activeDocument;
var myStories = app.activeDocument.stories.everyItem().getElements();
for (i = myStories.length - 1; i >= 0; i--){
var myTextFrames = myStories[i].textContainers;
for (j = myTextFrames.length - 1; j >= 0; j--) {
var stroke = myTextFrames[j].strokeWeight;
var color = myTextFrames[j].fillColor.name;
//alert (color)
if (myTextFrames[j].contents == "" && stroke == "0" && color == "None"){
//alert ("yes")
myTextFrames[j].remove();
}
}
}
nice job, thank you!
your script nicely removes really empty text frames, which are just trash, in fact...
unfortunately, after this cleaning I still can't move remaining frames to their own layer - I still must find out the way to convert empty, but filled/outlined text frames to "unassigned" first...
@winterm:
You can try this using script menu actions. This will only work, if the certain menu action is available.
It is not available if there is contents in the text frame (e.g. a blank character) or (much more important from a scripters point of view) if a threaded text frame is empty because it's contents cannot fit inside it and it's contents is an empty string.
Following code will single out empty text frames, select them and invoke a script menu action to set them to "Unassigned":
var _d = app.documents[0];
var _allStories = _d.stories;
for(var n=_allStories.length-1;n>=0;n--){
var _storyAllTextFrames = _allStories[n].textContainers;
for(var m=_storyAllTextFrames.length-1;m>=0;m--){
//If the contents of a text frame is an empty string:
if(_storyAllTextFrames[m].contents === ""){
_storyAllTextFrames[m].select();
//Convert frame to "Unassigned":
try{
app.scriptMenuActions.itemByID(11297).invoke();
}catch(e){};
};
};
};
//Trick to deselect the last selection
//Add a new textFrame, select and remove it:
var _tempTextFrame = _d.textFrames.add();
_tempTextFrame.select();
_tempTextFrame.remove();
@all: If there is a better way to deselect a selection please give an example…
Uwe
Hi Winterm,
I've corrected Uwe's script a little bit.
There is "contentType" property for text frame that can be changed.
var _d = app.documents[0],
_allStories = _d.stories;
for (var n = _allStories.length - 1; n >= 0; n--){
var _storyAllTextFrames = _allStories[n].textContainers;
for (var m = _storyAllTextFrames.length - 1; m >= 0; m--){
if (_storyAllTextFrames[m].contents === "")
_storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
}
}
Uwe,
To clear selection you can simply do this:
app.select(null);
or a little bit more complex:
app.select(NothingEnum.NOTHING);
Hope that helps.
--
Marijan (tomaxxi)
1. Use ContentType:
| contentType | ContentType: ContentType.UNASSIGNED ContentType.GRAPHIC_TYPE ContentType.TEXT_TYPE | r/w | The type of content that a frame can contain. |
_storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
2. Use app.select:
void select (selectableItems: varies[, existingSelection: SelectionOptions=SelectionOptions.REPLACE_WITH])
Selects the specified object(s).
| Parameter | Type | Description |
|---|---|---|
| selectableItems | Array of Objects NothingEnum Object SelectAll | The objects to select. Can accept: Object, Array of Objects, NothingEnum enumerator or SelectAll enumerator. |
| existingSelection | SelectionOptions: SelectionOptions.ADD_TO SelectionOptions.REMOVE_FROM SelectionOptions.REPLACE_WITH | The selection status of the Application in relation to previously selected objects. (Optional) (default:SelectionOptions.REPLACE_WITH) |
app.select(NothingEnum.NOTHING);
(Edit: Hi Marijan!)
Thank you, Marijan & Jongware to point to the right property "contentType" and to app.select(null).
I think the line:
_storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
needs a try-catch-wrapper:
try{
_storyAllTextFrames[m].contentType = ContentType.UNASSIGNED;
}catch(e){};
It could be that a threaded text frame has no contents because the contents is too big to fit inside.
contents === "" will perfectly match such an empty text frame, but you cannot asign a new contentType to it.
See my screen shot:
Uwe
Many thanks to all you, guys, for your so elegant solutions. Reading your codes, I can see how and why it works, but couldn't write something similar for ages...
So far I did "field testing" for Uwe's code, and it fits perfectly my needs in "case 2". Sometimes I get shapes, copy-pasted from Illustrator, and with content type: text applied in Id... Uwe's script fixes them back to "unassigned" too! Very nice.
I think so far I'll add Marijan's line for clearing selection (it's not so critical for practical purposes, though. It's just elegant) and some simple alert at the end - something like "job is done"...
Oh, and I need another free day to study Marijan's & Jongware's solutions - it's a valuable school to me and other fresh people here at forum. Thank you!
Ah, and recently I realized there is just another way to deselect after the script is done...
Laubender, its your way - calling Menu Action item by ID!
I just duplicated this piece of your script:
try{
app.scriptMenuActions.itemByID(11297).invoke();
}catch(e){};
and changed ID to 278 - it stands for "Deselect All" and does the trick too ![]()
North America
Europe, Middle East and Africa
Asia Pacific