Add a real example of remove-emphasis

This commit is contained in:
Eric Huss 2024-11-02 15:41:55 -07:00
parent 5ec4f65ac3
commit 9e3d533acc
10 changed files with 163 additions and 30 deletions

37
Cargo.lock generated
View file

@ -999,7 +999,7 @@ dependencies = [
"pathdiff",
"predicates",
"pretty_assertions",
"pulldown-cmark",
"pulldown-cmark 0.10.3",
"regex",
"select",
"semver",
@ -1014,6 +1014,16 @@ dependencies = [
"warp",
]
[[package]]
name = "mdbook-remove-emphasis"
version = "0.1.0"
dependencies = [
"mdbook",
"pulldown-cmark 0.12.2",
"pulldown-cmark-to-cmark",
"serde_json",
]
[[package]]
name = "memchr"
version = "2.7.2"
@ -1421,12 +1431,32 @@ dependencies = [
"unicase",
]
[[package]]
name = "pulldown-cmark"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
dependencies = [
"bitflags 2.5.0",
"memchr",
"unicase",
]
[[package]]
name = "pulldown-cmark-escape"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3"
[[package]]
name = "pulldown-cmark-to-cmark"
version = "18.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e02b63adcb49f2eb675b1694b413b3e9fedbf549dfe2cc98727ad97a0c30650"
dependencies = [
"pulldown-cmark 0.12.2",
]
[[package]]
name = "quote"
version = "1.0.36"
@ -1598,11 +1628,12 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.117"
version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]

View file

@ -1,3 +1,6 @@
[workspace]
members = [".", "examples/remove-emphasis/mdbook-remove-emphasis"]
[package]
name = "mdbook"
version = "0.4.40"
@ -73,3 +76,9 @@ name = "mdbook"
[[example]]
name = "nop-preprocessor"
test = true
[[example]]
name = "remove-emphasis"
path = "examples/remove-emphasis/test.rs"
crate-type = ["lib"]
test = true

1
examples/remove-emphasis/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
book

View file

@ -0,0 +1,5 @@
[book]
title = "remove-emphasis"
[preprocessor.remove-emphasis]
command = "cargo run --manifest-path=mdbook-remove-emphasis/Cargo.toml --locked"

View file

@ -0,0 +1,10 @@
[package]
name = "mdbook-remove-emphasis"
version = "0.1.0"
edition = "2021"
[dependencies]
mdbook = { version = "0.4.40", path = "../../.." }
pulldown-cmark = { version = "0.12.2", default-features = false }
pulldown-cmark-to-cmark = "18.0.0"
serde_json = "1.0.132"

View file

@ -0,0 +1,82 @@
//! This is a demonstration of an mdBook preprocessor which parses markdown
//! and removes any instances of emphasis.
use mdbook::book::{Book, Chapter};
use mdbook::errors::Error;
use mdbook::preprocess::{CmdPreprocessor, Preprocessor, PreprocessorContext};
use mdbook::BookItem;
use pulldown_cmark::{Event, Parser, Tag, TagEnd};
use std::io;
fn main() {
let mut args = std::env::args().skip(1);
match args.next().as_deref() {
Some("supports") => {
// Supports all renderers.
return;
}
Some(arg) => {
eprintln!("unknown argument: {arg}");
std::process::exit(1);
}
None => {}
}
if let Err(e) = handle_preprocessing() {
eprintln!("{}", e);
std::process::exit(1);
}
}
struct RemoveEmphasis;
impl Preprocessor for RemoveEmphasis {
fn name(&self) -> &str {
"remove-emphasis"
}
fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<Book, Error> {
let mut total = 0;
book.for_each_mut(|item| {
let BookItem::Chapter(ch) = item else {
return;
};
if ch.is_draft_chapter() {
return;
}
match remove_emphasis(&mut total, ch) {
Ok(s) => ch.content = s,
Err(e) => eprintln!("failed to process chapter: {e:?}"),
}
});
eprintln!("removed {total} emphasis");
Ok(book)
}
}
// ANCHOR: remove_emphasis
fn remove_emphasis(num_removed_items: &mut usize, chapter: &mut Chapter) -> Result<String, Error> {
let mut buf = String::with_capacity(chapter.content.len());
let events = Parser::new(&chapter.content).filter(|e| match e {
Event::Start(Tag::Emphasis) | Event::Start(Tag::Strong) => {
*num_removed_items += 1;
false
}
Event::End(TagEnd::Emphasis) | Event::End(TagEnd::Strong) => false,
_ => true,
});
Ok(pulldown_cmark_to_cmark::cmark(events, &mut buf).map(|_| buf)?)
}
// ANCHOR_END: remove_emphasis
pub fn handle_preprocessing() -> Result<(), Error> {
let pre = RemoveEmphasis;
let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())?;
let processed_book = pre.run(&ctx, book)?;
serde_json::to_writer(io::stdout(), &processed_book)?;
Ok(())
}

View file

@ -0,0 +1,3 @@
# Summary
- [Chapter 1](./chapter_1.md)

View file

@ -0,0 +1,3 @@
# Chapter 1
This has *light emphasis* and **bold emphasis**.

View file

@ -0,0 +1,13 @@
use mdbook::MDBook;
#[test]
fn remove_emphasis_works() {
// Tests that the remove-emphasis example works as expected.
// Workaround for https://github.com/rust-lang/mdBook/issues/1424
std::env::set_current_dir("examples/remove-emphasis").unwrap();
let book = MDBook::load(".").unwrap();
book.build().unwrap();
let ch1 = std::fs::read_to_string("book/chapter_1.html").unwrap();
assert!(ch1.contains("This has light emphasis and bold emphasis."));
}

View file

@ -68,33 +68,10 @@ The following code block shows how to remove all emphasis from markdown,
without accidentally breaking the document.
```rust
fn remove_emphasis(
num_removed_items: &mut usize,
chapter: &mut Chapter,
) -> Result<String> {
let mut buf = String::with_capacity(chapter.content.len());
let events = Parser::new(&chapter.content).filter(|e| {
let should_keep = match *e {
Event::Start(Tag::Emphasis)
| Event::Start(Tag::Strong)
| Event::End(Tag::Emphasis)
| Event::End(Tag::Strong) => false,
_ => true,
};
if !should_keep {
*num_removed_items += 1;
}
should_keep
});
cmark(events, &mut buf, None).map(|_| buf).map_err(|err| {
Error::from(format!("Markdown serialization failed: {}", err))
})
}
{{#rustdoc_include ../../../examples/remove-emphasis/mdbook-remove-emphasis/src/main.rs:remove_emphasis}}
```
For everything else, have a look [at the complete example][example].
Take a look at the [full example source][emphasis-example] for more details.
## Implementing a preprocessor with a different language
@ -122,11 +99,10 @@ if __name__ == '__main__':
```
[emphasis-example]: https://github.com/rust-lang/mdBook/tree/master/examples/remove-emphasis/
[preprocessor-docs]: https://docs.rs/mdbook/latest/mdbook/preprocess/trait.Preprocessor.html
[pc]: https://crates.io/crates/pulldown-cmark
[pctc]: https://crates.io/crates/pulldown-cmark-to-cmark
[example]: https://github.com/rust-lang/mdBook/blob/master/examples/nop-preprocessor.rs
[an example no-op preprocessor]: https://github.com/rust-lang/mdBook/blob/master/examples/nop-preprocessor.rs
[`CmdPreprocessor::parse_input()`]: https://docs.rs/mdbook/latest/mdbook/preprocess/trait.Preprocessor.html#method.parse_input
[`Book::for_each_mut()`]: https://docs.rs/mdbook/latest/mdbook/book/struct.Book.html#method.for_each_mut