recognize main language as first given in book.toml
This commit is contained in:
parent
985745531c
commit
6492faa1bc
106
src/book/mod.rs
106
src/book/mod.rs
|
@ -1,5 +1,8 @@
|
||||||
|
extern crate regex;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
pub mod book;
|
pub mod book;
|
||||||
pub mod bookconfig;
|
pub mod bookconfig;
|
||||||
pub mod toc;
|
pub mod toc;
|
||||||
|
@ -64,8 +67,12 @@ pub struct MDBook {
|
||||||
/// `./src`.
|
/// `./src`.
|
||||||
///
|
///
|
||||||
/// Translations have to be declared in `book.toml` in their separate
|
/// Translations have to be declared in `book.toml` in their separate
|
||||||
/// blocks. In this case `is_main_book = true` has to be set to mark the
|
/// blocks. The first in the TOML config will be recognized as the main
|
||||||
/// main book to avoid ambiguity.
|
/// translation, `is_main_book` will be set to true on it.
|
||||||
|
///
|
||||||
|
/// If the first in the TOML config is not the main translation, the user
|
||||||
|
/// has to set `is_main_book = true` to mark the main book to avoid
|
||||||
|
/// ambiguity.
|
||||||
///
|
///
|
||||||
/// For a single language, the book's properties can be set on the main
|
/// For a single language, the book's properties can be set on the main
|
||||||
/// block:
|
/// block:
|
||||||
|
@ -82,7 +89,6 @@ pub struct MDBook {
|
||||||
/// title = "Alice in Wonderland"
|
/// title = "Alice in Wonderland"
|
||||||
/// author = "Lewis Carroll"
|
/// author = "Lewis Carroll"
|
||||||
/// language = { name = "English", code = "en" }
|
/// language = { name = "English", code = "en" }
|
||||||
/// is_main_book = true
|
|
||||||
///
|
///
|
||||||
/// [[translations.fr]]
|
/// [[translations.fr]]
|
||||||
/// title = "Alice au pays des merveilles"
|
/// title = "Alice au pays des merveilles"
|
||||||
|
@ -184,34 +190,21 @@ impl MDBook {
|
||||||
|
|
||||||
debug!("[fn]: read_config");
|
debug!("[fn]: read_config");
|
||||||
|
|
||||||
// TODO refactor to a helper that returns Result?
|
// exit(2) is a clear indication for the user that something is wrong
|
||||||
|
// and we can't fix it for them.
|
||||||
// TODO Maybe some error handling instead of exit(2), although it is a
|
|
||||||
// clear indication for the user that something is wrong and we can't
|
|
||||||
// fix it for them.
|
|
||||||
|
|
||||||
let read_file = |path: PathBuf| -> String {
|
|
||||||
let mut data = String::new();
|
|
||||||
let mut f: File = match File::open(&path) {
|
|
||||||
Ok(x) => x,
|
|
||||||
Err(_) => {
|
|
||||||
error!("[*]: Failed to open {:?}", &path);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Err(_) = f.read_to_string(&mut data) {
|
|
||||||
error!("[*]: Failed to read {:?}", &path);
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
data
|
|
||||||
};
|
|
||||||
|
|
||||||
// Read book.toml or book.json if exists to a BTreeMap
|
// Read book.toml or book.json if exists to a BTreeMap
|
||||||
|
|
||||||
if Path::new(self.project_root.join("book.toml").as_os_str()).exists() {
|
if Path::new(self.project_root.join("book.toml").as_os_str()).exists() {
|
||||||
|
|
||||||
debug!("[*]: Reading config");
|
debug!("[*]: Reading config");
|
||||||
let text = read_file(self.project_root.join("book.toml"));
|
let text = match utils::fs::file_to_string(&self.project_root.join("book.toml")) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => {
|
||||||
|
error!("[*] Read error: {:#?}", e);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
match utils::toml_str_to_btreemap(&text) {
|
match utils::toml_str_to_btreemap(&text) {
|
||||||
Ok(x) => {self.parse_from_btreemap(&x);},
|
Ok(x) => {self.parse_from_btreemap(&x);},
|
||||||
|
@ -224,7 +217,13 @@ impl MDBook {
|
||||||
} else if Path::new(self.project_root.join("book.json").as_os_str()).exists() {
|
} else if Path::new(self.project_root.join("book.json").as_os_str()).exists() {
|
||||||
|
|
||||||
debug!("[*]: Reading config");
|
debug!("[*]: Reading config");
|
||||||
let text = read_file(self.project_root.join("book.json"));
|
let text = match utils::fs::file_to_string(&self.project_root.join("book.json")) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => {
|
||||||
|
error!("[*] Read error: {:#?}", e);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
match utils::json_str_to_btreemap(&text) {
|
match utils::json_str_to_btreemap(&text) {
|
||||||
Ok(x) => {self.parse_from_btreemap(&x);},
|
Ok(x) => {self.parse_from_btreemap(&x);},
|
||||||
|
@ -305,14 +304,13 @@ impl MDBook {
|
||||||
// keys to the default source and destination folder such as `/src/en`
|
// keys to the default source and destination folder such as `/src/en`
|
||||||
// and `./book/en`. This may be overridden if set specifically.
|
// and `./book/en`. This may be overridden if set specifically.
|
||||||
|
|
||||||
// TODO if no is_main_book = true was set in the config, find the first
|
|
||||||
// translation (as in the config) and mark it as the main.
|
|
||||||
|
|
||||||
if let Some(a) = config.get("translations") {
|
if let Some(a) = config.get("translations") {
|
||||||
if let Some(b) = a.as_table() {
|
if let Some(b) = a.as_table() {
|
||||||
|
|
||||||
let is_multilang: bool = b.iter().count() > 1;
|
let is_multilang: bool = b.iter().count() > 1;
|
||||||
|
|
||||||
|
let mut has_main_book_already = false;
|
||||||
|
|
||||||
for (key, conf) in b.iter() {
|
for (key, conf) in b.iter() {
|
||||||
let mut book = Book::new(&self.project_root);
|
let mut book = Book::new(&self.project_root);
|
||||||
|
|
||||||
|
@ -324,10 +322,59 @@ impl MDBook {
|
||||||
}
|
}
|
||||||
book.config.is_multilang = is_multilang;
|
book.config.is_multilang = is_multilang;
|
||||||
book.config.parse_from_btreemap(&d);
|
book.config.parse_from_btreemap(&d);
|
||||||
|
if book.config.is_main_book {
|
||||||
|
has_main_book_already = true;
|
||||||
|
}
|
||||||
self.translations.insert(key.to_owned(), book);
|
self.translations.insert(key.to_owned(), book);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there hasn't been a 'is_main_book = true' set in the
|
||||||
|
// config, we have to find the first translation as given in the
|
||||||
|
// config and assume it to be the main book.
|
||||||
|
//
|
||||||
|
// Since the config is a BTreeMap, in which entries are ordered
|
||||||
|
// by the keys, the order in which they appear in the book.toml
|
||||||
|
// file has to be deduced by matching the file contents with a
|
||||||
|
// Regex.
|
||||||
|
|
||||||
|
if !has_main_book_already {
|
||||||
|
if Path::new(self.project_root.join("book.toml").as_os_str()).exists() {
|
||||||
|
|
||||||
|
let text = match utils::fs::file_to_string(&self.project_root.join("book.toml")) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => {
|
||||||
|
error!("[*] Read error: {:#?}", e);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let re: Regex = Regex::new(r"\[\[translations\.(?P<key>[^]]+)\]\]").unwrap();
|
||||||
|
|
||||||
|
match re.captures(&text) {
|
||||||
|
Some(caps) => {
|
||||||
|
if let Some(key) = caps.name("key") {
|
||||||
|
if let Some(mut a) = self.translations.get_mut(key) {
|
||||||
|
a.config.is_main_book = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if Path::new(self.project_root.join("book.json").as_os_str()).exists() {
|
||||||
|
|
||||||
|
// Not going to bother with Regex-parsing JSON. We're
|
||||||
|
// only supporting it for <= v0.0.15 books where the format
|
||||||
|
// was simple and the translations key hasn't been introduced.
|
||||||
|
|
||||||
|
error!("When using the JSON file format for configuration, mark the main trainslation by setting the \"is_main_book\": \"true\" property. Or use the TOML format and the first translation will be recognized as the main language.");
|
||||||
|
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut book = Book::new(&self.project_root);
|
let mut book = Book::new(&self.project_root);
|
||||||
|
@ -337,6 +384,7 @@ impl MDBook {
|
||||||
self.translations.insert(key, book);
|
self.translations.insert(key, book);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Source: http://www.babelmatrix.org/works/en/Hardy%2C_Thomas-1840/At_a_Lunar_Eclipse/hu/31879-Egy_holdfogyatkoz%C3%A1skor?tr_id=585
|
||||||
|
|
||||||
|
[[translations.hu]]
|
||||||
|
title = "Egy holdfogyatkozáskor"
|
||||||
|
author = "Szabó Lőrinc"
|
||||||
|
language = { name = "Magyar", code = "hu" }
|
||||||
|
|
||||||
|
[[translations.en]]
|
||||||
|
title = "At a Lunar Eclipse"
|
||||||
|
translator = "Thomas Hardy"
|
||||||
|
language = { name = "English", code = "en" }
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
title = "Alice's Adventures in Wonderland"
|
title = "Alice's Adventures in Wonderland"
|
||||||
author = "Lewis Carroll"
|
author = "Lewis Carroll"
|
||||||
language = { name = "English", code = "en" }
|
language = { name = "English", code = "en" }
|
||||||
is_main_book = true
|
|
||||||
|
|
||||||
[[translations.fr]]
|
[[translations.fr]]
|
||||||
title = "Alice au pays des merveilles"
|
title = "Alice au pays des merveilles"
|
||||||
|
|
|
@ -89,3 +89,14 @@ fn it_renders_multilanguage_book() {
|
||||||
s = utils::fs::file_to_string(&chapter_path).unwrap();
|
s = utils::fs::file_to_string(&chapter_path).unwrap();
|
||||||
assert!(s.contains("<h1>Könnytó</h1>"));
|
assert!(s.contains("<h1>Könnytó</h1>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_recognizes_first_translation_as_main() {
|
||||||
|
let path = PathBuf::from(".").join("src").join("tests").join("book-noneng-main");
|
||||||
|
|
||||||
|
let mut proj = MDBook::new(&path);
|
||||||
|
proj.read_config();
|
||||||
|
|
||||||
|
let t = proj.translations.get("hu").unwrap();
|
||||||
|
assert!(t.config.is_main_book);
|
||||||
|
}
|
||||||
|
|
|
@ -107,7 +107,6 @@ indent_spaces = 2
|
||||||
[[translations.en]]
|
[[translations.en]]
|
||||||
title = "Alice's Adventures in Wonderland"
|
title = "Alice's Adventures in Wonderland"
|
||||||
author = "Lewis Carroll"
|
author = "Lewis Carroll"
|
||||||
is_main_book = true
|
|
||||||
|
|
||||||
[[translations.hu]]
|
[[translations.hu]]
|
||||||
title = "Alice Csodaországban"
|
title = "Alice Csodaországban"
|
||||||
|
|
Loading…
Reference in New Issue