1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-04-25 00:50:26 +02:00

Add mdbook-course to handle parsing frontmatter (#1224)

In v2 of the course, I'd like to include an estimate of the time to be
spent on each segment in the Markdown file. I think a good place for
such metadata is in the frontmatter.

For review purposes, though, I just want to display that information.
So, this is a start at a new mdbook preprocessor that just separates out
the frontmatter and includes it in a `<pre>` block. Eventually, I'd like
to parse it and put the time in the speaker notes.

---------

Co-authored-by: Martin Geisler <martin@geisler.net>
This commit is contained in:
Dustin J. Mitchell 2023-09-20 10:01:53 -04:00 committed by GitHub
parent ddc9ea1fa6
commit 4815264e2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 194 additions and 45 deletions

View File

@ -22,6 +22,10 @@ runs:
run: cargo install mdbook-i18n-helpers --locked --version 0.2.3
shell: bash
- name: Install exerciser
- name: Install mdbook-exerciser
run: cargo install --path mdbook-exerciser --locked
shell: bash
- name: Install mdbook-course
run: cargo install --path mdbook-course --locked
shell: bash

78
Cargo.lock generated
View File

@ -257,18 +257,18 @@ dependencies = [
[[package]]
name = "clap"
version = "4.4.2"
version = "4.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6"
checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.4.2"
version = "4.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08"
checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56"
dependencies = [
"anstream",
"anstyle",
@ -963,17 +963,6 @@ dependencies = [
"libc",
]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.2",
"libc",
"windows-sys",
]
[[package]]
name = "ipnet"
version = "2.8.0"
@ -987,7 +976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi 0.3.2",
"rustix 0.38.13",
"rustix",
"windows-sys",
]
@ -1038,12 +1027,6 @@ version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "linux-raw-sys"
version = "0.4.7"
@ -1098,6 +1081,16 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]]
name = "matter"
version = "0.1.0-alpha4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc16e839c57e0ad77957c42d39baab3692a1c6fa47692066470cddc24a5b0cd0"
dependencies = [
"lazy_static",
"regex",
]
[[package]]
name = "mdbook"
version = "0.4.34"
@ -1132,6 +1125,19 @@ dependencies = [
"warp",
]
[[package]]
name = "mdbook-course"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"log",
"matter",
"mdbook",
"pretty_env_logger",
"serde_json",
]
[[package]]
name = "mdbook-exerciser"
version = "0.1.0"
@ -1781,20 +1787,6 @@ dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.37.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
dependencies = [
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys 0.3.8",
"windows-sys",
]
[[package]]
name = "rustix"
version = "0.38.13"
@ -1804,7 +1796,7 @@ dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys 0.4.7",
"linux-raw-sys",
"windows-sys",
]
@ -1938,9 +1930,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.106"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
dependencies = [
"itoa",
"ryu",
@ -2131,7 +2123,7 @@ dependencies = [
"cfg-if",
"fastrand",
"redox_syscall",
"rustix 0.38.13",
"rustix",
"windows-sys",
]
@ -2157,11 +2149,11 @@ dependencies = [
[[package]]
name = "terminal_size"
version = "0.2.6"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
dependencies = [
"rustix 0.37.23",
"rustix",
"windows-sys",
]

View File

@ -1,6 +1,7 @@
[workspace]
members = [
"mdbook-exerciser",
"mdbook-course",
"src/exercises",
"src/bare-metal/useful-crates/allocator-example",
"src/bare-metal/useful-crates/zerocopy-example",

View File

@ -36,6 +36,7 @@ The course is built using a few tools:
- [mdbook-svgbob](https://github.com/boozook/mdbook-svgbob)
- [mdbook-i18n-helpers](https://github.com/google/mdbook-i18n-helpers)
- [mdbook-exerciser](mdbook-exerciser/)
- [mdbook-course](mdbook-course/)
First clone the repository:
@ -51,6 +52,7 @@ cargo install mdbook
cargo install mdbook-svgbob
cargo install mdbook-i18n-helpers
cargo install --path mdbook-exerciser
cargo install --path mdbook-course
```
Run

View File

@ -19,6 +19,7 @@ renderers = ["html"]
after = ["gettext"]
class = "bob"
[preprocessor.course]
# Enable this preprocessor to overlay a large red rectangle on the
# pages. This will show you an estimate of what the course
# participants can see during the presentation.
@ -29,7 +30,12 @@ class = "bob"
[output.html]
curly-quotes = true
additional-js = ["speaker-notes.js"]
additional-css = ["svgbob.css", "speaker-notes.css", "language-picker.css"]
additional-css = [
"svgbob.css",
"speaker-notes.css",
"language-picker.css",
"frontmatter.css",
]
site-url = "/comprehensive-rust/"
git-repository-url = "https://github.com/google/comprehensive-rust"
edit-url-template = "https://github.com/google/comprehensive-rust/edit/main/{path}"

7
frontmatter.css Normal file
View File

@ -0,0 +1,7 @@
pre.frontmatter {
float: right;
font-size: 80%;
width: 40%;
background: var(--sidebar-bg);
padding: 0.25em;
}

18
mdbook-course/Cargo.toml Normal file
View File

@ -0,0 +1,18 @@
[package]
name = "mdbook-course"
version = "0.1.0"
authors = ["Dustin Mitchell <djmitche@google.com>"]
edition = "2021"
license = "Apache-2.0"
publish = false
repository = "https://github.com/google/comprehensive-rust"
description = "An mdbook preprocessor for comprehensive-rust."
[dependencies]
anyhow = "1.0.68"
clap = "4.4.4"
log = "0.4.17"
matter = "0.1.0-alpha4"
mdbook = "0.4.25"
pretty_env_logger = "0.4.0"
serde_json = "1.0.107"

17
mdbook-course/README.md Normal file
View File

@ -0,0 +1,17 @@
# mdbook-course
This is an mdBook preprocessor to handle some specific details of Comprehensive
Rust.
## Frontmatter
The preprocessor parses "frontmatter" -- YAML between `---` at the beginning of
a Markdown file -- and removes it from the rendered result. At the moment, to
aid review of the new course, it places this content in a `<pre>` block.
## Future Work
- Parse the `minutes` property from frontmatter and
- Generate a course timeline
- Include timing information in the speaker notes
- Generate per-segment tables of contents.

View File

@ -0,0 +1,41 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use matter::matter;
use mdbook::book::{Book, BookItem};
use mdbook::preprocess::PreprocessorContext;
pub fn remove_frontmatter(
ctx: &PreprocessorContext,
book: &mut Book,
) -> anyhow::Result<()> {
let is_html = ctx.renderer == "html";
book.for_each_mut(|chapter| {
let BookItem::Chapter(chapter) = chapter else {
return;
};
if let Some((frontmatter, content)) = matter(&chapter.content) {
if is_html {
// For the moment, include the frontmatter in the slide in a floating <pre>, for review
// purposes.
let pre = format!(r#"<pre class="frontmatter">{frontmatter}</pre>"#);
chapter.content = format!("{pre}\n\n{content}");
} else {
// For non-HTML renderers, just strip the frontmatter.
chapter.content = content;
}
}
});
Ok(())
}

15
mdbook-course/src/lib.rs Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
pub mod frontmatter;

46
mdbook-course/src/main.rs Normal file
View File

@ -0,0 +1,46 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use clap::{Arg, Command};
use mdbook::preprocess::CmdPreprocessor;
use mdbook_course::frontmatter::remove_frontmatter;
use std::io::{stdin, stdout};
use std::process;
fn main() {
pretty_env_logger::init();
let app = Command::new("mdbook-course")
.about("mdbook preprocessor for Comprehensive Rust")
.subcommand(Command::new("supports").arg(Arg::new("renderer").required(true)));
let matches = app.get_matches();
if let Some(_) = matches.subcommand_matches("supports") {
// Support all renderers.
process::exit(0);
}
if let Err(e) = preprocess() {
eprintln!("{}", e);
process::exit(1);
}
}
fn preprocess() -> anyhow::Result<()> {
let (ctx, mut book) = CmdPreprocessor::parse_input(stdin())?;
remove_frontmatter(&ctx, &mut book)?;
serde_json::to_writer(stdout(), &book)?;
Ok(())
}