Copy link to clipboard
Copied
I will appreciate anyone that can point me in the right direction, my eyes are crossing from looking at scores of pages looking for solutions—probably in front of my nose.
Background:
We create ID pages by importing an XML file which is generated from our database. Photos and text/copy populate the page in individual frames from the fields in the database. However, empty fields in the database create frames as well. While they have no "real" content they do have some invisible tag characters.
My problem:
This is part of a larger script but for the moment my main concern is just some way for the script to distinguish between the "empty" frames and ones with live content (actual text characters) so these boxes can been moved to the pasteboard for possible future use.
If it's of any value, their constructor attribute is "TextFrame" BUT under the "Object/Content" menu, all is greyed out (no option to choose text, graphic, or unassigned, this is true regardless of whether the frames contain actual live content or not)
Below are two strategies I have tried:
1. **********************************
//This only moves completely overset text frames (which I don't want) and empty text boxes created in Indesign manually which is not relevant. It does not move any of the XML generated "empty" frames.
var myStories = app.activeDocument.stories.everyItem().getElements();
for (i = myStories.length - 1; i >= 0; i--){
var myTextFrames = myStories.textContainers;
for (j = myTextFrames.length - 1; j >= 0; j--) {
if (myTextFrames
myTextFrames
}
}
}
2. **********************************
I have used the script below with success in other scripts. However to capture text frames with no real characters I tried using the regex expression "\A\Z". This WORKS in the Indesign Find/Change utility, but when I use this expression for ".findWhat = '\A\Z';" it returns the alert "Error Number:21 Error String: undefined is not an object"
// Find empty text boxes and move
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
app.findChangeGrepOptions.properties = {includeFootnotes:false, includeHiddenLayers:false, includeMasterPages:true};
app.findGrepPreferences.findWhat = '\A\Z';
var noText = document.findGrep();
var noTextFrame = noText[0].parentTextFrames[0];
// Move empty frame
noTextFrame.move([-2, 0]);
//Reset Grep parameters to null
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
**********************************
Thanks in advance
Copy link to clipboard
Copied
Hi,
escape the escape in your findWhat statement:
app.findGrepPreferences.findWhat = "\\A\\Z";
Regards,
Uwe
Copy link to clipboard
Copied
Thanks for the quick reply.
With your suggested adjustment the script completes and no longer gives an error, it ignores the empty text frames as though they didn't exist.
Copy link to clipboard
Copied
Looking for \A\Z comes down to looking for zero contents, that is, it's the equivalent of if (myTextFrames
To test whether a frame contains just junk or is empty, try looking for .+ (using findGrep()). It looks as if InDesign's . matches not just every character (apart from \r), but only 'real' characters. . doesn't match the tag characters [ and ], for example. If that works, a frame is empty if its content == "" or if frame.findGrep().length == 0 (with findWhat = '.+' set).
Copy link to clipboard
Copied
Thanks Peter,
(findWhat = '.+' ) still won't find these elusive text frames. However I have a somewhat convoluted strategy that I believe will work. I have created a script to lock all text frames that contain "real" text. (This will require me to change my ID templates to autosize frames so no text frames are overset—a minor drawback.) From there I can select the problem frames using the "TextFrame" constructor name and do whatever.
When completed I will post for comments if anyone is interested.
BACK TO THE DRAWING BOARD: As mentioned above, I can lock all the "real" text boxes with a script. And I can move frames with the constructor name "TextFrames". However when I combine the two scripts OR if I manually lock some random "real" text frames, then the iteration for moving frames with the constructor attribute of "TextFrame" doesn't work. It seems when the "for" loop runs into a locked frame it creates some issue with continuing. Below is the script so far:
*******************************************************************************
try {
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = ".+";
with(app.activeDocument) {
for(Counter = textFrames.length-1; Counter >= 0; Counter--) {
var myResult = textFrames.item(Counter).findGrep();
if (myResult.length !== 0) {
textFrames.item(Counter).locked = true;
}
}
}
}
catch (myError) { // if there are no more frames to select then continue script
}
//This is supposed to move all frames with the constructor name "TextFrame" (unless locked)
var allItems = app.activeDocument.allPageItems;
for (i=0; i<allItems.length; i++){
if (allItems.constructor.name == "TextFrame"){
allItems.move([-1,-1]);
}
}
********************************************************************************
Copy link to clipboard
Copied
UPDATE:
With Peter's hints I have found a way to do what I want. However there is some odd and/or unexpected behavior. This script moves text frames with only tags and no real text and leaves other text frames with real text untouched as desired unless those text frames exist on the master page. I tried to limit the grep search to skip master pages but the method I used doesn't seem to work. Here is my script:
//**********************************************************************
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
//Here is where I tried to limit the search
app.findChangeGrepOptions.properties = {caseSensitive:false, wholeWord:false, includeFootnotes:false, includeHiddenLayers:false, includeLockedLayersForFind:true, includeMasterPages:false};
app.findGrepPreferences.findWhat = ".+";
with(app.activeDocument) {
for(Counter = textFrames.length-1; Counter >= 0; Counter--) {
var myResult = textFrames.item(Counter).findGrep();
if (myResult.length == 0) {
textFrames.item(Counter).move([-3, 0]);
}
}
}
//**********************************************************************
Copy link to clipboard
Copied
I think the problem is that you get all the text frames in the document, then search them. Setting findChangeGrepOptions then probably doesn't do very much.
Instead, get the frames from document pages only:
myFrames = app.activeDocument.pages.everyItem().textFrames.everyItem().getElements();
P.
PS: findChangeGrepOptions doesn't have the properties caseSensitive and wholeWord
Copy link to clipboard
Copied
For anyone interested and just to close this tread out—the issue with restricting the search to regular pages, as opposed to Master pages was solved by:
changing "with(app.activeDocument)" to "with(app.activeSpread)"
Thanks all