Word count

Hi,

I only just installed silver bullet, and have read only a little of the manual, so please forgive my lack of understanding.

I was wondering if it was possible to have a word count on a page that updates while I’m writing? I know about the “Stats: Show” command, but I would prefer not to have to press a button everytime I wanted to know my word count while typing. I was looking at using the “count” function, but I don’t know if I could access word count from a list somewhere.

Thanks

I would like to see that sort of miscellaneous information too, but I got stuck with it a little, so perhaps somebody more experienced will help us. I registered new custom function wordCount(text) so that I can influence what is considered to be a word using regular expression.

---
description: Returns count of words in text
tags:
  - meta
---

```space-script
silverbullet.registerFunction({name: 'wordCount'}, (text) => {
  return (text.match(/\b\w+\b/g) || []).length;
});
```

This can be placed anywhere in the space (reindex and reload is needed to make the function appear). Once generally available it can be used as simply as:

```template
{{wordCount("This sentence has five words.")}}
```

Now, I can measure any page’s word count from a simple template using the builtin readPage(name) function, even the page I am currently editing (weird enough):

```template
{{wordCount(readPage(@page.name))}}
```

It somewhat works. One must refresh it, which is a great limitation though. I guess the template can be hooked to the bottom of the page for example but I haven’t tested this yet so I cannot tell how it would behave.

I am interested what approach would more experienced users here take, so please share some ideas. Thanks.

1 Like
---
description: Adds statistics to pages
tags: template
hooks.bottom.where: "parent != 'builtin' and tags != 'meta' and tags != 'template'"
---
# Page Statistics
Word count: {{wordCount(stripFrontMatter(readPage(@page.name)))}}

I store widgets in /Library/Custom/Widget but any place within your space should work (again, reindex and reload is needed).

For widgets, order can be specified as well in the template’s frontmatter:

hooks.bottom:
  where: <condition>
  order: <number>

The stripFrontMatter() function is also a custom one:

---
description: Returns page content without front-matter
tags:
  - meta
---

```space-script
silverbullet.registerFunction({name: 'stripFrontMatter'}, (content) => {
  return content.toString().replace(/^---\n(([^\n]|\n)*?)---\n/, '');
})
```

The whole thing seems to work. @half1 :slight_smile:

3 Likes

Oh wow, awesome solution. It works great.

Thank you for the help :slight_smile:

The only thing that does not work for me is the order. I wanted the Page Statistics widget appear above the Linked Mentions widget from the Library/Core tree. I tried even negative values but the Linked Mentions still appeared as the first one! I had to change it’s order to 100, touching the Library/Core code which I do not want at all. It’s weird behaviour and it should be somewhat more clarified in the Widget Documentation where we read that

order (optional): in case you have multiple templates that have matching where expression, the one with the priority set to the lowest number wins.

I must be misinterpretting what it means or there is a bug not allowing negative numbers to be taken into account etc. I also assume that without the order, the default would be 0 (I haven’t prove that from source yet). I think this part of the documentation needs some more attention. @zef

UPDATE: I found out by experimenting that the default value of theorder is not 0. I looks like there is no default value for order meaning that widgets without it don’t participate in the ordering. I think this is wrong because you have to touch the core libraries in order to make the ordering work for the core widgets as well. @zef