1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-01-05 16:10:31 +02:00

No need to handle #include directives ourselves anymore.

The mdbook links preprocessor will process them before we get called.
This commit is contained in:
Andrew Walbran 2023-04-03 16:08:42 +01:00
parent edd9df042c
commit 3e224e6f55
2 changed files with 5 additions and 81 deletions

View File

@ -13,23 +13,17 @@
// limitations under the License.
use log::{info, trace};
use pulldown_cmark::{CowStr, Event, Parser, Tag};
use pulldown_cmark::{Event, Parser, Tag};
use std::{
fs::{create_dir_all, read_to_string, File},
fs::{create_dir_all, File},
io::Write,
path::Path,
};
const INCLUDE_START: &str = "{{#include ";
const INCLUDE_END: &str = "}}";
const FILENAME_START: &str = "<!-- File ";
const FILENAME_END: &str = " -->";
pub fn process(
input_directory: &Path,
output_directory: &Path,
input_contents: &str,
) -> anyhow::Result<()> {
pub fn process(output_directory: &Path, input_contents: &str) -> anyhow::Result<()> {
let parser = Parser::new(input_contents);
// Find a specially-formatted comment followed by a code block, and then call `write_output`
@ -66,7 +60,7 @@ pub fn process(
Event::Text(text) => {
info!("Text: {:?}", text);
if let Some(output_file) = &mut current_file {
write_output(text, input_directory, output_file)?;
output_file.write(text.as_bytes())?;
}
}
Event::End(Tag::CodeBlock(x)) => {
@ -79,65 +73,3 @@ pub fn process(
Ok(())
}
/// Writes the given output file based on the given code text from the Markdown input, processing
/// include directives as necessary.
fn write_output(
text: CowStr,
input_directory: &Path,
output_file: &mut File,
) -> anyhow::Result<()> {
for line in text.lines() {
info!("Line: {:?}", line);
if let (Some(start), Some(end)) =
(line.find(INCLUDE_START), line.find(INCLUDE_END))
{
let include = line[start + INCLUDE_START.len()..end].trim();
info!("Include {:?}", include);
if let Some(colon) = include.find(":") {
write_include(
&include[0..colon],
Some(&include[colon + 1..]),
input_directory,
output_file,
)?;
} else {
write_include(include, None, input_directory, output_file)?;
}
} else {
output_file.write(line.as_bytes())?;
output_file.write(b"\n")?;
}
}
Ok(())
}
/// Writes the given `section` (or all, if it is `None`) of the given included file (relative to the
/// `input_directory`) to the `output_file`.
fn write_include(
include_filename: &str,
section: Option<&str>,
input_directory: &Path,
output_file: &mut File,
) -> anyhow::Result<()> {
let full_include_filename = input_directory.join(include_filename);
let input_file = read_to_string(full_include_filename)?;
if let Some(section) = section {
let start_anchor = format!("ANCHOR: {}", section);
let end_anchor = format!("ANCHOR_END: {}", section);
for line in input_file
.lines()
.skip_while(|line| !line.contains(&start_anchor))
.skip(1)
.take_while(|line| !line.contains(&end_anchor))
{
output_file.write(line.as_bytes())?;
output_file.write(b"\n")?;
}
} else {
output_file.write(input_file.as_bytes())?;
}
Ok(())
}

View File

@ -55,21 +55,13 @@ fn process_all(book: &Book, output_directory: &Path) -> anyhow::Result<()> {
if let BookItem::Chapter(chapter) = item {
trace!("Chapter {:?} / {:?}", chapter.path, chapter.source_path);
if let Some(chapter_path) = &chapter.path {
let chapter_parent_directory =
chapter_path.parent().with_context(|| {
format!("Chapter file {:?} has no parent directory", chapter_path)
})?;
// Put the exercises in a subdirectory named after the chapter file, without its
// parent directories.
let chapter_output_directory =
output_directory.join(chapter_path.file_stem().with_context(
|| format!("Chapter {:?} has no file stem", chapter_path),
)?);
process(
&chapter_parent_directory,
&chapter_output_directory,
&chapter.content,
)?;
process(&chapter_output_directory, &chapter.content)?;
}
}
}