2

I am writing a novel in a Google Doc. When complete, it will have probably have in excess of 75 chapters. I am not writing those chapters sequentially. Consequently, I am not attempting to use Chapter numbers, but rather a placeholder of "Chapter_" for each chapter heading (to be used as a search term when I am ready to replace the placeholders).

However, as I get further into the process, I will want to periodically number the chapters sequentially. Rather than do this manually, I would like to be able to automate the process with a Google script.

The following script is almost there, except that it numbers all of the chapters as "Chapter 1." I suspect I need to load an array with the chapter numbers, but despite much research, I can not figure out how to do that.

function onOpen() {
  var ui = DocumentApp.getUi();
  ui.createMenu('Custom')
      .addItem('Renumber Chapters', 'reChapter')
      .addToUi();
}
function reChapter(){
  var doc = DocumentApp.getActiveDocument();
  body = doc.getBody();
  var n = 30;
      Logger.log(n);
  for (i = 0; i < n; i++) { 
    num = i+1
    newText = "Chapter "+num+"";
    body.replaceText("Chapter_", newText);
  }
}

At first, I thought perhaps the loop was not running, but upon checking my log, it is:

2:46:16 PM  Notice  Execution started
2:46:16 PM  Info    30.0
2:46:16 PM  Info    0.0
2:46:16 PM  Info    1.0
2:46:16 PM  Info    2.0
2:46:16 PM  Info    3.0 

Any help would be much appreciated.

Note: My starting point for this code was something close, but not quite on point at: another stackoverflow post/query

Just to be clear, rather than the chapters being renumbered as:

Chapter 1
Chapter 2
Chapter 3
and so on

They are coming out:
Chapter 1
Chapter 1
Chapter 1
etc.
6
  • 1
    body.replaceText() replaces all occurrences at once (see documentation). So, the first loop does all the replacing, and then the remaining loops do nothing. An alternative approach is shown in the answer here: Google App Script replaceText to replace only first occurrence of matched string. In other words, use their "find first" technique in your loop. Commented Jun 30, 2021 at 19:25
  • I wanted to add something (which may already be totally obvious): This updating of the Chapter_ placeholders is a one-shot process. Once the placeholders have gone, then you will need a different script function if you want to renumber your chapters again. I am not too familiar with Google Docs, but... do they not have something built-in which can renumber or sort by chapter headings (based on style types, etc.)? Commented Jun 30, 2021 at 19:52
  • 1
    @andrewjames-- Thanks a bunch mate. See revised code. Works great. And yes, I realize this was a one-time thing. But rewriting with regex to find "Chapter xxx" (i.e., "Chapter" plus one or more digits) pretty straight forward now that I know how to handle a loop like this. And no, Google Docs does not have such a renumbering protocol. Word does, but I prefer Google Docs for what I am doing, so this is a real time saver. Commented Jun 30, 2021 at 20:08
  • Glad it works. Why don't you post that as an answer, (with an acknowledgement to the other answer)? I think your answer is sufficiently different/extended to stand on its own. (if there was a more exact dupe, I missed it). Commented Jun 30, 2021 at 20:14
  • Happy to if you can give me an assist as to how. (I am somewhat new here.) Do I use the blue "Answer Your Question" button? And is there a formal way to do the acknowledgement? Commented Jun 30, 2021 at 20:30

1 Answer 1

1

Based upon @andrewjames on-point guidance, I rewrote the script as follows and it works. The key bit of code that made it work came from another discussion here at stackoverflow that @andrewjames brought to my attention (adapted herein in the end of the "reChapter" function and fully in the "replaceIt" function).

  function onOpen() {
  var ui = DocumentApp.getUi();
  ui.createMenu('Custom')
      .addItem('Renumber Chapters', 'reChapter')
      .addToUi();
}
function reChapter(){
  var n = 30;
  var replaceTerm = "Chapter_"
  var body = DocumentApp.getActiveDocument().getBody();
  for (i = 0; i < n; i++) { 
    num = i+1
    Logger.log(i);
    newText = "Chapter "+num+"";
    replaceIt(replaceTerm, body);
  }
}
// replaces the occurrences
function replaceIt(replaceTerm, body) {    
  var found = body.findText(replaceTerm);
  if (found) {
   var start = found.getStartOffset();
    var end = found.getEndOffsetInclusive();
    var text = found.getElement().asText();
  text.deleteText(start, end);
  text.insertText(start, newText);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.