Mastodon
//Ris Adams;

How to calculate estimated reading time

Cover image for How to calculate estimated reading time.

When publishing an article it is often a nice touch to let users know roughly how long it will take to read, and what level of investment they can expect to make. While every reader is different, the average reader can ingest about 150 - 200 words per minute, depending on the type of text.

This site uses a simple algorithm to calculate the estimated reading time. It is based on the number of words in the article, and the average reading speed of a reader. I currently use a Jekyll plugin (Github pages safe!) that can be included at the top of a post, but I have also included a simple javascript function that can be used anywhere.

This is not meant to be a perfect solution, but it is a good starting point for your implementation, and it is easy to understand.

The Jekyll Plugin

{% capture words %}
{{ content | number_of_words | minus: 180 }}
{% endcapture %}
{% assign words = words | plus: 0 %}
{% if words > 0 %}
  {% assign words = words | plus: 150 | divided_by: 150 %}
{%else%}
  {% assign words = 1 %}
{% endif %}

Estimated time to read: {{ words }} {%if words == 1 %}minute.{%else%}minutes.{%endif%}

The Javascript Function

const article_root = $('article.post'); // upddate with root element of main article.
const wc = wordCount(article_root.text());

console.log(readingSpeed(wc.words));

function readingSpeed(words) {
  'use strict';
  const avgReadingSpeed = (words / 200.0).toString();
  const rawSpeed = avgReadingSpeed.split(/\./, avgReadingSpeed);
  const rawSeconds = rawSpeed[0] * 60 + rawSpeed[1] * 0.6;
  let d = new Date(null);
  d.setSeconds(rawSeconds);
  const rawTime = d.toISOString().substr(14, 5).toString();
  console.info(`${words} words per minute: ${rawTime}`);
  const result = rawTime.split(':');
  return {
    minutes: result[0],
    seconds: result[1],
  };
}

function wordCount(val) {
  'use strict';
  const wom = val.match(/\S+/g);
  return {
    charactersNoSpaces: val.replace(/\s+/g, '').length,
    characters: val.length,
    words: wom ? wom.length : 0,
    lines: val.split(/\r*\n/).length,
  };
}
§