Skip to main content
M.Hasanin
Inspiring
September 18, 2022
Answered

Trying to Remove only Words in Black Color from Text Frames not other Words

  • September 18, 2022
  • 3 replies
  • 1429 views

Hi Experts,

Im Trying to Remove words in Black Color in text frames in the current document, the code is working but it removes so much and not working accuratley and some times removes word in black with red colored characters! as show here in the video :
https://drive.google.com/file/d/1XN6pQNsyZwh1u87Av_r9ZPKZMGLQIcQR/view?usp=sharing 

i want only to remove all the words in black color, but any word is mixed with another color like red i want to keep it and thanks in advance :

//DESCRIPTION :  Remove Words Colored in Black (Not Working Accurate!)


//UNDO Enabled
app.doScript(CatchMyError, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Remove Words Colored in Black");      
//RemoveBlackWords();


//Error Catcher for Function
function CatchMyError(){
    try {
        RemoveBlackWords();
    //Catch Error
    } catch (myError) {
    alert (myError,"ERROR!");
    exit();
    }
}

function RemoveBlackWords(){
var myDoc = app.documents[0];
var MyTextFrames = myDoc.textFrames.everyItem().getElements(); 

for( var i = 0; i<MyTextFrames.length; i++ ){
    for (j=0; j < MyTextFrames[i].paragraphs.length; j++){
        for (w=0; w < MyTextFrames[i].paragraphs[j].words.length; w++){
   
   //if Words in Black Color found it Shouid be Removed! But not all Word Removed! and Some times Extra Words Removed!
   if(MyTextFrames[i].paragraphs[j].words[w].fillColor == myDoc.colors.itemByName("Black")){
        MyTextFrames[i].paragraphs[j].words[w].remove();
                }
            }
        }
    }
}

  

This topic has been closed for replies.
Correct answer Peter Kahrel

The GREP expression \b\S+\b (with Black set in the Find format panel) doesn't match anything, which is a bug.

word.fillColor returns the fillColor of the first character only (which is consistent with InDesign's general behaviour).

What you have to do is to get a word's textStyleRanges and check whether any of their fillColor is not Black:

 

function allBlack (w) {
  var fills = w.textStyleRanges.everyItem().fillColor;
  for (var i = 0; i < fills.length; i++) {
    if (fills[i].name !== 'Black') {
      return false;
    }
  }
  return true;
}

words = app.documents[0].stories.everyItem().words.everyItem().getElements();
for (i = words.length-1; i >= 0; i--) {
  if (allBlack (words[i])) {
    words[i].remove();
  }
}

 P.

3 replies

Peter Kahrel
Community Expert
Peter KahrelCommunity ExpertCorrect answer
Community Expert
September 19, 2022

The GREP expression \b\S+\b (with Black set in the Find format panel) doesn't match anything, which is a bug.

word.fillColor returns the fillColor of the first character only (which is consistent with InDesign's general behaviour).

What you have to do is to get a word's textStyleRanges and check whether any of their fillColor is not Black:

 

function allBlack (w) {
  var fills = w.textStyleRanges.everyItem().fillColor;
  for (var i = 0; i < fills.length; i++) {
    if (fills[i].name !== 'Black') {
      return false;
    }
  }
  return true;
}

words = app.documents[0].stories.everyItem().words.everyItem().getElements();
for (i = words.length-1; i >= 0; i--) {
  if (allBlack (words[i])) {
    words[i].remove();
  }
}

 P.

M.Hasanin
M.HasaninAuthor
Inspiring
September 19, 2022

Thanks a lot @Peter Kahrel , this time i learned a new technique in scripting!, thanks again

Mohammad Hasanin
Willi Adelberger
Community Expert
Community Expert
September 18, 2022

Why not simple use find & replace?

M.Hasanin
M.HasaninAuthor
Inspiring
September 18, 2022

Thanks @Willi Adelberger for your reply, becuase if i will use find - change i have to search word by word! every time , scripting speeding the results and shorten the time and thank you again.

Mohammad Hasanin
Willi Adelberger
Community Expert
Community Expert
September 18, 2022

Find & Replace has an ALL-button.

m1b
Community Expert
Community Expert
September 18, 2022

Hi @M.Hasanin, have a look at these two functions:

function RemoveBlackText() {
    var myDoc = app.documents[0];
    var texts = myDoc.stories.everyItem().words.everyItem().textStyleRanges.everyItem().getElements();

    for (var i = texts.length - 1; i >= 0; i--) {
        if (texts[i].fillColor.name == "Black")
            texts[i].remove();
    }

};

function RemoveWordsWhoseFirstCharacterIsBlack() {
    var myDoc = app.documents[0];
    var words = myDoc.stories.everyItem().words.everyItem().getElements();

    for (var i = words.length - 1; i >= 0; i--) {
        if (words[i].fillColor.name == "Black")
            words[i].remove();
    }

};

Try them out and you will have an idea about what is going on. One issue is that when you are deleting objects in a collection, eg. words in a story, you must always go backwards, removing the last word first, because otherwise the references will be broken... so when you remove word 1 of story, all works fine, but when you remove word 2 of story, you are actually removing the word that was originally word 3, so the reference become out of sync.

- Mark 

M.Hasanin
M.HasaninAuthor
Inspiring
September 18, 2022

@m1b Thanks a lot , very interesting functions!, i learned new logic today!, and i will try to keep this in mind about backwards looping , thanks a lot to you, but acutally my problem is differenct!, i want to just remove any words in black color and keep other mixed colored word (that their characters are mixed in colors) , please see the picture below, the words in rectangle i need to remove them and keep other mixed color words! if this is possible! and thanks a lot again for your generous help :

Mohammad Hasanin
m1b
Community Expert
Community Expert
September 18, 2022

Oh I see. How about something like this?

function RemoveWordsWhoseEveryCharacterIsBlack() {
    var myDoc = app.documents[0];
    var words = myDoc.stories.everyItem().words.everyItem().getElements();

    wordsLoop:
    for (var i = words.length - 1; i >= 0; i--) {

        textStyleRangesLoop:
        for (var j = 0; j < words[i].textStyleRanges.length; j++) {

            if (words[i].textStyleRanges[j].fillColor.name != "Black")
                continue wordsLoop;

        }

        words[i].remove();
    }

};