From 1f09a11de5286d4073570476b7d935edfba4ff5b Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.me>
Date: Mon, 18 Mar 2024 05:19:22 -0700
Subject: feat(hayai): better algorithm

---
 src/lib/Tools/Hayai.svelte | 43 ++++++++++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 15 deletions(-)

(limited to 'src/lib/Tools/Hayai.svelte')

diff --git a/src/lib/Tools/Hayai.svelte b/src/lib/Tools/Hayai.svelte
index b7a80090..40577e71 100644
--- a/src/lib/Tools/Hayai.svelte
+++ b/src/lib/Tools/Hayai.svelte
@@ -20,13 +20,13 @@
 				if (zipEntry.dir) {
 					newZip.folder(relativePath);
 				} else if (relativePath.endsWith('.xhtml') || relativePath.endsWith('.html')) {
-					newZip.file(relativePath, applyBionicReading(await zipEntry.async('text')));
+					newZip.file(relativePath, applyBionicReadingToHTML(await zipEntry.async('text')));
 				} else {
 					newZip.file(relativePath, await zipEntry.async('arraybuffer'));
 				}
 			}
 
-			downloadEpub(
+			downloadEPUB(
 				await newZip.generateAsync({ type: 'blob' }),
 				`${file.name.split('.epub')[0]}_hayai.epub`
 			);
@@ -35,25 +35,38 @@
 		reader.readAsArrayBuffer(file);
 	};
 
-	const applyBionicReading = (content: string) => {
+	const applyBionicReadingToHTML = (content: string) => {
 		const contentParser = new DOMParser().parseFromString(content, 'text/html');
 
 		for (const paragraph of contentParser.getElementsByTagName('p'))
-			paragraph.innerHTML = (paragraph.textContent ?? '')
-				.split(/\s+/)
-				.map((word) => {
-					const strippedWord = word.replace(/[^\w]/g, '');
-					const halfLength = Math.ceil(strippedWord.length * 0.6);
-					const firstHalf = `<strong>${strippedWord.slice(0, halfLength)}</strong>`;
-					const secondHalf = strippedWord.slice(halfLength);
-					return `${firstHalf}${secondHalf}${word.slice(strippedWord.length)}`;
-				})
-				.join(' ');
+			paragraph.innerHTML = applyBionicReadingToString(paragraph.textContent ?? '');
 
 		return contentParser.documentElement.outerHTML;
 	};
 
-	const downloadEpub = (blob: Blob | MediaSource, fileName: string) => {
+	const applyBionicReadingToString = (text: string) =>
+		text
+			.split(/\s+/)
+			.map((word) => {
+				if (/^\W+$/.test(word) || word.length <= 2) return word;
+
+				let boldLength;
+
+				if (word.length <= 4) {
+					boldLength = 2;
+				} else if (word.length <= 7) {
+					boldLength = 3;
+				} else if (word.length <= 10) {
+					boldLength = 4;
+				} else {
+					boldLength = Math.ceil(word.length * 0.5);
+				}
+
+				return `<strong>${word.slice(0, boldLength)}</strong>${word.slice(boldLength)}`;
+			})
+			.join(' ');
+
+	const downloadEPUB = (blob: Blob | MediaSource, fileName: string) => {
 		const link = document.createElement('a');
 
 		link.href = URL.createObjectURL(blob);
@@ -67,7 +80,7 @@
 </script>
 
 <div class="card">
-	<b>Upl</b>oad <b>a</b>n <b>EP</b>UB, <b>rece</b>ive <b>a</b> "<b>bio</b>nic" <b>EP</b>UB.
+	{@html applyBionicReadingToString('Upload an EPUB, receive a "bionic" EPUB.')}
 
 	<p />
 
-- 
cgit v1.2.3

