toolkit for mdBook [mirror of my GitHub repo] docs.tonywu.dev/mdbookkit/
permalinks rust-analyzer mdbook
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: update docs (WIP)

Tony Wu 8063d291 11129c54

+536 -739
-2
crates/mdbook-rustdoc-links/src/tests/ra-known-quirks.md
··· 13 13 14 14 # macro_export 15 15 16 - - [std::vec!] 17 - - [std::format!] 18 16 - [tokio::main!]
+32 -26
crates/mdbook-rustdoc-links/src/tests/snaps/getting-started.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 61 3 4 expression: output 4 5 --- 5 6 # Getting started 6 7 7 - Follow these steps to start using `mdbook-rustdoc-link` in your book project! 8 - 9 8 ## Install 10 9 11 10 You will need to: 12 11 13 - 1. Have [rust-analyzer]: 12 + 1. Have [rust-analyzer].: 14 13 15 - - If you already use the [VS Code extension][ra-extension]: this crate automatically 16 - uses the server binary that comes with it, no extra setup is needed! 17 - - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure 18 - it's on your `PATH`. 14 + - If you already use the [VS Code extension][ra-extension], no setup is required: the 15 + preprocessor automatically uses the server binary packaged with it. 16 + - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure it 17 + is available on `PATH`. 19 18 20 - 2. Install this crate: 19 + 2. Install the preprocessor: 21 20 22 21 ``` 23 22 cargo install mdbookkit --features rustdoc-link 24 23 ``` 25 24 26 - Or you can grab precompiled binaries from [GitHub releases][gh-releases]. 25 + Alternatively, you may obtain precompiled binaries from [GitHub 26 + releases][gh-releases]. 27 + 28 + <!-- TODO: cargo binstall --> 27 29 28 30 ## Configure 29 31 30 - Configure your `book.toml` to use it as a [preprocessor]: 32 + Configure your `book.toml` to use the installed program as a [preprocessor]: 31 33 32 34 ```toml 33 35 [book] ··· 36 38 [preprocessor.rustdoc-link] 37 39 # mdBook will run `mdbook-rustdoc-link` 38 40 after = ["links"] 39 - # recommended, so that it can see content from {{#include}} as well 41 + # mdBook will run this preprocessor after the default `links` preprocessor. 42 + # This is recommended. It allows the preprocessor to see text embedded 43 + # via {{#include}} directives. 40 44 ``` 41 45 42 46 ## Write 43 47 44 - In your documentation, when you want to link to a Rust item, such as a type, a function, 45 - etc., simply use its name in place of a URL, like this: 48 + In your documentation, where you want to link to a Rust item, such as a type, a 49 + function, etc., simply use its name in place of a URL: 46 50 47 51 ```md 48 52 Like [`std::thread::spawn`], [`tokio::task::spawn`] returns a 49 53 [`JoinHandle`][tokio::task::JoinHandle] struct. 50 54 ``` 51 55 52 - The preprocessor will then turn them into hyperlinks: 56 + The preprocessor will convert such symbols into hyperlinks: 53 57 54 58 <figure class="fig-text"> 55 59 ··· 58 62 59 63 </figure> 60 64 61 - This works in both `mdbook build` and `mdbook serve`! 65 + The preprocessor runs in both `mdbook build` and `mdbook serve`. 62 66 63 67 ![screen recording of mdbook-rustdoc-link during mdbook build](media/screencap.webp) 64 68 65 - To read more about this project, feel free to return to [Overview](index.md#overview). 66 - 67 69 > [!IMPORTANT] 68 70 > 69 - > It is assumed that you are running `mdbook` within a Cargo project. 71 + > It is assumed that you are running mdBook from within a Cargo project. 70 72 > 71 73 > If you are working on a crate, and your book directory is within your source tree, 72 - > such as next to `Cargo.toml`, then running `mdbook` from there will "just work". 74 + > such as next to `Cargo.toml`, then running mdBook from there will "just work". 73 75 > 74 - > If your book doesn't belong to a Cargo project, refer to 75 - > [Workspace layout](workspace-layout.md) for more information on how you can setup up 76 - > the preprocessor. 76 + > If your book doesn't reside within a Cargo project, refer to 77 + > [Workspace layout](workspace-layout.md) for instructions on setting up the 78 + > preprocessor. 77 79 78 80 > [!TIP] 79 81 > ··· 82 84 > 83 85 > Items from `std` will generate links to <https://doc.rust-lang.org>, while items from 84 86 > third-party crates will generate links to <https://docs.rs>. 85 - > 86 - > So really, rust-analyzer is doing the heavy-lifting here. This crate is just the glue 87 - > code :) 87 + 88 + ## Next steps 89 + 90 + - See the full list of [supported syntax](supported-syntax.md). 91 + - Understand [how the preprocessor resolves links](name-resolution.md) under the hood. 92 + - Check out [available configuration options](configuration.md). 93 + - Learn about some [known issues and limitations](known-issues.md). 88 94 89 95 <!-- prettier-ignore-start --> 90 96
+3 -2
crates/mdbook-rustdoc-links/src/tests/snaps/getting-started.stderr.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 76 3 4 expression: report 4 5 --- 5 6 info: successfully resolved all links 6 - ╭─[getting-started:52:6] 7 + ╭─[getting-started:55:6] 7 8 8 9 │ Like [`std::thread::spawn`], [`tokio::task::spawn`] returns a 9 10 · ───────────┬────────── ───────────┬──────────
+13 -14
crates/mdbook-rustdoc-links/src/tests/snaps/index.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 61 3 4 expression: output 4 5 --- 5 6 # mdbook-rustdoc-link ··· 11 12 12 13 </div> 13 14 14 - **[_rustdoc_-style linking][rustdoc] for [mdBook]** (with the help of [rust-analyzer]). 15 + Link to Rust API docs by name in [mdBook], [_rustdoc_-style][rustdoc]. 15 16 16 - You write: 17 + Instead of manually finding and pasting URLs, you simply write ... 17 18 18 19 ```md 19 20 The [`option`][std::option] and [`result`][std::result] modules define optional and ··· 22 23 collections. [^1] 23 24 ``` 24 25 25 - You get: 26 + ... and you will get: 26 27 27 28 <figure class="fig-text"> 28 29 ··· 33 34 34 35 </figure> 35 36 36 - `mdbook-rustdoc-link` is an mdBook [preprocessor]. Using rust-analyzer, it converts type 37 - names, module paths, and so on, into links to online crate docs. No more finding and 38 - pasting URLs by hand. 39 - 40 37 <figure> 41 38 42 39 ![screen recording of mdbook-rustdoc-link during mdbook build](media/screencap.webp) 43 40 44 41 </figure> 45 42 43 + > [!NOTE] 44 + > 45 + > This preprocessor depends on [rust-analyzer] to accurately resolve Rust items. 46 + 46 47 ## Overview 47 48 48 - To get started, simply follow the [quickstart guide](getting-started.md)! 49 - 50 - If you would like to read more about this crate: 49 + Follow the [quickstart guide](getting-started.md) to try out the preprocessor. 51 50 52 51 For **writing documentation** — 53 52 54 - - To learn more about how it is resolving items into links, including 53 + - To learn more about how the preprocessor resolves items into links, including 55 54 [feature-gated items](name-resolution.md#feature-gated-items), see 56 55 [Name resolution](name-resolution.md). 57 - - To know how to link to other types of items like 56 + - To learn how to link to additional items such as 58 57 [functions, macros](supported-syntax.md#functions-and-macros), and 59 58 [implementors](supported-syntax.md#implementors-and-fully-qualified-syntax), see 60 59 [Supported syntax](supported-syntax.md). 61 60 62 - For **adapting this crate to your project** — 61 + For **making the preprocessor work with your project** — 63 62 64 63 - If you use [Cargo workspaces][workspaces], see specific instructions in 65 64 [Workspace layout](workspace-layout.md).
+48 -46
crates/mdbook-rustdoc-links/src/tests/snaps/known-issues.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 61 3 4 expression: output 4 5 --- 5 6 # Known issues 6 7 7 - <details class="toc" open> 8 - <summary>Sections</summary> 9 - 10 - - [Performance](#performance) 11 - - [Incorrect links](#incorrect-links) 12 - - [Macros](#macros) 13 - - [Trait items](#trait-items) 14 - - [Private items](#private-items) 15 - - [Unresolved items](#unresolved-items) 16 - - [Associated items on primitive types](#associated-items-on-primitive-types) 17 - - [Sites other than docs.rs](#sites-other-than-docsrs) 18 - - [Wrong line numbers in diagnostics](#wrong-line-numbers-in-diagnostics) 19 - 20 - </details> 21 - 22 8 ## Performance 23 9 24 10 `mdbook-rustdoc-link` itself doesn't need much processing power, but it invokes 25 - rust-analyzer, which does a full scan of your workspace. The larger your codebase is, 26 - the longer `mdbook` will have to wait for the preprocessor. This is the source of the 11 + rust-analyzer, which does a full scan of your workspace. The larger your workspace is, 12 + the longer mdBook will have to wait for the preprocessor. This is the source of the 27 13 majority of the run time. 28 14 29 15 There is an [experimental caching feature](caching.md#enabling-caching), which persists 30 16 query results after runs and reuses them when possible, avoiding spawning rust-analyzer 31 17 when your edit doesn't involve item links. 32 18 33 - ## Incorrect links 34 - 35 - In limited circumstances, the preprocessor generates links that are incorrect or 36 - inaccessible. 19 + ## Incorrect/unresolvable links 37 20 38 21 > [!NOTE] 39 22 > 40 - > The following observations are based on rust-analyzer 41 - > <ra-version>(version)</ra-version>. 23 + > The following observations are as of rust-analyzer <ra-version>(version)</ra-version>. 42 24 43 - ### Macros 25 + In some circumstances, the preprocessor generates links that are incorrect or 26 + inaccessible. 44 27 45 - Macros exported with [`#[macro_export]`][macro_export] are always exported at crate 46 - root, and are documented as such by rustdoc, but rust-analyzer currently generates links 47 - to the modules they are defined in. For example: 28 + ### Derive macros 48 29 49 - - [~~`panic!`~~](https://doc.rust-lang.org/stable/std/macros/macro.panic.html "panic!"), and many other `std` macros 50 - - The correct link is 51 - [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic] 52 - - [~~`serde_json::json!`~~](https://docs.rs/serde_json/1.0.140/serde_json/macros/macro.json.html "serde_json::json!") 53 - - The correct link is 54 - [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json] 30 + Previously, it was possible to link to the documentation for a derive macro instead of 31 + the derived trait by using the [macro syntax](supported-syntax.md#functions-and-macros), 32 + for example, by writing [`[serde::Serialize!]`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize") instead of 33 + [`[serde::Serialize]`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize"). 55 34 56 - Attribute macros generate links that use `macro.<macro_name>.html`, but rustdoc actually 57 - generates `attr.<macro_name>.html`. For example: 35 + This no longer works due to an upstream change. To link to such derive macros, you must 36 + use paths that directly point to them, for example, `serde_derive::Serialize`. 37 + 38 + ### Attribute macros 39 + 40 + Links generated by rust-analyzer for attribute macros end with 41 + `macro.<macro_name>.html`, but they should end with `attr.<macro_name>.html`. For 42 + example: 58 43 59 44 - [~~`tokio::main!`~~](https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html "tokio::main!") 60 45 - The correct link is ··· 87 72 The preprocessor does not yet warn you about links to private items: rust-analyzer will 88 73 generate links for items regardless of their crate-level visibility. 89 74 90 - ## Unresolved items 91 - 92 - ### Associated items on primitive types 93 - 94 - > [!NOTE] 95 - > 96 - > The following observations are based on rust-analyzer 97 - > <ra-version>(version)</ra-version>. 75 + ### Items on primitive types 98 76 99 77 Links to associated methods and items on primitive types are currently not resolved by 100 78 rust-analyzer. For example: ··· 106 84 107 85 Currently, items from crates other than `std` always generate links that point to 108 86 <https://docs.rs>. `mdbook-rustdoc-link` does not yet support configuring alternative 109 - hosting sites for crates (such as `wasm-bindgen` which hosts API docs under 110 - `https://rustwasm.github.io/wasm-bindgen/api/`). 87 + URL prefixes. 111 88 112 89 ## Wrong line numbers in diagnostics 113 90 ··· 129 106 130 107 Unless mdBook somehow gains [source map][sourcemap] support, this problem is unlikely to 131 108 ever be solved. 109 + 110 + ## Resolved issues 111 + 112 + ### Since rust-analyzer `2025-08-11` 113 + 114 + Previously, generated links to macros were often incorrect. These are currently 115 + [fixed upstream](https://github.com/rust-lang/rust-analyzer/pull/20384) as of 116 + rust-analyzer 117 + [`2025-08-11`](https://github.com/rust-lang/rust-analyzer/releases/tag/2025-08-11). 118 + 119 + <details> 120 + <summary>Original description</summary> 121 + 122 + Macros exported with [`#[macro_export]`][macro_export] are always exported at crate 123 + root, and are documented as such by rustdoc, but rust-analyzer currently generates links 124 + to the modules they are defined in. For example: 125 + 126 + - [~~`panic!`~~](https://doc.rust-lang.org/stable/std/macro.panic.html "panic!"), and many other `std` macros 127 + - The correct link is 128 + [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic] 129 + - [~~`serde_json::json!`~~](https://docs.rs/serde_json/1.0.145/serde_json/macro.json.html "serde_json::json!") 130 + - The correct link is 131 + [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json] 132 + 133 + </details> 132 134 133 135 <!-- prettier-ignore-start --> 134 136
+29 -14
crates/mdbook-rustdoc-links/src/tests/snaps/known-issues.stderr.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 76 3 4 expression: report 4 5 --- 5 6 info: successfully resolved all links 6 - ╭─[known-issues:45:3] 7 + ╭─[known-issues:27:25] 8 + │ the derived trait by using the [macro syntax](supported-syntax.md#functions-and-macros), 9 + │ for example, by writing [`[serde::Serialize!]`][serde::Serialize] instead of 10 + · ────────────────────┬──────────────────── 11 + · ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html 12 + │ [`[serde::Serialize]`][serde::Serialize]. 13 + · ────────────────────┬─────────────────── 14 + · ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html 7 15 8 - │ - [~~`panic!`~~], and many other `std` macros 9 - · ───────┬────── 10 - · ╰── https://doc.rust-lang.org/stable/std/macros/macro.panic.html 11 - │ - The correct link is 12 - │ [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic] 13 - │ - [~~`serde_json::json!`~~] 14 - · ────────────┬──────────── 15 - · ╰── https://docs.rs/serde_json/1.0.140/serde_json/macros/macro.json.html 16 - │ - The correct link is 17 - │ [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json] 16 + │ This no longer works due to an upstream change. To link to such derive macros, you must 17 + │ use paths that directly point to them, for example, `serde_derive::Serialize`. 18 + 19 + │ ### Attribute macros 18 20 19 - │ Attribute macros generate links that use `macro.<macro_name>.html`, but rustdoc actually 20 - │ generates `attr.<macro_name>.html`. For example: 21 + │ Links generated by rust-analyzer for attribute macros end with 22 + │ `macro.<macro_name>.html`, but they should end with `attr.<macro_name>.html`. For 23 + │ example: 21 24 22 25 │ - [~~`tokio::main!`~~] 23 26 · ──────────┬───────── ··· 44 47 · ╰── https://doc.rust-lang.org/stable/core/net/ip_addr/enum.IpAddr.html#method.from 45 48 46 49 ╰──── 50 + ╭─[known-issues:121:3] 51 + 52 + │ - [~~`panic!`~~], and many other `std` macros 53 + · ───────┬────── 54 + · ╰── https://doc.rust-lang.org/stable/std/macro.panic.html 55 + │ - The correct link is 56 + │ [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic] 57 + │ - [~~`serde_json::json!`~~] 58 + · ────────────┬──────────── 59 + · ╰── https://docs.rs/serde_json/1.0.145/serde_json/macro.json.html 60 + │ - The correct link is 61 + ╰────
+2 -3
crates/mdbook-rustdoc-links/src/tests/snaps/ra-known-quirks.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 61 3 4 expression: output 4 5 --- 5 6 # primitive types resolved to nightly ··· 17 18 18 19 # macro_export 19 20 20 - - [std::vec!](https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html "std::vec!") 21 - - [std::format!](https://doc.rust-lang.org/stable/alloc/macros/macro.format.html "std::format!") 22 21 - [tokio::main!](https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html "tokio::main!")
+2 -7
crates/mdbook-rustdoc-links/src/tests/snaps/ra-known-quirks.stderr.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 76 3 4 expression: report 4 5 --- 5 6 warning: failed to resolve some links ··· 32 33 33 34 │ # macro_export 34 35 35 - │ - [std::vec!] 36 - · ─────┬───── 37 - · ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html 38 - │ - [std::format!] 39 - · ───────┬────── 40 - · ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.format.html 41 36 │ - [tokio::main!] 42 37 · ───────┬────── 43 38 · ╰── https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html
+72 -100
crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 61 3 4 expression: output 4 5 --- 5 6 # Supported syntax ··· 11 12 12 13 </div> 13 14 14 - This page showcases all the syntax supported by `mdbook-rustdoc-link`. 15 - 16 - Most of the formats [supported by rustdoc][rustdoc-linking] are supported. Unsupported 15 + Most of the syntax [supported by rustdoc][rustdoc-linking] are supported. Unsupported 17 16 syntax and differences in behavior are emphasized below. 18 17 19 18 In general, specifying items as you would when writing Rust code should "just work". 20 - 21 - <details class="toc" open> 22 - <summary>Sections</summary> 23 - 24 - - [Types, modules, and associated items](#types-modules-and-associated-items) 25 - - [Generic parameters](#generic-parameters) 26 - - [Functions and macros](#functions-and-macros) 27 - - [Implementors and fully qualified syntax](#implementors-and-fully-qualified-syntax) 28 - - [Disambiguators](#disambiguators) 29 - - [Special types](#special-types) 30 - - [Struct fields](#struct-fields) 31 - - [Markdown link syntax](#markdown-link-syntax) 32 - - [Linking to page sections](#linking-to-page-sections) 33 - 34 - </details> 35 19 36 20 > [!TIP] 37 21 > 38 22 > This page is also used for snapshot testing! To see how all the links would look like 39 23 > in Markdown after they have been processed, see 40 - > [supported-syntax.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.snap) 24 + > [supported-syntax.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.snap) 41 25 > and 42 - > [supported-syntax.stderr.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.stderr.snap). 26 + > [supported-syntax.stderr.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.stderr.snap). 43 27 44 - ## Types, modules, and associated items 28 + ## Types, modules, associated items 45 29 46 30 > ```md 47 31 > Module [`alloc`][std::alloc] — Memory allocation APIs. ··· 67 51 68 52 ## Generic parameters 69 53 70 - Types can contain generic parameters. This is _compatible_ with rustdoc. 54 + Types may contain generic parameters. This is _compatible_ with rustdoc. 71 55 72 56 > ```md 73 57 > [`Vec<T>`] — A heap-allocated _vector_ that is resizable at runtime. ··· 87 71 > | [`&'a mut T`](https://doc.rust-lang.org/stable/core/marker/struct.PhantomData.html "std::marker::PhantomData<&'a mut T>") | **in**variant | 88 72 > | [`fn(T)`](https://doc.rust-lang.org/stable/core/marker/struct.PhantomData.html "std::marker::PhantomData<fn(T)>") | **contra**variant | 89 73 90 - This includes if you use turbofish: 74 + Turbofish are also supported: 91 75 92 76 > ```md 93 77 > `collect()` is one of the few times you’ll see the syntax affectionately known as the ··· 99 83 100 84 ## Functions and macros 101 85 102 - To indicate that an item is a function, add `()` after the function name. To indicate 103 - that an item is a macro, add `!` after the macro name, optionally followed by `()`, 104 - `[]`, or `{}`. This is _compatible_ with rustdoc. 105 - 106 - Note that there cannot be arguments within `()`, `[]`, or `{}`. 86 + Functions and macros can be linked to just like other named items. To distinguish a 87 + function from other items of the same name, add `()` after the function name. To 88 + distinguish a macro from other items of the same name, add `!` after the macro name. 89 + This is _compatible_ with rustdoc. 107 90 108 91 > ```md 109 - > [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally 110 - > use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]! 92 + > [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use 93 + > [`format`][std::fmt::format()] in place of [`format!`][std::format!]! 111 94 > ``` 112 95 > 113 - > [`vec!`](https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html "std::vec!")[^2] is different from [`vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), and don't accidentally 114 - > use [`format()`](https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html "std::fmt::format()") in place of [`format!()`](https://doc.rust-lang.org/stable/alloc/macros/macro.format.html "std::format!()")[^2]! 96 + > [`vec!`](https://doc.rust-lang.org/stable/alloc/macro.vec.html "std::vec!") is different from [`vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), and don't accidentally use 97 + > [`format`](https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html "std::fmt::format()") in place of [`format!`](https://doc.rust-lang.org/stable/alloc/macro.format.html "std::format!")! 115 98 116 - The macro syntax works for attribute and derive macros as well (even though this is not 117 - how they are invoked). 99 + Note that there cannot be arguments within `()`, `[]`, or `{}`. The `macro!` syntax 100 + works for attribute and derive macros as well (even though this is not how they are 101 + invoked). 118 102 119 - > ```md 120 - > There is a [derive macro][serde::Serialize!] to generate implementations of the 121 - > [`Serialize`][serde::Serialize] trait. 122 - > ``` 103 + > [!NOTE] 104 + > 105 + > As of rust-analyzer <ra-version>(version)</ra-version>, the `macro!` syntax can no 106 + > longer disambiguate between a derive macro and its corresponding trait. For example, 107 + > 108 + > > ``` 109 + > > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait. 110 + > > ``` 111 + > > 112 + > > Both [`serde::Serialize`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize") and [`serde::Serialize!`](https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html "serde::Serialize!") link to the `Serialize` trait. 123 113 > 124 - > There is a [derive macro](https://docs.rs/serde_derive/1.0.219/serde_derive/derive.Serialize.html "serde::Serialize!") to generate implementations of the 125 - > [`Serialize`](https://docs.rs/serde/1.0.219/serde/ser/trait.Serialize.html "serde::Serialize") trait. 114 + > To link to such derive macros, you must use paths that directly point to them, such as 115 + > `serde_derive::Serialize`. 126 116 127 - ## Implementors and fully qualified syntax 117 + ## Fully qualified paths 128 118 129 - Trait implementors may supply additional documentation about their implementations. To 130 - link to implemented items instead of the traits themselves, use fully qualified paths, 131 - including `<... as Trait>` if necessary. This is a _new feature_ that rustdoc does not 132 - currently support. 119 + Trait implementors may supply additional documentation about the implementation. To link 120 + to such documentation instead of the traits themselves, use fully qualified paths, 121 + including `<... as Trait>` if necessary. This is an _additional syntax_ that rustdoc 122 + does not currently support. 133 123 134 124 > ```md 135 125 > [`Result<T, E>`] implements [`IntoIterator`]; its ··· 150 140 > [!NOTE] 151 141 > 152 142 > If your type has generic parameters, you must supply concrete types for them for 153 - > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` won't 143 + > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` will not 154 144 > work, but `Result<(), ()>` will (unless there happen to be types `T` and `E` literally 155 145 > in scope). 156 146 157 - ## Disambiguators 158 - 159 - rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but 160 - ignored**: 161 - 162 - > ```md 163 - > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 164 - > ``` 165 - > 166 - > [`std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), [`mod@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "mod@std::vec"), and [`macro@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "macro@std::vec") all link to the `vec` _module_. 167 - 168 - This is largely okay because currently, duplicate names in Rust are allowed only if they 169 - correspond to items in different [namespaces], for example, between macros and modules, 170 - and between struct fields and methods — this is mostly covered by the function and macro 171 - syntax, described [above](#functions-and-macros). 172 - 173 - If you encounter items that must be disambiguated using rustdoc's disambiguator syntax, 174 - other than [the "special types" listed below](#special-types), please [file an 175 - issue][gh-issues]! 176 - 177 - ## Special types 178 - 179 - > [!WARNING] 180 - 181 - There is **no support** on types whose syntax is not a path; they are currently not 182 - parsed at all: 183 - 184 - > references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like 185 - > `*const T`, trait objects like `dyn Any`, and the never type `!` 186 - 187 - Note that such types can still be used as generic params, just not as standalone types. 188 - 189 - ## Struct fields 190 - 191 - > [!WARNING] 192 - 193 - Linking to struct fields is **not supported** yet. This is **incompatible** with 194 - rustdoc. 195 - 196 - ## Markdown link syntax 147 + ## Link format 197 148 198 149 All Markdown link formats supported by rustdoc are supported: 199 150 ··· 229 180 Shortcuts are supported, and can contain inline markups: 230 181 231 182 > ```md 232 - > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro. 183 + > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro. 233 184 > ``` 234 185 > 235 - > You can create a [`Vec`](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html "Vec") with [**`Vec::new`**](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html#method.new "Vec::new"), or by using the [*`vec!`*](https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html "vec!")[^2] macro. 236 - 237 - (The items must still be resolvable; in this case `Vec` and `vec!` come from the 238 - prelude.) 186 + > You can create a [`Vec`](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html "Vec") with [**`Vec::new`**](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html#method.new "Vec::new"), or by using the [*`vec!`*](https://doc.rust-lang.org/stable/alloc/macro.vec.html "vec!") macro. 239 187 240 188 ## Linking to page sections 241 189 242 - To link to a known section on a page, use a URL fragment, just like a normal link. This 243 - is _compatible_ with rustdoc. 190 + To link to a known section on a page, use a URL fragment, as you would otherwise specify 191 + for an HTTP URL. This is _compatible_ with rustdoc. 244 192 245 193 <!-- prettier-ignore-start --> 246 194 ··· 252 200 253 201 <!-- prettier-ignore-end --> 254 202 203 + ## Unsupported syntax 204 + 205 + ### Disambiguators 206 + 207 + rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but 208 + ignored.** To disambiguate functions and macros, use the 209 + [functions and macros](#functions-and-macros) syntax. 210 + 211 + > ```md 212 + > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 213 + > ``` 214 + > 215 + > [`std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "std::vec"), [`mod@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "mod@std::vec"), and [`macro@std::vec`](https://doc.rust-lang.org/stable/alloc/vec/index.html "macro@std::vec") all link to the `vec` _module_. 216 + 217 + ### Special types 218 + 219 + There is **no support** on types whose syntax is not a path; they are currently not 220 + parsed at all: 221 + 222 + > references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like 223 + > `*const T`, trait objects like `dyn Any`, and the never type `!` 224 + 225 + Note that such types can still be used as generic params, just not as standalone types. 226 + 227 + ### Struct fields 228 + 229 + Linking to struct fields is **not supported** yet. This is **incompatible** with 230 + rustdoc. 231 + 255 232 [^1]: 256 233 rust-analyzer's ability to generate links for enum variants like `Option::Some` was 257 234 improved only somewhat recently: before 258 235 [#19246](https://github.com/rust-lang/rust-analyzer/pull/19246), links for variants 259 236 and associated items may only point to the types themselves. If linking to such 260 237 items doesn't seem to work for you, be sure to upgrade to a newer rust-analyzer 261 - first! 262 - 263 - [^2]: 264 - As of rust-analyzer <ra-version>(version)</ra-version>, links generated for macros 265 - don't always work. Examples include [`std::format!`](https://doc.rust-lang.org/stable/alloc/macros/macro.format.html "std::format!") (seen above) and 266 - [`tokio::main!`](https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html "tokio::main!"). For more info, see [Known issues](known-issues.md#macros). 238 + first. 267 239 268 240 <!-- prettier-ignore-start --> 269 241
+65 -104
crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.stderr.snap
··· 1 1 --- 2 - source: crates/mdbookkit/tests/rustdoc_link.rs 2 + source: crates/mdbook-rustdoc-links/src/tests.rs 3 + assertion_line: 76 3 4 expression: report 4 5 --- 5 6 info: successfully resolved all links 6 - ╭─[supported-syntax:46:10] 7 + ╭─[supported-syntax:29:10] 7 8 │ > 8 9 │ > Module [`alloc`][std::alloc] — Memory allocation APIs. 9 10 · ──────────┬────────── ··· 34 35 35 36 │ ## Generic parameters 36 37 37 - │ Types can contain generic parameters. This is _compatible_ with rustdoc. 38 + │ Types may contain generic parameters. This is _compatible_ with rustdoc. 38 39 39 40 │ > ```md 40 41 │ > [`Vec<T>`] — A heap-allocated _vector_ that is resizable at runtime. ··· 60 61 · ─────────────────────┬──────────────────── 61 62 · ╰── https://doc.rust-lang.org/stable/core/marker/struct.PhantomData.html 62 63 63 - │ This includes if you use turbofish: 64 + │ Turbofish are also supported: 64 65 65 66 │ > ```md 66 67 │ > `collect()` is one of the few times you’ll see the syntax affectionately known as the ··· 74 75 75 76 │ ## Functions and macros 76 77 77 - │ To indicate that an item is a function, add `()` after the function name. To indicate 78 - │ that an item is a macro, add `!` after the macro name, optionally followed by `()`, 79 - │ `[]`, or `{}`. This is _compatible_ with rustdoc. 80 - 81 - │ Note that there cannot be arguments within `()`, `[]`, or `{}`. 78 + │ Functions and macros can be linked to just like other named items. To distinguish a 79 + │ function from other items of the same name, add `()` after the function name. To 80 + │ distinguish a macro from other items of the same name, add `!` after the macro name. 81 + │ This is _compatible_ with rustdoc. 82 82 83 83 │ > ```md 84 - │ > [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally 85 - │ > use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]! 84 + │ > [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use 85 + │ > [`format`][std::fmt::format()] in place of [`format!`][std::format!]! 86 86 │ > ``` 87 87 │ > 88 - │ > [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally 89 - · ─────────┬───────── ────────┬──────── 90 - · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 91 - · ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html 92 - │ > use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]! 93 - · ────────────────┬─────────────── ──────────────┬────────────── 94 - · │ ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.format.html 95 - · ╰── https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html 88 + │ > [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use 89 + · ─────────┬───────── ────────┬──────── 90 + · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 91 + · ╰── https://doc.rust-lang.org/stable/alloc/macro.vec.html 92 + │ > [`format`][std::fmt::format()] in place of [`format!`][std::format!]! 93 + · ───────────────┬────────────── ────────────┬──────────── 94 + · │ ╰── https://doc.rust-lang.org/stable/alloc/macro.format.html 95 + · ╰── https://doc.rust-lang.org/stable/alloc/fmt/fn.format.html 96 96 97 - │ The macro syntax works for attribute and derive macros as well (even though this is not 98 - │ how they are invoked). 97 + │ Note that there cannot be arguments within `()`, `[]`, or `{}`. The `macro!` syntax 98 + │ works for attribute and derive macros as well (even though this is not how they are 99 + │ invoked). 99 100 100 - │ > ```md 101 - │ > There is a [derive macro][serde::Serialize!] to generate implementations of the 102 - │ > [`Serialize`][serde::Serialize] trait. 103 - │ > ``` 101 + │ > [!NOTE] 102 + │ > 103 + │ > As of rust-analyzer <ra-version>(version)</ra-version>, the `macro!` syntax can no 104 + │ > longer disambiguate between a derive macro and its corresponding trait. For example, 104 105 │ > 105 - │ > There is a [derive macro][serde::Serialize!] to generate implementations of the 106 - · ────────────────┬──────────────── 107 - · ╰── https://docs.rs/serde_derive/1.0.219/serde_derive/derive.Serialize.html 108 - │ > [`Serialize`][serde::Serialize] trait. 109 - · ───────────────┬─────────────── 110 - · ╰── https://docs.rs/serde/1.0.219/serde/ser/trait.Serialize.html 106 + │ > > ``` 107 + │ > > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait. 108 + │ > > ``` 109 + │ > > 110 + │ > > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait. 111 + · ──────────┬───────── ──────────┬────────── 112 + · │ ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html 113 + · ╰── https://docs.rs/serde_core/1.0.228/serde_core/ser/trait.Serialize.html 114 + │ > 115 + │ > To link to such derive macros, you must use paths that directly point to them, such as 116 + │ > `serde_derive::Serialize`. 111 117 112 - │ ## Implementors and fully qualified syntax 118 + │ ## Fully qualified paths 113 119 114 - │ Trait implementors may supply additional documentation about their implementations. To 115 - │ link to implemented items instead of the traits themselves, use fully qualified paths, 116 - │ including `<... as Trait>` if necessary. This is a _new feature_ that rustdoc does not 117 - │ currently support. 120 + │ Trait implementors may supply additional documentation about the implementation. To link 121 + │ to such documentation instead of the traits themselves, use fully qualified paths, 122 + │ including `<... as Trait>` if necessary. This is an _additional syntax_ that rustdoc 123 + │ does not currently support. 118 124 119 125 │ > ```md 120 126 │ > [`Result<T, E>`] implements [`IntoIterator`]; its ··· 147 153 │ > [!NOTE] 148 154 │ > 149 155 │ > If your type has generic parameters, you must supply concrete types for them for 150 - │ > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` won't 156 + │ > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` will not 151 157 │ > work, but `Result<(), ()>` will (unless there happen to be types `T` and `E` literally 152 158 │ > in scope). 153 159 154 - │ ## Disambiguators 155 - 156 - │ rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but 157 - │ ignored**: 158 - 159 - │ > ```md 160 - │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 161 - │ > ``` 162 - │ > 163 - │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 164 - · ──────┬───── ────────┬─────── ─────────┬──────── 165 - · │ │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 166 - · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 167 - · ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 168 - 169 - │ This is largely okay because currently, duplicate names in Rust are allowed only if they 170 - │ correspond to items in different [namespaces], for example, between macros and modules, 171 - │ and between struct fields and methods — this is mostly covered by the function and macro 172 - │ syntax, described [above](#functions-and-macros). 173 - 174 - │ If you encounter items that must be disambiguated using rustdoc's disambiguator syntax, 175 - │ other than [the "special types" listed below](#special-types), please [file an 176 - │ issue][gh-issues]! 177 - 178 - │ ## Special types 179 - 180 - │ > [!WARNING] 181 - 182 - │ There is **no support** on types whose syntax is not a path; they are currently not 183 - │ parsed at all: 184 - 185 - │ > references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like 186 - │ > `*const T`, trait objects like `dyn Any`, and the never type `!` 187 - 188 - │ Note that such types can still be used as generic params, just not as standalone types. 189 - 190 - │ ## Struct fields 191 - 192 - │ > [!WARNING] 193 - 194 - │ Linking to struct fields is **not supported** yet. This is **incompatible** with 195 - │ rustdoc. 196 - 197 - │ ## Markdown link syntax 160 + │ ## Link format 198 161 199 162 │ All Markdown link formats supported by rustdoc are supported: 200 163 ··· 236 199 │ Shortcuts are supported, and can contain inline markups: 237 200 238 201 │ > ```md 239 - │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro. 202 + │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro. 240 203 │ > ``` 241 204 │ > 242 - │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro. 205 + │ > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro. 243 206 · ───┬─── ────────┬─────── ─────┬──── 244 - · │ │ ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.vec.html 207 + · │ │ ╰── https://doc.rust-lang.org/stable/alloc/macro.vec.html 245 208 · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html#method.new 246 209 · ╰── https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html 247 210 248 - │ (The items must still be resolvable; in this case `Vec` and `vec!` come from the 249 - │ prelude.) 250 - 251 211 │ ## Linking to page sections 252 212 253 - │ To link to a known section on a page, use a URL fragment, just like a normal link. This 254 - │ is _compatible_ with rustdoc. 213 + │ To link to a known section on a page, use a URL fragment, as you would otherwise specify 214 + │ for an HTTP URL. This is _compatible_ with rustdoc. 255 215 256 216 │ <!-- prettier-ignore-start --> 257 217 ··· 265 225 266 226 │ <!-- prettier-ignore-end --> 267 227 268 - │ [^1]: 269 - │ rust-analyzer's ability to generate links for enum variants like `Option::Some` was 270 - │ improved only somewhat recently: before 271 - │ [#19246](https://github.com/rust-lang/rust-analyzer/pull/19246), links for variants 272 - │ and associated items may only point to the types themselves. If linking to such 273 - │ items doesn't seem to work for you, be sure to upgrade to a newer rust-analyzer 274 - │ first! 228 + │ ## Unsupported syntax 275 229 276 - │ [^2]: 277 - │ As of rust-analyzer <ra-version>(version)</ra-version>, links generated for macros 278 - │ don't always work. Examples include [`std::format!`] (seen above) and 279 - · ────────┬─────── 280 - · ╰── https://doc.rust-lang.org/stable/alloc/macros/macro.format.html 281 - │ [`tokio::main!`]. For more info, see [Known issues](known-issues.md#macros). 282 - · ────────┬─────── 283 - · ╰── https://docs.rs/tokio-macros/2.5.0/tokio_macros/macro.main.html 230 + │ ### Disambiguators 231 + 232 + │ rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but 233 + │ ignored.** To disambiguate functions and macros, use the 234 + │ [functions and macros](#functions-and-macros) syntax. 235 + 236 + │ > ```md 237 + │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 238 + │ > ``` 239 + │ > 240 + │ > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 241 + · ──────┬───── ────────┬─────── ─────────┬──────── 242 + · │ │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 243 + · │ ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 244 + · ╰── https://doc.rust-lang.org/stable/alloc/vec/index.html 284 245 285 246 ╰────
+7 -93
docs/app/main.css
··· 158 158 &[open] > summary { 159 159 margin-block-end: 1rem; 160 160 } 161 - 162 - &.toc { 163 - > summary { 164 - margin-block-end: 0; 165 - font-weight: bold; 166 - cursor: pointer; 167 - } 168 - 169 - li { 170 - margin-block: 0.25rem; 171 - } 172 - } 173 161 } 174 162 175 163 blockquote { ··· 179 167 border-block-end: none; 180 168 181 169 &:not(.blockquote-tag) { 182 - border-inline-start: 0.25rem solid var(--quote-border); 170 + border-inline-start: 4px solid var(--quote-border); 183 171 } 184 172 185 173 > :last-child { 186 174 margin-block-end: 0; 187 175 } 188 - } 189 - 190 - .mdbook-alerts { 191 - padding: 0.3rem 0 0.5rem 1rem; 192 - border-left: 0.25rem solid var(--mdbook-alerts-color); 193 176 194 - .mdbook-alerts-title { 195 - margin-block-end: 0; 196 - user-select: none; 197 - } 198 - 199 - .mdbook-alerts-icon { 200 - position: relative; 201 - top: 1px; 202 - } 203 - 204 - > :nth-child(2) { 205 - margin-block-start: 1rem; 206 - } 207 - 208 - > :nth-child(2):last-child { 209 - margin-block-start: 0.5rem; 210 - } 211 - } 212 - 213 - blockquote, 214 - .mdbook-alerts { 215 177 > * { 216 178 opacity: 0.9; 217 179 } 218 180 219 - > blockquote, 220 - > .mdbook-alerts, 221 - > .mdbook-alerts-title { 181 + > blockquote { 222 182 opacity: 1; 223 183 } 224 184 } ··· 297 257 &:has(> figcaption:last-child) { 298 258 margin-block-end: 1.2rem; 299 259 } 260 + } 261 + 262 + .blockquote-tag-title svg { 263 + position: relative; 264 + top: 1px; 300 265 } 301 266 } 302 267 ··· 434 399 left: -40px; 435 400 width: 100vw; 436 401 } 437 - 438 - > .mdbook-alerts { 439 - padding-inline-end: 15px; 440 - } 441 402 } 442 403 443 404 .nav-wrapper { ··· 481 442 html.ayu { 482 443 .fig-text { 483 444 background-color: #191f2680; 484 - } 485 - } 486 - 487 - html.coal, 488 - html.navy, 489 - html.ayu { 490 - .mdbook-alerts-warning { 491 - --mdbook-alerts-color: #d29922; 492 - } 493 - 494 - .mdbook-alerts-note { 495 - --mdbook-alerts-color: #4493f8; 496 - } 497 - 498 - .mdbook-alerts-tip { 499 - --mdbook-alerts-color: #3fb950; 500 - } 501 - 502 - .mdbook-alerts-important { 503 - --mdbook-alerts-color: #ab7df8; 504 - } 505 - 506 - .mdbook-alerts-caution { 507 - --mdbook-alerts-color: #f85149; 508 - } 509 - } 510 - 511 - html.light, 512 - html.rust { 513 - .mdbook-alerts-warning { 514 - --mdbook-alerts-color: #9a6700; 515 - } 516 - 517 - .mdbook-alerts-note { 518 - --mdbook-alerts-color: #0969da; 519 - } 520 - 521 - .mdbook-alerts-tip { 522 - --mdbook-alerts-color: #1a7f37; 523 - } 524 - 525 - .mdbook-alerts-important { 526 - --mdbook-alerts-color: #8250df; 527 - } 528 - 529 - .mdbook-alerts-caution { 530 - --mdbook-alerts-color: #d1242f; 531 445 } 532 446 } 533 447
+1 -1
docs/book.toml
··· 32 32 33 33 [preprocessor.rustdoc-links] 34 34 after = ["links"] 35 - # cache-dir = "build" 35 + cache-dir = "build" 36 36 command = "cargo run --package mdbook-rustdoc-links" 37 37 manifest-dir = "." 38 38 rust-analyzer = "cargo run --package util-rust-analyzer -- analyzer"
+26 -27
docs/src/rustdoc-link/caching.md
··· 1 1 # Caching 2 2 3 3 By default, `mdbook-rustdoc-link` spawns a fresh `rust-analyzer` process every time it 4 - runs. rust-analyzer then reindexes your entire project before resolving links. 4 + runs. rust-analyzer must then reindex your entire project before being able to resolve 5 + links. 5 6 6 - This makes the `mdbook serve` command significantly slower, more so if your project 7 - contains a large number of dependencies. It is as if for every live reload, you had to 8 - reopen your editor. 7 + This makes the `mdbook serve` command significantly less responsive, which gets worse if 8 + your project contains a large number of dependencies. It is as if for every live reload, 9 + you had to reopen your editor. 9 10 10 11 To mitigate this, there is an experimental caching feature. The feature is disabled by 11 12 default. 12 13 13 14 ## Enabling caching 14 15 15 - In your `book.toml`, in the `[preprocessor.rustdoc-link]` table, set 16 + In `book.toml`, in the `[preprocessor.rustdoc-link]` table, set 16 17 [`cache-dir`](configuration.md#cache-dir) to the relative path of a directory of your 17 - choice (_other than_ your book's `build-dir`), for example: 18 + choice, _outside_ of your book's `build-dir`, for example: 18 19 19 20 ```toml 20 21 [preprocessor.rustdoc-link] ··· 22 23 # You could also point to an arbitrary directory in target/ 23 24 ``` 24 25 25 - Now, when `mdbook` rebuilds your book during `build` or `serve`, the preprocessor reuses 26 - the previous resolution and **skips rust-analyzer entirely if** your edit does not 27 - involve changes in the set of Rust items to be linked, that is, no new items unseen in 28 - the previous build. 26 + This enables the preprocessor to persist the list of links resolved during a build. When 27 + mdBook rebuilds your book during `build` or `serve`, the preprocessor reuses the 28 + previous resolution and **skips rust-analyzer entirely if** your edit does not involve 29 + changes in the set of Rust items to be linked, that is, if there are no new items unseen 30 + in the previous build. 29 31 30 32 > [!IMPORTANT] 31 33 > ··· 34 36 > file could trigger additional reloads. See [Specify exclude 35 37 > patterns][specify-exclude-patterns] in the mdBook documentation. 36 38 > 37 - > **Do not** use your book's `build-dir` as the `cache-dir`: `mdbook` clears the output 39 + > Items that fail to resolve are not included in the cache. If such "broken" links 40 + > persist in the Markdown source, cache will be invalidated on every run, and 41 + > rust-analyzer will always run. 42 + > 43 + > **Do not** use your book's `build-dir` as the `cache-dir`: mdbook clears the output 38 44 > directory on every build, making this setup useless. 39 45 40 46 ## How it works ··· 46 52 47 53 The effectiveness of this mechanism is based on the following assumptions: 48 54 49 - - Most of the changes made during authoring don't actually involve item links. 55 + - Most of the changes made during authoring don't involve item links. 50 56 - Assuming the environment is unchanged, the same set of items should resolve to the 51 57 same set of links. 52 58 53 - The cache keeps the following information in a `cache.json`: 59 + The cache keeps the following information in a `cache.json` file: 54 60 55 61 - The set of items to be resolved, and their resolved links 56 62 - The environment, as a checksum over the contents of: ··· 63 69 If a subsequent run has the same set of items (or a subset) and the same checksum 64 70 (meaning you did not update your code), then the preprocessor simply reuses the previous 65 71 results. 66 - 67 - > [!TIP] 68 - > 69 - > Items that fail to resolve are not included in the cache. 70 - > 71 - > If you keep such broken links in your Markdown source, the cache will permanently 72 - > miss, and rust-analyzer will run on every edit. 73 72 74 73 ## Help wanted 🙌 75 74 ··· 118 117 119 118 ### Postscript 120 119 121 - `mdbook` encourages a stateless architecture for preprocessors. Preprocessors are 122 - expected to work like pure functions over the entire book, even for `mdbook serve`. 123 - Preprocessors are not informed on whether they are invoked as part of `mdbook build` 124 - (prefer fresh starts) or `mdbook serve` (maintain states between run). 120 + mdBook encourages a stateless architecture for preprocessors. Preprocessors are expected 121 + to work like pure functions over the entire book, even for `mdbook serve`. Preprocessors 122 + are not informed on whether they are invoked as part of `mdbook build` (prefer fresh 123 + starts) or `mdbook serve` (maintain states between run). 125 124 126 125 `rust-analyzer`, meanwhile, has a stateful architecture that also doesn't yet have 127 126 [persistent caching][ra-persistent-cache][^1]. It is [designed][ra-architecture] to take ··· 129 128 edited) entirely in memory. 130 129 131 130 So `rust-analyzer` has an extremely incremental architecture, perfect for complex 132 - languages like Rust, and `mdbook` has an explicitly non-incremental architecture, 133 - perfect for rendering Markdown. This makes them somewhat challenging to work well 134 - together in a live-reload scenario. 131 + languages like Rust, and mdBook has an explicitly non-incremental architecture, perfect 132 + for rendering Markdown. This makes them somewhat challenging to work well together in a 133 + live-reload scenario. 135 134 136 135 [^1]: 137 136 It was mentioned that the [recently updated, salsa-ified rust-analyzer][salsa]
+18 -27
docs/src/rustdoc-link/continuous-integration.md
··· 1 1 # Continuous integration 2 2 3 3 This page gives information and tips for using `mdbook-rustdoc-link` in a continuous 4 - integration (CI) environment. 5 - 6 - The preprocessor behaves differently in terms of logging, error handling, etc., when it 7 - detects it is running in CI. 8 - 9 - <details class="toc" open> 10 - <summary>Sections</summary> 11 - 12 - - [Detecting CI](#detecting-ci) 13 - - [Installing rust-analyzer](#installing-rust-analyzer) 14 - - [Logging](#logging) 15 - - [Error handling](#error-handling) 16 - 17 - </details> 4 + integration (CI) environment. The preprocessor optimizes some behaviors for CI, in terms 5 + of error handling, logging, etc. 18 6 19 7 ## Detecting CI 20 8 21 - To determine whether it is running in CI, the preprocessor honors the `CI` environment 22 - variable. Specifically: 9 + To determine whether it is running in a CI environment, the preprocessor honors the `CI` 10 + environment variable. Specifically: 23 11 24 12 - If `CI` is set to `"true"`, then it is considered in CI[^ci-true]; 25 13 - Otherwise, it is considered not in CI. 26 14 27 - Most major CI/CD services, such as [GitHub Actions][github-actions-ci] and [GitLab 28 - CI/CD][gitlab-ci], automatically configure this variable for you. 15 + Providers such as [GitHub Actions][github-actions-ci] and [GitLab CI/CD][gitlab-ci] have 16 + this variable configured by default. 29 17 30 18 ## Installing rust-analyzer 31 19 32 20 rust-analyzer must be on `PATH` when running in CI[^ra-on-path]. 33 21 34 - One way is to install it via [rustup][rustup-ra]. For example, in [GitHub 22 + One way to install it is via [rustup][rustup-ra]. For example, in [GitHub 35 23 Actions][dtolnay/rust-toolchain], you can use: 36 24 37 25 ```yaml ··· 43 31 44 32 > [!NOTE] 45 33 > 46 - > Be aware that rust-analyzer from rustup follows Rust's release schedule, which means 47 - > it may lag behind the version bundled with the VS Code extension. 34 + > rust-analyzer from rustup follows Rust's release schedule, which may lag behind the 35 + > version bundled with the VS Code extension. 48 36 49 37 ## Logging 38 + 39 + <!-- TODO: --> 50 40 51 41 By default, the preprocessor shows a progress spinner when it is running. 52 42 ··· 57 47 58 48 ## Error handling 59 49 60 - By default, when the preprocessor encounters any non-fatal issues, such as when a link 61 - fails to resolve, it prints them as warnings but continues to run. This is so that your 62 - book continues to build via `mdbook serve` while you make edits. 50 + When running locally, when the preprocessor encounters any non-fatal issues, such as 51 + when a link fails to resolve, it prints them as warnings but continues to run. This is 52 + so that your book continues to build via `mdbook serve` while you make edits. 63 53 64 54 When running in CI, all such warnings are promoted to errors. The preprocessor will exit 65 - with a non-zero status code when there are warnings, which will fail your build. This 66 - prevents outdated or incorrect links from being accidentally deployed. 55 + with a non-zero status code which will fail your build. This is to prevent outdated or 56 + incorrect links from being accidentally deployed. 67 57 68 58 You can explicitly control this behavior using the 69 59 [`fail-on-warnings`](configuration.md#fail-on-warnings) option. 70 60 71 61 [^ra-on-path]: 72 - Unless you use the [`rust-analyzer`](configuration.md#rust-analyzer) option. 62 + You may alternatively specify a command to use for rust-analyzer via the 63 + [`rust-analyzer`](configuration.md#rust-analyzer) configuration option. 73 64 74 65 [^ci-true]: 75 66 Specifically, when `CI` is anything other than `""`, `"0"`, or `"false"`. The logic
+30 -25
docs/src/rustdoc-link/getting-started.md
··· 1 1 # Getting started 2 2 3 - Follow these steps to start using `mdbook-rustdoc-link` in your book project! 4 - 5 3 ## Install 6 4 7 5 You will need to: 8 6 9 - 1. Have [rust-analyzer]: 7 + 1. Have [rust-analyzer].: 10 8 11 - - If you already use the [VS Code extension][ra-extension]: this crate automatically 12 - uses the server binary that comes with it, no extra setup is needed! 13 - - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure 14 - it's on your `PATH`. 9 + - If you already use the [VS Code extension][ra-extension], no setup is required: the 10 + preprocessor automatically uses the server binary packaged with it. 11 + - Otherwise, [install][ra-install] rust-analyzer (e.g. via `rustup`) and make sure it 12 + is available on `PATH`. 15 13 16 - 2. Install this crate: 14 + 2. Install the preprocessor: 17 15 18 16 ``` 19 17 cargo install mdbookkit --features rustdoc-link 20 18 ``` 21 19 22 - Or you can grab precompiled binaries from [GitHub releases][gh-releases]. 20 + Alternatively, you may obtain precompiled binaries from [GitHub 21 + releases][gh-releases]. 22 + 23 + <!-- TODO: cargo binstall --> 23 24 24 25 ## Configure 25 26 26 - Configure your `book.toml` to use it as a [preprocessor]: 27 + Configure your `book.toml` to use the installed program as a [preprocessor]: 27 28 28 29 ```toml 29 30 [book] ··· 32 33 [preprocessor.rustdoc-link] 33 34 # mdBook will run `mdbook-rustdoc-link` 34 35 after = ["links"] 35 - # recommended, so that it can see content from {{#include}} as well 36 + # mdBook will run this preprocessor after the default `links` preprocessor. 37 + # This is recommended. It allows the preprocessor to see text embedded 38 + # via {{#include}} directives. 36 39 ``` 37 40 38 41 ## Write 39 42 40 - In your documentation, when you want to link to a Rust item, such as a type, a function, 41 - etc., simply use its name in place of a URL, like this: 43 + In your documentation, where you want to link to a Rust item, such as a type, a 44 + function, etc., simply use its name in place of a URL: 42 45 43 46 ```md 44 47 Like [`std::thread::spawn`], [`tokio::task::spawn`] returns a 45 48 [`JoinHandle`][tokio::task::JoinHandle] struct. 46 49 ``` 47 50 48 - The preprocessor will then turn them into hyperlinks: 51 + The preprocessor will convert such symbols into hyperlinks: 49 52 50 53 <figure class="fig-text"> 51 54 ··· 54 57 55 58 </figure> 56 59 57 - This works in both `mdbook build` and `mdbook serve`! 60 + The preprocessor runs in both `mdbook build` and `mdbook serve`. 58 61 59 62 ![screen recording of mdbook-rustdoc-link during mdbook build](media/screencap.webp) 60 - 61 - To read more about this project, feel free to return to [Overview](index.md#overview). 62 63 63 64 > [!IMPORTANT] 64 65 > 65 - > It is assumed that you are running `mdbook` within a Cargo project. 66 + > It is assumed that you are running mdBook from within a Cargo project. 66 67 > 67 68 > If you are working on a crate, and your book directory is within your source tree, 68 - > such as next to `Cargo.toml`, then running `mdbook` from there will "just work". 69 + > such as next to `Cargo.toml`, then running mdBook from there will "just work". 69 70 > 70 - > If your book doesn't belong to a Cargo project, refer to 71 - > [Workspace layout](workspace-layout.md) for more information on how you can setup up 72 - > the preprocessor. 71 + > If your book doesn't reside within a Cargo project, refer to 72 + > [Workspace layout](workspace-layout.md) for instructions on setting up the 73 + > preprocessor. 73 74 74 75 > [!TIP] 75 76 > ··· 78 79 > 79 80 > Items from `std` will generate links to <https://doc.rust-lang.org>, while items from 80 81 > third-party crates will generate links to <https://docs.rs>. 81 - > 82 - > So really, rust-analyzer is doing the heavy-lifting here. This crate is just the glue 83 - > code :) 82 + 83 + ## Next steps 84 + 85 + - See the full list of [supported syntax](supported-syntax.md). 86 + - Understand [how the preprocessor resolves links](name-resolution.md) under the hood. 87 + - Check out [available configuration options](configuration.md). 88 + - Learn about some [known issues and limitations](known-issues.md). 84 89 85 90 <!-- prettier-ignore-start --> 86 91
+11 -13
docs/src/rustdoc-link/index.md
··· 7 7 8 8 </div> 9 9 10 - **[_rustdoc_-style linking][rustdoc] for [mdBook]** (with the help of [rust-analyzer]). 10 + Link to Rust API docs by name in [mdBook], [_rustdoc_-style][rustdoc]. 11 11 12 - You write: 12 + Instead of manually finding and pasting URLs, you simply write ... 13 13 14 14 ```md 15 15 The [`option`][std::option] and [`result`][std::result] modules define optional and ··· 18 18 collections. [^1] 19 19 ``` 20 20 21 - You get: 21 + ... and you will get: 22 22 23 23 <figure class="fig-text"> 24 24 ··· 29 29 30 30 </figure> 31 31 32 - `mdbook-rustdoc-link` is an mdBook [preprocessor]. Using rust-analyzer, it converts type 33 - names, module paths, and so on, into links to online crate docs. No more finding and 34 - pasting URLs by hand. 35 - 36 32 <figure> 37 33 38 34 ![screen recording of mdbook-rustdoc-link during mdbook build](media/screencap.webp) 39 35 40 36 </figure> 41 37 42 - ## Overview 38 + > [!NOTE] 39 + > 40 + > This preprocessor depends on [rust-analyzer] to accurately resolve Rust items. 43 41 44 - To get started, simply follow the [quickstart guide](getting-started.md)! 42 + ## Overview 45 43 46 - If you would like to read more about this crate: 44 + Follow the [quickstart guide](getting-started.md) to try out the preprocessor. 47 45 48 46 For **writing documentation** — 49 47 50 - - To learn more about how it is resolving items into links, including 48 + - To learn more about how the preprocessor resolves items into links, including 51 49 [feature-gated items](name-resolution.md#feature-gated-items), see 52 50 [Name resolution](name-resolution.md). 53 - - To know how to link to other types of items like 51 + - To learn how to link to additional items such as 54 52 [functions, macros](supported-syntax.md#functions-and-macros), and 55 53 [implementors](supported-syntax.md#implementors-and-fully-qualified-syntax), see 56 54 [Supported syntax](supported-syntax.md). 57 55 58 - For **adapting this crate to your project** — 56 + For **making the preprocessor work with your project** — 59 57 60 58 - If you use [Cargo workspaces][workspaces], see specific instructions in 61 59 [Workspace layout](workspace-layout.md).
+46 -45
docs/src/rustdoc-link/known-issues.md
··· 1 1 # Known issues 2 2 3 - <details class="toc" open> 4 - <summary>Sections</summary> 5 - 6 - - [Performance](#performance) 7 - - [Incorrect links](#incorrect-links) 8 - - [Macros](#macros) 9 - - [Trait items](#trait-items) 10 - - [Private items](#private-items) 11 - - [Unresolved items](#unresolved-items) 12 - - [Associated items on primitive types](#associated-items-on-primitive-types) 13 - - [Sites other than docs.rs](#sites-other-than-docsrs) 14 - - [Wrong line numbers in diagnostics](#wrong-line-numbers-in-diagnostics) 15 - 16 - </details> 17 - 18 3 ## Performance 19 4 20 5 `mdbook-rustdoc-link` itself doesn't need much processing power, but it invokes 21 - rust-analyzer, which does a full scan of your workspace. The larger your codebase is, 22 - the longer `mdbook` will have to wait for the preprocessor. This is the source of the 6 + rust-analyzer, which does a full scan of your workspace. The larger your workspace is, 7 + the longer mdBook will have to wait for the preprocessor. This is the source of the 23 8 majority of the run time. 24 9 25 10 There is an [experimental caching feature](caching.md#enabling-caching), which persists 26 11 query results after runs and reuses them when possible, avoiding spawning rust-analyzer 27 12 when your edit doesn't involve item links. 28 13 29 - ## Incorrect links 30 - 31 - In limited circumstances, the preprocessor generates links that are incorrect or 32 - inaccessible. 14 + ## Incorrect/unresolvable links 33 15 34 16 > [!NOTE] 35 17 > 36 - > The following observations are based on rust-analyzer 37 - > <ra-version>(version)</ra-version>. 18 + > The following observations are as of rust-analyzer <ra-version>(version)</ra-version>. 38 19 39 - ### Macros 20 + In some circumstances, the preprocessor generates links that are incorrect or 21 + inaccessible. 22 + 23 + ### Derive macros 24 + 25 + Previously, it was possible to link to the documentation for a derive macro instead of 26 + the derived trait by using the [macro syntax](supported-syntax.md#functions-and-macros), 27 + for example, by writing [`[serde::Serialize!]`][serde::Serialize] instead of 28 + [`[serde::Serialize]`][serde::Serialize]. 40 29 41 - Macros exported with [`#[macro_export]`][macro_export] are always exported at crate 42 - root, and are documented as such by rustdoc, but rust-analyzer currently generates links 43 - to the modules they are defined in. For example: 30 + This no longer works due to an upstream change. To link to such derive macros, you must 31 + use paths that directly point to them, for example, `serde_derive::Serialize`. 44 32 45 - - [~~`panic!`~~], and many other `std` macros 46 - - The correct link is 47 - [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic] 48 - - [~~`serde_json::json!`~~] 49 - - The correct link is 50 - [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json] 33 + ### Attribute macros 51 34 52 - Attribute macros generate links that use `macro.<macro_name>.html`, but rustdoc actually 53 - generates `attr.<macro_name>.html`. For example: 35 + Links generated by rust-analyzer for attribute macros end with 36 + `macro.<macro_name>.html`, but they should end with `attr.<macro_name>.html`. For 37 + example: 54 38 55 39 - [~~`tokio::main!`~~] 56 40 - The correct link is ··· 83 67 The preprocessor does not yet warn you about links to private items: rust-analyzer will 84 68 generate links for items regardless of their crate-level visibility. 85 69 86 - ## Unresolved items 87 - 88 - ### Associated items on primitive types 89 - 90 - > [!NOTE] 91 - > 92 - > The following observations are based on rust-analyzer 93 - > <ra-version>(version)</ra-version>. 70 + ### Items on primitive types 94 71 95 72 Links to associated methods and items on primitive types are currently not resolved by 96 73 rust-analyzer. For example: ··· 102 79 103 80 Currently, items from crates other than `std` always generate links that point to 104 81 <https://docs.rs>. `mdbook-rustdoc-link` does not yet support configuring alternative 105 - hosting sites for crates (such as `wasm-bindgen` which hosts API docs under 106 - `https://rustwasm.github.io/wasm-bindgen/api/`). 82 + URL prefixes. 107 83 108 84 ## Wrong line numbers in diagnostics 109 85 ··· 125 101 126 102 Unless mdBook somehow gains [source map][sourcemap] support, this problem is unlikely to 127 103 ever be solved. 104 + 105 + ## Resolved issues 106 + 107 + ### Since rust-analyzer `2025-08-11` 108 + 109 + Previously, generated links to macros were often incorrect. These are currently 110 + [fixed upstream](https://github.com/rust-lang/rust-analyzer/pull/20384) as of 111 + rust-analyzer 112 + [`2025-08-11`](https://github.com/rust-lang/rust-analyzer/releases/tag/2025-08-11). 113 + 114 + <details> 115 + <summary>Original description</summary> 116 + 117 + Macros exported with [`#[macro_export]`][macro_export] are always exported at crate 118 + root, and are documented as such by rustdoc, but rust-analyzer currently generates links 119 + to the modules they are defined in. For example: 120 + 121 + - [~~`panic!`~~], and many other `std` macros 122 + - The correct link is 123 + [https://doc.rust-lang.org/stable/std~~/macros~~/macro.panic.html][panic] 124 + - [~~`serde_json::json!`~~] 125 + - The correct link is 126 + [https://docs.rs/serde_json/1.0.140/serde_json~~/macros~~/macro.json.html][serde_json::json] 127 + 128 + </details> 128 129 129 130 <!-- prettier-ignore-start --> 130 131
+17 -19
docs/src/rustdoc-link/motivation.md
··· 1 1 # Motivation 2 2 3 - [rustdoc supports linking to items by name][rustdoc], a.k.a. [intra-doc 4 - links][intra-doc-link]. This is awesome for at least two reasons: 3 + [rustdoc supports linking to items by name][rustdoc]. This is awesome for at least two 4 + reasons: 5 5 6 - - It's convenient. It could be as simple as [just adding brackets][uv-brackets]. 7 - - [Docs.rs](https://docs.rs) will generate cross-crate links that are version-pinned. 6 + - It's convenient. It could be as simple as [just adding brackets around 7 + names][uv-brackets]. 8 + - Links generated via rustdoc are version-pinned. Instead of seeing links that default 9 + to the latest version, where items may have been moved or deleted, you get the 10 + versions that your packages actually depend on. 8 11 9 12 mdBook doesn't have the luxury of accessing compiler internals yet, so you are left with 10 - manually sourcing links from docs.rs. Then one of two things could happen: 13 + manually sourcing links from [docs.rs](https://docs.rs). Then one of two things could 14 + happen: 11 15 12 - - APIs are mentioned without linking to reference docs. 13 - 14 - This is probably fine for tutorials and examples, but it does mean readers of your 15 - docs won't be able to move from guides to references as easily. 16 + - APIs are mentioned without appropriate links to reference docs. 16 17 17 - - You do want at least some cross-references, but it is cumbersome to find and copy the 18 - correct links, and even more so to maintain them. 18 + This may be fine for tutorials and examples. However, readers of your docs will not be 19 + able to navigate between guides and references as easily as it could have been. 19 20 20 - Links to docs.rs often use `latest` as the version, which could become out-of-sync 21 - with your code, especially if they point to third-party or unstable APIs. 21 + - You do want at least some reference links. It could quickly become cumbersome to find 22 + and copy the correct links by hand, and even more so to maintain them over time. 22 23 23 24 `mdbook-rustdoc-link` is the tooling answer to these problems. _Effortless, correct, and 24 25 good practice — choose all three!_ 25 26 26 - > [!NOTE] 27 + > [!TIP] 27 28 > 28 - > That being said, sometimes manually specifying URLs is the best option. 29 - > 30 - > Most importantly, writing links by name means they won't be rendered as such when your 31 - > Markdown source is displayed elsewhere. If your document is also intended for places 32 - > like GitHub or crates.io, then you should probably not use this preprocessor. 29 + > This style of linking is also known as "intra-doc links" — read more about it in the 30 + > [original RFC][intra-doc-link]. 33 31 34 32 <!-- prettier-ignore-start --> 35 33
+25 -41
docs/src/rustdoc-link/name-resolution.md
··· 1 1 # Name resolution 2 2 3 - `mdbook-rustdoc-link` resolves items in the context of your crate's "entrypoint", which 4 - is usually your `lib.rs` or `main.rs` (the [specific rules](#which-entrypoint) are 5 - mentioned below). 3 + The preprocessor resolves items **in the scope of your crate's "entrypoint."** This is 4 + usually `lib.rs` or `main.rs` (the [exact rules](#which-entrypoint) are mentioned 5 + below). 6 6 7 7 > [!TIP] 8 8 > 9 - > If you use Cargo workspaces, or if your source tree has special layout, see 10 - > [Workspace layout](workspace-layout.md) for more information. 11 - 12 - An item must be **in scope in the entrypoint** for the proprocessor to generate a link 13 - for it. 9 + > If you use Cargo workspaces, or if your source tree has a custom layout, consult 10 + > [Workspace layout](workspace-layout.md) for additional instructions. 14 11 15 12 For example, with the following as `lib.rs`: 16 13 ··· 29 26 Items in the entrypoint can be linked to with just their names: 30 27 31 28 > ```md 32 - > [`Diagnostics`] encapsulates possible issues detected within Markdown sources. 29 + > [`Diagnostics`] contains issues detected within Markdown sources. 33 30 > 34 31 > This crate uses the [`Context`] trait from [`anyhow`]. 35 32 > ``` 36 33 > 37 - > [`Diagnostics`] encapsulates possible issues detected within Markdown sources. 34 + > [`Diagnostics`] contains issues detected within Markdown sources. 38 35 > 39 36 > This crate uses the [`Context`] trait from [`anyhow`]. 40 37 ··· 46 43 > 47 44 > [`FromIterator`] is in the prelude starting from Rust 2021. 48 45 49 - Though technically not required — to make items from your crate more distinguishable 50 - from others in your Markdown source, you can write `crate::*`: 46 + To distinguish an item as being from your crate rather than from a third-party crate, 47 + you may write `crate::*`, although this is not required: 51 48 52 49 > ```md 53 50 > The [`is_ci`][crate::error::is_ci] function detects whether the preprocessor is ··· 67 64 > 68 65 > [`JoinSet`][tokio::task::JoinSet] is analogous to Python's `asyncio.as_completed`. 69 66 70 - > [!TIP] 71 - > 72 - > In short, write links the way you `use` an item in your `lib.rs` or `main.rs`. 73 - 74 - The preprocessor will emit a warning if an item cannot be resolved: 67 + The preprocessor emits warnings for items that cannot be resolved: 75 68 76 69 <figure> 77 70 ··· 84 77 </figcaption> 85 78 86 79 </figure> 87 - 88 - This is something to remember especially if you are including doc comments as part of 89 - your Markdown docs. Only rustdoc has the ability to [resolve names from where the 90 - comments are written][rustdoc-scoping], so links that work in doc comments may not work 91 - when using this preprocessor! 92 80 93 81 ## Feature-gated items 94 82 ··· 112 100 > 113 101 > [Tutorial for clap's Derive API][clap::_derive::_tutorial] 114 102 115 - ## Which entrypoint 103 + ## Which "entrypoint"? 116 104 117 105 For this preprocessor, the "entrypoint" is usually `src/lib.rs` or `src/main.rs`. 118 106 ··· 126 114 127 115 > [!NOTE] 128 116 > 129 - > The following are implementation details. See 130 - > [rustdoc_link/mod.rs](/crates/mdbookkit/src/bin/rustdoc_link/mod.rs). 117 + > The following are implementation details. 131 118 132 - `mdbook-rustdoc-link` parses your book and collects every link that looks like a Rust 133 - item. Then it synthesizes a Rust function that spells out all the items, which looks 134 - roughly like this: 119 + The preprocessor parses your book and collects every link that looks like a Rust item. 120 + Then it synthesizes a Rust function that spells out all the items, which could look 121 + something like: 135 122 136 123 ```rs 137 124 fn __ded48f4d_0c4f_4950_b17d_55fd3b2a0c86__ () { ··· 144 131 } 145 132 ``` 146 133 147 - > Note that this is barely valid Rust — `Result::<T, E>;` is a type without a value, and 148 - > you wouldn't use `serde::Serialize` as a regular macro. 149 - > 150 - > This is where language servers like rust-analyzer excel — they can [provide maximally 151 - > useful information out of badly-shaped code][why-lsp]. 152 - 153 - The preprocessor appends this fake function to your `lib.rs` or `main.rs` (in memory, it 154 - doesn't modify your file) and [sends][didOpen] it to rust-analyzer. Then, for each item 155 - that needs to be resolved, the preprocessor sends an [external documentation 156 - request][externalDocs]. 134 + The preprocessor appends this fake function to your `lib.rs` or `main.rs` (in memory) 135 + and [sends][didOpen] it to rust-analyzer. Then, for each item that needs to be resolved, 136 + the preprocessor sends an [external documentation request][externalDocs]. 157 137 158 138 ```json 159 139 { ··· 165 145 } 166 146 } 167 147 ``` 168 - 169 - Hence item names in your book must be resolvable from your crate entrypoint! 170 148 171 149 This process is as if you had typed a name into your source file and used the "Open 172 - Docs" feature — except it's fully automated. 150 + Docs" feature — except it is automated. 173 151 174 152 <figure id="media-open-docs"> 175 153 <img src="media/open-docs.png" alt="the Open Docs option in VS Code"> ··· 181 159 } 182 160 } 183 161 </style> 162 + 163 + > Note that the synthesized function is barely valid Rust — `Result::<T, E>;` is a type 164 + > without a value, and you wouldn't use `serde::Serialize` as a regular macro. 165 + > 166 + > This is where language servers like rust-analyzer excel — they can [provide maximally 167 + > useful information out of badly-shaped code][why-lsp]. 184 168 185 169 <!-- prettier-ignore-start --> 186 170
+3 -6
docs/src/rustdoc-link/standalone-usage.md
··· 1 1 # Standalone usage 2 2 3 - You can use `mdbook-rustdoc-link` as a standalone Markdown processor from the command 4 - line. 5 - 6 - Simply use the `markdown` subcommand, send your Markdown through stdin, and receive the 7 - result through stdout, for example: 3 + You can use `mdbook-rustdoc-link` as a standalone Markdown processor via the `markdown` 4 + subcommand: send your Markdown through stdin, and receive the result through stdout, for 5 + example: 8 6 9 7 ```bash 10 8 mdbook-rustdoc-link markdown < README.md ··· 16 14 17 15 <figure id="media-open-docs"> 18 16 <img src="media/standalone-usage.png" alt="example using mdbook-rustdoc-link as a command line tool"> 19 - <figcaption>Use it in any text processing pipeline!</figcaption> 20 17 </figure> 21 18 22 19 <style>
+70 -99
docs/src/rustdoc-link/supported-syntax.md
··· 7 7 8 8 </div> 9 9 10 - This page showcases all the syntax supported by `mdbook-rustdoc-link`. 11 - 12 - Most of the formats [supported by rustdoc][rustdoc-linking] are supported. Unsupported 10 + Most of the syntax [supported by rustdoc][rustdoc-linking] are supported. Unsupported 13 11 syntax and differences in behavior are emphasized below. 14 12 15 13 In general, specifying items as you would when writing Rust code should "just work". 16 14 17 - <details class="toc" open> 18 - <summary>Sections</summary> 19 - 20 - - [Types, modules, and associated items](#types-modules-and-associated-items) 21 - - [Generic parameters](#generic-parameters) 22 - - [Functions and macros](#functions-and-macros) 23 - - [Implementors and fully qualified syntax](#implementors-and-fully-qualified-syntax) 24 - - [Disambiguators](#disambiguators) 25 - - [Special types](#special-types) 26 - - [Struct fields](#struct-fields) 27 - - [Markdown link syntax](#markdown-link-syntax) 28 - - [Linking to page sections](#linking-to-page-sections) 29 - 30 - </details> 31 - 32 15 > [!TIP] 33 16 > 34 17 > This page is also used for snapshot testing! To see how all the links would look like 35 18 > in Markdown after they have been processed, see 36 - > [supported-syntax.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.snap) 19 + > [supported-syntax.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.snap) 37 20 > and 38 - > [supported-syntax.stderr.snap](/crates/mdbookkit/tests/snaps/rustdoc_link/supported-syntax.stderr.snap). 21 + > [supported-syntax.stderr.snap](/crates/mdbook-rustdoc-links/src/tests/snaps/supported-syntax.stderr.snap). 39 22 40 - ## Types, modules, and associated items 23 + ## Types, modules, associated items 41 24 42 25 > ```md 43 26 > Module [`alloc`][std::alloc] — Memory allocation APIs. ··· 63 46 64 47 ## Generic parameters 65 48 66 - Types can contain generic parameters. This is _compatible_ with rustdoc. 49 + Types may contain generic parameters. This is _compatible_ with rustdoc. 67 50 68 51 > ```md 69 52 > [`Vec<T>`] — A heap-allocated _vector_ that is resizable at runtime. ··· 83 66 > | [`&'a mut T`][std::marker::PhantomData<&'a mut T>] | **in**variant | 84 67 > | [`fn(T)`][std::marker::PhantomData<fn(T)>] | **contra**variant | 85 68 86 - This includes if you use turbofish: 69 + Turbofish are also supported: 87 70 88 71 > ```md 89 72 > `collect()` is one of the few times you’ll see the syntax affectionately known as the ··· 95 78 96 79 ## Functions and macros 97 80 98 - To indicate that an item is a function, add `()` after the function name. To indicate 99 - that an item is a macro, add `!` after the macro name, optionally followed by `()`, 100 - `[]`, or `{}`. This is _compatible_ with rustdoc. 101 - 102 - Note that there cannot be arguments within `()`, `[]`, or `{}`. 81 + Functions and macros can be linked to just like other named items. To distinguish a 82 + function from other items of the same name, add `()` after the function name. To 83 + distinguish a macro from other items of the same name, add `!` after the macro name. 84 + This is _compatible_ with rustdoc. 103 85 104 86 > ```md 105 - > [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally 106 - > use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]! 87 + > [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use 88 + > [`format`][std::fmt::format()] in place of [`format!`][std::format!]! 107 89 > ``` 108 90 > 109 - > [`vec!`][std::vec!][^2] is different from [`vec`][std::vec], and don't accidentally 110 - > use [`format()`][std::fmt::format()] in place of [`format!()`][std::format!()][^2]! 91 + > [`vec!`][std::vec!] is different from [`vec`][std::vec], and don't accidentally use 92 + > [`format`][std::fmt::format()] in place of [`format!`][std::format!]! 111 93 112 - The macro syntax works for attribute and derive macros as well (even though this is not 113 - how they are invoked). 94 + Note that there cannot be arguments within `()`, `[]`, or `{}`. The `macro!` syntax 95 + works for attribute and derive macros as well (even though this is not how they are 96 + invoked). 114 97 115 - > ```md 116 - > There is a [derive macro][serde::Serialize!] to generate implementations of the 117 - > [`Serialize`][serde::Serialize] trait. 118 - > ``` 98 + > [!NOTE] 99 + > 100 + > As of rust-analyzer <ra-version>(version)</ra-version>, the `macro!` syntax can no 101 + > longer disambiguate between a derive macro and its corresponding trait. For example, 119 102 > 120 - > There is a [derive macro][serde::Serialize!] to generate implementations of the 121 - > [`Serialize`][serde::Serialize] trait. 103 + > > ``` 104 + > > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait. 105 + > > ``` 106 + > > 107 + > > Both [`serde::Serialize`] and [`serde::Serialize!`] link to the `Serialize` trait. 108 + > 109 + > To link to such derive macros, you must use paths that directly point to them, such as 110 + > `serde_derive::Serialize`. 122 111 123 - ## Implementors and fully qualified syntax 112 + ## Fully qualified paths 124 113 125 - Trait implementors may supply additional documentation about their implementations. To 126 - link to implemented items instead of the traits themselves, use fully qualified paths, 127 - including `<... as Trait>` if necessary. This is a _new feature_ that rustdoc does not 128 - currently support. 114 + Trait implementors may supply additional documentation about the implementation. To link 115 + to such documentation instead of the traits themselves, use fully qualified paths, 116 + including `<... as Trait>` if necessary. This is an _additional syntax_ that rustdoc 117 + does not currently support. 129 118 130 119 > ```md 131 120 > [`Result<T, E>`] implements [`IntoIterator`]; its ··· 146 135 > [!NOTE] 147 136 > 148 137 > If your type has generic parameters, you must supply concrete types for them for 149 - > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` won't 138 + > rust-analyzer to be able to locate an implementation. That is, `Result<T, E>` will not 150 139 > work, but `Result<(), ()>` will (unless there happen to be types `T` and `E` literally 151 140 > in scope). 152 141 153 - ## Disambiguators 154 - 155 - rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but 156 - ignored**: 157 - 158 - > ```md 159 - > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 160 - > ``` 161 - > 162 - > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 163 - 164 - This is largely okay because currently, duplicate names in Rust are allowed only if they 165 - correspond to items in different [namespaces], for example, between macros and modules, 166 - and between struct fields and methods — this is mostly covered by the function and macro 167 - syntax, described [above](#functions-and-macros). 168 - 169 - If you encounter items that must be disambiguated using rustdoc's disambiguator syntax, 170 - other than [the "special types" listed below](#special-types), please [file an 171 - issue][gh-issues]! 172 - 173 - ## Special types 174 - 175 - > [!WARNING] 176 - 177 - There is **no support** on types whose syntax is not a path; they are currently not 178 - parsed at all: 179 - 180 - > references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like 181 - > `*const T`, trait objects like `dyn Any`, and the never type `!` 182 - 183 - Note that such types can still be used as generic params, just not as standalone types. 184 - 185 - ## Struct fields 186 - 187 - > [!WARNING] 188 - 189 - Linking to struct fields is **not supported** yet. This is **incompatible** with 190 - rustdoc. 191 - 192 - ## Markdown link syntax 142 + ## Link format 193 143 194 144 All Markdown link formats supported by rustdoc are supported: 195 145 ··· 225 175 Shortcuts are supported, and can contain inline markups: 226 176 227 177 > ```md 228 - > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro. 178 + > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro. 229 179 > ``` 230 180 > 231 - > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_][^2] macro. 232 - 233 - (The items must still be resolvable; in this case `Vec` and `vec!` come from the 234 - prelude.) 181 + > You can create a [`Vec`] with [**`Vec::new`**], or by using the [_`vec!`_] macro. 235 182 236 183 ## Linking to page sections 237 184 238 - To link to a known section on a page, use a URL fragment, just like a normal link. This 239 - is _compatible_ with rustdoc. 185 + To link to a known section on a page, use a URL fragment, as you would otherwise specify 186 + for an HTTP URL. This is _compatible_ with rustdoc. 240 187 241 188 <!-- prettier-ignore-start --> 242 189 ··· 248 195 249 196 <!-- prettier-ignore-end --> 250 197 198 + ## Unsupported syntax 199 + 200 + ### Disambiguators 201 + 202 + rustdoc's [disambiguator syntax][disambiguator] `prefix@name` is **accepted but 203 + ignored.** To disambiguate functions and macros, use the 204 + [functions and macros](#functions-and-macros) syntax. 205 + 206 + > ```md 207 + > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 208 + > ``` 209 + > 210 + > [`std::vec`], [`mod@std::vec`], and [`macro@std::vec`] all link to the `vec` _module_. 211 + 212 + ### Special types 213 + 214 + There is **no support** on types whose syntax is not a path; they are currently not 215 + parsed at all: 216 + 217 + > references `&T`, slices `[T]`, arrays `[T; N]`, tuples `(T1, T2)`, pointers like 218 + > `*const T`, trait objects like `dyn Any`, and the never type `!` 219 + 220 + Note that such types can still be used as generic params, just not as standalone types. 221 + 222 + ### Struct fields 223 + 224 + Linking to struct fields is **not supported** yet. This is **incompatible** with 225 + rustdoc. 226 + 251 227 [^1]: 252 228 rust-analyzer's ability to generate links for enum variants like `Option::Some` was 253 229 improved only somewhat recently: before 254 230 [#19246](https://github.com/rust-lang/rust-analyzer/pull/19246), links for variants 255 231 and associated items may only point to the types themselves. If linking to such 256 232 items doesn't seem to work for you, be sure to upgrade to a newer rust-analyzer 257 - first! 258 - 259 - [^2]: 260 - As of rust-analyzer <ra-version>(version)</ra-version>, links generated for macros 261 - don't always work. Examples include [`std::format!`] (seen above) and 262 - [`tokio::main!`]. For more info, see [Known issues](known-issues.md#macros). 233 + first. 263 234 264 235 <!-- prettier-ignore-start --> 265 236
+16 -25
docs/src/rustdoc-link/workspace-layout.md
··· 3 3 As mentioned in [Name resolution](name-resolution.md), the preprocessor must know where 4 4 your crate's entrypoint is. 5 5 6 - To do that, it tries to find a `Cargo.toml` by running 6 + To do that, it will try to locate the nearest `Cargo.toml` by running 7 7 [`cargo locate-project`][locate-project], by default from the current working directory. 8 8 9 - If you have a single-crate setup, this should "just work", regardless of where your book 10 - directory is within your source tree. 9 + If you have a single-package setup, this should "just work", regardless of where your 10 + book directory is within your source tree. 11 11 12 12 If you are using [Cargo workspaces][workspaces], then the preprocessor may fail with the 13 13 message: ··· 16 16 Error: Cargo.toml does not have any lib or bin target 17 17 ``` 18 18 19 - This means it found your workspace `Cargo.toml` instead of a member crate's. To use the 20 - preprocessor in this case, some extra setup is needed. 21 - 22 - <details class="toc" open> 23 - <summary>Sections</summary> 24 - 25 - - [Using the `manifest-dir` option](#using-the-manifest-dir-option) 26 - - [Placing your book inside a member crate](#placing-your-book-inside-a-member-crate) 27 - - [Documenting multiple crates](#documenting-multiple-crates) 28 - - [Using without a Cargo project](#using-without-a-cargo-project) 29 - 30 - </details> 19 + In this case, the preprocessor has located the workspace `Cargo.toml` rather than that 20 + of a specific package, and some extra setup is required. 31 21 32 22 ## Using the `manifest-dir` option 33 23 34 24 In your `book.toml`, in the `[preprocessor.rustdoc-link]` table, set the 35 25 [`manifest-dir`](configuration.md#manifest-dir) option to the relative path to a member 36 - crate. 26 + package. 37 27 38 28 For example, if you have the following workspace layout: 39 29 ··· 62 52 > `manifest-dir` should be a path **relative to `book.toml`**, not relative to workspace 63 53 > root. 64 54 65 - ## Placing your book inside a member crate 55 + ## Placing your book inside a member package 66 56 67 - If you have a "main" crate, you can also move your book directory to that crate, and run 68 - `mdbook` from there: 57 + If you have a "main" package, you can also move your book directory to that package, and 58 + run mdBook from there: 69 59 70 60 ``` 71 61 my-workspace/ ··· 82 72 └── ... 83 73 ``` 84 74 85 - ## Documenting multiple crates 75 + ## Documenting multiple packages 86 76 87 - If you would like to document items from several independent crates, but still would 77 + If you would like to document items from several independent packages, but still would 88 78 like to centralize your book in one place — unfortunately, the preprocessor does not yet 89 79 have the ability to work with multiple entrypoints. 90 80 91 - A possible workaround would be to turn your book folder into a private crate that 92 - depends on the crates you would like to document. Then you can link to them as if they 93 - were third-party crates. 81 + A possible workaround would be to turn your book folder into a private package that 82 + depends on the packages you would like to document. Then you can link to them as if they 83 + were third-party packages. The generated links will point to the original packages 84 + instead of this private package. 94 85 95 86 ``` 96 87 my-workspace/ ··· 126 117 (e.g. perhaps you would like to mention `std`) — unfortunately, the preprocessor does 127 118 not yet support running without a Cargo project. 128 119 129 - Instead, you can setup your book project as a private, dummy crate. 120 + Instead, you can setup your book project as a private, dummy package. 130 121 131 122 ``` 132 123 my-book/