Section Word Count in Google Docs
Asked Answered
P

2

9

Is it possible for a Google Docs add-on to count word per heading (section)? The following image shows what I want.

screenshot

Is there a way to display this kind of word count information in a sidebar or any other way?

Parve answered 23/12, 2017 at 17:3 Comment(2)
Could THIS be what You are looking for??Check it out.Broaden
Thank you, but that is not what I am looking for. What I want is section word count (so I will have multiple word counts for the same document) You can refer to the image link.Parve
M
5

Here is a script that does this. In Google Docs, headings are a kind of paragraph distinguished by their getHeading() attribute. There are thus 9 levels of paragraphs: title, subtitle, h1... h6, and normal.

The script first finds the level of each paragraph and the word count of each paragraph. Then, for each paragraph, it loops over all subsequent "normal" paragraphs, adding their word counts; this stops when another paragraph of equal or higher level is reached.

My understanding that the words in headings themselves should not be included in word counts, but that can be changed if desired.

Since this is not an add-on, there is no sidebar to display information in. I just append the results at the end, copying each heading there and appending (X words) to its text. It looks like this:

Book title (108 words)
 Chapter 1 (54 words)
  Section 1 (15 words)
  Section 2 (20 words)
 Chapter 2 (54 words)
  Section 1 (54 words)
   Subsection 1 (31 words)
   Subsection 2 (13 words)

In my sample text, Chapter 1 has some "intro" normal text before its first section, which is why its word count is higher than the sum of word counts of its two sections.

Script:

function countPerSection() {                
  var body = DocumentApp.getActiveDocument().getBody();
  var para = body.getParagraphs();
  var levels = para.map(function(p) {
    return [DocumentApp.ParagraphHeading.TITLE, 
            DocumentApp.ParagraphHeading.SUBTITLE, 
            DocumentApp.ParagraphHeading.HEADING1,
            DocumentApp.ParagraphHeading.HEADING2,
            DocumentApp.ParagraphHeading.HEADING3,
            DocumentApp.ParagraphHeading.HEADING4,
            DocumentApp.ParagraphHeading.HEADING5,
            DocumentApp.ParagraphHeading.HEADING6,
            DocumentApp.ParagraphHeading.NORMAL].indexOf(p.getHeading());
  });
  var paraCounts = para.map(function (p) {
    return p.getText().split(/\W+/).length;
  });

  var counts = [];
  for (var i = 0; i < para.length; i++) {
    var count = 0;
    for (var j = i+1; j < para.length; j++) {
      if (levels[j] <= levels[i]) {
        break;
      }
      if (levels[j] == 8) {
        count += paraCounts[j];
      }
    }
    counts.push(count);
  }

  for (var i = 0; i < para.length; i++) {
    if (levels[i] < 8) {
      body.appendParagraph(para[i].copy()).appendText(" (" + counts[i] + " words)");
    }
  }
}
Malfeasance answered 23/12, 2017 at 19:43 Comment(5)
This looks exactly as what I need. I just can't seem to make it work. Where do I save the script and how I make it run? Thank you..Parve
Go to Tools > Script Editor. Enter the code. Click Save. Click Run. For more details, see tutorial at developers.google.com/apps-script/overviewMalfeasance
Thank for the fast answer. I check the tutorial and did everything. It give my an error though: TypeError: Cannot call method "getBody" of null. (line 2, file "Code")Parve
Oh, the tutorial explains scripts in the context of a "stand-alone" script. This one should be attached ("bound") to the document in which you want to count words. In that document, go to Tools > Script Editor, and enter code there.Malfeasance
Men, that works beautifully! Thank you very much. As a side, you should consider making ad add-on for Google Doc with a sidebar that output his data in real time. Thank you again.Parve
A
3

I edited the previous answer to put the word count next to each header instead of all at the bottom, and you'll see it in the outline too. I also added a function that will remove all of the counts as well, so you can keep them without having to worry about CTRL-Z 'ing or manually deleting them. Hopefully this is useful for somebody else!

function countPerSection() {                
  var body = DocumentApp.getActiveDocument().getBody();
  var para = body.getParagraphs();
  var levels = para.map(function(p) {
    return [DocumentApp.ParagraphHeading.TITLE, 
            DocumentApp.ParagraphHeading.SUBTITLE, 
            DocumentApp.ParagraphHeading.HEADING1,
            DocumentApp.ParagraphHeading.HEADING2,
            DocumentApp.ParagraphHeading.HEADING3,
            DocumentApp.ParagraphHeading.HEADING4,
            DocumentApp.ParagraphHeading.HEADING5,
            DocumentApp.ParagraphHeading.HEADING6,
            DocumentApp.ParagraphHeading.NORMAL].indexOf(p.getHeading());
  });
  var paraCounts = para.map(function (p) {
    return p.getText().split(/\W+/).length;
  });

  // var counts = [];
  for (var i = 0; i < para.length; i++) {
    var count = 0;
    for (var j = i+1; j < para.length; j++) {
      if (levels[j] <= levels[i]) {
        break;
      }
      if (levels[j] == 8) {
        count += paraCounts[j];
      }
    }
    if (levels[i] < 8) {
      para[i].appendText(" (" + count + " words)");
    }
  }
}

function removeCountPerSection(){
  var docBody = DocumentApp.getActiveDocument().getBody();
  docBody.replaceText('\\([0123456789]* words\\)', "");
}
Accidie answered 12/2, 2021 at 2:7 Comment(1)
Is there any way to make this live, so that the count updates it self every minute or so?Misalliance

© 2022 - 2024 — McMap. All rights reserved.