diff --git a/src/build/render.rs b/src/build/render.rs index 7c58220..9d2ea87 100644 --- a/src/build/render.rs +++ b/src/build/render.rs @@ -80,10 +80,11 @@ pub fn layout( "##); let lang_code = &site.language.code; + let dir_attribute = if site.language.rtl { r#"dir="rtl""# } else { "" }; formatdoc!(r#" - + {head} {body} diff --git a/src/site.rs b/src/site.rs index b2292d7..4d1c7ca 100644 --- a/src/site.rs +++ b/src/site.rs @@ -15,6 +15,7 @@ use crate::{ Translations, Video }; +use crate::util::is_rtl_language; #[derive(Clone, Debug)] pub enum AspectRatio { @@ -29,6 +30,8 @@ pub enum AspectRatio { pub struct Language { pub code: String, pub default: bool, + /// Whether this is a right-to-left language + pub rtl: bool, pub translations: Translations } @@ -91,6 +94,7 @@ impl Language { Language { code: String::from("en"), default: true, + rtl: false, translations: Translations::en() } } @@ -102,13 +106,14 @@ impl Language { _ => Translations::en() }; - Language::manual(code.to_string(), translations) + Language::manual(code, translations) } - pub fn manual(code: String, translations: Translations) -> Language { + pub fn manual(code: &str, translations: Translations) -> Language { Language { - code, + code: code.to_string(), default: false, + rtl: is_rtl_language(code), translations } } diff --git a/src/util.rs b/src/util.rs index 3294840..1b32e14 100644 --- a/src/util.rs +++ b/src/util.rs @@ -76,6 +76,30 @@ pub fn hash_closure(closure: impl FnOnce(&mut DefaultHasher)) -> String { URL_SAFE_NO_PAD.encode(hasher.finish().to_le_bytes()) } +/// Based on data from https://meta.wikimedia.org/wiki/Template:List_of_language_names_ordered_by_code +/// In the long(est) term might need better data, better implementation or updates, but for +/// quite a while this could probably cover the vast majority of usecases in the wild. +pub fn is_rtl_language(code: &str) -> bool { + match code { + "ar" | + "arc" | + "arz" | + "ckb" | + "dv" | + "fa" | + "ha" | + "he" | + "khw" | + "ks" | + "ps" | + "sd" | + "ur" | + "uz_AF" | + "yi" => true, + _ => false + } +} + /// Takes seconds, formats it like "0:13", "3:15", "2:06:48" pub fn precise_duration(seconds: f32) -> String { if seconds < 60.0 {