Michael-F-Bryan/mdbook-epub

Required to downgrade mdbook to 0.3.7

madhavajay opened this issue · 30 comments

mdbook-epub is awesome by the way! :)

I followed install instructions and added the epub entry to the master (commit bfe1ab96d717d1dda50e499b360f2e2f57e1750a) of nomicon:

+[output.epub]

Then ran:

 ~/Desktop/dev/nomicon   master ●  mdbook build
2020-07-03 08:32:02 [INFO] (mdbook::book): Book building has started
2020-07-03 08:32:02 [INFO] (mdbook::book): Running the epub backend
2020-07-03 08:32:02 [INFO] (mdbook::renderer): Invoking the "epub" renderer
Error: Incompatible mdbook version, expected 0.3.7 but got 0.4.0
2020-07-03 08:32:02 [ERROR] (mdbook::renderer): Renderer exited with non-zero return code.
2020-07-03 08:32:02 [ERROR] (mdbook::utils): Error: Rendering failed
2020-07-03 08:32:02 [ERROR] (mdbook::utils): 	Caused By: The "epub" renderer failed
$ mdbook --version
mdbook v0.4.0

Downgrading:

$ cargo uninstall mdbook
$ cargo install mdbook --version 0.3.7
$ mdbook build
2020-07-03 08:51:39 [INFO] (mdbook::book): Book building has started
2020-07-03 08:51:39 [INFO] (mdbook::book): Running the epub backend
2020-07-03 08:51:39 [INFO] (mdbook::renderer): Invoking the "epub" renderer
2020-07-03 08:51:39 [INFO] (mdbook::book): Running the html backend

Success!

tmpfs commented

Hi, I just ran into the same problem but cannot downgrade. @Michael-F-Bryan is this easily fixable? Are you interested in a PR to fix it?

FWIW, I am using mdbook@0.4 as a library so do not wish to downgrade as I am trying to keep a clear upgrade path. Upgrading mdbook as a crate from 0.37 to 0.40 was seamless so my hunch is that upgrading here should be easy too - happy to be corrected!

We should just need to bump the mdbook dependency to 0.4 and because we're using the version number exposed by mdbook, our version check should work with the latest version.

It also may be a good idea to relax the version check so instead of requiring exactly 0.4.0 (or whatever the version mdbook-epub is compiled for) it can accept anything greater but within the same minor version. That way when 0.4.1 is released we aren't broken again.

tmpfs commented

Great, i think we can use a tilde requirement quite easily, something like:

VersionReq::parse(&format!("~{}", MDBOOK_VERSION))?;

Will take a closer look tomorrow.

tmpfs commented

What i have discovered so far is that the chapter path is now an Option so i just called as_ref().unwrap() on them and then discovered that various error handling has trait implementation errors. I am not sure why as i am not familiar with the failure crate.

tmpfs commented

@Michael-F-Bryan can you elucidate how I can get failure to play nice with mdbook::errors::Error?

I have a little experience writing error traits manually and using thiserror just not clear what the process is for failure.

These are the errors:

error[E0277]: the trait bound `mdbook::errors::Error: std::error::Error` is not satisfied
  --> src/bin/mdbook-epub.rs:42:51
   |
42 |         let md = MDBook::load(&args.root).map_err(SyncFailure::new)?;
   |                                                   ^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `mdbook::errors::Error`
   |
   = note: required by `failure::SyncFailure::<E>::new`

error[E0277]: the trait bound `mdbook::errors::Error: std::error::Error` is not satisfied
  --> src/bin/mdbook-epub.rs:42:18
   |
42 |         let md = MDBook::load(&args.root).map_err(SyncFailure::new)?;
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `mdbook::errors::Error`
   |
   = note: required by `failure::SyncFailure::<E>::new`

error[E0277]: the trait bound `failure::SyncFailure<mdbook::errors::Error>: failure::Fail` is not satisfied
  --> src/bin/mdbook-epub.rs:42:68
   |
42 |         let md = MDBook::load(&args.root).map_err(SyncFailure::new)?;
   |                                                                    ^ the trait `failure::Fail` is not implemented for `failure::SyncFailure<mdbook::errors::Error>`
   |
   = help: the following implementations were found:
             <failure::SyncFailure<E> as failure::Fail>
   = note: required because of the requirements on the impl of `std::convert::From<failure::SyncFailure<mdbook::errors::Error>>` for `failure::Error`
   = note: required by `std::convert::From::from`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `mdbook-epub`.

This is after upgrading to mdbook@0.4.0 and fixing the initial Option issue noted above.

@Michael-F-Bryan can you elucidate how I can get failure to play nice with mdbook::errors::Error?

What error type do mdbook use? Nowadays I'll use normal types implementing std::error::Error (sometimes using thiserror to write the impl if I'm lazy) or anyhow if I just need a generic error type.

The easiest solution would be to use whatever error types mdbook use.

tmpfs commented

Ok, I think anyhow would be the right thing to do here as it's a program not a library; would that be acceptable to you if I rip out failure and use anyhow instead?

@tmpfs, sounds good to me 👍

I actually read this awesome article the other day on both anyhow and thiserror which explains how they work and their purpose / advantages:
https://nick.groenen.me/posts/rust-error-handling/

tmpfs commented

Thanks @madhavajay, good article. I actually ended up going with thiserror as it has better ergonomics for my taste, see #35 .

Is there any chance to use this backend with mdBook v0.4+?

Same problem on Windows: Error: Incompatible mdbook version, expected 0.3.7 but got 0.4.6.

Thank you!

wzf03 commented

I have found a really simple solution.
Just clone this project and compile it by yourself after cargo update

cargo update
cargo install --path .

Done.

That indicates that the fix is in master, but no version containing that fix has been published to crates.io yet.
Seems a version bump is required @Michael-F-Bryan

@blandger or @glottologist, would you be able to look into this? You should have permission to upload new versions to crates.io.

I'll try to look that and build, but I'm not sure I know how to do release build and put it into crates.
Should I do something special for release?

This page from the Cargo Book should explain the process and how to authenticate with crates.io, but the bare minimum you need to do is change the version number in Cargo.toml and run cargo publish.

I normally use the cargo release patch --sign command because it automates the process of bumping version numbers, making a "released v1.2.3" commit and tagging it, publishing to crates.io, and bumping to a -dev version.

@blandger @Michael-F-Bryan I can do this if no-one else has picked it up yet?

Same issue here.

Error: Incompatible mdbook version, expected 0.3.7 but got 0.4.5

@glottologist @akiradeveloper update changes were merged into master. I will try to tag and publish new version into crates soon.

If you hurry to run that asap...
Usually I'm using my own locally patched mdbook-epub version from:
https://github.com/blandger/mdbook-epub/blob/add_links_preprocessing/Cargo.toml
(patched epub-builder to have correct epub files on Eink-readers, patched mdBook to correctly process included /*.rs files in epub text as code pieces, tested mostly for rust-book)

I use linux command like that:
param to see the log RUST_LOG=debug is optional, but it can be used in case error for diagnosis.
/path_to_md_book_sources/ is folder with 'book.toml' in root

RUST_LOG=debug /mdbook-epub/target/debug/mdbook-epub /path_to_md_book_sources/

it's up to you which one to use. Hope the original works well for you,

@Michael-F-Bryan
Looks like not enough permissions (on crates or where) ?

Latest step of cargo publish gives error:

error: failed to publish to registry at https://crates.io
Caused by:
  the remote server responded with an error: this crate exists but you don't seem to be an owner. If you believe this is a mistake, perhaps you need to accept an invitation to be an owner before publishing.

Do you see any pending invites on crates.io?

2022-01-06_16-16-40-12

Yes I see, accepted and tried one more time.
I'll solve next issue

error: failed to publish to registry at https://crates.io
Caused by:
  the remote server responded with an error: wildcard (`*`) dependency constraints are not allowed on crates.io. See https://doc.rust-lang.org/cargo/faq.html#can-libraries-use--as-a-version-for-their-dependencies for more information

Done.
New version is published.
Does it look correct or did I miss something?

https://crates.io/crates/mdbook-epub/versions

Thanks. I updated to the new version

$ cargo install mdbook-epub --version 0.4.14-alpha.0

Now the version mismatch seems to be resolved but how can I solve this new error?

$ mdbook build
2022-01-07 11:31:02 [INFO] (mdbook::book): Book building has started
2022-01-07 11:31:02 [INFO] (mdbook::book): Running the epub backend
2022-01-07 11:31:02 [INFO] (mdbook::renderer): Invoking the "epub" renderer
thread 'main' panicked at 'Failed finding/fetch resource taken from content? Look up content for possible error...: Io(Os { code: 2, kind: NotFound, message: "No such file or directory" })', /Users/akira.hayakawa/.cargo/registry/src/github.com-1ecc6299db9ec823/mdbook-epub-0.4.14-alpha.0/src/generator.rs:170:48
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2022-01-07 11:31:03 [ERROR] (mdbook::renderer): Renderer exited with non-zero return code.
2022-01-07 11:31:03 [ERROR] (mdbook::utils): Error: Rendering failed
2022-01-07 11:31:03 [ERROR] (mdbook::utils): 	Caused By: The "epub" renderer failed

It should related to this part of the code.

    fn additional_assets(&mut self) -> Result<(), Error> {
        debug!("Embedding additional assets");

        let error = String::from("Failed finding/fetch resource taken from content? Look up content for possible error...");
        // resources::find can emit very unclear error based on internal MD content,
        // so let's give a tip to user in error message
        let assets = resources::find(self.ctx).expect(&error);

I don't know why it is trying to find a additional assets while I am not setting anything about it in config

[output.epub]

My thought on this is that the intention is early return if the assets are not found and it is a simple degrade from this patch 78d9927

You have some kind of embedded resource in the source MD file, like picture or similar...
You have to specify them explicitly in book.toml file like below

[output.epub]
cover-image = "img/book_cover.jpg"
additional-resources = ["img/ferris/does_not_compile.svg","img/ferris/not_desired_behavior.svg","img/trpl15-02.svg","img/trpl15-03.svg","img/trpl15-04.svg"]

so they will be processed correctly and embedded into epub. Much better to use RUST_LOG=debug because it gives better error reporting in log. That's up to you,

Folders look like that :
rustbook/book.toml
rustbook/src/img/ferris/does_not_compile.svg

@blandger

Not working yet.

Surprisingly, only adding output.epub to the dummy book works although Chapter1.md includes a path to an image. Why not needing additional-resources in this case?

$ git di
diff --git a/tests/dummy/book.toml b/tests/dummy/book.toml
index 02d506ee..d8242859 100644
--- a/tests/dummy/book.toml
+++ b/tests/dummy/book.toml
@@ -3,3 +3,5 @@ title = "DummyBook"
 authors = []
 multilingual = false
 src = "src"
+
+[output.epub]

Also, the example in README seems to indicate that the additional-resources should be some relative path starting from dot, which is not consistent with your advice above. Which is correct?

[output.epub]
additional-css = ["./path/to/main.css"]
use-default-css = false
cover-image = "ebook-cover.png"
additional-resources = ["./assets/Open-Sans-Regular.ttf"]

My book structure is like this which is normally renderable when output.epub lines are removed.

book.toml

// content of book.toml
src = "book-src"
[output.epub]
additional-resources = ["images/x.png"]

book-src
book-src/SUMMARY.md
book-src/x.md // includes images/y.png
book-src/images/y.png

Oh it is working!

I found one of my documents includes a path to web image. The error message is still not helpful.

Also, I finally realize we don't need to add all the images as long as they are found under src directory. My book now works with output.epub line only.

@akiradeveloper

dummy book works although Chapter1.md includes a path to an image. Why not needing additional-resources in this case?

As far as I remember internal logic makes two predictions about possible resource placement, like try to find relatively to /src or /root (if I'm not mistaken) and can find it 'silently'. If those two are failed the additional-resources can help to work around alternative placement. Otherwise it fails with error as you showed after first attempt.

...my documents includes a path to web image

Yes, that doesn't work. Some notes about external resources:
http://idpf.org/epub/30/spec/epub30-publications.html#sec-resource-locations

Closed.

Sad that Similar issue encountered with the 0.4.34 version from crates.io (with mirror rsproxy) fix by update mdbook to the 0.4.35 version

> cargo install mdbook-epub -f                                                                                                                          
   Compiling mdbook v0.4.35
   Compiling mdbook-epub v0.4.34                                                                                                                      
    Finished release [optimized] target(s) in 3m 24s
   Replacing D:\Program Files\.cargo\bin\mdbook-epub.exe
    Replaced package `mdbook-epub v0.4.25 (registry `rsproxy`)` with `mdbook-epub v0.4.34` (executable `mdbook-epub.exe`)
> mdbook build
2023-11-28 22:48:44 [INFO] (mdbook::book): Book building has started
2023-11-28 22:48:44 [INFO] (mdbook::book): Running the epub backend
2023-11-28 22:48:44 [INFO] (mdbook::renderer): Invoking the "epub" renderer
Running mdbook-epub as plugin...
[2023-11-28T14:48:44Z ERROR mdbook_epub] Incompatible mdbook version got 0.4.35 expected 0.4.26
2023-11-28 22:48:44 [ERROR] (mdbook::renderer): Renderer exited with non-zero return code.
2023-11-28 22:48:44 [ERROR] (mdbook::utils): Error: Rendering failed
2023-11-28 22:48:44 [ERROR] (mdbook::utils):    Caused By: The "epub" renderer failed
> rustup --version
rustup 1.26.0 (5af9b9484 2023-04-05)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.72.0 (5680fa18f 2023-08-23)`