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 图像

Download history 26405/week @ 2024-03-14 19800/week @ 2024-03-21 31444/week @ 2024-03-28 21324/week @ 2024-04-04 19877/week @ 2024-04-11 23069/week @ 2024-04-18 21917/week @ 2024-04-25 19599/week @ 2024-05-02 20246/week @ 2024-05-09 28987/week @ 2024-05-16 22107/week @ 2024-05-23 22114/week @ 2024-05-30 16126/week @ 2024-06-06 15152/week @ 2024-06-13 19281/week @ 2024-06-20 15866/week @ 2024-06-27

70,714 每月下载量
71 个crate中(直接使用45个) 使用

MIT 许可证

18KB
115

embed-doc-image

embed-doc-image 是一个proc宏crate,它简化了在Rust文档中嵌入图像的过程。

请参阅文档了解动机、使用说明等信息。

贡献

我乐意接受以拉取请求、错误报告或功能请求形式的贡献。

对于重大贡献,我更希望您首先提出一个issue,以便我们可以讨论所提议的更改是否合适。

致谢

作为一个经验不足的proc宏黑客,如果没有Rust编程语言社区Discord服务器上几位个人的帮助,我无法到达这个解决方案,特别是

许可证

本crate采用MIT许可证。有关详细信息,请参阅LICENSE


lib.rs:

在文档中嵌入图像。

此crate允许在rustdoc生成的文档中可移植地嵌入图像。应支持标准兼容网页的图像格式。如果您遇到问题,请提交一个issue。继续阅读以了解其工作原理。

展示

请参阅展示文档以了解带有嵌入图像的示例。

请还检查源代码,以了解展示crate的完整示例。

动机

一张图胜千言。这句经常被引用的谚语对于技术文档同样适用。精心制作的图表可以让新用户立即掌握复杂库的高层架构。几何惯例的插图可以大大减少科学库用户之间的混淆。尽管图像在技术文档中起着核心作用,但在 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来生成使用夜间编译器的正确文档。

它是如何工作的

问题的核心是 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服务器上几位个人的帮助,我无法到达这个解决方案,特别是

依赖项

~1.5MB
~40K SLoC