Scribble Hub: Display Current Chapter Word Count

Adds the word count of the current chapter underneath the chapter statistics

Versión del día 13/5/2024. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey to install this script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name           Scribble Hub: Display Current Chapter Word Count
// @namespace      https://github.com/w4tchdoge
// @version        1.1.2-20240513_200521
// @description    Adds the word count of the current chapter underneath the chapter statistics
// @author         w4tchdoge
// @homepage       https://github.com/w4tchdoge/MISC-UserScripts
// @match          *://*.scribblehub.com/read/*/chapter/*
// @license        AGPL-3.0-or-later
// @history        1.1.2 — Fix script not working on chapters without an author note
// @history        1.1.1 — Switch to using Intl.NumberFormat for making the word count thousands separated
// @history        1.1.0 — Change position of word count element and change wording of word count
// @history        1.0.0 — Initial release
// ==/UserScript==

(function () {
	`use strict`;

	// Attempted conversion of the Ruby regex code AO3 uses to JavaScript by looking at:
	// https://github.com/otwcode/otwarchive/blob/943f585818005be8df269d84ca454af478150e75/config/config.yml#L453
	// https://github.com/otwcode/otwarchive/blob/943f585818005be8df269d84ca454af478150e75/lib/word_counter.rb#L26
	// https://github.com/otwcode/otwarchive/blob/943f585818005be8df269d84ca454af478150e75/lib/word_counter.rb#L30C9-L31C95
	// Has not been tested on non-English works, feedback would be appreciated
	const word_count_regex = /\p{Script=Han}|\p{Script=Hiragana}|\p{Script=Katakana}|\p{Script=Thai}|((?!\p{Script=Han}|\p{Script=Hiragana}|\p{Script=Katakana}|\p{Script=Thai})\w)+/gu;

	// Get element that contains the chapter stats
	const chp_stats = document.querySelector(`#main\\ read\\ chapter .chapter_stats`);

	// Def vars used in word counting
	// var chp_raw_node, auth_note_node, chp_raw_text, auth_note_text, chp_raw_word_count, auth_note_word_count, word_count;
	var chp_raw_node, auth_note_node, chp_raw_text, auth_note_text, chp_raw_word_count, auth_note_word_count, word_count;

	// Get 1st elem to be word counted
	chp_raw_node = document.querySelector(`#chp_raw`).cloneNode(true);

	// Get the text context of the elements to be counted
	// chp_raw_text = chp_raw_node.textContent;
	// auth_note_text = auth_note_node.textContent;

	// Count the number of words
	// Counting method from:
	// https://stackoverflow.com/a/76673564/11750206
	// Regex substitutions from:
	// https://github.com/otwcode/otwarchive/blob/943f585818005be8df269d84ca454af478150e75/lib/word_counter.rb#L30C33-L30C68
	// chp_raw_word_count = [...chp_raw_text.replaceAll(/--/g, `—`).replaceAll(/['’‘-]/g, ``).matchAll(word_count_regex)].length;
	// auth_note_word_count = [...auth_note_text.replaceAll(/--/g, `—`).replaceAll(/['’‘-]/g, ``).matchAll(word_count_regex)].length;

	// if-else for the case that the author note does not exist
	if (Boolean(document.querySelector(`#chp_raw div .wi_authornotes_body`))) { // if author notes exists

		// Remove auth note from chp_raw_node
		chp_raw_node.removeChild(chp_raw_node.querySelector(`div.wi_authornotes`));

		// Get chp text to be counted
		chp_raw_text = chp_raw_node.textContent;

		// Get 2nd elem to be word counted
		auth_note_node = document.querySelector(`#chp_raw div .wi_authornotes_body`).cloneNode(true);

		// Get auth note text to be counted
		auth_note_text = auth_note_node.textContent;

		// Count the number of words
		// Counting method from:
		// https://stackoverflow.com/a/76673564/11750206
		// Regex substitutions from:
		// https://github.com/otwcode/otwarchive/blob/943f585818005be8df269d84ca454af478150e75/lib/word_counter.rb#L30C33-L30C68
		chp_raw_word_count = [...chp_raw_text.replaceAll(/--/g, `—`).replaceAll(/['’‘-]/g, ``).matchAll(word_count_regex)].length;
		auth_note_word_count = [...auth_note_text.replaceAll(/--/g, `—`).replaceAll(/['’‘-]/g, ``).matchAll(word_count_regex)].length;

		// Check if chapter word count is very small
		// If true use auth_note_word_count as word count
		// const chp_raw_frac_total_count = chp_raw_word_count / (chp_raw_word_count + auth_note_word_count);
		const chp_raw_frac_total_count = chp_raw_word_count / (chp_raw_word_count + auth_note_word_count);
		if (chp_raw_frac_total_count < 0.05) {
			word_count = auth_note_word_count;
		} else {
			word_count = chp_raw_word_count;
		}

	}
	else {
		// Get the text to be counted
		chp_raw_text = chp_raw_node.textContent;
		// count the text
		word_count = [...chp_raw_text.replaceAll(/--/g, `—`).replaceAll(/['’‘-]/g, ``).matchAll(word_count_regex)].length;
	}

	// Add thousands seperators to the word count
	// Reference for Intl.NumberFormat: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
	word_count = new Intl.NumberFormat({ style: "decimal" }).format(word_count);

	// console.log(`SH Ch Word Counter Output: ${word_count}`);

	// Create element that will display the current chapter word count
	var WordCount_elm = Object.assign(document.createElement(`span`), {
		id: `userscript-word-count-span`,
		style: `display: block; text-align: center; margin: 0.5em 0 0 0`,
		innerHTML: `Words in Chapter: ${word_count}`
	});

	// Add the word count element
	chp_stats.after(WordCount_elm);
})();