UNPKG

simple-odf

Version:

Open Document Format made easy using pure JavaScript and Node.js

152 lines (151 loc) 6.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DomVisitor = void 0; const fs_1 = require("fs"); const draw_1 = require("../api/draw"); const office_1 = require("../api/office"); const text_1 = require("../api/text"); const DrawElementName_1 = require("./DrawElementName"); const OdfAttributeName_1 = require("./OdfAttributeName"); const OdfElementName_1 = require("./OdfElementName"); const OdfTextElementWriter_1 = require("./OdfTextElementWriter"); const TextElementName_1 = require("./TextElementName"); const IMAGE_ENCODING = 'base64'; const HYPERLINK_LINK_TYPE = 'simple'; class DomVisitor { constructor(commonStyles, automaticStyles) { this.commonStyles = commonStyles; this.automaticStyles = automaticStyles; } visit(odfElement, document, parent) { let currentElement; if (odfElement instanceof text_1.Heading) { currentElement = this.visitHeading(odfElement, document, parent); } else if (odfElement instanceof text_1.Hyperlink) { currentElement = this.visitHyperlink(odfElement, document, parent); } else if (odfElement instanceof draw_1.Image) { currentElement = this.visitImage(odfElement, document, parent); } else if (odfElement instanceof text_1.List) { currentElement = this.visitList(odfElement, document, parent); } else if (odfElement instanceof text_1.ListItem) { currentElement = this.visitListItem(document, parent); } else if (odfElement instanceof text_1.OdfTextElement) { currentElement = this.visitOdfText(odfElement, document, parent); } else if (odfElement instanceof text_1.Paragraph) { currentElement = this.visitParagraph(odfElement, document, parent); } else if (odfElement instanceof office_1.TextBody) { currentElement = this.visitTextBody(document, parent); } odfElement.getAll().forEach((odfChildElement) => { this.visit(odfChildElement, document, currentElement); }); } visitHeading(heading, document, parent) { const headingElement = document.createElement(TextElementName_1.TextElementName.TextHeading); headingElement.setAttribute(OdfAttributeName_1.OdfAttributeName.TextOutlineLevel, heading.getLevel().toString(10)); parent.appendChild(headingElement); this.setStyleName(heading, headingElement); return headingElement; } visitHyperlink(hyperlink, document, parent) { const hyperlinkElement = document.createElement(TextElementName_1.TextElementName.TextHyperlink); hyperlinkElement.setAttribute(OdfAttributeName_1.OdfAttributeName.XlinkType, HYPERLINK_LINK_TYPE); hyperlinkElement.setAttribute(OdfAttributeName_1.OdfAttributeName.XlinkHref, hyperlink.getURI()); parent.appendChild(hyperlinkElement); this.visitOdfText(hyperlink, document, hyperlinkElement); return hyperlinkElement; } visitImage(image, document, parent) { const frameElement = document.createElement(DrawElementName_1.DrawElementName.DrawFrame); frameElement.setAttribute(OdfAttributeName_1.OdfAttributeName.TextAnchorType, image.getAnchorType()); const width = image.getWidth(); if (width !== undefined) { frameElement.setAttribute(OdfAttributeName_1.OdfAttributeName.SvgWidth, width + 'mm'); } const height = image.getHeight(); if (height !== undefined) { frameElement.setAttribute(OdfAttributeName_1.OdfAttributeName.SvgHeight, height + 'mm'); } parent.appendChild(frameElement); this.embedImage(document, frameElement, image); return frameElement; } visitList(list, document, parent) { if (list.size() === 0) { return parent; } const listElement = document.createElement(TextElementName_1.TextElementName.TextList); parent.appendChild(listElement); this.setStyleName(list, listElement); return listElement; } visitListItem(document, parent) { const listItemElement = document.createElement(TextElementName_1.TextElementName.TextListItem); parent.appendChild(listItemElement); return listItemElement; } visitOdfText(odfText, document, parent) { new OdfTextElementWriter_1.OdfTextElementWriter().write(odfText, document, parent); return parent; } visitParagraph(paragraph, document, parent) { const paragraphElement = document.createElement(TextElementName_1.TextElementName.TextParagraph); parent.appendChild(paragraphElement); this.setStyleName(paragraph, paragraphElement); return paragraphElement; } visitTextBody(document, parent) { const bodyElement = document.createElement(OdfElementName_1.OdfElementName.OfficeBody); parent.appendChild(bodyElement); const textElement = document.createElement(OdfElementName_1.OdfElementName.OfficeText); bodyElement.appendChild(textElement); return textElement; } setStyleName(odfElement, domElement) { let styleName = this.getAutomaticStyleName(odfElement); if (styleName === undefined) { styleName = this.getCommonStyleName(odfElement); } if (styleName !== undefined) { domElement.setAttribute(OdfAttributeName_1.OdfAttributeName.TextStyleName, styleName); } } getAutomaticStyleName(odfElement) { const style = odfElement.getStyle(); return style !== undefined ? this.automaticStyles.getName(style) : undefined; } getCommonStyleName(odfElement) { const styleName = odfElement.getStyleName(); return styleName !== undefined ? this.commonStyles.getName(styleName) : undefined; } /** * Creates the image element and embeds the denoted image base64 encoded binary data. * * @param {Document} document The XML document * @param {Element} frameElement The parent node in the DOM (`draw:frame`) * @param {Image} image The image * @private */ embedImage(document, frameElement, image) { const imageElement = document.createElement(DrawElementName_1.DrawElementName.DrawImage); frameElement.appendChild(imageElement); const binaryData = document.createElement(OdfElementName_1.OdfElementName.OfficeBinaryData); imageElement.appendChild(binaryData); const rawImage = (0, fs_1.readFileSync)(image.getPath()); const base64Image = rawImage.toString(IMAGE_ENCODING); const textNode = document.createTextNode(base64Image); binaryData.appendChild(textNode); } } exports.DomVisitor = DomVisitor;