Estimate text reading times
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.1 KiB

/*
Package readingtime estimates text reading times
We use non-scientific means of first establishing the number of words in a
given text and then based on read speeds from http://www.readingsoft.com/
calculate the time required to read that number of words in the text.
*/
package readingtime
import (
"regexp"
"strings"
"time"
)
// Reader profile average reading times in words per minute from http://www.readingsoft.com/
const (
InsufficientScreenReaderSpeed = 100.0
InsufficientPaperReaderSpeed = 110.0
AverageScreenReaderSpeed = 200.0
AveragePaperReaderSpeed = 240.0
FastScreenReaderSpeed = 300.0
FastPaperReaderSpeed = 400.0
AccomplishedScreenReaderSpeed = 700.0
AccomplishedPaperReaderSpeed = 1000.0
)
// Defaults.
var (
DefaultWordsPerMinute = AverageScreenReaderSpeed
DefaultWords = regexp.MustCompile(`\s`)
DefaultRound = time.Second
Default = Estimator{}
)
// Estimator can estimate the reading time.
type Estimator struct {
WordsPerMinute float64
// Words matcher.
Words *regexp.Regexp
// Round duration value, set to 1 to disable rounding.
Round time.Duration
// NoStrip skips trimming of white space characters.
NoStrip bool
}
// Estimate the reading time for a given text.
func (e Estimator) Estimate(text string) time.Duration {
if !e.NoStrip {
text = strings.TrimSpace(text)
}
if len(text) == 0 {
// Fast path
return 0
}
var (
wordsPerSecond float64
words int
)
if e.WordsPerMinute == 0 {
wordsPerSecond = DefaultWordsPerMinute / 60
} else {
wordsPerSecond = e.WordsPerMinute / 60
}
if e.Words == nil {
words = len(DefaultWords.Split(text, -1))
} else {
words = len(e.Words.Split(text, -1))
}
duration := time.Duration(float64(time.Second) * (float64(words) / wordsPerSecond))
if e.Round == 0 {
duration = (duration / DefaultRound) * DefaultRound
} else {
duration = (duration / e.Round) * e.Round
}
return duration
}
// Estimate the reading time for a given text using defaults.
func Estimate(text string) time.Duration {
return Default.Estimate(text)
}