Skip to content

Commit d69523a

Browse files
committed
add listing link preprocessor
1 parent 6875f02 commit d69523a

File tree

6 files changed

+77
-0
lines changed

6 files changed

+77
-0
lines changed

book.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ git-repository-url = "https://github.com/rust-lang/book"
3838
[preprocessor.trpl-note]
3939

4040
[preprocessor.trpl-listing]
41+
[preprocessor.trpl-listing-link]
4142
output-mode = "default"
4243

4344
[rust]

packages/mdbook-trpl/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ path = "src/bin/note.rs"
1111
name = "mdbook-trpl-listing"
1212
path = "src/bin/listing.rs"
1313

14+
[[bin]]
15+
name = "mdbook-trpl-listing-link"
16+
path = "src/bin/listing_link.rs"
17+
1418
[[bin]]
1519
name = "mdbook-trpl-heading"
1620
path = "src/bin/heading.rs"
@@ -29,6 +33,7 @@ pulldown-cmark-to-cmark = "19"
2933
serde_json = "1"
3034
thiserror = "1.0.60"
3135
toml = "0.8.12"
36+
regex = "1.5"
3237

3338
[dev-dependencies]
3439
assert_cmd = "2"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use std::io;
2+
3+
use clap::{self, Parser, Subcommand};
4+
use mdbook::preprocess::{CmdPreprocessor, Preprocessor};
5+
6+
use mdbook_trpl::listing_link::ListingLinkPreprocessor;
7+
8+
fn main() -> Result<(), String> {
9+
let cli = Cli::parse();
10+
if let Some(Command::Supports { renderer }) = cli.command {
11+
return if ListingLinkPreprocessor.supports_renderer(&renderer) {
12+
Ok(())
13+
} else {
14+
Err(format!("Renderer '{renderer}' is unsupported"))
15+
};
16+
}
17+
18+
let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())
19+
.map_err(|e| format!("{e}"))?;
20+
let processed = ListingLinkPreprocessor
21+
.run(&ctx, book)
22+
.map_err(|e| format!("{e}"))?;
23+
serde_json::to_writer(io::stdout(), &processed).map_err(|e| format!("{e}"))
24+
}
25+
26+
/// A simple preprocessor for handling listing links in _The Rust Programming Language_.
27+
#[derive(Parser, Debug)]
28+
struct Cli {
29+
#[command(subcommand)]
30+
command: Option<Command>,
31+
}
32+
33+
#[derive(Subcommand, Debug)]
34+
enum Command {
35+
/// Is the renderer supported?
36+
///
37+
/// All renderers are supported! This is the contract for mdBook.
38+
Supports { renderer: String },
39+
}

packages/mdbook-trpl/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod config;
22
mod figure;
33
mod heading;
44
mod listing;
5+
pub mod listing_link;
56
mod note;
67

78
pub use config::Mode;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use mdbook::{
2+
book::Book,
3+
errors::Result,
4+
preprocess::{Preprocessor, PreprocessorContext},
5+
BookItem,
6+
};
7+
use regex::Regex;
8+
9+
pub struct ListingLinkPreprocessor;
10+
11+
impl Preprocessor for ListingLinkPreprocessor {
12+
fn name(&self) -> &str {
13+
"trpl-listing-link"
14+
}
15+
16+
fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<Book> {
17+
let re = Regex::new(r"Listing\s(\d+-\d+)").unwrap();
18+
19+
book.for_each_mut(|item| {
20+
if let BookItem::Chapter(ref mut chapter) = item {
21+
chapter.content = re.replace_all(&chapter.content, r##"<a href="#listing-$1" class="listing-link">Listing $1</a>"##).to_string();
22+
}
23+
});
24+
25+
Ok(book)
26+
}
27+
28+
fn supports_renderer(&self, renderer: &str) -> bool {
29+
renderer == "html" || renderer == "markdown" || renderer == "test"
30+
}
31+
}

packages/mdbook-trpl/src/listing_link/tests.rs

Whitespace-only changes.

0 commit comments

Comments
 (0)