Browse Source

update original

pull/1381/head
funkill2 2 years ago
parent
commit
c86742d3f9
  1. 2
      rustbook-en/.github/workflows/main.yml
  2. 2203
      rustbook-en/Cargo.lock
  3. 45
      rustbook-en/Cargo.toml
  4. 8
      rustbook-en/book.toml
  5. 12
      rustbook-en/nostarch/book.toml
  6. 16
      rustbook-en/packages/mdbook-trpl-note/Cargo.toml
  7. 51
      rustbook-en/packages/mdbook-trpl-note/README.md
  8. 285
      rustbook-en/packages/mdbook-trpl-note/src/lib.rs
  9. 38
      rustbook-en/packages/mdbook-trpl-note/src/main.rs
  10. 22
      rustbook-en/packages/mdbook-trpl-note/tests/integration/main.rs
  11. 46
      rustbook-en/packages/tools/Cargo.toml
  12. 4
      rustbook-en/packages/tools/src/bin/concat_chapters.rs
  13. 0
      rustbook-en/packages/tools/src/bin/convert_quotes.rs
  14. 5
      rustbook-en/packages/tools/src/bin/lfp.rs
  15. 3
      rustbook-en/packages/tools/src/bin/link2print.rs
  16. 7
      rustbook-en/packages/tools/src/bin/release_listings.rs
  17. 0
      rustbook-en/packages/tools/src/bin/remove_hidden_lines.rs
  18. 2
      rustbook-en/packages/tools/src/bin/remove_links.rs
  19. 5
      rustbook-en/packages/tools/src/bin/remove_markup.rs
  20. 2
      rustbook-en/src/ch10-03-lifetime-syntax.md
  21. 13
      rustbook-en/theme/semantic-notes.css
  22. 2
      rustbook-en/tools/nostarch.sh

2
rustbook-en/.github/workflows/main.yml

@ -43,6 +43,8 @@ jobs: @@ -43,6 +43,8 @@ jobs:
mkdir bin
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin
echo "$(pwd)/bin" >> ${GITHUB_PATH}
- name: Install mdbook-trpl-note
run: cargo install --path packages/mdbook-trpl-note
- name: Install aspell
run: sudo apt-get install aspell
- name: Install shellcheck

2203
rustbook-en/Cargo.lock generated

File diff suppressed because it is too large Load Diff

45
rustbook-en/Cargo.toml

@ -1,44 +1,13 @@ @@ -1,44 +1,13 @@
[package]
name = "rust-book"
version = "0.0.1"
description = "The Rust Book"
edition = "2021"
[workspace]
members = ["packages/*"]
default-members = ["packages/*"]
resolver = "2"
exclude = ["linkchecker"] # part of the CI workflow
[[bin]]
name = "concat_chapters"
path = "tools/src/bin/concat_chapters.rs"
[[bin]]
name = "convert_quotes"
path = "tools/src/bin/convert_quotes.rs"
[[bin]]
name = "lfp"
path = "tools/src/bin/lfp.rs"
[[bin]]
name = "link2print"
path = "tools/src/bin/link2print.rs"
[[bin]]
name = "release_listings"
path = "tools/src/bin/release_listings.rs"
[[bin]]
name = "remove_hidden_lines"
path = "tools/src/bin/remove_hidden_lines.rs"
[[bin]]
name = "remove_links"
path = "tools/src/bin/remove_links.rs"
[[bin]]
name = "remove_markup"
path = "tools/src/bin/remove_markup.rs"
[dependencies]
[workspace.dependencies]
walkdir = "2.3.1"
docopt = "1.1.0"
mdbook = "0.4.37"
serde = "1.0"
regex = "1.3.3"
lazy_static = "1.4.0"

8
rustbook-en/book.toml

@ -1,8 +1,14 @@ @@ -1,8 +1,14 @@
# Sync any changes to this *other than where explicitly specified* with the copy
# in `nostarch/book.toml`!
[book]
title = "The Rust Programming Language"
authors = ["Steve Klabnik", "Carol Nichols", "Contributions from the Rust Community"]
[output.html]
additional-css = ["ferris.css", "theme/2018-edition.css"]
additional-css = ["ferris.css", "theme/2018-edition.css", "theme/semantic-notes.css"]
additional-js = ["ferris.js"]
git-repository-url = "https://github.com/rust-lang/book"
# Do not sync this preprocessor; it is for the HTML renderer only.
[preprocessor.trpl-note]

12
rustbook-en/nostarch/book.toml

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
[book]
title = "The Rust Programming Language"
authors = ["Steve Klabnik", "Carol Nichols", "Contributions from the Rust Community"]
src = "../src" # needs to be explicit (it is implicit in `/book.toml`).
[output.html]
additional-css = ["../ferris.css", "../theme/2018-edition.css", "../theme/semantic-notes.css"]
additional-js = ["../ferris.js"]
git-repository-url = "https://github.com/rust-lang/book"
[build]
build-dir = "../tmp"

16
rustbook-en/packages/mdbook-trpl-note/Cargo.toml

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
[package]
name = "mdbook-trpl-note"
version = "1.0.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.5.4", features = ["derive"] }
mdbook = { workspace = true }
pulldown-cmark = { version = "0.10.3", features = ["simd"] }
pulldown-cmark-to-cmark = "13.0.0"
serde_json = "1.0.116"
[dev-dependencies]
assert_cmd = "2.0.14"

51
rustbook-en/packages/mdbook-trpl-note/README.md

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
# mdbook-trpl-note
This is a *very* simple [preprocessor][pre] for [mdBook][mdbook], focused specifically on the content of _The Rust Programming Language_ book. This preprocessor takes Markdown like this—
```markdown
> Note: This is some material we want to provide more emphasis for, because it
> is important in some way!
Some text.
> ## Some subject
>
> Here is all the important things to know about that particular subject.
```
—and rewrites the Markdown to this:
```html
<section class="note" aria-role="note">
This is some material we want to provide more emphasis for, because it is
important in some way!
</section>
Some text.
<section class="note" aria-role="note">
## Some subject
Here is all the important things to know about that particular subject.
</section>
```
This allows using the relatively standard Markdown convention of (incorrectly!) using blockquotes for “callouts” or “notes” like this, while still producing semantic HTML which conveys the actual intent.
> [!NOTE]
> This is *not* a full “admonition” preprocessor, and it is not remotely compliant with [the GitHub “alert” syntax][alerts]. It exists almost entirely for the sake of providing better semantic HTML for _The Rust Programming Language_ book with a minimum of disruption to existing workflows!
>
> You are probably better off using one of the other existing alert/admonition preprocessors:
>
> - [mdbook-alerts][mdbook-alerts]
> - [mdbook-admonish][mdbook-admonish]
[pre]: https://rust-lang.github.io/mdBook/format/configuration/preprocessors.html
[mdbook]: https://github.com/rust-lang/mdBook
[alerts]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
[mdbook-alerts]: https://github.com/lambdalisue/rs-mdbook-alerts
[mdbook-admonish]: https://github.com/tommilligan/mdbook-admonish

285
rustbook-en/packages/mdbook-trpl-note/src/lib.rs

@ -0,0 +1,285 @@ @@ -0,0 +1,285 @@
use mdbook::{
book::Book,
errors::Result,
preprocess::{Preprocessor, PreprocessorContext},
BookItem,
};
use pulldown_cmark::{
Event::{self, *},
Parser, Tag, TagEnd,
};
use pulldown_cmark_to_cmark::cmark;
/// A simple preprocessor for semantic notes in _The Rust Programming Language_.
///
/// Takes in Markdown like this:
///
/// ```markdown
/// > Note: This is a note.
/// ```
///
/// Spits out Markdown like this:
///
/// ```markdown
/// <section class="note" aria-role="note">
///
/// This is a note.
///
/// </section>
/// ```
pub struct TrplNote;
impl Preprocessor for TrplNote {
fn name(&self) -> &str {
"simple-note-preprocessor"
}
fn run(&self, _ctx: &PreprocessorContext, mut book: Book) -> Result<mdbook::book::Book> {
book.for_each_mut(|item| {
if let BookItem::Chapter(ref mut chapter) = item {
chapter.content = rewrite(&chapter.content);
}
});
Ok(book)
}
fn supports_renderer(&self, renderer: &str) -> bool {
renderer == "html"
}
}
pub fn rewrite(text: &str) -> String {
let parser = Parser::new(text);
let mut events = Vec::new();
let mut state = Default;
for event in parser {
match (&mut state, event) {
(Default, Start(Tag::BlockQuote)) => {
state = StartingBlockquote(vec![Start(Tag::BlockQuote)]);
}
(StartingBlockquote(blockquote_events), Text(content)) => {
if content.starts_with("Note: ") {
// This needs the "extra" `SoftBreak`s so that when the final rendering pass
// happens, it does not end up treating the internal content as inline *or*
// treating the HTML tags as inline tags:
//
// - Content inside HTML blocks is only rendered as Markdown when it is
// separated from the block HTML elements: otherwise it gets treated as inline
// HTML and *not* rendered.
// - Along the same lines, an HTML tag that happens to be directly adjacent to
// the end of a previous Markdown block will end up being rendered as part of
// that block.
events.extend([
SoftBreak,
SoftBreak,
Html(r#"<section class="note" aria-role="note">"#.into()),
SoftBreak,
SoftBreak,
Start(Tag::Paragraph),
Text(content),
]);
state = InNote;
} else {
events.append(blockquote_events);
events.push(Text(content));
state = Default;
}
}
(StartingBlockquote(_blockquote_events), heading @ Start(Tag::Heading { .. })) => {
events.extend([
SoftBreak,
SoftBreak,
Html(r#"<section class="note" aria-role="note">"#.into()),
SoftBreak,
SoftBreak,
heading,
]);
state = InNote;
}
(StartingBlockquote(ref mut events), Start(Tag::Paragraph)) => {
events.push(Start(Tag::Paragraph));
}
(InNote, End(TagEnd::BlockQuote)) => {
// As with the start of the block HTML, the closing HTML must be
// separated from the Markdown text by two newlines.
events.extend([SoftBreak, SoftBreak, Html("</section>".into())]);
state = Default;
}
(_, event) => {
events.push(event);
}
}
}
let mut buf = String::new();
cmark(events.into_iter(), &mut buf).unwrap();
buf
}
use State::*;
#[derive(Debug)]
enum State<'e> {
Default,
StartingBlockquote(Vec<Event<'e>>),
InNote,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_note() {
let text = "Hello, world.\n\nThis is some text.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<p>Hello, world.</p>\n<p>This is some text.</p>\n"
);
}
#[test]
fn with_note() {
let text = "> Note: This is some text.\n> It keeps going.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<p>Note: This is some text.\nIt keeps going.</p>\n</section>"
);
}
#[test]
fn regular_blockquote() {
let text = "> This is some text.\n> It keeps going.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<blockquote>\n<p>This is some text.\nIt keeps going.</p>\n</blockquote>\n"
);
}
#[test]
fn combined() {
let text = "> Note: This is some text.\n> It keeps going.\n\nThis is regular text.\n\n> This is a blockquote.\n";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<p>Note: This is some text.\nIt keeps going.</p>\n</section>\n<p>This is regular text.</p>\n<blockquote>\n<p>This is a blockquote.</p>\n</blockquote>\n"
);
}
#[test]
fn blockquote_then_note() {
let text = "> This is quoted.\n\n> Note: This is noted.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<blockquote>\n<p>This is quoted.</p>\n</blockquote>\n<section class=\"note\" aria-role=\"note\">\n<p>Note: This is noted.</p>\n</section>"
);
}
#[test]
fn note_then_blockquote() {
let text = "> Note: This is noted.\n\n> This is quoted.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<p>Note: This is noted.</p>\n</section>\n<blockquote>\n<p>This is quoted.</p>\n</blockquote>\n"
);
}
#[test]
fn with_h1_note() {
let text = "> # Header\n > And then some note content.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<h1>Header</h1>\n<p>And then some note content.</p>\n</section>"
);
}
#[test]
fn with_h2_note() {
let text = "> ## Header\n > And then some note content.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<h2>Header</h2>\n<p>And then some note content.</p>\n</section>"
);
}
#[test]
fn with_h3_note() {
let text = "> ### Header\n > And then some note content.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<h3>Header</h3>\n<p>And then some note content.</p>\n</section>"
);
}
#[test]
fn with_h4_note() {
let text = "> #### Header\n > And then some note content.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<h4>Header</h4>\n<p>And then some note content.</p>\n</section>"
);
}
#[test]
fn with_h5_note() {
let text = "> ##### Header\n > And then some note content.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<h5>Header</h5>\n<p>And then some note content.</p>\n</section>"
);
}
#[test]
fn with_h6_note() {
let text = "> ###### Header\n > And then some note content.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<h6>Header</h6>\n<p>And then some note content.</p>\n</section>"
);
}
#[test]
fn h1_then_blockquote() {
let text = "> # Header\n > And then some note content.\n\n> This is quoted.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<section class=\"note\" aria-role=\"note\">\n<h1>Header</h1>\n<p>And then some note content.</p>\n</section>\n<blockquote>\n<p>This is quoted.</p>\n</blockquote>\n"
);
}
#[test]
fn blockquote_then_h1_note() {
let text = "> This is quoted.\n\n> # Header\n > And then some note content.";
let processed = rewrite(text);
assert_eq!(
render_markdown(&processed),
"<blockquote>\n<p>This is quoted.</p>\n</blockquote>\n<section class=\"note\" aria-role=\"note\">\n<h1>Header</h1>\n<p>And then some note content.</p>\n</section>"
);
}
fn render_markdown(text: &str) -> String {
let parser = Parser::new(text);
let mut buf = String::new();
pulldown_cmark::html::push_html(&mut buf, parser);
buf
}
}

38
rustbook-en/packages/mdbook-trpl-note/src/main.rs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
use std::io;
use clap::{self, Parser, Subcommand};
use mdbook::preprocess::{CmdPreprocessor, Preprocessor};
use mdbook_trpl_note::TrplNote;
fn main() -> Result<(), String> {
let cli = Cli::parse();
let simple_note = TrplNote;
if let Some(Command::Supports { renderer }) = cli.command {
return if simple_note.supports_renderer(&renderer) {
Ok(())
} else {
Err(format!("Renderer '{renderer}' is unsupported"))
};
}
let (ctx, book) =
CmdPreprocessor::parse_input(io::stdin()).map_err(|e| format!("blah: {e}"))?;
let processed = simple_note.run(&ctx, book).map_err(|e| format!("{e}"))?;
serde_json::to_writer(io::stdout(), &processed).map_err(|e| format!("{e}"))
}
/// A simple preprocessor for semantic notes 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 },
}

22
rustbook-en/packages/mdbook-trpl-note/tests/integration/main.rs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
use assert_cmd::Command;
#[test]
fn supports_html_renderer() {
let cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))
.unwrap()
.args(["supports", "html"])
.ok();
assert!(cmd.is_ok());
}
#[test]
fn errors_for_other_renderers() {
let cmd = Command::cargo_bin(env!("CARGO_PKG_NAME"))
.unwrap()
.args(["supports", "total-nonsense"])
.ok();
assert!(cmd.is_err());
}
// It would be nice to add an actual fixture for an mdbook, but doing *that* is
// going to be a bit of a pain, and what I have should cover it for now.

46
rustbook-en/packages/tools/Cargo.toml

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
[package]
name = "rust-book-tools"
version = "0.0.1"
description = "The Rust Book"
edition = "2021"
[[bin]]
name = "concat_chapters"
path = "src/bin/concat_chapters.rs"
[[bin]]
name = "convert_quotes"
path = "src/bin/convert_quotes.rs"
[[bin]]
name = "lfp"
path = "src/bin/lfp.rs"
[[bin]]
name = "link2print"
path = "src/bin/link2print.rs"
[[bin]]
name = "release_listings"
path = "src/bin/release_listings.rs"
[[bin]]
name = "remove_hidden_lines"
path = "src/bin/remove_hidden_lines.rs"
[[bin]]
name = "remove_links"
path = "src/bin/remove_links.rs"
[[bin]]
name = "remove_markup"
path = "src/bin/remove_markup.rs"
[dependencies]
walkdir = { workspace = true }
docopt = { workspace = true }
serde = { workspace = true }
regex = { workspace = true }
lazy_static = { workspace = true }
flate2 = { workspace = true }
tar = { workspace = true }

4
rustbook-en/tools/src/bin/concat_chapters.rs → rustbook-en/packages/tools/src/bin/concat_chapters.rs

@ -1,6 +1,3 @@ @@ -1,6 +1,3 @@
#[macro_use]
extern crate lazy_static;
use std::collections::BTreeMap;
use std::env;
use std::fs::{create_dir, read_dir, File};
@ -9,6 +6,7 @@ use std::io::{Read, Write}; @@ -9,6 +6,7 @@ use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::exit;
use lazy_static::lazy_static;
use regex::Regex;
static PATTERNS: &[(&str, &str)] = &[

0
rustbook-en/tools/src/bin/convert_quotes.rs → rustbook-en/packages/tools/src/bin/convert_quotes.rs

5
rustbook-en/tools/src/bin/lfp.rs → rustbook-en/packages/tools/src/bin/lfp.rs

@ -1,11 +1,12 @@ @@ -1,11 +1,12 @@
// We have some long regex literals, so:
// ignore-tidy-linelength
use docopt::Docopt;
use serde::Deserialize;
use std::io::BufRead;
use std::{fs, io, path};
use docopt::Docopt;
use serde::Deserialize;
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize())

3
rustbook-en/tools/src/bin/link2print.rs → rustbook-en/packages/tools/src/bin/link2print.rs

@ -1,11 +1,12 @@ @@ -1,11 +1,12 @@
// FIXME: we have some long lines that could be refactored, but it's not a big deal.
// ignore-tidy-linelength
use regex::{Captures, Regex};
use std::collections::HashMap;
use std::io;
use std::io::Read;
use regex::{Captures, Regex};
fn main() {
write_md(parse_links(parse_references(read_md())));
}

7
rustbook-en/tools/src/bin/release_listings.rs → rustbook-en/packages/tools/src/bin/release_listings.rs

@ -1,7 +1,3 @@ @@ -1,7 +1,3 @@
#[macro_use]
extern crate lazy_static;
use regex::Regex;
use std::error::Error;
use std::fs;
use std::fs::File;
@ -9,6 +5,9 @@ use std::io::prelude::*; @@ -9,6 +5,9 @@ use std::io::prelude::*;
use std::io::{BufReader, BufWriter};
use std::path::{Path, PathBuf};
use lazy_static::lazy_static;
use regex::Regex;
fn main() -> Result<(), Box<dyn Error>> {
// Get all listings from the `listings` directory
let listings_dir = Path::new("listings");

0
rustbook-en/tools/src/bin/remove_hidden_lines.rs → rustbook-en/packages/tools/src/bin/remove_hidden_lines.rs

2
rustbook-en/tools/src/bin/remove_links.rs → rustbook-en/packages/tools/src/bin/remove_links.rs

@ -1,5 +1,3 @@ @@ -1,5 +1,3 @@
extern crate regex;
use regex::{Captures, Regex};
use std::collections::HashSet;
use std::io;

5
rustbook-en/tools/src/bin/remove_markup.rs → rustbook-en/packages/tools/src/bin/remove_markup.rs

@ -1,9 +1,8 @@ @@ -1,9 +1,8 @@
extern crate regex;
use regex::{Captures, Regex};
use std::io;
use std::io::Read;
use regex::{Captures, Regex};
fn main() {
write_md(remove_markup(read_md()));
}

2
rustbook-en/src/ch10-03-lifetime-syntax.md

@ -8,7 +8,7 @@ One detail we didn’t discuss in the [“References and @@ -8,7 +8,7 @@ One detail we didn’t discuss in the [“References and
Borrowing”][references-and-borrowing]<!-- ignore --> section in Chapter 4 is
that every reference in Rust has a *lifetime*, which is the scope for which
that reference is valid. Most of the time, lifetimes are implicit and inferred,
just like most of the time, types are inferred. We must only annotate types
just like most of the time, types are inferred. We only have to annotate types
when multiple types are possible. In a similar way, we must annotate lifetimes
when the lifetimes of references could be related in a few different ways. Rust
requires us to annotate the relationships using generic lifetime parameters to

13
rustbook-en/theme/semantic-notes.css

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
/*
This is copied directly from the styles for blockquotes, because notes were
historically rendered *as* blockquotes. This keeps the presentation of them
identical while updating the presentation.
*/
.note {
margin: 20px 0;
padding: 0 20px;
color: var(--fg);
background-color: var(--quote-bg);
border-block-start: 0.1em solid var(--quote-border);
border-block-end: 0.1em solid var(--quote-border);
}

2
rustbook-en/tools/nostarch.sh

@ -9,7 +9,7 @@ rm -rf tmp/*.md @@ -9,7 +9,7 @@ rm -rf tmp/*.md
rm -rf tmp/markdown
# Render the book as Markdown to include all the code listings
MDBOOK_OUTPUT__MARKDOWN=1 mdbook build -d tmp
MDBOOK_OUTPUT__MARKDOWN=1 mdbook build nostarch
# Get all the Markdown files
find tmp/markdown -name "${1:-\"\"}*.md" -print0 | \

Loading…
Cancel
Save