deno.land / x / lume@v2.1.4 / plugins / reading_info.ts

reading_info.ts
نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { merge } from "../core/utils/object.ts";
import type Site from "../core/site.ts";
export interface Options { /** The key name to store the reading info value and the filter */ name?: string;
/** The list extensions this plugin applies to */ extensions?: string[];
/** The words per minute a reader can read (default: 275) */ wordsPerMinute?: number;}
export const defaults: Options = { name: "readingInfo", extensions: [".md"], wordsPerMinute: 275,};
export default function (userOptions?: Options) { const options = merge(defaults, userOptions);
return (site: Site) => { site.preprocess(options.extensions, (pages) => { pages.forEach((page) => { const { content, lang } = page.data;
page.data[options.name] = readingInfo( typeof content === "string" ? content : undefined, lang as string, ); }); });
site.filter("readingInfo", readingInfo); };
function readingInfo(content?: string, lang = "en"): ReadingInfo { if (!content || typeof content !== "string") { return { words: 0, minutes: 0, time: 0, }; }
const segmenter = new Intl.Segmenter(lang, { granularity: "word", });
let wordCount = 0; for (const word of segmenter.segment(content)) { if (word.isWordLike) { wordCount++; } }
const minutes = wordCount / options.wordsPerMinute; const time = Math.round(minutes * 60 * 1000); const displayTime = Math.ceil(parseFloat(minutes.toFixed(2)));
return { words: wordCount, minutes: displayTime, time, }; }}
export interface ReadingInfo { /** The number of words in the content */ words: number;
/** The number of minutes it takes to read the content */ minutes: number;
/** The number of milliseconds it takes to read the content */ time: number;}
lume

Version Info

Tagged at
7 months ago