rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.67k stars 12.75k forks source link

Include images in rustdoc output #32104

Open emoon opened 8 years ago

emoon commented 8 years ago

As written by Luthaf over here

https://users.rust-lang.org/t/include-images-in-rustdoc-output/3487

"Hi rustaceans!

Images in documentation can be really useful to provide some insight on algorithms or modules organisation.

It is already possible to insert a link to an image in documentation comment

/// ![Alt version](url://for/this/image.png)

But using this method, we only get to include images already available in some place of Internet.

Is it a way to make rustdoc copy some files to the target/doc folder, so that it is easy to include specific images in the documentation? The same could go for other static files, like specific CSS or JS.

Is it possible yet? If not, do you think it is worth it?"

I this this would be awesome to include as sometimes using images is much easier when explain something than showing text.

bluss commented 8 years ago

I second this, images can greatly help explaining (geometrical split_at example).

jimblandy commented 6 years ago

Since the focus is on doxidize now, rustdoc is in maintenance-only mode. Should this be closed?

cc: @steveklabnik

steveklabnik commented 6 years ago

I'd say "maintenance-only" mode is a bit strong; rustdoc has its own team and they're still working on new stuff. It's entirely possible that this will get added to rustdoc.

TotalKrill commented 6 years ago

Would love this as well! Has there been any updates?

ZhangHanDong commented 5 years ago

It‘s work

//! <div>
//! <img src="../../../images/rustbook.jpg" height="300" width="220" />
//! </div>
//! <hr/>
crepererum commented 5 years ago

That only works locally if you're building the docs for your own crate. Does not work on docs.rs or if the crate is a dependency of something else.

Background: The referred image is not copied / tracked.

ZhangHanDong commented 5 years ago

@crepererum you're right. One solution is to separate the doc file and manually modify it.

crepererum commented 5 years ago

Or you host the image somewhere, like on GitHub pages (that's what ndarray is doing here https://github.com/rust-ndarray/ndarray/blob/master/src/impl_views.rs )

TotalKrill commented 5 years ago

I think what would be most optimal is if there could be a folder where images for the doc could be stored in the crate folder structure.

There is one huge painpoint here though, and that is a lot of people just love to generate extremely large pictures to include in the crates. For no reason: ClickBait article with example

So if this should be in the code, the file size should be limited.

donbright commented 5 years ago

There is a workaround.

You can insert the image data, base64 encoded, directly into your rust source code comments, and rust-doc will pass this to the html, where it will become an inline image in the html code. This is based on rfc2397 aka the data URI.

http://www.bigfastblog.com/embed-base64-encoded-images-inline-in-html https://tools.ietf.org/html/rfc2397

$ base64 ../images/mypicture.png  | awk ' { print "/// " $1 } ' > myfile.b64
myfile.rs:

/// my function does blah blah blah. here is a picture:
/// <div>
/// <img src="data:image/png;base64,
/// iVBORw0KGgetcetcetc                       <-- copy/paste myfile.b64 here
/// ....                                      <-- several dozen lines of myfile.b64
/// JDIOIDondio00778==                        <-- last line of myfile.b64
/// ">
/// </div>
fn myfunction(x:u64)->bool { x<5 }
$ cargo doc

Now the html file under target/whatever will have the png image baked inside of it as base64 code.

I think this might be possible with svg but havent tested.


I think it might be nice to consider if rustdoc could do this on it's own, automatically, taking a <img src=../../image.png file, encoding it as base64, and inline it into the html file itself, without the user having to insert base64 directly into their rust comments.

GuillaumeGomez commented 4 years ago

I don't think this is a good idea: it'd force rustdoc to download the content to know if it's an image or a video or anything else. Also, from a security perspective, I think this wouldd be an issue as well (cc @pietroalbini ).

pietroalbini commented 4 years ago

From my point of view it'd be fine if rustdoc included images present in the crate's source tarball into the generated docs. It definitely should not download images from the Internet.

GuillaumeGomez commented 4 years ago

I don't see the difference between local image and one from the internet. In both case, it can't be trusted.

TotalKrill commented 4 years ago

Well then, I am guessing the current way to input it into a comment as base64 isnt much different.

The end result should still be an image shown online, wherever it is a link to an image, or an image generated from base64.

Nothing can be trusted anywhere, but still we do it.

pietroalbini commented 4 years ago

I don't see the difference between local image and one from the internet. In both case, it can't be trusted.

You can do the same thing with workarounds today, and you'll still be able to do it with workarounds in the future. Besides, it's a legit feature request.

GuillaumeGomez commented 4 years ago

Indeed, I don't know why but I was kinda confusing the URL thing... Then yes, it'll require to move the file content to a given target and be sure to not have conflicts. Urg... Headache ahead! I'll try to do it in not too long from now.

Luthaf commented 4 years ago

Then yes, it'll require to move the file content to a given target and be sure to not have conflicts.

A possible solution for this would be to hash the image content, move them to target/doc/{crate}/static-img/{hash}.{ext}, and rewrite the links in the generated HTML accordingly. (static-img not being a valid module name should not clash with other files)

GuillaumeGomez commented 4 years ago

If I hash the path, it might be easier, indeed. I didn't want to create another folder but that would fix the naming conflict so I think I'll do that. Thanks for the tips!

Luthaf commented 4 years ago

I would rather hash the file content than the path, since the same file might be referred to by different .rs files, using different paths.

tspiteri commented 4 years ago

With this feature, would it also be possible to link to a file included in the crate inside the doc(html_root_url) attribute?

dherman commented 3 years ago

I ran into this today and would love to see it happen. @GuillaumeGomez is this something I could help with? I've never contributed to rustdoc before but if you'd be interested in mentoring me maybe I could help implement it?

GuillaumeGomez commented 3 years ago

It's a tricky issue on many aspects. I tried a first implementation as you can see in #68734. But honestly, I'm not sure if this is a good idea as a first contribution on rustdoc because a lot of questions are not really answered... I prefer to say this so you know what you're stepping into before spending a lot of time working on it. But if you still want to give it a try, maybe take a quick look at #68734 and go for it!

dherman commented 3 years ago

I appreciate the warning 😅 I'll take a look!

TornaxO7 commented 3 years ago

Is there any process yet? I'd like to add some images into the docs as well :)

phoekz commented 3 years ago

In addition to images, I also would love to add small GIFs and videos. I am currently using this workaround for my local docs:

/// <div>
///   <video width="640" autoplay muted loop>
///     <source src="../../../my-video.mp4" type="video/mp4">
///   </video>
/// </div>
Dirbaio commented 2 years ago

If your image is a SVG, you can include it directly with include_str!, as SVG is valid HTML.

//! # BLahblah
//! 
//! blahblah
//!
#![doc=include_str!("shared-bus.svg")]
//!
//! blahblahblah
TotalKrill commented 2 years ago

We should encourage usage of SVG as format in documentation output, it is a well working format for block-diagrams, flowcharts and similar things that are actually useful for documentation purposes.

Nice tip though!

Andlon commented 2 years ago

If you can rely on Rust >= 1.54, then using embed-doc-image is also similarly simple:

/// A diagram of something
///
/// ![Diagram](diagram_label)
/// 
/// The rest of the docs.
#![doc = embed_image!("diagram_label", "images/diagram.png")]

This should work with all major file formats supported on the web, and works both locally and on docs.rs. The example code in the docs is much more complex because they explain how to have a graceful fallback to Rust < 1.54. If you don't need this then it's simple to use. I should probably update the docs with the simpler case first.

Admittedly the crate could still need some improvements in terms of conditionally enabling the feature (so that, for example, for non-doc builds you can easily skip the embed macro compilation). I'm too pressed on time for doing that myself atm, but it wouldn't take too much effort to improve further - though there should probably be a brief discussion about design first.

GuillaumeGomez commented 2 years ago

You can make it generate cfg(doc) and it'll only be generated when rustdoc is running.

Andlon commented 2 years ago

@GuillaumeGomez: that sounds perfect. Seems like cfg(doc) has not been stabilized yet, is this correct? According to https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html.

GuillaumeGomez commented 2 years ago

doc(cfg()) != cfg(doc). :wink: It's been stable for a while now. There is also cfg(doctest) (which is when you run rustdoc --test).

GuillaumeGomez commented 2 years ago

The documentation is here.

Andlon commented 2 years ago

@GuillaumeGomez: that's very interesting! I was led to believe otherwise by the following sentence in the unstable book (see link above):

image

I couldn't find out when cfg(doc) was stabilized. This would be useful info for documenting a fallback solution. Do you know where to find this info?

While this cfg directive seems very useful in the context of embedding images, it doesn't directly solve the issue of embed-doc-image, which is that you'll end up including syn and some other dependencies in your non-doc builds. I believe it's not possible to conditionally enable a Cargo feature only for doc builds somehow, is it?

EDIT: It would however lead to an improvement in the sense that no doc-related code is generated for non-doc builds, other than having to build the dependencies.

GuillaumeGomez commented 2 years ago

No even though there is an open issue about that on cargo. But it hasn't received much attention unfortunately.

As for cfg(doc), it's stable since 1.40.

GuillaumeGomez commented 2 years ago

And here is the cargo issue.

GuillaumeGomez commented 1 year ago

I opened an RFC for this feature: https://github.com/rust-lang/rfcs/pull/3397

ryanpeach commented 9 months ago

This is how I did it in Github Actions, not complicated, might not be worth a full RFC. However, it would be nice if rustdoc could do this natively so it could check if the image link is valid. https://github.com/ryanpeach/OrbitingSandRust/pull/102

GuillaumeGomez commented 9 months ago

Sure, it works in your CI, but how does it work for crates depending on yours? Are your images included into your crate package? If so you're doing something very wrong.

ryanpeach commented 9 months ago

Just including my PR so that others looking for a more immediate solution who find this on google can see an example.

frewsxcv commented 8 months ago

Sure, it works in your CI, but how does it work for crates depending on yours? Are your images included into your crate package? If so you're doing something very wrong.

Is there a particular issue with including images in a crate package besides size?

GuillaumeGomez commented 8 months ago

Not that I can think of. The RFC is currently on hold until the potential cargo archive format becomes a reality (as mentioned here).

frewsxcv commented 8 months ago

If so you're doing something very wrong.

@GuillaumeGomez So if this is the only way to do it, then why is it "very wrong"?

GuillaumeGomez commented 8 months ago

I answered (too aggressively) to:

This is how I did it in Github Actions, not complicated, might not be worth a full RFC. However, it would be nice if rustdoc could do this natively so it could check if the image link is valid. https://github.com/ryanpeach/OrbitingSandRust/pull/102

In particular this part:

might not be worth a full RFC

The fact that we might includes megabytes (if not more) of data by default only for documentation sounds like something that should be very carefully considered.