Break long table rows into multiple lines in documentation
Asked Answered
C

2

7

I want to document my crate and include a table in the documentation:

//! Demonstrating MarkDown tables.
//!
//! | Foo | Bar | Baz | Qux |
//! | --- | --- | --- | --- |
//! | Hail the turbofish `::<>` | Ferris for president πŸ¦€ | I can't think of any more "funny" things | oopsie |
//!

Rendering this with cargo doc results in:

correct table

This is what I want. However, you might have noticed that the one source code line is very long. In fact, over 100 characters long. Like many Rust projects, I want to keep all my lines under 100 characters long. So I tried to break the line somehow.

All of these versions:

//! | Foo | Bar | Baz | Qux |
//! | --- | --- | --- | --- |
//! | Hail the turbofish `::<>` | Ferris for president πŸ¦€ 
//! I can't think of any more "funny" things | oopsie |

//! | Foo | Bar | Baz | Qux |
//! | --- | --- | --- | --- |
//! | Hail the turbofish `::<>` | Ferris for president πŸ¦€ |
//! I can't think of any more "funny" things | oopsie |

//! | Foo | Bar | Baz | Qux |
//! | --- | --- | --- | --- |
//! | Hail the turbofish `::<>` | Ferris for president πŸ¦€
//! | I can't think of any more "funny" things | oopsie |

//! | Foo | Bar | Baz | Qux |
//! | --- | --- | --- | --- |
//! | Hail the turbofish `::<>` | Ferris for president πŸ¦€ |
//! | I can't think of any more "funny" things | oopsie |

//! | Foo | Bar | Baz | Qux |
//! | --- | --- | --- | --- |
//! | Hail the turbofish `::<>` | Ferris for president πŸ¦€ \
//! I can't think of any more "funny" things | oopsie |

Results in:

enter image description here

What options do I have to include long table rows in my documentation without violating the line length limit?

Canvasback answered 24/3, 2019 at 14:35 Comment(2)
rustdoc utilizes pulldown-cmark and there's no support for what you want. You have to use HTML as already answered. Or a) create separate .md files, prepare build.rs to convert .md -> .rs file (prepend //! or ///) and use include!, b) wait for Add external doc attribute to rustc or c) use nightly with rdoc. – Stingaree
@Stingaree Do you want to add that as an answer? You could just refer to the existing answer regarding HTML and provide a tiny example of how to use this external doc attribute. That would be neat :) – Canvasback
S
2

HTML

As already answered by Francis, you have to use HTML if you'd like to keep short lines. rustdoc utilizes pulldown-cmark and there's no support for what you want.

Include external documentation

nightly & doc

Tracking issue: rfc 1990 - add external doc attribute to rustc. In case of nightly toolchain, you can enable external_doc feature and include external Markdown files with #[doc(include = "../some/path")].

One thing to note - no matter in what module you will use #[doc(include = "...")], the path is always relative to the crate root (lib.rs, main.rs, ...).

Example:

.
|____Cargo.toml
|____Cargo.lock
|____doc
| |____foo-bar-bar.md
|____src
| |____main-hallo.md
| |____foo
| | |____mod.rs
| | |____bar.rs
| |____main.rs

src/main.rs:

#![feature(external_doc)]

pub mod foo;

#[doc(include = "main-hallo.md")]
pub fn hallo() {}

fn main() {}

src/foo/bar.rs:

#[doc(include = "../doc/foo-bar-bar.md")]
pub struct Bar;

You can keep separate Markdown documentation in the src/ folder, you can have it in a separate folder like doc/, etc. But the path is always relative to the crate root.

nightly & rdoc

There's also rdoc compiler plugin (requires nightly), which basically does the same thing. How to enable & use it is described in the project README.md.

stable

For stable, I'd do the following:

  • documentation in separate Markdown files,
  • custom build.rs which will scan for .md files and outputs them as .rs files (same content, just prepend every line with /// or //!),
    • put them in the std::env::var("OUT_DIR") folder,
  • include them in your source code,
    • via include!(concat!(env!("OUT_DIR"), "/main-hallo-md.rs"));.

rustfmt & nightly

There's comment_width option (defaults to 80) & wrap_comments option (defaults to false). This helps you to keep comments up to some width. But I tried it with the long Markdown table line and it wrapped it -> broken table. Don't use it.

Stingaree answered 30/3, 2019 at 15:37 Comment(1)
Great answer! Thanks for exploring all kinds of possible solutions. – Canvasback
L
5

Use HTML markup.

//! Demonstrating HTML tables.
//!
//! <table>
//!     <thead>
//!         <tr>
//!             <th>Foo</th>
//!             <th>Bar</th>
//!             <th>Baz</th>
//!             <th>Quux</th>
//!         </tr>
//!     </thead>
//!     <tbody>
//!         <tr>
//!             <td>Hail the turbofish <code>::&lt;></code></td>
//!             <td>Ferris for president πŸ¦€</td>
//!             <td>
//!                 I can't think of any
//!                 more "funny" things
//!             </td>
//!             <td>oopsie</td>
//!         </tr>
//!     </tbody>
//! </table>
Lodgings answered 24/3, 2019 at 15:23 Comment(0)
S
2

HTML

As already answered by Francis, you have to use HTML if you'd like to keep short lines. rustdoc utilizes pulldown-cmark and there's no support for what you want.

Include external documentation

nightly & doc

Tracking issue: rfc 1990 - add external doc attribute to rustc. In case of nightly toolchain, you can enable external_doc feature and include external Markdown files with #[doc(include = "../some/path")].

One thing to note - no matter in what module you will use #[doc(include = "...")], the path is always relative to the crate root (lib.rs, main.rs, ...).

Example:

.
|____Cargo.toml
|____Cargo.lock
|____doc
| |____foo-bar-bar.md
|____src
| |____main-hallo.md
| |____foo
| | |____mod.rs
| | |____bar.rs
| |____main.rs

src/main.rs:

#![feature(external_doc)]

pub mod foo;

#[doc(include = "main-hallo.md")]
pub fn hallo() {}

fn main() {}

src/foo/bar.rs:

#[doc(include = "../doc/foo-bar-bar.md")]
pub struct Bar;

You can keep separate Markdown documentation in the src/ folder, you can have it in a separate folder like doc/, etc. But the path is always relative to the crate root.

nightly & rdoc

There's also rdoc compiler plugin (requires nightly), which basically does the same thing. How to enable & use it is described in the project README.md.

stable

For stable, I'd do the following:

  • documentation in separate Markdown files,
  • custom build.rs which will scan for .md files and outputs them as .rs files (same content, just prepend every line with /// or //!),
    • put them in the std::env::var("OUT_DIR") folder,
  • include them in your source code,
    • via include!(concat!(env!("OUT_DIR"), "/main-hallo-md.rs"));.

rustfmt & nightly

There's comment_width option (defaults to 80) & wrap_comments option (defaults to false). This helps you to keep comments up to some width. But I tried it with the long Markdown table line and it wrapped it -> broken table. Don't use it.

Stingaree answered 30/3, 2019 at 15:37 Comment(1)
Great answer! Thanks for exploring all kinds of possible solutions. – Canvasback

© 2022 - 2024 β€” McMap. All rights reserved.