Skip to main content
Inspiring
April 28, 2025
Answered

Script to change red text to black?

  • April 28, 2025
  • 1 reply
  • 3190 views

Background: We use red font to indicate changes in the draft document. Then we change the red text back to black before issuing the final version of the document. We sometimes have master page borders and artwork that we use red text with that we do NOT want to change.

 

Four questions:

 

  • Is there a way to manually search for red text and find it? I didn't see it in the find and replace options? (If I could find it manually, I would be better able to find a way to script it.)

 

  • Is there a way to script this? I found a script on here to find and replace text, but I don't think this would be the same thing. I know tables present some difficulty, in that if press Ctrl-A to select all and change the font, I usually have to change the tables.

 

  • My lead would prefer for the script to find the red text and prompt if you want to change it or not? (He's worried about the automated script changing the artwork and/or occasional (rare) times that we actually want red text in the document). Can this be done?

 

  • Finally (easier, but I'm not sure how) - could a script be written that would change the active selection to red text? (Basically, the same thing as selecting red from the color portion of the graphics toolbar, but from a button on a script window and without having to go through the drop-down.)

 

Thanks in advance!

 

-

Correct answer Marshall_Brooks
var doc, textRange;

doc = app.ActiveDoc;
textRange = doc.TextSelection;

applyTextColor (textRange, "Black", doc);

function applyTextColor (textRange, colorName, doc) {
    
    var color, prop;
    
    // Get the color object.
    color = doc.GetNamedColor (colorName);
    // Make sure the color exists in the document.
    if (color.ObjectValid () === 1) {
        // Make a property list containing the color.
        prop = new PropVal ();
        prop.propIdent.num = Constants.FP_Color;
        prop.propVal.valType = Constants.FT_Id;
        prop.propVal.obj = color;
        // Apply the color to the text.
        doc.SetTextPropVal (textRange, prop);    
    }
}

@frameexpert - THANK YOU!!!!

 

I got the script working. Seems to do fine. Here is the full find and replace script in case anyone searches this thread:

main();

function main(){  
  var doc = app.ActiveDoc;
  if(!doc.ObjectValid())
  {
    alert("No active document. Cannot continue.");
    return;   
  }
FindAndReplaceColor(doc, doc.MainFlowInDoc, 'Red', 'Black') ;
}

function FindAndReplaceColor(doc, flow, findString, replaceString) {
// https://community.adobe.com/t5/framemaker-discussions/find-replace/td-p/3581679#4032650
// https://community.adobe.com/t5/framemaker-discussions/find-and-replace-text/td-p/14438481#M82917
//  https://community.adobe.com/t5/framemaker-discussions/script-to-change-red-text-to-black/m-p/15293234
var tr = new TextRange();
var restoreTR, frame = 0;
var loopCounter = 0, replacementCounter = 0;
var findParams = new PropVals();
//if the flow object is not valid, assume the main flow
if(doc.ObjectValid() && !flow.ObjectValid()){
flow = doc.MainFlowInDoc;
}

//get the first text frame in the flow, a starting point to
//find the first paragraph
if(flow.ObjectValid()){
frame = flow.FirstTextFrameInFlow;
}

//At this point, if we don't have a frame object, might as well abort.
if(!frame.ObjectValid()){
Alert("Could not find a starting point for the search. Cannot continue." , Constants.FF_ALERT_CONTINUE_WARN);
return replacementCounter;
}

//store the original text selection as an amenity to restore after the action.
restoreTR = doc.TextSelection;

//now, set up the starting text range as the very beginning
//of the flow. We'll move straight from beginning to end.
tr.beg.obj = tr.end.obj = frame.FirstPgf;
tr.beg.offset = tr.end.offset = 0;

//set up our find parameters. We want to configure it to look
//for the color format. We don't need
//the find to wrap because we are controlling the flow from
//beginning to end.
findParams = AllocatePropVals(1);
 var color = doc.GetNamedColor (findString);
findParams[0].propIdent.num = Constants.FP_Color;
findParams[0].propVal.valType = Constants.FT_Id;
findParams[0].propVal.obj = color;

//initialize the errno global, which will be used to
//track the progress of the find and replace
FA_errno = Constants.FE_Success;

//and do an initial find to get started.
tr = doc.Find(tr.beg, findParams);

//now, run the find and replace loop as long as we keep finding things.
//The loop counter is just an emergency back door in case something
//goes critically wrong and causes an endless loop.
while(FA_errno === Constants.FE_Success && loopCounter++ < 1000){

//set up the text range to change the color
doc.TextSelection = tr;

//clear it - Uncomment this line to test if the search is finding the correct items.
//activeDoc.Clear(0);

// Change the color:
applyTextColor (tr, replaceString, doc);

//increment our return counter
if(FA_errno === Constants.FE_Success){
replacementCounter++;
}

//...and find the next instance. We'll reset FA_errno again just in case
//something screwy happened while we were replacing text.
FA_errno = Constants.FE_Success;
tr = doc.Find(tr.beg, findParams);
}

//we're done. Restore the document to it's original area of display
doc.TextSelection = restoreTR;
doc.ScrollToText(restoreTR);

return replacementCounter;
} // End FindAndReplaceString

function applyTextColor (textRange, colorName, doc) {
    
    var color, prop;
    
    // Get the color object.
    color = doc.GetNamedColor (colorName);
    // Make sure the color exists in the document.
    if (color.ObjectValid () === 1) {
        // Make a property list containing the color.
        prop = new PropVal ();
        prop.propIdent.num = Constants.FP_Color;
        prop.propVal.valType = Constants.FT_Id;
        prop.propVal.obj = color;
        // Apply the color to the text.
        doc.SetTextPropVal (textRange, prop);    
    }
} // End applyTextColor

1 reply

frameexpert
Community Expert
Community Expert
April 28, 2025

Changing text properties is always tricky because it can be difficult to revert to the default settings. The best way to do this in FrameMaker is to use Conditional Text because, while you can show the condition indicator (red text, etc.), it doesn't affect the underlying text properties. Plus, you can temporarily hide the condition indicator for printing, etc.

 

All of what you asked about is scriptable, although it's complex enough where it will likely require some cost. I would be glad to discuss the project with you off list. Alternatively, you could break these down into multiple tasks and post them as individual questions here on the forum. 

Inspiring
April 28, 2025

@frameexpert - Thank you. I appreciate the offer. I did some experimenting and discovered I can manually change it by searching for Character Formats. Let me do some more experimenting and I'll let you know how it goes.

frameexpert
Community Expert
Community Expert
April 28, 2025

Even if you decide to do it manually, I would still suggest you try Condition Formats instead of just changing font colors. You can search for Condition Formats too.