Implement translation fallback of files included with preprocessing

This commit is contained in:
Ruin0x11 2020-08-29 16:11:47 -07:00
parent 5fed5e866d
commit d6c27abc22
4 changed files with 79 additions and 20 deletions

View File

@ -48,17 +48,21 @@ impl Preprocessor for LinkPreprocessor {
.unwrap();
let src_dir = ctx.root.join(src_dir);
let fallback_src_dir = ctx
.config
.get_localized_src_path(ctx.config.default_language().as_ref())
.unwrap();
let fallback_src_dir = ctx.root.join(fallback_src_dir);
book.for_each_mut(|section: &mut BookItem| {
if let BookItem::Chapter(ref mut ch) = *section {
if let Some(ref chapter_path) = ch.path {
let base = chapter_path
.parent()
.map(|dir| src_dir.join(dir))
.expect("All book items have a parent");
let parent = chapter_path.parent().expect("All book items have a parent");
let base = src_dir.join(parent);
let fallback = fallback_src_dir.join(parent);
let mut chapter_title = ch.name.clone();
let content =
replace_all(&ch.content, base, chapter_path, 0, &mut chapter_title);
let content = replace_all(&ch.content, base, Some(fallback), chapter_path, 0, &mut chapter_title);
ch.content = content;
if chapter_title != ch.name {
ctx.chapter_titles
@ -76,9 +80,10 @@ impl Preprocessor for LinkPreprocessor {
fn replace_all<P1, P2>(
s: &str,
path: P1,
fallback: Option<P1>,
source: P2,
depth: usize,
chapter_title: &mut String,
chapter_title: &mut String
) -> String
where
P1: AsRef<Path>,
@ -88,6 +93,7 @@ where
// the indices after that will not correspond,
// we therefore have to store the difference to correct this
let path = path.as_ref();
let fallback = fallback.as_ref();
let source = source.as_ref();
let mut previous_end_index = 0;
let mut replaced = String::new();
@ -95,13 +101,14 @@ where
for link in find_links(s) {
replaced.push_str(&s[previous_end_index..link.start_index]);
match link.render_with_path(&path, chapter_title) {
match link.render_with_path(&path, fallback, chapter_title) {
Ok(new_content) => {
if depth < MAX_LINK_NESTED_DEPTH {
if let Some(rel_path) = link.link_type.relative_path(path) {
replaced.push_str(&replace_all(
&new_content,
rel_path,
None,
source,
depth + 1,
chapter_title,
@ -323,6 +330,7 @@ impl<'a> Link<'a> {
fn render_with_path<P: AsRef<Path>>(
&self,
base: P,
fallback: Option<P2>,
chapter_title: &mut String,
) -> Result<String> {
let base = base.as_ref();
@ -330,7 +338,20 @@ impl<'a> Link<'a> {
// omit the escape char
LinkType::Escaped => Ok((&self.link_text[1..]).to_owned()),
LinkType::Include(ref pat, ref range_or_anchor) => {
let target = base.join(pat);
let mut target = base.join(pat);
if !target.exists() {
if let Some(fallback) = fallback {
let fallback_target = fallback.as_ref().join(pat);
if fallback_target.exists() {
debug!(
"Included file fallback: {:?} => {:?}",
target, fallback_target
);
target = fallback_target;
}
}
}
fs::read_to_string(&target)
.map(|s| match range_or_anchor {
@ -346,7 +367,20 @@ impl<'a> Link<'a> {
})
}
LinkType::RustdocInclude(ref pat, ref range_or_anchor) => {
let target = base.join(pat);
let mut target = base.join(pat);
if !target.exists() {
if let Some(fallback) = fallback {
let fallback_target = fallback.as_ref().join(pat);
if fallback_target.exists() {
debug!(
"Included file fallback: {:?} => {:?}",
target, fallback_target
);
target = fallback_target;
}
}
}
fs::read_to_string(&target)
.map(|s| match range_or_anchor {
@ -366,7 +400,20 @@ impl<'a> Link<'a> {
})
}
LinkType::Playground(ref pat, ref attrs) => {
let target = base.join(pat);
let mut target = base.join(pat);
if !target.exists() {
if let Some(fallback) = fallback {
let fallback_target = fallback.as_ref().join(pat);
if fallback_target.exists() {
debug!(
"Included file fallback: {:?} => {:?}",
target, fallback_target
);
target = fallback_target;
}
}
}
let mut contents = fs::read_to_string(&target).with_context(|| {
format!(
@ -444,7 +491,7 @@ mod tests {
{{#include file.rs}} << an escaped link!
```";
let mut chapter_title = "test_replace_all_escaped".to_owned();
assert_eq!(replace_all(start, "", "", 0, &mut chapter_title), end);
assert_eq!(replace_all(start, "", None, "", 0, &mut chapter_title), end);
}
#[test]
@ -456,7 +503,7 @@ mod tests {
# My Chapter
";
let mut chapter_title = "test_set_chapter_title".to_owned();
assert_eq!(replace_all(start, "", "", 0, &mut chapter_title), end);
assert_eq!(replace_all(start, "", None, "", 0, &mut chapter_title), end);
assert_eq!(chapter_title, "My Title");
}

View File

@ -518,10 +518,11 @@ more text with spaces
let _ = env_logger::builder().is_test(true).try_init();
let test = |dest, path, exists, expected| {
let src_dir = tempfile::tempdir().unwrap();
let path = PathBuf::from(path);
let ctx = if exists {
Some(RenderMarkdownContext {
path: PathBuf::from(path),
path: path,
src_dir: PathBuf::new(),
language: None,
fallback_language: None,
@ -534,7 +535,7 @@ more text with spaces
let fallback_dir = src_dir.path().join("en");
fs::create_dir_all(&fallback_dir).unwrap();
let chapter_path = fallback_dir.join(path).join(dest);
let chapter_path = fallback_dir.join(path.parent().unwrap()).join(dest);
fs::create_dir_all(chapter_path.parent().unwrap()).unwrap();
debug!("Create: {}", chapter_path.display());
File::create(&chapter_path)
@ -543,7 +544,7 @@ more text with spaces
.unwrap();
Some(RenderMarkdownContext {
path: PathBuf::from(path),
path: path,
src_dir: PathBuf::from(src_dir.path()),
language: Some(String::from("ja")),
fallback_language: Some(String::from("en")),
@ -557,17 +558,17 @@ more text with spaces
);
};
test("../b/summary.md", "a.md", true, "../b/summary.html");
test("../b/summary.md", "a/index.md", true, "../b/summary.html");
test(
"../b/summary.md",
"a.md",
"a/index.md",
false,
"../../en/../b/summary.html",
);
test("../c/summary.md", "a/b.md", true, "../c/summary.html");
test("../c/summary.md", "a/b/index.md", true, "../c/summary.html");
test(
"../c/summary.md",
"a/b.md",
"a/b/index.md",
false,
"../../../en/../c/summary.html",
);

View File

@ -0,0 +1,6 @@
fn main() {
println!("Hello World!");
#
# // You can even hide lines! :D
# println!("I am hidden! Expand the code snippet to see me");
}

View File

@ -12,4 +12,9 @@ Here is an [inline link](missing-summary-chapter.md) to a page missing from this
Also, here is an [inline link](blah.md) to a page missing from both translations. It should point to this language's 404 page.
Here is a file included from the default language.
```rust
{{ #include example.rs }}
```
The substitution won't work if you specify the `-l`/`--language` option, since it only builds a single translation in that case.