Is there a way to conceal text in Google Docs while keeping the underline visible using Google Apps Script?

I’m a teacher looking to create tests with built-in answers that can be toggled on and off. I want to make text invisible by changing its color to white, but keep the underline black. When I click a button, I’d like the hidden text to turn red, making it visible again.

I tried writing a script, but it’s not working as expected. Here’s a simplified version of what I attempted:

function hideShowAnswers() {
  const doc = DocumentApp.getActiveDocument();
  const answerPattern = '<<.*?>>';
  
  doc.getParagraphs().forEach(para => {
    const foundText = para.findText(answerPattern);
    if (foundText) {
      const color = foundText.getElement().getForegroundColor(foundText.getStartOffset());
      const newColor = color === '#ffffff' ? '#ff0000' : '#ffffff';
      foundText.getElement().setForegroundColor(foundText.getStartOffset(), foundText.getEndOffsetInclusive(), newColor);
    }
  });
}

The script doesn’t find any matching text. How can I fix this to make it work properly? Any help would be appreciated!

I’ve had success with a similar approach, but your script needs a few tweaks. The main issue is that findText() returns a Range object, not the text itself. Try modifying your code to work with the Range directly:

function hideShowAnswers() {
  const doc = DocumentApp.getActiveDocument();
  const body = doc.getBody();
  const answerPattern = '<<.*?>>';
  
  let foundElement = body.findText(answerPattern);
  while (foundElement) {
    const element = foundElement.getElement();
    const start = foundElement.getStartOffset();
    const end = foundElement.getEndOffsetInclusive();
    const color = element.getForegroundColor(start);
    const newColor = color === '#ffffff' ? '#ff0000' : '#ffffff';
    element.setForegroundColor(start, end, newColor);
    element.setUnderline(start, end, true);
    foundElement = body.findText(answerPattern, foundElement);
  }
}

This should work better for toggling visibility while keeping the underline. Remember to add a menu item or button to run the script easily.

hey elizabeths, i’ve got a trick that might work 4 u. try this script:

function toggleAnswers() {
  var doc = DocumentApp.getActiveDocument();
  var body = doc.getBody();
  var regex = /<<.*?>>/g;
  
  var result;
  while (result = body.findText(regex, result)) {
    var el = result.getElement();
    var s = result.getStartOffset();
    var e = result.getEndOffsetInclusive();
    
    var color = el.getForegroundColor(s) === '#ffffff' ? '#ff0000' : '#ffffff';
    el.setForegroundColor(s, e, color);
    el.setUnderline(s, e, true);
  }
}

this should do the trick. lmk if u need more help!

I’ve dealt with similar challenges in my teaching. Here’s a script that worked for me:

function toggleAnswers() {
  var doc = DocumentApp.getActiveDocument();
  var body = doc.getBody();
  var regex = /<<.*?>>/g;
  
  var searchResult;
  while (searchResult = body.findText(regex, searchResult)) {
    var element = searchResult.getElement();
    var start = searchResult.getStartOffset();
    var end = searchResult.getEndOffsetInclusive();
    
    var currentColor = element.getForegroundColor(start);
    var newColor = (currentColor === '#ffffff') ? '#ff0000' : '#ffffff';
    
    element.setForegroundColor(start, end, newColor);
    element.setUnderline(start, end, true);
  }
}

This script toggles answer visibility while maintaining underlines. It searches for text between << >> markers, switching between white (hidden) and red (visible). Remember to create a custom menu to run the script easily. Hope this helps!