UNPKG

majas

Version:

Format-agnostic structure converter.

53 lines (52 loc) 2.06 kB
import sanitize from 'sanitize-filename'; import { FormatterBase } from '../core/Formatter.js'; import {} from '../fstree.js'; import { uniqify } from '../util/string.js'; import { map } from '../util/misc.js'; export const DefaultOptions = { baseDirname: '.', baseFilename: 'out', filename: title => title, }; export default class Filesystem extends FormatterBase { options; constructor(format, options) { super(format); this.options = { ...DefaultOptions, ...options }; } parseImpl(input) { if (typeof input.children === 'string') { return { title: input.title, content: input.children, }; } return { title: input.title, children: { ordered: false, items: Array.from(input.children, ([name, child]) => this.parseImpl({ title: name, children: child })), }, }; } emit(output) { const children = new Map(); const walk = (parent, node, index) => { const filename = map(t => sanitize(this.options.filename(t, index), { replacement: this.options.invalidFilenameCharReplacement, }), node.title) ?? index?.toString(); if (node.content !== undefined) { const contentFilename = uniqify(`${filename ?? this.options.baseFilename}.${output.format.fileExtensions[0] ?? 'txt'}`, s => parent.has(s)); parent.set(contentFilename, (this.options.header?.(node.title, index) ?? '') + node.content); } if (node.children?.items.length || node.content === undefined) { const childrenDirname = uniqify(filename ?? this.options.baseDirname, s => parent.has(s)); const children = new Map(); parent.set(childrenDirname, children); node.children?.items.forEach((n, i) => walk(children, n, i + 1)); } }; walk(children, output.root); return children; } }