myst-to-docx
Version:
Export from a MyST Markdown document to Microsoft Word (*.docx)
77 lines (76 loc) • 2.68 kB
JavaScript
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);
}
}