UNPKG

myst-to-docx

Version:

Export from a MyST Markdown document to Microsoft Word (*.docx)

77 lines (76 loc) 2.68 kB
import { RuleId, fileError, fileWarn } from 'myst-common'; import { Paragraph, TextRun } from 'docx'; import { defaultHandlers } from './schema.js'; export class DocxSerializer { constructor(file, options, frontmatter) { var _a; this.footnotes = {}; this.current = []; this.frontmatter = {}; this.file = file; this.data = {}; this.handlers = (_a = options.handlers) !== null && _a !== void 0 ? _a : defaultHandlers; this.options = options !== null && options !== void 0 ? options : {}; this.children = []; this.numbering = []; this.frontmatter = frontmatter !== null && frontmatter !== void 0 ? frontmatter : {}; } render(node, parent) { if (!this.handlers[node.type]) { fileError(this.file, `Node of type "${node.type}" is not supported by docx renderer`, { node, source: 'myst-to-docx:render', ruleId: RuleId.docxRenders, }); return; } this.handlers[node.type](this, node, parent); } renderChildren(parent, paragraphOpts, runOpts) { if (!('children' in parent)) { const node = parent; fileWarn(this.file, `Expected children for node of type ${node.type}`, { node, ruleId: RuleId.docxRenders, }); return; } parent.children.forEach((node) => { if (paragraphOpts) this.addParagraphOptions(paragraphOpts); if (runOpts) this.addRunOptions(runOpts); this.render(node, parent); }); } addParagraphOptions(opts) { var _a; this.data.nextParagraphOpts = { ...(_a = this.data) === null || _a === void 0 ? void 0 : _a.nextParagraphOpts, ...opts }; } addRunOptions(opts) { this.data.nextRunOpts = { ...this.data.nextRunOpts, ...opts }; } text(text, opts) { if (!text) return; this.current.push(new TextRun({ text, ...this.data.nextRunOpts, ...opts })); delete this.data.nextRunOpts; } closeBlock(props, force = false) { if (this.current.length === 0 && !props && !force) { delete this.data.nextParagraphOpts; return; } const paragraph = new Paragraph({ children: this.current, ...this.data.nextParagraphOpts, ...props, }); this.current = []; delete this.data.nextParagraphOpts; this.children.push(paragraph); } blankLine(props) { this.closeBlock(props, true); } }