6

i am new to google doc script.

in a google doc, i need to search for several text strings (e.g., "student 1" in lightface font) to replace these text strings with another text string (e.g., "Student A"), but in boldface font.

to search and replace, i use the following code:

function docReplace() {

  var body = DocumentApp.getActiveDocument().getBody();
  // change "student 1" to "Student A" in boldface
  body.replaceText("student 1", "Student A");

}

the above code only replaces "student 1" with "Student A" using the current font of google doc, but i don't know how to change the font from lightface to boldface.

i tried

body.replaceText("student 1", "<b>Student A</b>");

of course, the above code did not work.

any help would be much appreciated. thank you.

Rubén
  • 34,714
  • 9
  • 70
  • 166
Luke V
  • 351
  • 1
  • 2
  • 7

2 Answers2

8

a pedestrian way to replace a text string (e.g., "student 1") that has many occurrences in a google doc by a new text string (e.g., "Student A") in boldface, is two steps:

1- write a function (called, say, docReplace) to do a search and replace in regular / normal font (no boldface):

function docReplace() {

  var body = DocumentApp.getActiveDocument().getBody();
  // change "student 1" to "Student A"
  body.replaceText("student 1", "Student A");

}

2- write a function (called, say, boldfaceText) to do a search for the desired text (e.g., "Student A") and the two offset values for this text (i.e., startOffset and endOffsetInclusive) at each occurrence to set the font for the characters within these offset values to boldface:

function boldfaceText(findMe) {

  // put to boldface the argument
  var body = DocumentApp.getActiveDocument().getBody();
  var foundElement = body.findText(findMe);

  while (foundElement != null) {
    // Get the text object from the element
    var foundText = foundElement.getElement().asText();

    // Where in the Element is the found text?
    var start = foundElement.getStartOffset();
    var end = foundElement.getEndOffsetInclusive();

    // Change the background color to yellow
    foundText.setBold(start, end, true);

    // Find the next match
    foundElement = body.findText(findMe, foundElement);
  }

}

the above code for boldfaceText was inspired from that in the post Finding text (multiple times) and highlighting.

an offset value for a character is simply the integer that describes the location of that character in the document, with the very first character having the offset value 1 (it's like the coordinate of the character).

use "Student A" as argument for a call to the function boldfaceText, i.e.,

boldfaceText("Student A");

which could be embedded into the function docReplace, i.e.,

function docReplace() {

  var body = DocumentApp.getActiveDocument().getBody();
  // change "student 1" to "Student A"
  body.replaceText("student 1", "Student A");

  // set all occurrences of "Student A" to boldface
  boldfaceText("Student A");

}

in the google doc, simply run the script docReplace to change all occurrences of "student 1" into "Student A" in boldface.

the above two functions (docReplace and boldfaceText) could be a good way to introduce newbies (like me) to google doc scripts. after some time playing with google doc scripts to gain some familiarity, learn Robin's more elegant and advanced code that does the above two steps all at once.

Community
  • 1
  • 1
Luke V
  • 351
  • 1
  • 2
  • 7
  • Well done Luke, this solution is not less advanced at all, if you were to leave out the comments it would probably take you the same amount of lines. Good work going out and finding this out for yourself, I'm sure you learned a lot more getting to this than youncan from my solution (I learned a lot myself as I haven't written any macros for google docs yet so my solution could probably be optimized too). I just want to ask you to accept one of our responses (whichever one you consider better) as the answer so people in the future will be able to get on the right track easily. – Robin Gertenbach Oct 19 '15 at 20:02
  • thanks, Robin, for your comments. i would be biased for me to select a "better" answer since it would take me a while before i can understand your code. it would be greatly helpful to learn your code if you could point to some web pages that would explain the syntax of some elements of your coding such as "new RegExp(output,"g")", "re.exec(text)", "index.index", etc. my guess is that one can find the syntax in the Java Script (JS) language. perhaps you have some good recommendations from where to start learning JS. thank you. – Luke V Oct 20 '15 at 00:46
  • If you think your way is easier to understand then it's reasonable that you use accept your answer. The best way to learn is to have a project and try to get it working. Don't be discouraged, JS and GAS have a thousand ways to do one thing which makes them very expressive but also confusing at times so don't be discouraged if a solution you see is different from what you had in mind. The GAS reference has some excellent guides (https://developers.google.com/apps-script/overview) For Javascript in general you could give codeacademy a try. Hope this helps – Robin Gertenbach Oct 20 '15 at 08:15
  • hi Robin, following your suggestion, i started a project to capitalize sentences in a google doc at http://stackoverflow.com/questions/33294140/google-doc-script-to-capitalize-sentences and got stuck after a while. perhaps you could help. thanks. – Luke V Oct 23 '15 at 02:59
3

Replacing one string by the other could be done with an easy find and replace.

Setting them bold is a bit more difficult as you have to get the text element of the body and also find the start and end position of every occurrence the word.

Since regular expressions in JS don't return an array of matches but instead an array of properties of the current match you have to loop through the function, which always starts after the last match.

 function docReplace(input, output) {
  var re = new RegExp(output,"g");
  var body = DocumentApp.getActiveDocument().getBody();
  body.replaceText(input, output);

  var text = body.getText();
  var index;
  while(true){
    index = re.exec(text)
    if(index == null){break}
    body.editAsText().setBold(index.index, output.length + index.index, true);
  }
}
Robin Gertenbach
  • 10,316
  • 3
  • 25
  • 37
  • thanks, Robin. the problem with appending .setBold(true) was that the entire document was set to boldface, which was **not** what i wanted. i only wanted the replacement text "**Student A**" set to boldface, leaving the rest of the text in the document intact. – Luke V Oct 19 '15 at 13:47
  • Please check the updated function, it takes an input converts it to output and makes all occurrences of it bold. – Robin Gertenbach Oct 19 '15 at 16:18
  • thanks, Robin. your new code is more elegant and advanced and i am at a lost of how to use it. i don't see anywhere in your code that i can replace the text "student 1" with the text "**Student A**" in boldface. perhaps, i should set input as "student 1" and output as "Student A". yes, that's right, i got it. your code does work. – Luke V Oct 19 '15 at 18:50
  • before i saw Robin's new code, i had found a more pedestrian way (not as elegant and advanced as Robin's) to achieve the same goal, and will document here for newbies like me. i will need to spend some time to dissect Robin's code to understand and to learn from his code. – Luke V Oct 19 '15 at 18:58
  • Yeah, my function took arguments so you could replace any string with any other bold string, I forgot to mention that. – Robin Gertenbach Oct 19 '15 at 20:04