@@ -12,6 +12,8 @@ import { resolveInputTarget } from "../../project/project-index.ts";
1212import { projectFormatOutputDir } from "../../project/project-shared.ts" ;
1313import { kProjectType , ProjectContext } from "../../project/types.ts" ;
1414import {
15+ BookChapterEntry ,
16+ BookPart ,
1517 kBookAppendix ,
1618 kBookChapters ,
1719} from "../../project/types/book/book-config.ts" ;
@@ -78,12 +80,14 @@ const asciidocBookExtension = {
7880} ;
7981
8082async function bookRootPageMarkdown ( project : ProjectContext ) {
83+ const bookContents = bookConfig (
84+ kBookChapters ,
85+ project . config ,
86+ ) as BookChapterEntry [ ] ;
87+
8188 // Find chapter and appendices
8289 const chapters = await resolveBookInputs (
83- bookConfig (
84- kBookChapters ,
85- project . config ,
86- ) as string [ ] ,
90+ bookContents ,
8791 project ,
8892 ( input : string ) => {
8993 // Exclude the index page from the chapter list (since we'll append
@@ -107,8 +111,8 @@ async function bookRootPageMarkdown(project: ProjectContext) {
107111 const fileContents = [
108112 "\n```{=asciidoc}\n\n" ,
109113 levelOffset ( "+1" ) ,
110- include ( chapters ) ,
111- appendix ( appendices ) ,
114+ partsAndChapters ( chapters , chapter ) ,
115+ partsAndChapters ( appendices , appendix ) ,
112116 levelOffset ( "-1" ) ,
113117 "```\n" ,
114118 ] ;
@@ -120,45 +124,84 @@ function levelOffset(offset: string) {
120124 return `:leveloffset: ${ offset } \n` ;
121125}
122126
123- function include ( chapters : string [ ] ) {
124- return chapters . map ( ( chap ) => {
125- return `include::${ chap } []\n` ;
127+ function partsAndChapters (
128+ entries : BookChapterEntry [ ] ,
129+ include : ( path : string ) => string ,
130+ ) {
131+ return entries . map ( ( entry ) => {
132+ if ( typeof ( entry ) === "string" ) {
133+ return include ( entry ) ;
134+ } else {
135+ const partOutput : string [ ] = [ ] ;
136+ partOutput . push ( levelOffset ( "-1" ) ) ;
137+ partOutput . push ( `= ${ entry . part } ` ) ;
138+ partOutput . push ( levelOffset ( "+1" ) ) ;
139+
140+ for ( const chap of entry . chapters ) {
141+ partOutput . push ( include ( chap ) ) ;
142+ }
143+
144+ return partOutput . join ( "\n" ) ;
145+ }
126146 } ) . join ( "\n" ) ;
127147}
128148
129- function appendix ( apps : string [ ] ) {
130- if ( apps . length > 0 ) {
131- return apps . map ( ( app ) => {
132- return `[appendix]\ninclude::${ app } []\n` ;
133- } ) . join ( "\n" ) ;
134- } else {
135- return "" ;
136- }
149+ function chapter ( path : string ) {
150+ return `include::${ path } []\n` ;
151+ }
152+
153+ function appendix ( path : string ) {
154+ return `[appendix]\n${ chapter ( path ) } \n` ;
137155}
138156
139157async function resolveBookInputs (
140- inputs : string [ ] ,
158+ inputs : BookChapterEntry [ ] ,
141159 project : ProjectContext ,
142160 filter ?: ( input : string ) => boolean ,
143161) {
144- const outputs : string [ ] = [ ] ;
145- for ( const input of inputs ) {
162+ const resolveChapter = async ( input : string ) => {
146163 if ( filter && ! filter ( input ) ) {
147- continue ;
148- }
149- const target = await resolveInputTarget (
150- project ,
151- input ,
152- false ,
153- ) ;
154- if ( target ) {
155- const [ dir , stem ] = dirAndStem ( target ?. outputHref ) ;
156- const outputFile = join (
157- dir ,
158- `${ stem } .adoc` ,
164+ return undefined ;
165+ } else {
166+ const target = await resolveInputTarget (
167+ project ,
168+ input ,
169+ false ,
159170 ) ;
171+ if ( target ) {
172+ const [ dir , stem ] = dirAndStem ( target ?. outputHref ) ;
173+ const outputFile = join (
174+ dir ,
175+ `${ stem } .adoc` ,
176+ ) ;
177+
178+ return outputFile ;
179+ } else {
180+ return undefined ;
181+ }
182+ }
183+ } ;
160184
161- outputs . push ( outputFile ) ;
185+ const outputs : BookChapterEntry [ ] = [ ] ;
186+ for ( const input of inputs ) {
187+ if ( typeof ( input ) === "string" ) {
188+ const chapterOutput = await resolveChapter ( input ) ;
189+ if ( chapterOutput ) {
190+ outputs . push ( chapterOutput ) ;
191+ }
192+ } else {
193+ const entry = input as BookPart ;
194+ const entryOutput = {
195+ part : entry . part ,
196+ chapters : [ ] as string [ ] ,
197+ } ;
198+ for ( const chapter of entry . chapters ) {
199+ const resolved = await resolveChapter ( chapter ) ;
200+ if ( resolved ) {
201+ entryOutput . chapters . push ( resolved ) ;
202+ }
203+ }
204+ outputs . push ( entryOutput ) ;
162205 }
163206 }
164207 return outputs ;
0 commit comments