#docs #import #comments #rustdoc #include

app rustdoc-include

A utility for importing external Markdown files into *.rs file as doc comments

1 unstable release

0.1.2 May 12, 2024

#180 in Development tools


778 lines


Crates.io Actions Status

A utility for importing external Markdown files into *.rs file as doc comments.


In Rust, you can use #[doc = include_str!("...")] to import external markdown files in your doc comments. However, when using this method to import code examples, the location of errors in the code examples will not be correctly reported.

For example, consider the following case:

// src/lib.rs
#![doc = include_str!("doc.md")]
# src/doc.md

running 1 test
test src\lib.rs - (line 4) ... FAILED


---- src\lib.rs - (line 4) stdout ----
error[E0425]: cannot find function `invalid_func` in this scope
 --> src\lib.rs:5:1
3 | invalid_func();
  | ^^^^^^^^^^^^ not found in this scope

The error location is reported as src/lib.rs:5 instead of src/doc.md:3, and IDE jump functionality will not work correctly.

rustdoc-include solves this problem by copying the documentation from markdown files and embedding it into *.rs files. Furthermore, after initially importing the documentation, you can easily synchronize the *.rs files with the markdown files by running rustdoc-include again.


You can install this tool with cargo install.

cargo install rustdoc-include


First, add // #[include_doc("{filepath}", start)] and // #[include_doc("{filepath}", end)] to the rust source code as follows

// #[include_doc("file.md", start)]
// #[include_doc("file.md", end)]
fn main() {}

Next, create a markdown file with the path specified in the comment you just added.

# Title

this is main function.

Run rustdoc-include with the --root option to specify the path to the directory containing rust source code and markdown file.

rustdoc-include --root ./

This tool will update the rust source code to look like this

// #[include_doc("file.md", start)]
/// # Title
/// this is main function.
// #[include_doc("file.md", end)]
fn main() {}

This tool replaces the area enclosed by // #[include_doc("{filepath}", start)] and // #[include_doc("{filepath}", end)] with the contents of the markdown file. So if you rerun the same command after updating the markdown file, you can synchronize the doc comment in the source code with the external markdown file.

Import doc comments for enclosing item

You can import an external file as a doc comment for the enclosing item by writing // #![include_doc(...)] instead of // #[include_doc(...)] as follows

// #![include_doc("file.md", start)]
// #![include_doc("file.md", end)]

Use relative path

The path to the imported markdown file can also be specified relative to the source file.

// #[include_doc("../dir/file.md", start)]
// #[include_doc("../dir/file.md", end)]

However, it is not possible to import files outside the directory specified by the --root option.

Restrict the scope of import

You can restrict the range to be imported by adding arguments to start and end for // #[include_doc("{filepath}", start)] and // #[include_doc("{filepath}", end)].


Specifies the starting line number of the range to be imported.

- line 1
- line 2
- line 3
// #[include_doc("file.md", start(2))]
// #[include_doc("file.md", end)]
fn main() {}
// #[include_doc("file.md", start(2))]
/// - line 2
/// - line 3
// #[include_doc("file.md", end)]
fn main() {}


Set the starting line of the range to be imported by specifying the text of that line.


Specifies the ending line number of the range to be imported.


Specifies the ending line of the range to be imported by specifying number of lines from the end.


Set the ending line of the range to be imported by specifying the text of that line.


This project is dual licensed under Apache-2.0/MIT. See the two LICENSE-* files for details.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


~169K SLoC