From badc921429c420e51782caf6a543176111e98bc1 Mon Sep 17 00:00:00 2001 From: Gambhiro Date: Mon, 16 Jan 2017 17:49:21 +0000 Subject: [PATCH] cross-link translations by translation_id and src_path --- src/book/mod.rs | 41 +++++++++++ src/book/toc.rs | 41 +++++++++++ .../src/en/long-tale.md | 4 ++ .../src/fr/SUMMARY.md | 2 +- .../src/fr/{larmes.md => tears.md} | 0 .../src/hu/SUMMARY.md | 2 +- .../src/hu/tarka-farka.md | 4 ++ .../src/hu/{konnyto.md => tears.md} | 0 src/tests/hbs_renderer_multilang.rs | 36 +++++++--- src/tests/mdbook_test.rs | 13 +++- src/tests/summary_test.rs | 18 +++++ src/tests/toc_test.rs | 68 ++++++++++++++++++- 12 files changed, 215 insertions(+), 14 deletions(-) rename src/tests/book-wonderland-multilang/src/fr/{larmes.md => tears.md} (100%) rename src/tests/book-wonderland-multilang/src/hu/{konnyto.md => tears.md} (100%) diff --git a/src/book/mod.rs b/src/book/mod.rs index c6ed943f..939dc67b 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -496,6 +496,46 @@ impl MDBook { None => {}, } + // Find a translation for the links that are still None + + for (key, trl) in final_links.clone().iter() { + match trl.link { + Some(_) => { continue; }, + None => {}, + } + + let b: &Book = self.translations.get(key).unwrap(); + let flat_toc = toc::flat_toc(&b.toc); + + for item in flat_toc.iter() { + match *item { + TocItem::Numbered(ref i) | + TocItem::Unnumbered(ref i) | + TocItem::Unlisted(ref i) => { + + // Note that this will also add a link to itself, which is good. + + if content.is_it_a_translation_of(i) { + if let Some(mut a) = i.chapter.get_dest_path() { + // Join the path to the language code, i.e. en/tears.html + a = PathBuf::from(key.to_string()).join(a); + let path = String::from(a.to_str().unwrap()); + + final_links.insert( + key.to_owned(), + TranslationLink::new_with_link(key.to_owned(), path) + ); + } else { + debug!("It's a translation but dest_path is not set: {:#?}", i); + } + break; + } + }, + TocItem::Spacer => {}, + } + } + } + let a: Vec = final_links.values().map(|x| x.clone()).collect(); newcontent.chapter.translation_links = Some(a); @@ -640,3 +680,4 @@ impl MDBook { // } } + diff --git a/src/book/toc.rs b/src/book/toc.rs index 84beaf74..d7510b8b 100644 --- a/src/book/toc.rs +++ b/src/book/toc.rs @@ -55,6 +55,28 @@ impl TocContent { } } + pub fn is_it_a_translation_of(&self, checking: &TocContent) -> bool { + // if the user has set the same translation_id on them + if let Some(ref a) = self.chapter.translation_id { + if let Some(ref b) = checking.chapter.translation_id { + if a == b { + return true; + } + } + } + + // if src_path matches + if let Some(ref a) = self.chapter.get_src_path() { + if let Some(ref b) = checking.chapter.get_src_path() { + if a == b { + return true; + } + } + } + + false + } + // TODO update // /// This function takes a slice `&[x,y,z]` and returns the corresponding sub-chapter if it exists. @@ -74,3 +96,22 @@ impl TocContent { // } // } } + +pub fn flat_toc(toc: &Vec) -> Vec { + let mut flattened: Vec = vec![]; + for i in toc.iter() { + match *i { + TocItem::Numbered(ref x) | + TocItem::Unnumbered(ref x) | + TocItem::Unlisted(ref x) => { + flattened.push(i.clone()); + if let Some(ref subs) = x.sub_items { + let mut a = flat_toc(subs); + flattened.append(&mut a); + } + }, + TocItem::Spacer => { flattened.push(i.clone()); }, + } + } + flattened +} diff --git a/src/tests/book-wonderland-multilang/src/en/long-tale.md b/src/tests/book-wonderland-multilang/src/en/long-tale.md index dec8091d..d9b5196d 100644 --- a/src/tests/book-wonderland-multilang/src/en/long-tale.md +++ b/src/tests/book-wonderland-multilang/src/en/long-tale.md @@ -1,3 +1,7 @@ ++++ +translation_id = "caucus race" ++++ + # A Caucus-Race and a Long Tale ![Tail](images/Tail.png) diff --git a/src/tests/book-wonderland-multilang/src/fr/SUMMARY.md b/src/tests/book-wonderland-multilang/src/fr/SUMMARY.md index 0ca6d6d6..8dbb9e6f 100644 --- a/src/tests/book-wonderland-multilang/src/fr/SUMMARY.md +++ b/src/tests/book-wonderland-multilang/src/fr/SUMMARY.md @@ -3,7 +3,7 @@ [Titre](titre.md) - [Au fond du terrier](terrier.md) -- [La mare aux larmes](larmes.md) +- [La mare aux larmes](tears.md) - [La course cocasse](cocasse.md) - [L'habitation du lapin blanc]() - [Conseils d'une chenille]() diff --git a/src/tests/book-wonderland-multilang/src/fr/larmes.md b/src/tests/book-wonderland-multilang/src/fr/tears.md similarity index 100% rename from src/tests/book-wonderland-multilang/src/fr/larmes.md rename to src/tests/book-wonderland-multilang/src/fr/tears.md diff --git a/src/tests/book-wonderland-multilang/src/hu/SUMMARY.md b/src/tests/book-wonderland-multilang/src/hu/SUMMARY.md index 2e9daf5a..a66b8c8a 100644 --- a/src/tests/book-wonderland-multilang/src/hu/SUMMARY.md +++ b/src/tests/book-wonderland-multilang/src/hu/SUMMARY.md @@ -3,7 +3,7 @@ [Címoldal](cimoldal.md) - [Lenn, a Nyuszi barlangjában](nyuszi.md) -- [Könnytó](konnyto.md) +- [Könnytó](tears.md) - [Körbecsukó meg az egér hosszú tarka farka](tarka-farka.md) - [Gyíkocska]() - [A hernyó tanácsot ad]() diff --git a/src/tests/book-wonderland-multilang/src/hu/tarka-farka.md b/src/tests/book-wonderland-multilang/src/hu/tarka-farka.md index f3617efe..b5b92616 100644 --- a/src/tests/book-wonderland-multilang/src/hu/tarka-farka.md +++ b/src/tests/book-wonderland-multilang/src/hu/tarka-farka.md @@ -1,3 +1,7 @@ ++++ +translation_id = "caucus race" ++++ + # Körbecsukó meg az egér hosszú tarka farka ![Tarka-farka](images/Tail.png) diff --git a/src/tests/book-wonderland-multilang/src/hu/konnyto.md b/src/tests/book-wonderland-multilang/src/hu/tears.md similarity index 100% rename from src/tests/book-wonderland-multilang/src/hu/konnyto.md rename to src/tests/book-wonderland-multilang/src/hu/tears.md diff --git a/src/tests/hbs_renderer_multilang.rs b/src/tests/hbs_renderer_multilang.rs index 32cb99f6..5ce7ca5a 100644 --- a/src/tests/hbs_renderer_multilang.rs +++ b/src/tests/hbs_renderer_multilang.rs @@ -27,7 +27,7 @@ fn it_renders_multilanguage_book() { chapter_path = proj.get_dest_base().join("index.html"); s = utils::fs::file_to_string(&chapter_path).unwrap(); - assert!(s.contains("Alice's Adventures in Wonderland")); + assert!(s.contains("Titlepage - Alice's Adventures in Wonderland")); assert!(s.contains("

Alice's Adventures in Wonderland

")); assert!(s.contains("")); @@ -40,13 +40,13 @@ fn it_renders_multilanguage_book() { assert!(s.contains("li>2. The Pool of Tears")); book_path = proj.translations.get("fr").unwrap().config.get_dest(); - chapter_path = book_path.join("larmes.html"); + chapter_path = book_path.join("tears.html"); s = utils::fs::file_to_string(&chapter_path).unwrap(); assert!(s.contains("

La mare aux larmes

")); assert!(s.contains("")); book_path = proj.translations.get("hu").unwrap().config.get_dest(); - chapter_path = book_path.join("konnyto.html"); + chapter_path = book_path.join("tears.html"); s = utils::fs::file_to_string(&chapter_path).unwrap(); assert!(s.contains("

Könnytó

")); assert!(s.contains("")); @@ -55,6 +55,15 @@ fn it_renders_multilanguage_book() { assert!(proj.get_dest_base().join("images").join("Queen.jpg").exists()); + // Test if default translation indexes are displayed + + book_path = proj.translations.get("hu").unwrap().config.get_dest(); + chapter_path = book_path.join("tarka-farka.html"); + s = utils::fs::file_to_string(&chapter_path).unwrap(); + assert!(s.contains("en")); + assert!(s.contains("hu")); + assert!(s.contains("fr")); + // Test if translation links given in the TOML header were rendered book_path = proj.translations.get("en").unwrap().config.get_dest(); @@ -63,14 +72,23 @@ fn it_renders_multilanguage_book() { assert!(s.contains("hu")); assert!(s.contains("fr")); - // Test if default translation links are set + // Test if translation links by translation_id were found - book_path = proj.translations.get("hu").unwrap().config.get_dest(); - chapter_path = book_path.join("tarka-farka.html"); + book_path = proj.translations.get("en").unwrap().config.get_dest(); + chapter_path = book_path.join("long-tale.html"); s = utils::fs::file_to_string(&chapter_path).unwrap(); - assert!(s.contains("en")); - assert!(s.contains("hu")); - assert!(s.contains("fr")); + assert!(s.contains("en")); + assert!(s.contains("fr")); + assert!(s.contains("hu")); + + // Test if translation links by src_path were found + + book_path = proj.translations.get("en").unwrap().config.get_dest(); + chapter_path = book_path.join("tears.html"); + s = utils::fs::file_to_string(&chapter_path).unwrap(); + assert!(s.contains("en")); + assert!(s.contains("fr")); + assert!(s.contains("hu")); // Test if print.html is produced for each translations diff --git a/src/tests/mdbook_test.rs b/src/tests/mdbook_test.rs index 1a76138b..b5c6076a 100644 --- a/src/tests/mdbook_test.rs +++ b/src/tests/mdbook_test.rs @@ -107,6 +107,7 @@ indent_spaces = 2 [[translations.en]] title = "Alice's Adventures in Wonderland" author = "Lewis Carroll" +is_main_book = true [[translations.hu]] title = "Alice Csodaországban" @@ -168,10 +169,18 @@ name = "Kosztolányi Dezső" // Hashmaps are unordered. They don't always print their keys in the same order. + assert_eq!(result.indent_spaces, expected.indent_spaces); + assert_eq!( - format!("{:#?} {:#?} {:#?}", result.indent_spaces, result.translations.get("en").unwrap(), result.translations.get("hu").unwrap()), - format!("{:#?} {:#?} {:#?}", expected.indent_spaces, expected.translations.get("en").unwrap(), expected.translations.get("hu").unwrap()) + format!("{:#?}", result.translations.get("en").unwrap()), + format!("{:#?}", expected.translations.get("en").unwrap()) ); + + assert_eq!( + format!("{:#?}", result.translations.get("hu").unwrap()), + format!("{:#?}", expected.translations.get("hu").unwrap()) + ); + } #[test] diff --git a/src/tests/summary_test.rs b/src/tests/summary_test.rs index 8e882ba5..8042fbf3 100644 --- a/src/tests/summary_test.rs +++ b/src/tests/summary_test.rs @@ -46,6 +46,7 @@ fn it_parses_summary_to_tocitems() { "index.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -67,6 +68,7 @@ fn it_parses_summary_to_tocitems() { "README.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -92,6 +94,7 @@ fn it_parses_summary_to_tocitems() { "cli/cli-tool.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -111,6 +114,7 @@ fn it_parses_summary_to_tocitems() { "cli/init.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -137,6 +141,7 @@ fn it_parses_summary_to_tocitems() { "cli/build.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -163,6 +168,7 @@ fn it_parses_summary_to_tocitems() { "cli/watch.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -189,6 +195,7 @@ fn it_parses_summary_to_tocitems() { "cli/serve.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -215,6 +222,7 @@ fn it_parses_summary_to_tocitems() { "cli/test.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -250,6 +258,7 @@ fn it_parses_summary_to_tocitems() { "format/format.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -269,6 +278,7 @@ fn it_parses_summary_to_tocitems() { "format/summary.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -295,6 +305,7 @@ fn it_parses_summary_to_tocitems() { "format/config.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -321,6 +332,7 @@ fn it_parses_summary_to_tocitems() { "format/theme/theme.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -340,6 +352,7 @@ fn it_parses_summary_to_tocitems() { "format/theme/index-hbs.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -367,6 +380,7 @@ fn it_parses_summary_to_tocitems() { "format/theme/syntax-highlighting.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -404,6 +418,7 @@ fn it_parses_summary_to_tocitems() { "format/mathjax.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -430,6 +445,7 @@ fn it_parses_summary_to_tocitems() { "format/rust.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -465,6 +481,7 @@ fn it_parses_summary_to_tocitems() { "lib/lib.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, @@ -491,6 +508,7 @@ fn it_parses_summary_to_tocitems() { "misc/contributors.html" ), translation_links: None, + translation_id: None, authors: None, translators: None, description: None, diff --git a/src/tests/toc_test.rs b/src/tests/toc_test.rs index 4b64139c..a8fac14b 100644 --- a/src/tests/toc_test.rs +++ b/src/tests/toc_test.rs @@ -1,7 +1,8 @@ #[cfg(test)] use book::chapter::Chapter; -use book::toc::TocContent; +use book::toc::{TocItem, TocContent, flat_toc}; +use parse::summary::parse_level; #[test] fn it_should_produce_the_section_as_string() { @@ -11,3 +12,68 @@ fn it_should_produce_the_section_as_string() { let expected = "1.9.4.".to_string(); assert_eq!(result, expected); } + +#[test] +fn it_flattens_toc() { + let text = r#" +# Summary + +[Introduction](misc/introduction.md) + +- [mdBook](README.md) +- [Command Line Tool](cli/cli-tool.md) + - [init](cli/init.md) + - [build](cli/build.md) + - [watch](cli/watch.md) + - [serve](cli/serve.md) + - [test](cli/test.md) +- [Format](format/format.md) + - [SUMMARY.md](format/summary.md) + - [Configuration](format/config.md) + - [Theme](format/theme/theme.md) + - [index.hbs](format/theme/index-hbs.md) + - [Syntax highlighting](format/theme/syntax-highlighting.md) + - [MathJax Support](format/mathjax.md) + - [Rust code specific features](format/rust.md) +- [Rust Library](lib/lib.md) +----------- +[Contributors](misc/contributors.md) +"#; + + let toc = parse_level(&mut text.split('\n').collect(), 0, vec![0], true).unwrap(); + + let flat = flat_toc(&toc); + + let result: Vec = flat.iter().map(|x| { + match *x { + TocItem::Numbered(ref i) | + TocItem::Unnumbered(ref i) | + TocItem::Unlisted(ref i) => i.chapter.title.to_owned(), + TocItem::Spacer => "spacer".to_string(), + } + }).collect::>(); + + let expected = r#"[ + "Introduction", + "mdBook", + "Command Line Tool", + "init", + "build", + "watch", + "serve", + "test", + "Format", + "SUMMARY.md", + "Configuration", + "Theme", + "index.hbs", + "Syntax highlighting", + "MathJax Support", + "Rust code specific features", + "Rust Library", + "spacer", + "Contributors" +]"#; + + assert_eq!(format!("{:#?}", result), expected); +}