Skip to content

Commit a3a05c5

Browse files
committed
Add support for parts in asciidoc output
1 parent 582e4f2 commit a3a05c5

File tree

2 files changed

+82
-33
lines changed

2 files changed

+82
-33
lines changed

src/format/asciidoc/format-asciidoc.ts

Lines changed: 76 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { resolveInputTarget } from "../../project/project-index.ts";
1212
import { projectFormatOutputDir } from "../../project/project-shared.ts";
1313
import { kProjectType, ProjectContext } from "../../project/types.ts";
1414
import {
15+
BookChapterEntry,
16+
BookPart,
1517
kBookAppendix,
1618
kBookChapters,
1719
} from "../../project/types/book/book-config.ts";
@@ -78,12 +80,14 @@ const asciidocBookExtension = {
7880
};
7981

8082
async 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

139157
async 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;

src/project/types/book/book-config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,12 @@ const kDownloadableItems: Record<string, { name: string; icon: string }> = {
422422
"docx": { name: "Docx", icon: "file-word" },
423423
};
424424

425+
export type BookChapterEntry = BookPart | string;
426+
export interface BookPart {
427+
part: string;
428+
chapters: string[];
429+
}
430+
425431
interface BookChapterItem extends SidebarItem {
426432
part?: string;
427433
chapters?: BookChapterItem[];

0 commit comments

Comments
 (0)