2
2
#![ allow( missing_docs) ]
3
3
4
4
use mdbook:: { errors:: Error , preprocess:: Preprocessor } ;
5
+ use sections:: Section ;
5
6
mod argument_visitor;
6
7
mod markdown;
7
8
mod sections;
@@ -10,6 +11,46 @@ const LAD_EXTENSION: &str = "lad.json";
10
11
11
12
pub struct LADPreprocessor ;
12
13
14
+ impl LADPreprocessor {
15
+ /// Checks if a chapter is a LAD file.
16
+ 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
+ /// Process a chapter that is a LAD file.
26
+ ///
27
+ /// `parent` is the optional parent chapter reference,
28
+ /// and `chapter_index` is the index of the chapter among its siblings.
29
+ 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
+
13
54
impl Preprocessor for LADPreprocessor {
14
55
fn name ( & self ) -> & str {
15
56
"lad-preprocessor"
@@ -20,62 +61,69 @@ impl Preprocessor for LADPreprocessor {
20
61
_ctx : & mdbook:: preprocess:: PreprocessorContext ,
21
62
mut book : mdbook:: book:: Book ,
22
63
) -> mdbook:: errors:: Result < mdbook:: book:: Book > {
23
- let mut errors = Vec :: default ( ) ;
64
+ let mut errors = Vec :: new ( ) ;
24
65
66
+ // first replace children in parents
25
67
book. for_each_mut ( |item| {
26
- if let mdbook:: BookItem :: Chapter ( chapter) = item {
27
- let is_lad_chapter = chapter
28
- . source_path
29
- . as_ref ( )
30
- . and_then ( |a| a. file_name ( ) )
31
- . is_some_and ( |a| a. to_string_lossy ( ) . ends_with ( LAD_EXTENSION ) ) ;
68
+ if let mdbook:: BookItem :: Chapter ( parent) = item {
69
+ // First, collect the indices and new chapters for LAD file chapters.
70
+ 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
+ // Then, apply the replacements.
95
+ 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
+ } ) ;
32
102
33
- if !is_lad_chapter {
34
- log:: debug!( "Skipping non-LAD chapter: {:?}" , chapter. source_path) ;
35
- log:: trace!(
36
- "Non-LAD chapter: {}" ,
37
- serde_json:: to_string_pretty( & chapter) . unwrap_or_default( )
38
- ) ;
103
+ // then try match items themselves
104
+ book. for_each_mut ( |item| {
105
+ if let mdbook:: BookItem :: Chapter ( chapter) = item {
106
+ if !LADPreprocessor :: is_lad_file ( chapter) {
39
107
return ;
40
108
}
41
109
42
- let chapter_title = chapter. name . clone ( ) ;
43
-
44
- let lad = match ladfile:: parse_lad_file ( & chapter. content ) {
45
- Ok ( lad) => lad,
110
+ let new_chapter = match LADPreprocessor :: process_lad_chapter ( chapter, None , 0 ) {
111
+ Ok ( new_chapter) => new_chapter,
46
112
Err ( e) => {
47
- log:: debug!( "Failed to parse LAD file: {:?}" , e) ;
48
- errors. push ( Error :: new ( e) . context ( "Failed to parse LAD file" ) ) ;
113
+ errors. push ( e) ;
49
114
return ;
50
115
}
51
116
} ;
52
117
53
- log:: debug!(
54
- "Parsed LAD file: {}" ,
55
- serde_json:: to_string_pretty( & lad) . unwrap_or_default( )
56
- ) ;
57
-
58
- let sections = sections:: lad_file_to_sections ( & lad, Some ( chapter_title) ) ;
59
-
60
- let new_chapter = sections:: section_to_chapter (
61
- sections,
62
- Some ( chapter) ,
63
- chapter. parent_names . clone ( ) ,
64
- chapter. number . clone ( ) ,
65
- None ,
66
- None ,
67
- ) ;
68
-
69
- // serialize chapter to json
70
- log:: debug!(
71
- "New chapter: {}" ,
72
- serde_json:: to_string_pretty( & new_chapter) . unwrap_or_default( )
73
- ) ;
74
-
75
118
* chapter = new_chapter;
76
119
}
77
120
} ) ;
78
121
122
+ log:: debug!(
123
+ "Book after LAD processing: {}" ,
124
+ serde_json:: to_string_pretty( & book) . unwrap_or_default( )
125
+ ) ;
126
+
79
127
if !errors. is_empty ( ) {
80
128
// return on first error
81
129
for error in errors {
0 commit comments