Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ git-repository-url = "https://github.com/rust-lang/book"
[preprocessor.trpl-note]

[preprocessor.trpl-listing]
[preprocessor.trpl-listing-link]
output-mode = "default"

[rust]
Expand Down
3 changes: 2 additions & 1 deletion packages/mdbook-trpl/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions packages/mdbook-trpl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ path = "src/bin/note.rs"
name = "mdbook-trpl-listing"
path = "src/bin/listing.rs"

[[bin]]
name = "mdbook-trpl-listing-link"
path = "src/bin/listing_link.rs"

[[bin]]
name = "mdbook-trpl-heading"
path = "src/bin/heading.rs"
Expand All @@ -29,6 +33,7 @@ pulldown-cmark-to-cmark = "19"
serde_json = "1"
thiserror = "1.0.60"
toml = "0.8.12"
regex = "1.5"

[dev-dependencies]
assert_cmd = "2"
Expand Down
39 changes: 39 additions & 0 deletions packages/mdbook-trpl/src/bin/listing_link.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::io;

use clap::{self, Parser, Subcommand};
use mdbook::preprocess::{CmdPreprocessor, Preprocessor};

use mdbook_trpl::listing_link::ListingLinkPreprocessor;

fn main() -> Result<(), String> {
let cli = Cli::parse();
if let Some(Command::Supports { renderer }) = cli.command {
return if ListingLinkPreprocessor.supports_renderer(&renderer) {
Ok(())
} else {
Err(format!("Renderer '{renderer}' is unsupported"))
};
}

let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())
.map_err(|e| format!("{e}"))?;
let processed = ListingLinkPreprocessor
.run(&ctx, book)
.map_err(|e| format!("{e}"))?;
serde_json::to_writer(io::stdout(), &processed).map_err(|e| format!("{e}"))
}

/// A simple preprocessor for handling listing links in _The Rust Programming Language_.
#[derive(Parser, Debug)]
struct Cli {
#[command(subcommand)]
command: Option<Command>,
}

#[derive(Subcommand, Debug)]
enum Command {
/// Is the renderer supported?
///
/// All renderers are supported! This is the contract for mdBook.
Supports { renderer: String },
}
1 change: 1 addition & 0 deletions packages/mdbook-trpl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod config;
mod figure;
mod heading;
mod listing;
pub mod listing_link;
mod note;

pub use config::Mode;
Expand Down
55 changes: 55 additions & 0 deletions packages/mdbook-trpl/src/listing_link/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use mdbook::{
book::Book,
errors::Result,
preprocess::{Preprocessor, PreprocessorContext},
BookItem,
};
use regex::Regex;
use std::collections::HashMap;

pub struct ListingLinkPreprocessor;

impl Preprocessor for ListingLinkPreprocessor {
fn name(&self) -> &str {
"trpl-listing-link"
}

fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<Book> {
let number_re = Regex::new(r#"id="listing-(\d+-\d+)"#).unwrap();
let listing_re = Regex::new(r"Listing\s(\d+-\d+)").unwrap();
let mut listings: HashMap<String, String> = HashMap::new();

// Collect all number patterns and their corresponding filenames
book.for_each_mut(|item| {
if let BookItem::Chapter(ref mut chapter) = item {
if let Some(ref path) = chapter.path {
let filename = path.to_string_lossy().to_string();
for cap in number_re.captures_iter(&chapter.content) {
let number = cap[1].to_string();
listings.insert(number, filename.clone());
}
}
}
});

// Replace listing references with absolute href with filename and listing number hash
book.for_each_mut(|item| {
if let BookItem::Chapter(ref mut chapter) = item {
chapter.content = listing_re.replace_all(&chapter.content, |caps: &regex::Captures| {
let listing_number = &caps[1];
let href = listings.get(listing_number).map_or_else(
|| format!("#listing-{}", listing_number),
|file| format!("{}#listing-{}", file, listing_number)
);
format!(r##"<a href="{}" class="listing-link">Listing {}</a>"##, href, listing_number)
}).to_string();
}
});

Ok(book)
}

fn supports_renderer(&self, renderer: &str) -> bool {
renderer == "html" || renderer == "markdown" || renderer == "test"
}
}
Empty file.
5 changes: 2 additions & 3 deletions src/ch16-02-message-passing.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ First, in Listing 16-6, we’ll create a channel but not do anything with it.
Note that this won’t compile yet because Rust can’t tell what type of values we
want to send over the channel.

<span class="filename">Filename: src/main.rs</span>
<Listing number="16-6" file-name="src/main.rs" caption="Creating a channel and assigning the two halves to `tx` and `rx`">

```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-06/src/main.rs}}
```

<span class="caption">Listing 16-6: Creating a channel and assigning the two
halves to `tx` and `rx`</span>
</Listing>

We create a new channel using the `mpsc::channel` function; `mpsc` stands for
_multiple producer, single consumer_. In short, the way Rust’s standard library
Expand Down