book/Chapters.ts
import { promise as glob } from 'glob-promise';
import { HtmlRR0SsgContext } from '../RR0SsgContext';
import { LinkType } from 'ssg-api';
import path from 'path';
export class Chapter {
readonly context: HtmlRR0SsgContext;
subs: Chapter[] = [];
constructor(parentContext: HtmlRR0SsgContext, protected startFileName: string) {
this.context = parentContext.clone();
}
async scan() {
this.context.read(this.startFileName);
const dir = path.dirname(this.context.inputFile.name);
const fileName = path.basename(this.context.inputFile.name);
const subFileNames = await glob(path.join(dir, '*/', fileName));
this.subs = [];
for (const subFileName of subFileNames) {
const subChapter = new Chapter(this.context, subFileName);
this.subs.push(subChapter);
await subChapter.scan();
}
}
toString(prefix = '- '): string {
const file = this.context.inputFile;
return `${prefix + file.name}: "${file.title}", meta=${JSON.stringify(file.meta)}, links=${JSON.stringify(
file.links)}
${this.subs.map(subFile => subFile.toString(' ' + prefix)).join('')}`;
}
async update(parent?: Chapter) {
const file = this.context.outputFile;
const meta = file.meta;
const links = file.links;
if (parent) {
const parentFile = parent.context.outputFile;
const parentMeta = parentFile.meta;
meta.author = parentMeta.author;
meta.copyright = parentMeta.copyright;
links.contents = {
type: LinkType.contents,
url: path.join("/", parentFile.name),
text: parentFile.title
};
links.start = parentFile.links.start;
} else {
links.start = {
type: LinkType.start,
url: path.join("/", this.startFileName),
text: file.title
};
}
let prev: Chapter | undefined;
for (const sub of this.subs) {
const subFile = sub.context.outputFile;
if (prev) {
prev.context.outputFile.links.next = {
type: LinkType.next,
url: path.join("/", subFile.name),
text: subFile.title
};
}
sub.context.outputFile.links.prev = prev ? {
type: LinkType.prev,
url: path.join("/", prev.context.outputFile.name),
text: prev.context.outputFile.title
} : undefined;
await sub.update(this);
prev = sub;
}
}
}
/*
const args = new CLI().getArgs();
const startFileName = args.start;
const context = new RR0SsgContextImpl('fr', new TimeContext({
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: '2-digit',
minute: '2-digit'
}
));
const file = HtmlSsgFile.read(context, startFileName);
const startFileNames = [file.name];
const variants = file.lang.variants;
for (const variant of variants) {
const parsed = path.parse(startFileName);
const variantFileName = path.join(parsed.dir, `${parsed.name}_${variant}${parsed.ext}`);
startFileNames.push(variantFileName);
}
for (const startFileName of startFileNames) {
const chapter = new Chapter(context as unknown as HtmlRR0SsgContext, startFileName);
chapter.scan().then(async () => {
console.log('*** Before:\n', chapter.toString());
await chapter.update();
console.log('\n*** After:\n', chapter.toString());
}).catch(e => {
console.error(e);
});
}
*/