@@ -39,17 +39,19 @@ fn create_missing(src_dir: &Path, summary: &Summary) -> Result<()> {
39
39
let next = items. pop ( ) . expect ( "already checked" ) ;
40
40
41
41
if let SummaryItem :: Link ( ref link) = * next {
42
- let filename = src_dir. join ( & link. location ) ;
43
- if !filename. exists ( ) {
44
- if let Some ( parent) = filename. parent ( ) {
45
- if !parent. exists ( ) {
46
- fs:: create_dir_all ( parent) ?;
42
+ if let Some ( ref location) = link. location {
43
+ let filename = src_dir. join ( location) ;
44
+ if !filename. exists ( ) {
45
+ if let Some ( parent) = filename. parent ( ) {
46
+ if !parent. exists ( ) {
47
+ fs:: create_dir_all ( parent) ?;
48
+ }
47
49
}
48
- }
49
- debug ! ( "Creating missing file {}" , filename. display( ) ) ;
50
+ debug ! ( "Creating missing file {}" , filename. display( ) ) ;
50
51
51
- let mut f = File :: create ( & filename) ?;
52
- writeln ! ( f, "# {}" , link. name) ?;
52
+ let mut f = File :: create ( & filename) ?;
53
+ writeln ! ( f, "# {}" , link. name) ?;
54
+ }
53
55
}
54
56
55
57
items. extend ( & link. nested_items ) ;
@@ -152,7 +154,7 @@ pub struct Chapter {
152
154
/// Nested items.
153
155
pub sub_items : Vec < BookItem > ,
154
156
/// The chapter's location, relative to the `SUMMARY.md` file.
155
- pub path : PathBuf ,
157
+ pub path : Option < PathBuf > ,
156
158
/// An ordered list of the names of each chapter above this one, in the hierarchy.
157
159
pub parent_names : Vec < String > ,
158
160
}
@@ -168,11 +170,31 @@ impl Chapter {
168
170
Chapter {
169
171
name : name. to_string ( ) ,
170
172
content,
171
- path : path. into ( ) ,
173
+ path : Some ( path. into ( ) ) ,
174
+ parent_names,
175
+ ..Default :: default ( )
176
+ }
177
+ }
178
+
179
+ /// Create a new draft chapter that is not attached to a source markdown file and has
180
+ /// thus no content.
181
+ pub fn new_draft ( name : & str , parent_names : Vec < String > ) -> Self {
182
+ Chapter {
183
+ name : name. to_string ( ) ,
184
+ content : String :: new ( ) ,
185
+ path : None ,
172
186
parent_names,
173
187
..Default :: default ( )
174
188
}
175
189
}
190
+
191
+ /// Check if the chapter is a draft chapter, meaning it has no path to a source markdown file
192
+ pub fn is_draft_chapter ( & self ) -> bool {
193
+ match self . path {
194
+ Some ( _) => false ,
195
+ None => true ,
196
+ }
197
+ }
176
198
}
177
199
178
200
/// Use the provided `Summary` to load a `Book` from disk.
@@ -202,7 +224,7 @@ pub(crate) fn load_book_from_disk<P: AsRef<Path>>(summary: &Summary, src_dir: P)
202
224
} )
203
225
}
204
226
205
- fn load_summary_item < P : AsRef < Path > > (
227
+ fn load_summary_item < P : AsRef < Path > + Clone > (
206
228
item : & SummaryItem ,
207
229
src_dir : P ,
208
230
parent_names : Vec < String > ,
@@ -215,40 +237,46 @@ fn load_summary_item<P: AsRef<Path>>(
215
237
}
216
238
}
217
239
218
- fn load_chapter < P : AsRef < Path > > (
240
+ fn load_chapter < P : AsRef < Path > + Clone > (
219
241
link : & Link ,
220
242
src_dir : P ,
221
243
parent_names : Vec < String > ,
222
244
) -> Result < Chapter > {
223
- debug ! ( "Loading {} ({})" , link. name, link. location. display( ) ) ;
224
- let src_dir = src_dir. as_ref ( ) ;
245
+ let mut ch = if let Some ( ref link_location) = link. location {
246
+ debug ! ( "Loading {} ({})" , link. name, link_location. display( ) ) ;
247
+ let src_dir = src_dir. as_ref ( ) ;
248
+
249
+ let location = if link_location. is_absolute ( ) {
250
+ link_location. clone ( )
251
+ } else {
252
+ src_dir. join ( link_location)
253
+ } ;
225
254
226
- let location = if link. location . is_absolute ( ) {
227
- link. location . clone ( )
228
- } else {
229
- src_dir. join ( & link. location )
230
- } ;
255
+ let mut f = File :: open ( & location)
256
+ . chain_err ( || format ! ( "Chapter file not found, {}" , link_location. display( ) ) ) ?;
231
257
232
- let mut f = File :: open ( & location)
233
- . chain_err ( || format ! ( "Chapter file not found, {}" , link. location. display( ) ) ) ?;
258
+ let mut content = String :: new ( ) ;
259
+ f. read_to_string ( & mut content)
260
+ . chain_err ( || format ! ( "Unable to read \" {}\" ({})" , link. name, location. display( ) ) ) ?;
234
261
235
- let mut content = String :: new ( ) ;
236
- f . read_to_string ( & mut content )
237
- . chain_err ( || format ! ( "Unable to read \" {} \" ({})" , link . name , location . display ( ) ) ) ? ;
262
+ let stripped = location
263
+ . strip_prefix ( & src_dir )
264
+ . expect ( "Chapters are always inside a book" ) ;
238
265
239
- let stripped = location
240
- . strip_prefix ( & src_dir)
241
- . expect ( "Chapters are always inside a book" ) ;
266
+ Chapter :: new ( & link. name , content, stripped, parent_names. clone ( ) )
267
+ } else {
268
+ Chapter :: new_draft ( & link. name , parent_names. clone ( ) )
269
+ } ;
242
270
243
271
let mut sub_item_parents = parent_names. clone ( ) ;
244
- let mut ch = Chapter :: new ( & link . name , content , stripped , parent_names ) ;
272
+
245
273
ch. number = link. number . clone ( ) ;
246
274
247
275
sub_item_parents. push ( link. name . clone ( ) ) ;
248
276
let sub_items = link
249
277
. nested_items
250
278
. iter ( )
251
- . map ( |i| load_summary_item ( i, src_dir, sub_item_parents. clone ( ) ) )
279
+ . map ( |i| load_summary_item ( i, src_dir. clone ( ) , sub_item_parents. clone ( ) ) )
252
280
. collect :: < Result < Vec < _ > > > ( ) ?;
253
281
254
282
ch. sub_items = sub_items;
@@ -376,15 +404,15 @@ And here is some \
376
404
name : String :: from ( "Nested Chapter 1" ) ,
377
405
content : String :: from ( "Hello World!" ) ,
378
406
number : Some ( SectionNumber ( vec ! [ 1 , 2 ] ) ) ,
379
- path : PathBuf :: from ( "second.md" ) ,
407
+ path : Some ( PathBuf :: from ( "second.md" ) ) ,
380
408
parent_names : vec ! [ String :: from( "Chapter 1" ) ] ,
381
409
sub_items : Vec :: new ( ) ,
382
410
} ;
383
411
let should_be = BookItem :: Chapter ( Chapter {
384
412
name : String :: from ( "Chapter 1" ) ,
385
413
content : String :: from ( DUMMY_SRC ) ,
386
414
number : None ,
387
- path : PathBuf :: from ( "chapter_1.md" ) ,
415
+ path : Some ( PathBuf :: from ( "chapter_1.md" ) ) ,
388
416
parent_names : Vec :: new ( ) ,
389
417
sub_items : vec ! [
390
418
BookItem :: Chapter ( nested. clone( ) ) ,
@@ -408,7 +436,7 @@ And here is some \
408
436
sections : vec ! [ BookItem :: Chapter ( Chapter {
409
437
name: String :: from( "Chapter 1" ) ,
410
438
content: String :: from( DUMMY_SRC ) ,
411
- path: PathBuf :: from( "chapter_1.md" ) ,
439
+ path: Some ( PathBuf :: from( "chapter_1.md" ) ) ,
412
440
..Default :: default ( )
413
441
} ) ] ,
414
442
..Default :: default ( )
@@ -448,7 +476,7 @@ And here is some \
448
476
name: String :: from( "Chapter 1" ) ,
449
477
content: String :: from( DUMMY_SRC ) ,
450
478
number: None ,
451
- path: PathBuf :: from( "Chapter_1/index.md" ) ,
479
+ path: Some ( PathBuf :: from( "Chapter_1/index.md" ) ) ,
452
480
parent_names: Vec :: new( ) ,
453
481
sub_items: vec![
454
482
BookItem :: Chapter ( Chapter :: new(
@@ -500,7 +528,7 @@ And here is some \
500
528
name: String :: from( "Chapter 1" ) ,
501
529
content: String :: from( DUMMY_SRC ) ,
502
530
number: None ,
503
- path: PathBuf :: from( "Chapter_1/index.md" ) ,
531
+ path: Some ( PathBuf :: from( "Chapter_1/index.md" ) ) ,
504
532
parent_names: Vec :: new( ) ,
505
533
sub_items: vec![
506
534
BookItem :: Chapter ( Chapter :: new(
@@ -537,7 +565,7 @@ And here is some \
537
565
let summary = Summary {
538
566
numbered_chapters : vec ! [ SummaryItem :: Link ( Link {
539
567
name: String :: from( "Empty" ) ,
540
- location: PathBuf :: from( "" ) ,
568
+ location: Some ( PathBuf :: from( "" ) ) ,
541
569
..Default :: default ( )
542
570
} ) ] ,
543
571
..Default :: default ( )
@@ -556,7 +584,7 @@ And here is some \
556
584
let summary = Summary {
557
585
numbered_chapters : vec ! [ SummaryItem :: Link ( Link {
558
586
name: String :: from( "nested" ) ,
559
- location: dir,
587
+ location: Some ( dir) ,
560
588
..Default :: default ( )
561
589
} ) ] ,
562
590
..Default :: default ( )
0 commit comments