mdbook_lad_preprocessor/
lib.rs1#![allow(missing_docs)]
3
4use mdbook::{errors::Error, preprocess::Preprocessor};
5use sections::Section;
6mod argument_visitor;
7mod markdown;
8mod sections;
9
10const LAD_EXTENSION: &str = "lad.json";
11
12pub struct LADPreprocessor;
13
14impl LADPreprocessor {
15 fn is_lad_file(chapter: &mdbook::book::Chapter) -> bool {
17 chapter
18 .source_path
19 .as_ref()
20 .and_then(|a| a.file_name())
21 .map(|s| s.to_string_lossy().ends_with(LAD_EXTENSION))
22 .unwrap_or(false)
23 }
24
25 fn process_lad_chapter(
30 chapter: &mdbook::book::Chapter,
31 parent: Option<&mdbook::book::Chapter>,
32 chapter_index: usize,
33 ) -> Result<mdbook::book::Chapter, Error> {
34 let chapter_title = chapter.name.trim_end_matches(".lad.json").to_owned();
35 let ladfile = ladfile::parse_lad_file(&chapter.content)
36 .map_err(|e| Error::new(e).context("Failed to parse LAD file"))?;
37 log::debug!(
38 "Parsed LAD file: {}",
39 serde_json::to_string_pretty(&ladfile).unwrap_or_default()
40 );
41 let new_chapter = Section::Summary {
42 ladfile: &ladfile,
43 title: Some(chapter_title),
44 }
45 .into_chapter(parent, chapter_index);
46 log::debug!(
47 "New chapter: {}",
48 serde_json::to_string_pretty(&new_chapter).unwrap_or_default()
49 );
50 Ok(new_chapter)
51 }
52}
53
54impl Preprocessor for LADPreprocessor {
55 fn name(&self) -> &str {
56 "lad-preprocessor"
57 }
58
59 fn run(
60 &self,
61 _ctx: &mdbook::preprocess::PreprocessorContext,
62 mut book: mdbook::book::Book,
63 ) -> mdbook::errors::Result<mdbook::book::Book> {
64 let mut errors = Vec::new();
65
66 book.for_each_mut(|item| {
68 if let mdbook::BookItem::Chapter(parent) = item {
69 let replacements: Vec<(usize, mdbook::book::Chapter)> = parent
71 .sub_items
72 .iter()
73 .enumerate()
74 .filter_map(|(idx, item)| {
75 if let mdbook::BookItem::Chapter(chapter) = item {
76 if LADPreprocessor::is_lad_file(chapter) {
77 match LADPreprocessor::process_lad_chapter(
78 chapter,
79 Some(parent),
80 idx,
81 ) {
82 Ok(new_chapter) => return Some((idx, new_chapter)),
83 Err(e) => {
84 errors.push(e);
85 return None;
86 }
87 }
88 }
89 }
90 None
91 })
92 .collect();
93
94 for (idx, new_chapter) in replacements {
96 if let mdbook::BookItem::Chapter(chapter) = &mut parent.sub_items[idx] {
97 *chapter = new_chapter;
98 }
99 }
100 }
101 });
102
103 book.for_each_mut(|item| {
105 if let mdbook::BookItem::Chapter(chapter) = item {
106 if !LADPreprocessor::is_lad_file(chapter) {
107 return;
108 }
109
110 let new_chapter = match LADPreprocessor::process_lad_chapter(chapter, None, 0) {
111 Ok(new_chapter) => new_chapter,
112 Err(e) => {
113 errors.push(e);
114 return;
115 }
116 };
117
118 *chapter = new_chapter;
119 }
120 });
121
122 log::debug!(
123 "Book after LAD processing: {}",
124 serde_json::to_string_pretty(&book).unwrap_or_default()
125 );
126
127 if !errors.is_empty() {
128 for error in errors {
130 log::error!("{}", error);
131 Err(error)?;
132 }
133 }
134
135 Ok(book)
136 }
137}