|
| 1 | +use mdbook::renderer::RenderContext; |
| 2 | +use serde::Deserialize; |
| 3 | +use std::collections::BTreeMap; |
| 4 | +use std::io; |
| 5 | + |
| 6 | +#[derive(Deserialize)] |
| 7 | +struct I18nConfiguration { |
| 8 | + languages: BTreeMap<String, String>, |
| 9 | + default_language: Option<String>, |
| 10 | + |
| 11 | + #[serde(default)] |
| 12 | + translate_all_languages: bool, |
| 13 | + #[serde(default)] |
| 14 | + move_translations_to_html_directory: bool, |
| 15 | +} |
| 16 | + |
| 17 | +fn main() { |
| 18 | + let mut stdin = io::stdin(); |
| 19 | + |
| 20 | + // Get the configs |
| 21 | + let ctx = RenderContext::from_json(&mut stdin).unwrap(); |
| 22 | + let i18n_config: I18nConfiguration = ctx |
| 23 | + .config |
| 24 | + .get_deserialized_opt("output.i18n-helpers") |
| 25 | + .unwrap() |
| 26 | + .unwrap(); |
| 27 | + |
| 28 | + if !i18n_config.translate_all_languages { |
| 29 | + return; |
| 30 | + } |
| 31 | + |
| 32 | + let mut mdbook = mdbook::MDBook::load(&ctx.root).expect("Failed to load book"); |
| 33 | + // Overwrite with current values from stdin. |
| 34 | + mdbook.book = ctx.book.clone(); |
| 35 | + mdbook.config = ctx.config.clone(); |
| 36 | + mdbook.root = ctx.root.clone(); |
| 37 | + |
| 38 | + let book_config = mdbook |
| 39 | + .config |
| 40 | + .get_mut("output.i18n-helpers") |
| 41 | + .expect("No output.i18n-helpers config in book.toml"); |
| 42 | + // Set translate_all_languages to false for nested builds to prevent infinite recursion. |
| 43 | + book_config |
| 44 | + .as_table_mut() |
| 45 | + .expect("output.i18n-helpers config in book.toml is not a table") |
| 46 | + .insert( |
| 47 | + String::from("translate_all_languages"), |
| 48 | + toml::Value::Boolean(false), |
| 49 | + ); |
| 50 | + |
| 51 | + let output_directory = ctx.destination.parent().unwrap(); |
| 52 | + let default_language = &i18n_config.default_language; |
| 53 | + |
| 54 | + for language in i18n_config.languages.keys() { |
| 55 | + // Skip current language and default language. |
| 56 | + if Some(language) == ctx.config.book.language.as_ref() { |
| 57 | + continue; |
| 58 | + } |
| 59 | + if let Some(default_language) = default_language { |
| 60 | + if default_language == language { |
| 61 | + continue; |
| 62 | + } |
| 63 | + } |
| 64 | + let translation_path = output_directory.join(language); |
| 65 | + |
| 66 | + // Book doesn't implement clone, so we just mutate in place. |
| 67 | + mdbook.config.book.language = Some(language.clone()); |
| 68 | + mdbook.config.book.multilingual = true; |
| 69 | + mdbook.config.build.build_dir = translation_path; |
| 70 | + mdbook.build().unwrap_or_else(|_| panic!("Failed to build translation for language: {}", |
| 71 | + language)); |
| 72 | + if i18n_config.move_translations_to_html_directory { |
| 73 | + std::fs::rename( |
| 74 | + output_directory.join(language).join("html"), |
| 75 | + output_directory.join("html").join(language), |
| 76 | + ) |
| 77 | + .unwrap_or_else(|_| panic!("Failed to move translation for language {language} to output directory")); |
| 78 | + } |
| 79 | + } |
| 80 | +} |
0 commit comments