Add `text_direction` property in general book metadata
Text direction can selected in the config via the `text_direction` attribute in `book.toml`, or be derived from the book's language.
This commit is contained in:
parent
3a99899114
commit
819a108f07
|
@ -46,6 +46,9 @@ This is general information about your book.
|
|||
`src` directly under the root folder. But this is configurable with the `src`
|
||||
key in the configuration file.
|
||||
- **language:** The main language of the book, which is used as a language attribute `<html lang="en">` for example.
|
||||
This is also used to derive the direction of text (RTL, LTR) within the book.
|
||||
- **text_direction**: The direction of text in the book: Left-to-right (LTR) or Right-to-left (RTL). Possible values: `ltr`, `rtl`.
|
||||
When not specified, the correct text direction is derived from the book's `language` attribute.
|
||||
|
||||
**book.toml**
|
||||
```toml
|
||||
|
@ -55,6 +58,7 @@ authors = ["John Doe", "Jane Doe"]
|
|||
description = "The example book covers examples."
|
||||
src = "my-src" # the source files will be found in `root/my-src` instead of `root/src`
|
||||
language = "en"
|
||||
text-direction = "ltr"
|
||||
```
|
||||
|
||||
### Rust options
|
||||
|
|
220
src/config.rs
220
src/config.rs
|
@ -411,6 +411,9 @@ pub struct BookConfig {
|
|||
pub multilingual: bool,
|
||||
/// The main language of the book.
|
||||
pub language: Option<String>,
|
||||
/// The direction of text in the book: Left-to-right (LTR) or Right-to-left (RTL).
|
||||
/// When not specified, the correct text direction is derived from [BookConfig::language].
|
||||
pub text_direction: Option<TextDirection>,
|
||||
}
|
||||
|
||||
impl Default for BookConfig {
|
||||
|
@ -422,6 +425,44 @@ impl Default for BookConfig {
|
|||
src: PathBuf::from("src"),
|
||||
multilingual: false,
|
||||
language: Some(String::from("en")),
|
||||
text_direction: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BookConfig {
|
||||
/// Gets the realized text direction, either from [BookConfig::text_direction]
|
||||
/// or derived from [BookConfig::language], to be used by templating engines.
|
||||
pub fn realized_text_direction(&self) -> TextDirection {
|
||||
if let Some(direction) = self.text_direction {
|
||||
direction
|
||||
} else {
|
||||
TextDirection::from_lang_code(&self.language.clone().unwrap_or_default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Text direction to use for HTML output
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum TextDirection {
|
||||
/// Left to right.
|
||||
#[serde(rename = "ltr")]
|
||||
LeftToRight,
|
||||
/// Right to left
|
||||
#[serde(rename = "rtl")]
|
||||
RightToLeft,
|
||||
}
|
||||
|
||||
impl TextDirection {
|
||||
/// Gets the text direction from language code
|
||||
pub fn from_lang_code(code: &str) -> Self {
|
||||
match code {
|
||||
// list sourced from here: https://github.com/abarrak/rtl/blob/master/lib/rtl/core.rb#L16
|
||||
"ar" | "ara" | "arc" | "ae" | "ave" | "egy" | "he" | "heb" | "nqo" | "pal" | "phn"
|
||||
| "sam" | "syc" | "syr" | "fa" | "per" | "fas" | "ku" | "kur" | "ur" | "urd" => {
|
||||
TextDirection::RightToLeft
|
||||
}
|
||||
_ => TextDirection::LeftToRight,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -788,6 +829,7 @@ mod tests {
|
|||
multilingual: true,
|
||||
src: PathBuf::from("source"),
|
||||
language: Some(String::from("ja")),
|
||||
text_direction: None,
|
||||
};
|
||||
let build_should_be = BuildConfig {
|
||||
build_dir: PathBuf::from("outputs"),
|
||||
|
@ -1140,6 +1182,184 @@ mod tests {
|
|||
assert_eq!(&get_404_output_file(&html_config.input_404), "missing.html");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_direction_ltr() {
|
||||
let src = r#"
|
||||
[book]
|
||||
text-direction = "ltr"
|
||||
"#;
|
||||
|
||||
let got = Config::from_str(src).unwrap();
|
||||
assert_eq!(got.book.text_direction, Some(TextDirection::LeftToRight));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_direction_rtl() {
|
||||
let src = r#"
|
||||
[book]
|
||||
text-direction = "rtl"
|
||||
"#;
|
||||
|
||||
let got = Config::from_str(src).unwrap();
|
||||
assert_eq!(got.book.text_direction, Some(TextDirection::RightToLeft));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_direction_none() {
|
||||
let src = r#"
|
||||
[book]
|
||||
"#;
|
||||
|
||||
let got = Config::from_str(src).unwrap();
|
||||
assert_eq!(got.book.text_direction, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_text_direction() {
|
||||
let mut cfg = BookConfig::default();
|
||||
|
||||
// test deriving the text direction from language codes
|
||||
cfg.language = Some("ar".into());
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||
|
||||
cfg.language = Some("he".into());
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||
|
||||
cfg.language = Some("en".into());
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||
|
||||
cfg.language = Some("ja".into());
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||
|
||||
// test forced direction
|
||||
cfg.language = Some("ar".into());
|
||||
cfg.text_direction = Some(TextDirection::LeftToRight);
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||
|
||||
cfg.language = Some("ar".into());
|
||||
cfg.text_direction = Some(TextDirection::RightToLeft);
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||
|
||||
cfg.language = Some("en".into());
|
||||
cfg.text_direction = Some(TextDirection::LeftToRight);
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::LeftToRight);
|
||||
|
||||
cfg.language = Some("en".into());
|
||||
cfg.text_direction = Some(TextDirection::RightToLeft);
|
||||
assert_eq!(cfg.realized_text_direction(), TextDirection::RightToLeft);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_drection_from_lang_code() {
|
||||
// test all right-to-left languages
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("ar"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("ara"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("arc"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("ae"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("ave"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("egy"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("he"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("heb"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("nqo"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("pal"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("phn"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("sam"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("syc"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("syr"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("fa"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("per"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("fas"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("ku"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("kur"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("ur"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("urd"),
|
||||
TextDirection::RightToLeft
|
||||
);
|
||||
|
||||
// test some left-to-right languages
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("de"),
|
||||
TextDirection::LeftToRight
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("en"),
|
||||
TextDirection::LeftToRight
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("es"),
|
||||
TextDirection::LeftToRight
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("ja"),
|
||||
TextDirection::LeftToRight
|
||||
);
|
||||
assert_eq!(
|
||||
TextDirection::from_lang_code("sv"),
|
||||
TextDirection::LeftToRight
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Invalid configuration file")]
|
||||
fn invalid_language_type_error() {
|
||||
|
|
Loading…
Reference in New Issue