cross-link by section number if TOC are structurally the same
This commit is contained in:
parent
badc921429
commit
aa54d95a23
|
@ -430,11 +430,11 @@ impl MDBook {
|
|||
.map(|item| {
|
||||
match *item {
|
||||
TocItem::Numbered(ref i) =>
|
||||
TocItem::Numbered(self.set_translation_links(i)),
|
||||
TocItem::Numbered(self.set_translation_links(i, key.to_owned())),
|
||||
TocItem::Unnumbered(ref i) =>
|
||||
TocItem::Unnumbered(self.set_translation_links(i)),
|
||||
TocItem::Unnumbered(self.set_translation_links(i, key.to_owned())),
|
||||
TocItem::Unlisted(ref i) =>
|
||||
TocItem::Unlisted(self.set_translation_links(i)),
|
||||
TocItem::Unlisted(self.set_translation_links(i, key.to_owned())),
|
||||
TocItem::Spacer =>
|
||||
TocItem::Spacer,
|
||||
}
|
||||
|
@ -475,7 +475,7 @@ impl MDBook {
|
|||
Some(default_links)
|
||||
}
|
||||
|
||||
fn set_translation_links(&mut self, content: &TocContent) -> TocContent {
|
||||
fn set_translation_links(&mut self, content: &TocContent, key: String) -> TocContent {
|
||||
let mut final_links: BTreeMap<String, TranslationLink> = BTreeMap::new();
|
||||
let mut newcontent: TocContent = content.clone();
|
||||
|
||||
|
@ -498,6 +498,9 @@ impl MDBook {
|
|||
|
||||
// Find a translation for the links that are still None
|
||||
|
||||
let orig_book: &Book = self.translations.get(&key).unwrap();
|
||||
let orig_toc_id = toc::toc_node_count_id(&orig_book.toc);
|
||||
|
||||
for (key, trl) in final_links.clone().iter() {
|
||||
match trl.link {
|
||||
Some(_) => { continue; },
|
||||
|
@ -507,6 +510,8 @@ impl MDBook {
|
|||
let b: &Book = self.translations.get(key).unwrap();
|
||||
let flat_toc = toc::flat_toc(&b.toc);
|
||||
|
||||
let by_section: bool = toc::toc_node_count_id(&b.toc) == orig_toc_id;
|
||||
|
||||
for item in flat_toc.iter() {
|
||||
match *item {
|
||||
TocItem::Numbered(ref i) |
|
||||
|
@ -515,7 +520,7 @@ impl MDBook {
|
|||
|
||||
// Note that this will also add a link to itself, which is good.
|
||||
|
||||
if content.is_it_a_translation_of(i) {
|
||||
if content.is_it_a_translation_of(i, true, true, by_section) {
|
||||
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);
|
||||
|
|
|
@ -55,8 +55,14 @@ impl TocContent {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_it_a_translation_of(&self, checking: &TocContent) -> bool {
|
||||
pub fn is_it_a_translation_of(&self,
|
||||
checking: &TocContent,
|
||||
by_tr_id: bool,
|
||||
by_src_path: bool,
|
||||
by_section: bool) -> bool {
|
||||
|
||||
// if the user has set the same translation_id on them
|
||||
if by_tr_id {
|
||||
if let Some(ref a) = self.chapter.translation_id {
|
||||
if let Some(ref b) = checking.chapter.translation_id {
|
||||
if a == b {
|
||||
|
@ -64,8 +70,10 @@ impl TocContent {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if src_path matches
|
||||
if by_src_path {
|
||||
if let Some(ref a) = self.chapter.get_src_path() {
|
||||
if let Some(ref b) = checking.chapter.get_src_path() {
|
||||
if a == b {
|
||||
|
@ -73,6 +81,22 @@ impl TocContent {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if section string matches, useful when TOC structure matches but
|
||||
// titles and paths are translated. Can test that with
|
||||
// toc_node_count_id().
|
||||
if by_section {
|
||||
if let Some(_) = self.section {
|
||||
let a = self.section_as_string();
|
||||
if let Some(_) = checking.section {
|
||||
let b = checking.section_as_string();
|
||||
if a == b {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
@ -115,3 +139,34 @@ pub fn flat_toc(toc: &Vec<TocItem>) -> Vec<TocItem> {
|
|||
}
|
||||
flattened
|
||||
}
|
||||
|
||||
/// Produces a String that can be used to check if two TOCs have the same
|
||||
/// structure. It recursively counts the items at each level, ignoring Spacer
|
||||
/// items.
|
||||
pub fn toc_node_count_id(toc: &Vec<TocItem>) -> String {
|
||||
let mut counters = String::new();
|
||||
|
||||
let c = toc.iter().filter(|x| {
|
||||
match **x {
|
||||
TocItem::Spacer => { false },
|
||||
_ => { true },
|
||||
}}).count();
|
||||
|
||||
counters.push_str(&format!("{}", c));
|
||||
|
||||
for i in toc.iter() {
|
||||
match *i {
|
||||
TocItem::Numbered(ref x) |
|
||||
TocItem::Unnumbered(ref x) |
|
||||
TocItem::Unlisted(ref x) => {
|
||||
if let Some(ref subs) = x.sub_items {
|
||||
let a = toc_node_count_id(subs);
|
||||
counters.push_str(&a);
|
||||
}
|
||||
},
|
||||
TocItem::Spacer => {},
|
||||
}
|
||||
}
|
||||
|
||||
counters
|
||||
}
|
||||
|
|
|
@ -64,32 +64,28 @@ fn it_renders_multilanguage_book() {
|
|||
assert!(s.contains("<a href=\"hu/index.html\">hu</a>"));
|
||||
assert!(s.contains("<a href=\"fr/index.html\">fr</a>"));
|
||||
|
||||
// Test if translation links given in the TOML header were rendered
|
||||
// Test if translation links are found
|
||||
|
||||
book_path = proj.translations.get("en").unwrap().config.get_dest();
|
||||
|
||||
chapter_path = book_path.join("rabbit-hole.html");
|
||||
s = utils::fs::file_to_string(&chapter_path).unwrap();
|
||||
assert!(s.contains("<a href=\"en/rabbit-hole.html\">en</a>"));
|
||||
assert!(s.contains("<a href=\"hu/nyuszi.html\">hu</a>"));
|
||||
assert!(s.contains("<a href=\"fr/terrier.html\">fr</a>"));
|
||||
|
||||
// Test if translation links by translation_id were found
|
||||
|
||||
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("<a href=\"en/long-tale.html\">en</a>"));
|
||||
assert!(s.contains("<span>fr</span>"));
|
||||
assert!(s.contains("<a href=\"hu/tarka-farka.html\">hu</a>"));
|
||||
|
||||
// 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("<a href=\"en/tears.html\">en</a>"));
|
||||
assert!(s.contains("<a href=\"fr/tears.html\">fr</a>"));
|
||||
assert!(s.contains("<a href=\"hu/tears.html\">hu</a>"));
|
||||
|
||||
chapter_path = book_path.join("long-tale.html");
|
||||
s = utils::fs::file_to_string(&chapter_path).unwrap();
|
||||
assert!(s.contains("<a href=\"en/long-tale.html\">en</a>"));
|
||||
assert!(s.contains("<a href=\"fr/cocasse.html\">fr</a>"));
|
||||
assert!(s.contains("<a href=\"hu/tarka-farka.html\">hu</a>"));
|
||||
|
||||
// Test if print.html is produced for each translations
|
||||
|
||||
book_path = proj.translations.get("en").unwrap().config.get_dest();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#[cfg(test)]
|
||||
|
||||
use book::chapter::Chapter;
|
||||
use book::toc::{TocItem, TocContent, flat_toc};
|
||||
use book::toc::{TocItem, TocContent, flat_toc, toc_node_count_id};
|
||||
use parse::summary::parse_level;
|
||||
|
||||
#[test]
|
||||
|
@ -77,3 +77,37 @@ fn it_flattens_toc() {
|
|||
|
||||
assert_eq!(format!("{:#?}", result), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_counts_toc_id_string() {
|
||||
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 counters = toc_node_count_id(&toc);
|
||||
|
||||
assert_eq!(counters, "6552".to_string());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue