# Rustdoc: include an external markdown file as a \*separate\* page

**URL:** <https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994>\
**Category:** tools and infrastructure\
**Created:** [January 20, 2022, 11:22am UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994 "2022-01-20T11:22:57Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kixunil](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kixunil/32/4110_2.png) [@Kixunil](https://internals.rust-lang.org/u/Kixunil)\
**Post date:** [January 20, 2022, 11:22am UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/1 "2022-01-20T11:22:58Z")

</div>

Maybe this already exists but I tried to search and didn't find anything so I assume it doesn't (or is, ironically, undocumented). I would like to have some way of including a markdown file or a set (directory) of files to extend the documentation with more in-depth explanations on separate pages.

I'm writing a crate that's a bit more complicated than usual but also not so complicated to require serde.rs-style documentation. I'd prefer to have the extended doc in a separate page generated by rustdoc so that those who already know general ideas and only need to look up e.g. item names are not bothered with tutorial-level documentation.

There are multiple advantages:

- All docs in single page, single style people don't have to jump around too much
- The doc is included in the source code so anyone can render it locally
- Doesn't depend on web-based VCS third parties like github (nothing wrong with github IMO, just nice to not rely on it)
- People don't have to worry too much about HTML style/formatting/etc.
- Currently making an empty module with documentation seems like the best hack but it's clearly a hack.

Possible disadvantages:

- People could abuse it to publish non-crate things but [this is already happening](https://docs.rs/dtolnay/latest/dtolnay/) and doesn't seem too bad. At least it'd look nicer. 🙂
- Added complexity. I think it shouldn't be too bad, all the things required are already in rustdoc, they just have to be rewired appropriately.
- People could be confused and accidentally put there things that belong to API documentation. However people can write bad or even missing doc already, so it's not a good argument.

---

<div class="post-metadata">

**Author:** ![shanesveller](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/shanesveller/32/4694_2.png) [@shanesveller](https://internals.rust-lang.org/u/shanesveller)\
**Post date:** [January 20, 2022, 1:58pm UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/2 "2022-01-20T13:58:08Z")

</div>

As a user I don't have a strong opinion one way or another, but to share an example of prior art, [HexDocs](https://hexdocs.pm) is the equivalent of `rustdoc` for the Elixir ecosystem and is powered by the [ExDoc](https://github.com/elixir-lang/ex_doc) library, and authors may include "Guide" pages to offer things like tours, tutorials, and prose explanations around practices.

As a specific example I think the [documentation](https://hexdocs.pm/absinthe/start.html#background) for the Absinthe package capitalized on it nicely, as it offers a lot of instructive content that don't intuitively relate directly to specific code modules. Including it there rather than on a bespoke, separate documentation site means the other features of the documentation, such as interlinking, are still readily available.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [January 20, 2022, 3:40pm UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/3 "2022-01-20T15:40:29Z")

</div>

Yes, that would be useful. Another case of a hack:

> **[cargo\_crev::doc::user - Rust](https://docs.rs/cargo-crev/latest/cargo_crev/doc/user/index.html)**
>
> User documentation

---

<div class="post-metadata">

**Author:** ![Kixunil](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kixunil/32/4110_2.png) [@Kixunil](https://internals.rust-lang.org/u/Kixunil)\
**Post date:** [January 20, 2022, 4:53pm UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/4 "2022-01-20T16:53:31Z")

</div>

That docs look really cool! I'd be happy to see something like that in Rust.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [January 20, 2022, 6:27pm UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/5 "2022-01-20T18:27:34Z")

</div>

FWIW, docs-rs [already has a separate documentation page from the API docs](https://docs.rs/crate/serde/latest). I think it'd be useful to have an officially supported place to put "guide-level"/"book" documentation within the `cargo doc` ecosystem, but I also think that having the API documentation clearly separate from the guide documentation (though both can and should cross-link) is useful.

It's kind of sad that [doxidize](https://steveklabnik.github.io/doxidize/design-guide.html) died off. (Though I'm glad that rustdoc got easier enough to contribute to that it _could_ die off!) In a perfect world, doxidize could've been that tool. From its design docs:

> Many Rust users love Rustdoc, so why change the way it works? The core reason is this:
> 
> > Rustdoc is designed for API documentation, and does a great job of it. But there's more to docs than just API docs. Doxidize is built to consider all forms of documentation your project needs.
> 
> This perspective means that Doxidize has to make several different decisions from `rustdoc` . Namely, while `rustdoc` has just barely grown to understand documentation written outside of Rust source, Doxidize was built around this idea. This means that the API docs adapt to the more general needs of docs, rather than fitting all docs into API docs.

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [January 20, 2022, 9:22pm UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/6 "2022-01-20T21:22:33Z")

</div>

There's some previous issues about integrating mdBook into either of `rustdoc` or docs.rs that are probably relevant.

I do somewhat feel like being able to include single markdown pages (_not_ a tree of pages, only as leaf pages below an existing item) might be useful enough as a middleground to support; in addition to having the ability for more complex mdBook backed documents.

> <https://github.com/rust-lang/rust/issues/66249>
>
> It doesn't seem to be possible to include external markdown files without using …\`include\_file!\`. By this I mean your file would have to be included in your code hierarchy and it's not possible to have it as a separate hierarchy.
> 
> This could be useful for getting-started (even though usually included in the README), debugging-tips, or various tutorials.
> 
> A few ideas where this could be used:
> \- Be able to point rustdoc to some folder with markdown files, and it would render them all for the user to use freely in the code as normal links
> \- Added as an entry in the left column alongside Module, Structs, Enums, etc. Either a single entry to an index that the user would have to create, or a custom hierarchy that the user would define.

> <https://github.com/rust-lang/docs.rs/issues/1293>
>
> \# Motivation
> 
> One of the best aspects of docs.rs is that it encourages develop…ers to create high-quality API-focused documentation by removing roadblocks around building and hosting the generated content.
> 
> I think it would be wonderful to extend this concept to building and hosting longer-form documentation produced by mdBook. This will encourage developers to produce this style of content as a complement to the rustdoc-generated documentation.
> 
> \# Guide-level explanation
> 
> 1. Add this to your Cargo.toml:
> 
> \`\`\`toml
> \[package.metadata.docs.rs\]
> mdbook = "some-subdir"
> \`\`\`
> 
> 1. Push your code to crates.io
> 
> 1. After a bit, visit \`https://docs.rs/book/crate-name/x.y.z\`
> 
> \# Drawbacks
> 
> \- Increased load on the build machines.
> - May be negligible compared to building dependencies
> \- Increased crate sizes
> - Text content isn't that big, but books may include media like images. 
> 
> \# Unresolved questions
> 
> \- How do we make access to the book "obvious"?
> - Suggestion: Make it another tab in the top bar
> - Suggestion: Make it another button next to 'Documentation'
> \- How do we handle different themes between rustdoc and mdBook?
> - Suggestion: Don't worry about it, allow them to differ
> - Suggestion: Add "rustdoc dark theme" and "rustdoc light theme" to mdBook, only enable those themes + ayu (the common themes) when generating the book
> \- How frequently can books be built?
> - Suggestion: Only when crates are pushed
> \- How does a user access the book content?   
> - Suggestion: \`https://docs.rs/book/crate-name/x.y.z\`
> - Suggestion: \`https://docs.rs/crate-name/book/x.y.z\`
> - Suggestion: \`https://docs.rs/crate-name/x.y.z/book-name\` (where \`book-name\` is the name of the book, not a hard-coded string)
> \- How does the builder access the book source?
> - Suggestion: The book source code is packaged with the crate uploaded to crates.io
> \- Do we support multiple versions of mdBook?
> - Suggestion: Only support the latest version
> \- Do we support mdBook plugins?
> - Suggestion: None to start with
> \- Do we support multiple books per crate?
> - Suggestion: Only support one book. Books can have sections, multiple crates can be uploaded, or people can perform their own hosting. 
> \- How do we bind the JS events for the theme change? Should we limit it to the book or apply it to the rest of docs.rs too?
> 
> \# Future possibilities
> 
> \- Improve the UX on docs.rs to make the integration better
> 
> \---
> 
> Please feel free to edit this summary comment!

---

<div class="post-metadata">

**Author:** ![epage](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/epage/32/3171_2.png) [@epage](https://internals.rust-lang.org/u/epage)\
**Post date:** [January 20, 2022, 10:13pm UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/7 "2022-01-20T22:13:43Z")

</div>

Count [clap in as another use case](https://github.com/clap-rs/clap/issues/3189) which is similar to the serde case.

Things on the list needed for clap (independent of the implementation details, like using mdBook):

- Intra-doc links:
  - The [derive reference](https://github.com/clap-rs/clap/tree/master/examples/derive_ref) makes many references to parts of the clap API that would be helped by being able to link
  - Each of the traits that can be derived link to the derive reference and we need a maintainable way of keeping this (we don't put the documentation on the traits because its large and cross-cutting)

- Sourcing external files (speaking of mdBook). Clap's documentation has large examples that need more testing than standard rustdoc tests can provide. Our `md` pages that would be pulled in with this proposal currently link out to those files. This isn't ideal today and, depending on how this proposal is implemented, those links would then break. Of course bringing along the `.rs` files is a stopgap but the ideal is sourcing them like you can do in mdBook. Having seen serde's mdBook documentation, I'm assuming they'd get value from this as well.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [April 20, 2022, 10:14pm UTC](https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/8 "2022-04-20T22:14:34Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
