5个版本
0.1.4 | 2021年5月26日 |
---|---|
0.1.3 | 2021年5月26日 |
0.1.2 | 2021年5月26日 |
0.1.1 | 2021年5月26日 |
0.1.0 | 2021年5月26日 |
#210 in 图像
70,714 每月下载量
在 71 个crate中(直接使用45个) 使用
18KB
115 行
embed-doc-image
embed-doc-image
是一个proc宏crate,它简化了在Rust文档中嵌入图像的过程。
请参阅文档了解动机、使用说明等信息。
贡献
我乐意接受以拉取请求、错误报告或功能请求形式的贡献。
对于重大贡献,我更希望您首先提出一个issue,以便我们可以讨论所提议的更改是否合适。
致谢
作为一个经验不足的proc宏黑客,如果没有Rust编程语言社区Discord服务器上几位个人的帮助,我无法到达这个解决方案,特别是
- Yandros (github.com/danielhenrymantilla)
- Nemo157 (github.com/Nemo157)
许可证
本crate采用MIT许可证。有关详细信息,请参阅LICENSE
。
lib.rs
:
在文档中嵌入图像。
此crate允许在rustdoc
生成的文档中可移植地嵌入图像。应支持标准兼容网页的图像格式。如果您遇到问题,请提交一个issue。继续阅读以了解其工作原理。
展示
请参阅展示文档以了解带有嵌入图像的示例。
动机
一张图胜千言。这句经常被引用的谚语对于技术文档同样适用。精心制作的图表可以让新用户立即掌握复杂库的高层架构。几何惯例的插图可以大大减少科学库用户之间的混淆。尽管图像在技术文档中起着核心作用,但在 Rust 文档中嵌入图像,以便在不同本地安装和docs.rs上都能正确工作,一直是rustdoc 的长期问题。
这个crate代表了一个基于过程宏的精心解决方案,它绕过了当前rustdoc的限制,并实现了一种实际可行的便携式嵌入图像的方法。
如何在文档中嵌入图像
首先,您需要依赖这个crate。在cargo.toml
[dependencies]
// Replace x.x with the latest version
embed-doc-image = "x.x"
下一步取决于您是想将图像嵌入到内部属性文档还是外部属性文档。内部属性文档通常用于文档crate级或模块级的文档,通常以//!
开始每一行。外部属性文档用于大多数其他形式的文档,例如函数和结构体文档。外部属性文档通常以///
开始每一行。
在这两种情况下,所有图像路径相对于crate根目录。
在外部属性文档中嵌入图像
外部属性文档通常用于记录函数、结构体、特质、宏等。让我们考虑记录一个函数并将图像嵌入到其文档中
// Import the attribute macro
use embed_doc_image::embed_doc_image;
/// Foos the bar.
///
/// Let's drop an image below this text.
///
/// ![Alt text goes here][myimagelabel]
///
/// And another one.
///
/// ![A Foobaring][foobaring]
///
/// We can include any number of images in the above fashion. The important part is that
/// you match the label ("myimagelabel" or "foobaring" in this case) with the label in the
/// below attribute macro.
// Paths are always relative to the **crate root**
#[embed_doc_image("myimagelabel", "images/foo.png")]
#[embed_doc_image("foobaring", "assets/foobaring.jpg")]
fn foobar() {}
就是这样!如果您运行cargo doc
,您应该能够看到在foobar
的文档中您的图像,并且它也应该在没有问题的docs.rs
上工作。
在内部属性文档中嵌入图像
宏对内部属性做任何事情的能力非常有限。事实上,在撰写本文时,Rust 1.54(当时尚未发布)之前,实际上并不存在。这也意味着我们无法直接使用我们的方法来嵌入 Rust < 1.54 的文档中的图像。然而,我们可以使我们的代码在 Rust < 1.54 下编译,并注入一条显眼的提示信息,表明某些图像丢失。docs.rs
,它始终使用夜间编译器,将能够显示图像。只要我们使用 Rust >= 1.54(或夜间),我们也将能够在本地正确嵌入图像。以下是您如何在crate级或模块级文档中嵌入图像的方法
//! My awesome crate for fast foobaring in latent space.
//!
// Important: note the blank line of documentation on each side of the image lookup table.
// The "image lookup table" can be placed anywhere, but we place it here together with the
// warning if the `doc-images` feature is not enabled.
#![cfg_attr(feature = "doc-images",
cfg_attr(all(),
doc = ::embed_doc_image::embed_image!("myimagelabel", "images/foo.png"),
doc = ::embed_doc_image::embed_image!("foobaring", "assets/foobaring.png")))]
#![cfg_attr(
not(feature = "doc-images"),
doc = "**Doc images not enabled**. Compile with feature `doc-images` and Rust version >= 1.54 \
to enable."
)]
//!
//! Let's use our images:
//! ![Alt text goes here][myimagelabel] ![A Foobaring][foobaring]
遗憾的是,目前无法在cfg_attr
中检测 Rust 版本。因此,我们必须依靠功能标志来切换合适的图像嵌入。我们需要在Cargo.toml
中添加以下内容
[features]
doc-images = []
[package.metadata.docs.rs]
# docs.rs uses a nightly compiler, so by instructing it to use our `doc-images` feature we
# ensure that it will render any images that we may have in inner attribute documentation.
features = ["doc-images"]
让我们总结一下
docs.rs
将正确渲染我们的文档,并包含图像。- 本地
- 对于 Rust >= 1.54,使用
--features doc-images
,本地文档将正确渲染图像。 - 对于 Rust < 1.54:本地文档将缺少一些图像,并将包含一条警告,说明如何启用合适的图像嵌入。
- 我们也可以使用例如
cargo +nightly doc --features doc-images
来生成使用夜间编译器的正确文档。
- 对于 Rust >= 1.54,使用
它是如何工作的
问题的核心是 rustdoc
没有跟踪本地存储的图像以及将其携带到最终文档的机制。因此,目前 docs.rs
上的图像只能在互联网上某处托管图像,并通过其URL包含图像。然而,这存在许多问题。
- 您需要托管图像,这给crate作者带来了相当多的额外工作。
- 图像仅在其托管期间可用。
- 在没有互联网访问的情况下,本地文档中的图像将无法工作。
- 除非作者手动仔细处理,否则图像不会进行版本控制。也就是说,作者必须仔细提供crate所有版本的图像,并使用一致的命名约定,以确保旧版本crate的文档显示与特定版本一致的图像。
该crate采用的解决方案基于2017年一个Reddit评论中的评论。简而言之,Rustdoc允许以以下方式在Markdown中提供图像
![Alt text][myimagelabel]
[myimagelabel]: data:image/png;base64,BaSe64EnCoDeDdAtA
基本上,我们可以使用Markdown链接/图像的"参考"功能,在图像本身所在位置之外提供图像的URL,但我们不是提供URL,而是在Markdown文档中直接提供图像的二进制数据。
然而,手动使用图像做这件事会极大地杂乱文档,这似乎不太理想。相反,我们以编程的方式进行。这个crate中可用的宏本质上遵循这个想法
- 输入一个相对于crate根的标签和图像路径。
- 确定MIME类型(基于扩展名)和
base64
编码的图像。 - 生成适当的文档字符串,并将其注入crate/函数/结构体等的Markdown文档中。
显然,这仍然相当黑客式,但似乎是一个可行的解决方案,直到rustdoc
提供适当的支持,到那时我们可能会感到高兴,并把这个crate遗留在历史长河中。
致谢
作为一个经验不足的proc宏黑客,如果没有Rust编程语言社区Discord服务器上几位个人的帮助,我无法到达这个解决方案,特别是
- Yandros (github.com/danielhenrymantilla)
- Nemo157 (github.com/Nemo157)
依赖项
~1.5MB
~40K SLoC