aboutsummaryrefslogtreecommitdiffstats
path: root/src/lang-guess.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/lang-guess.js')
-rw-r--r--src/lang-guess.js10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/lang-guess.js b/src/lang-guess.js
index 6d62e30..6911f73 100644
--- a/src/lang-guess.js
+++ b/src/lang-guess.js
@@ -26,7 +26,7 @@ const STOP = {
en: 'the and is to of in that it for you with this on are be have not was but they'.split(' '),
es: 'el la de que y en los es un una por con para las del se no como más pero'.split(' '),
fr: 'le la les de des et est un une pour que qui dans pas sur avec ce il nous vous'.split(' '),
- de: 'der die und das ist nicht ein eine ich zu mit den auf für sich dem des auch wir'.split(' '),
+ de: 'der die und das ist nicht ein eine ich zu mit den auf für sich dem des auch wir du wie man noch schon aber oder wenn hast habe bin bist kann nur mal jetzt hier sind wird'.split(' '),
pt: 'o a de que e do da em um uma para com não os as se mais por isso você'.split(' '),
id: 'yang dan di ini itu dengan untuk tidak dari ada saya akan ke juga bisa kita sudah atau kalau aku'.split(' '),
tr: 've bir bu için ile de da çok ne gibi daha ama var ben sen mi değil kadar her olan'.split(' '),
@@ -37,6 +37,13 @@ const STOP = {
pl: 'i w nie na się z to że jest do co jak ale tak o po czy już'.split(' '),
};
const STOPSETS = Object.fromEntries(Object.entries(STOP).map(([k, v]) => [k, new Set(v)]));
+// Letters only some languages write: one counts as one more common word.
+// A short line has few of those ("Weißt Du wie man die kriegt?" had only
+// "die" before the list grew, and went untranslated as maybe-English).
+const MARKS = {
+ de: /[ßäöü]/i, es: /[ñ¿¡]/i, pt: /[ãõ]/i, fr: /[œèêëîïû]/i, tr: /[ğşı]/i, pl: /[łąęśźżń]/i,
+ vi: /[ạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹđ]/i,
+};
// The text a reader actually reads: no links, no nostr references, no tags.
export const proseOf = (text) => String(text || '')
@@ -67,6 +74,7 @@ export function guessLang(text) {
if (words.length < 4) return null;
const score = {};
for (const w of words) for (const [l, set] of Object.entries(STOPSETS)) if (set.has(w)) score[l] = (score[l] || 0) + 1;
+ for (const [l, re] of Object.entries(MARKS)) if (re.test(prose)) score[l] = (score[l] || 0) + 1;
const ranked = Object.entries(score).sort((a, b) => b[1] - a[1]);
if (!ranked.length || ranked[0][1] < 2) return null;
if (ranked[1] && ranked[0][1] < ranked[1][1] * 1.5) return null;