This commit is contained in:
amitm02
2018-10-17 09:15:32 +03:00
parent 9d9dd62f00
commit 3f3fd05cb1
12 changed files with 94 additions and 147 deletions

View File

@ -283,16 +283,19 @@ export class File {
...newGroup,
default: header.header,
};
break;
case HeaderReferenceType.FIRST:
newGroup = {
...newGroup,
first: header.header,
};
break;
case HeaderReferenceType.EVEN:
newGroup = {
...newGroup,
even: header.header,
};
break;
default:
newGroup = {
...newGroup,

View File

@ -1,5 +1,5 @@
import * as fastXmlParser from "fast-xml-parser";
import { convertToXmlComponent, ImportedRootElementAttributes, parseOptions } from "file/xml-components";
import { convertToXmlComponent, ImportedRootElementAttributes, ImportedXmlComponent } from "file/xml-components";
import { Element as XMLElement, xml2js } from "xml-js";
import { Styles } from "./";
export class ExternalStylesFactory {
@ -25,25 +25,24 @@ export class ExternalStylesFactory {
* </w:styles>
* @param externalStyles context from styles.xml
*/
public newInstance(externalStyles: string): Styles {
const xmlStyles = fastXmlParser.parse(externalStyles, parseOptions)["w:styles"];
// create styles with attributes from the parsed xml
const importedStyle = new Styles(new ImportedRootElementAttributes(xmlStyles._attr));
public newInstance(xmlData: string): Styles {
const xmlObj = xml2js(xmlData, { compact: false }) as XMLElement;
// convert other elements (not styles definitions, but default styles and so on ...)
Object.keys(xmlStyles)
.filter((element) => element !== "_attr" && element !== "w:style")
.forEach((element) => {
const converted = convertToXmlComponent(element, xmlStyles[element]);
if (Array.isArray(converted)) {
converted.forEach((c) => importedStyle.push(c));
} else {
importedStyle.push(converted);
}
});
let stylesXmlElement: XMLElement | undefined;
for (const xmlElm of xmlObj.elements || []) {
if (xmlElm.name === "w:styles") {
stylesXmlElement = xmlElm;
}
}
if (stylesXmlElement === undefined) {
throw new Error("can not find styles element");
}
// convert the styles one by one
xmlStyles["w:style"].map((style) => convertToXmlComponent("w:style", style)).forEach(importedStyle.push.bind(importedStyle));
const importedStyle = new Styles(new ImportedRootElementAttributes(stylesXmlElement.attributes));
const stylesElements = stylesXmlElement.elements || [];
for (const childElm of stylesElements) {
importedStyle.push(convertToXmlComponent(childElm) as ImportedXmlComponent);
}
return importedStyle;
}
}

View File

@ -1,82 +1,30 @@
// tslint:disable:no-any
// import * as fastXmlParser from "fast-xml-parser";
import { flatMap } from "lodash";
import { Element as XmlElement } from "xml-js";
import { IXmlableObject, XmlComponent } from ".";
import { Element } from 'xml-js';
export const parseOptions = {
ignoreAttributes: false,
attributeNamePrefix: "",
attrNodeName: "_attr",
};
export function convertToXmlComponentOld(elementName: string, element: any): ImportedXmlComponent | ImportedXmlComponent[] {
const xmlElement = new ImportedXmlComponent(elementName, element._attr);
if (Array.isArray(element)) {
const out: any[] = [];
element.forEach((itemInArray) => {
out.push(convertToXmlComponentOld(elementName, itemInArray));
});
return flatMap(out);
} else if (typeof element === "object") {
Object.keys(element)
.filter((key) => key !== "_attr")
.map((item) => convertToXmlComponentOld(item, element[item]))
.forEach((converted) => {
if (Array.isArray(converted)) {
converted.forEach(xmlElement.push.bind(xmlElement));
} else {
xmlElement.push(converted);
}
});
} else if (element !== "") {
xmlElement.push(element);
}
return xmlElement;
}
/**
* Converts the given xml element (in json format) into XmlComponent.
* Note: If element is array, them it will return ImportedXmlComponent[]. Example for given:
* element = [
* { w:t: "val 1"},
* { w:t: "val 2"}
* ]
* will return
* [
* ImportedXmlComponent { rootKey: "w:t", root: [ "val 1" ]},
* ImportedXmlComponent { rootKey: "w:t", root: [ "val 2" ]}
* ]
*
* @param elementName name (rootKey) of the XmlComponent
* @param element the xml element in json presentation
*/
export function convertToXmlComponent(elementName: string, element: Element): ImportedXmlComponent {
const xmlComponent = new ImportedXmlComponent(elementName, element.attributes);
if (element.elements) {
for (const child of element.elements) {
if (child.type === undefined) {
continue;
}
switch (child.type) {
case 'element':
if (child.name === undefined) {
continue;
}
xmlComponent.push(convertToXmlComponent(child.name, child));
break;
case 'text':
xmlComponent.push(<string>(child.text));
break;
}
}
}
return xmlComponent;
}
export function convertToXmlComponent(element: XmlElement): ImportedXmlComponent | string | undefined {
switch (element.type) {
case "element":
const xmlComponent = new ImportedXmlComponent(element.name as string, element.attributes);
const childElments = element.elements || [];
for (const childElm of childElments) {
const child = convertToXmlComponent(childElm);
if (child !== undefined) {
xmlComponent.push(child);
}
}
return xmlComponent;
case "text":
return element.text as string;
default:
return undefined;
}
}
/**
* Represents imported xml component from xml file.

View File

@ -1,5 +1,8 @@
export interface IXmlAttribute {
[key: string]: string | number | boolean;
}
export interface IXmlableObject extends Object {
_attr?: { [key: string]: string | number | boolean };
_attr?: IXmlAttribute;
}
// Needed because of: https://github.com/s-panferov/awesome-typescript-loader/issues/432