3

Some Question and Answers can get lengthy and you only know when you're going to spend too much time once you're half way.

This userscript will add the approximate reading time at the top of each post.

For the curious readers, here it is in all it's glory:

// ==UserScript==
// @name         Add reading time
// @namespace   https://meta.stackexchange.com/users/158100/rene
// @version      0.3
// @description  adds reading time to each question and answer
// @author       rene
// @match        https://*.stackoverflow.com/questions/*
// @match        https://*.stackexchange.com/questions/*
// @match        https://*.superuser.com/questions/*
// @match        https://*.serverfault.com/questions/*
// @match        https://*.askubuntu.com/questions/*
// @match        https://*.stackapps.com/questions/*
// @match        https://*.mathoverflow.net/questions/*
// @grant        none
// ==/UserScript==

(function($) {
    'use strict';

    function numberOfWords(text) {
        var wordsregex = /\b(\w+)\b/g,
            match,
            tot = 0;
        while ((match = wordsregex.exec(text)) !== null) {
            // This is necessary to avoid infinite loops with zero-width matches, as found on https://regex101.com/r/byXy4H/1/
            if (match.index === wordsregex.lastIndex) {
                regex.lastIndex++;
            }
            tot++;
        }
        // console.log('words: ' + tot);
        return tot;
    }

    function numberOfImages($post) {
        var tagCount = 0;
        ['img', 'svg'].forEach(function(elem) {
            tagCount += $post.find(elem).length;
        });
        // console.log('images: ' + tagCount);
        return tagCount;
    }

    function readingTimeInMinutes(wordCount, imageCount) {
        // words is 275 per minute, no idea how images influence that
        const WPM = 275;
        const SecondsPerImage = 15;
        var wordMinutes = ((wordCount || 0) / WPM),
            imageMinutes = ((imageCount || 0) * SecondsPerImage) / 60;

        // add and ceil()
        return Math.ceil(wordMinutes + imageMinutes, 1);
    }

    $('.post-text').each(function () {
        var words = numberOfWords(this.textContent);
        var images = numberOfImages($(this));
        var minutes = readingTimeInMinutes(words, images);
        // giant S
        var minutelabel = minutes === 1 ? "minute": "minutes";
        if (minutes > 1) {
            $(this)
                .prepend(
                $('<span>')
                .text(minutes + ' min read')
                .prop('title', minutes + ' ' + minutelabel +' reading time for ' + words + ' words and ' + images + ' images')
                .addClass('label-key')
            );
        } else {
            console.log('no reading time shown for ' + minutes + ' ' + minutelabel +' reading time for ' + words + ' words and ' + images + ' images');
        }
    });
})($);

The script is tested with TamperMonkey on Chrome/Win10. If you desperately want this on GreaseMonkey 4 on Firefox, I need to be bribed.

You can find the source on GitHub here where I also take bug reports.

For direct install with TamperMonkey click here

If you rather first have a look what it will look like, here is a screenshot with it in action:

Happy reading! (You have spend 2 minutes reading this, sorry for wasting your time)

This userscript was inspired by What if we had approx “read times” displayed? asked by user NVZ

5
  • Feature-request: Hide it when it's simply "1 min read"?
    – NVZ
    Nov 25, 2017 at 10:16
  • @NVZ that is now implemented as well as a improved word count and added "reading" time for images as well.
    – rene
    Nov 25, 2017 at 11:29
  • Updated to 0.3. Nice.
    – NVZ
    Nov 25, 2017 at 11:31
  • Tampermonkey (and Violentmonkey) also work on that lame browser that's now dead to me (rhymes with DirePox). Nov 25, 2017 at 16:35
  • 1
    Need to update screenshot here as well
    – NVZ
    Nov 26, 2017 at 21:15

0

You must log in to answer this question.

Browse other questions tagged .