Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: image not found in README.md while mdbook build #120

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use thiserror::Error;
use std::path::PathBuf;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
Expand Down Expand Up @@ -42,6 +42,9 @@ pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),

#[error(transparent)]
AssetOutsideSrcDir(#[from] std::path::StripPrefixError),

#[error(transparent)]
Book(#[from] mdbook::errors::Error),
#[error(transparent)]
Expand Down
17 changes: 8 additions & 9 deletions src/resources/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,7 @@ impl Asset {
return Err(Error::AssetFile(absolute_location));
}
// Use filename as embedded file path with content from absolute_location.
let binding = utils::normalize_path(Path::new(link));
debug!("Extracting file name from = {:?}, binding = '{binding:?}'", &full_filename.display());
let filename = if cfg!(target_os = "windows") {
binding.as_os_str().to_os_string()
.into_string().expect("Error getting filename for Local Asset").replace('\\', "/")
Comment on lines -87 to -89
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if that is good to remove that code. I remember there were problems on Win, so I added that piece of code. I doubt that is good.

Copy link
Contributor Author

@dieterplex dieterplex Dec 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any exact cases could be added to testcases?

Things like https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That code is related to problem of building epub book on Windows platform. We should change window's based '\' to path like '/' as that should be by epub specification.

See also
#[test] fn test_normalize_path_win() {

#11

} else {
String::from(binding.as_path().to_str().unwrap())
};
let filename = full_filename.strip_prefix(src_dir)?;

let asset = Asset::new(
filename,
Expand All @@ -112,7 +105,13 @@ impl Asset {
pub(crate) fn compute_asset_path_by_src_and_link(link: &str, chapter_dir: &PathBuf) -> PathBuf {
let mut reassigned_asset_root: PathBuf = PathBuf::from(chapter_dir);
let link_string = String::from(link);
// if chapter is a MD file, remove if from path
// mdbook built-in link preprocessor have `README.md` renamed and `index.md` is not exist
// strip the converted filename in the path
if chapter_dir.ends_with("index.md") && !chapter_dir.exists() {
debug!("It seems a `README.md` chapter, adjust the chapter root.");
reassigned_asset_root.pop();
}
// if chapter is a MD file or not exist, remove if from path
if chapter_dir.is_file() {
reassigned_asset_root.pop();
}
Expand Down
12 changes: 9 additions & 3 deletions src/resources/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@ pub(crate) fn find(ctx: &RenderContext) -> Result<HashMap<String, Asset>, Error>
continue;
}
for link in find_assets_in_markdown(&ch.content)? {
let asset = match Url::parse(&link) {
Ok(url) => Asset::from_url(url, &ctx.destination),
Err(_) => Asset::from_local(&link, &src_dir, ch.path.as_ref().unwrap()),
let asset = if let Ok(url) = Url::parse(&link) {
Asset::from_url(url, &ctx.destination)
} else {
let result = Asset::from_local(&link, &src_dir, ch.path.as_ref().unwrap());
if let Err(Error::AssetOutsideSrcDir(_)) = result {
warn!("Asset '{link}' is outside source dir '{src_dir:?}' and ignored");
continue;
};
blandger marked this conversation as resolved.
Show resolved Hide resolved
result
}?;

// that is CORRECT generation way
Expand Down
9 changes: 9 additions & 0 deletions tests/dummy/src/02_advanced/Epub_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions tests/dummy/src/02_advanced/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# README.md tests

## image link

![Awesome image in the same folder](Epub_logo.svg "Awesome")
4 changes: 4 additions & 0 deletions tests/dummy/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@

- [Chapter 1](./chapter_1.md)
- [Getting started](01_getting_started/02_article.md)

# Advanced

- [README.md tests](./02_advanced/README.md)
27 changes: 24 additions & 3 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,38 @@ fn look_for_chapter_1_heading() {
assert!(content.contains("<h1>Chapter 1</h1>"));
}

#[test]
#[serial]
fn look_for_chapter_2_image_link_in_readme() {
init_logging();
let mut doc = generate_epub().unwrap();

let path = if cfg!(target_os = "linux") {
Path::new("OEBPS").join("02_advanced").join("README.html") // linux
} else {
Path::new("OEBPS/02_advanced/README.html").to_path_buf() // windows with 'forward slash' /
};
let content = doc.0.get_resource_str_by_path(path).unwrap();

assert!(content.contains("<img src=\"Epub_logo.svg\""));
}

#[test]
#[serial]
fn rendered_document_contains_all_chapter_files_and_assets() {
init_logging();
debug!("rendered_document_contains_all_chapter_files_and_assets...");
let chapters = vec!["chapter_1.html", "rust-logo.png"];
let chapters = vec![
"chapter_1.html",
"rust-logo.png",
"02_advanced/README.html",
"02_advanced/Epub_logo.svg",
];
let mut doc = generate_epub().unwrap();
debug!("Number of internal epub resources = {:?}", doc.0.resources);
// number of internal epub resources for dummy test book
assert_eq!(10, doc.0.resources.len());
assert_eq!(2, doc.0.spine.len());
assert_eq!(12, doc.0.resources.len());
assert_eq!(3, doc.0.spine.len());
assert_eq!(doc.0.mdata("title").unwrap(), "DummyBook");
assert_eq!(doc.0.mdata("language").unwrap(), "en");
debug!(
Expand Down