mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-04-25 08:53:01 +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:
parent
edd9df042c
commit
3e224e6f55
@ -13,23 +13,17 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use log::{info, trace};
|
use log::{info, trace};
|
||||||
use pulldown_cmark::{CowStr, Event, Parser, Tag};
|
use pulldown_cmark::{Event, Parser, Tag};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{create_dir_all, read_to_string, File},
|
fs::{create_dir_all, File},
|
||||||
io::Write,
|
io::Write,
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
const INCLUDE_START: &str = "{{#include ";
|
|
||||||
const INCLUDE_END: &str = "}}";
|
|
||||||
const FILENAME_START: &str = "<!-- File ";
|
const FILENAME_START: &str = "<!-- File ";
|
||||||
const FILENAME_END: &str = " -->";
|
const FILENAME_END: &str = " -->";
|
||||||
|
|
||||||
pub fn process(
|
pub fn process(output_directory: &Path, input_contents: &str) -> anyhow::Result<()> {
|
||||||
input_directory: &Path,
|
|
||||||
output_directory: &Path,
|
|
||||||
input_contents: &str,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
let parser = Parser::new(input_contents);
|
let parser = Parser::new(input_contents);
|
||||||
|
|
||||||
// Find a specially-formatted comment followed by a code block, and then call `write_output`
|
// 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) => {
|
Event::Text(text) => {
|
||||||
info!("Text: {:?}", text);
|
info!("Text: {:?}", text);
|
||||||
if let Some(output_file) = &mut current_file {
|
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)) => {
|
Event::End(Tag::CodeBlock(x)) => {
|
||||||
@ -79,65 +73,3 @@ pub fn process(
|
|||||||
|
|
||||||
Ok(())
|
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(())
|
|
||||||
}
|
|
||||||
|
@ -55,21 +55,13 @@ fn process_all(book: &Book, output_directory: &Path) -> anyhow::Result<()> {
|
|||||||
if let BookItem::Chapter(chapter) = item {
|
if let BookItem::Chapter(chapter) = item {
|
||||||
trace!("Chapter {:?} / {:?}", chapter.path, chapter.source_path);
|
trace!("Chapter {:?} / {:?}", chapter.path, chapter.source_path);
|
||||||
if let Some(chapter_path) = &chapter.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
|
// Put the exercises in a subdirectory named after the chapter file, without its
|
||||||
// parent directories.
|
// parent directories.
|
||||||
let chapter_output_directory =
|
let chapter_output_directory =
|
||||||
output_directory.join(chapter_path.file_stem().with_context(
|
output_directory.join(chapter_path.file_stem().with_context(
|
||||||
|| format!("Chapter {:?} has no file stem", chapter_path),
|
|| format!("Chapter {:?} has no file stem", chapter_path),
|
||||||
)?);
|
)?);
|
||||||
process(
|
process(&chapter_output_directory, &chapter.content)?;
|
||||||
&chapter_parent_directory,
|
|
||||||
&chapter_output_directory,
|
|
||||||
&chapter.content,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user