Skip to content

Instantly share code, notes, and snippets.

@richie5um
Created July 25, 2022 18:13
Show Gist options
  • Save richie5um/edca22a6d7423d63a92b0837487077e8 to your computer and use it in GitHub Desktop.
Save richie5um/edca22a6d7423d63a92b0837487077e8 to your computer and use it in GitHub Desktop.
name: Read SmzCustomXml
description: ''
host: WORD
api_set: {}
script:
content: |
$("#get-xml").click(() =>
tryCatch(() => {
getCustomJson();
})
);
async function getCustomJson() {
await Word.run(async (ctx) => {
const promise = new Promise((resolve, reject) => {
const smzNamespace = "https://schemas.summize.com/token/1.0";
Office.context.document.customXmlParts.getByNamespaceAsync(smzNamespace, async (result) => {
if (result.status !== "succeeded") {
return reject(result);
}
const xmlParts = result.value;
let customJsons = [];
for (let xmlPart of xmlParts) {
const id = xmlPart.id.replace("{", "").replace("}", "");
const customJson = await this.getCustomJsonById(id);
customJsons.push({ id, json: customJson });
}
customJsons = customJsons.filter((x) => x !== undefined);
return resolve(customJsons);
});
});
await promise.then((items) => {
for(let item of items) {
console.log(JSON.stringify(item, null, 2));
}
});
});
}
async function getCustomJsonById(id) {
if (typeof Word === "undefined") {
return Promise.reject();
}
return Word.run(async (ctx) => {
id = `{${id}}`;
const promise = new Promise((resolve, reject) => {
Office.context.document.customXmlParts.getByIdAsync(id, async function(result) {
if (result.status !== "succeeded" || result.value === undefined) {
return reject(result);
}
const xmlPart = result.value;
xmlPart.getNodesAsync("*", async (result) => {
if (result.status !== "succeeded") {
return reject(result);
}
// This doesn't feel right, but I can't get the xpath working. So, hey ho.
const nodes = result.value.filter((x) => x.baseName === "json");
if (nodes.length === 0) {
return reject(result);
}
nodes[0].getTextAsync((result) => {
if (result.status !== "succeeded") {
return reject(result);
}
const json = JSON.parse(decodeForXml(result.value));
return resolve(json);
});
});
});
});
return promise;
}).catch((err) => {
console.log("OfficeService-Error: " + JSON.stringify(err));
if (err instanceof OfficeExtension.Error) {
console.log("OfficeService-Debug info: " + JSON.stringify(err.debugInfo));
}
});
}
function encodeForXml(xml: string) {
return xml
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;");
}
function decodeForXml(xml: string) {
return xml
.replace(/&apos;/g, "'")
.replace(/&quot;/g, '"')
.replace(/&gt;/g, ">")
.replace(/&lt;/g, "<")
.replace(/&amp;/g, "&");
}
/** Default helper for invoking an action and handling errors. */
async function tryCatch(callback) {
try {
await callback();
} catch (error) {
// Note: In a production add-in, you'd want to notify the user through your add-in's UI.
console.error(error);
}
}
language: typescript
template:
content: "<section class=\"samples ms-font-m\">\n\t<button id=\"get-xml\" class=\"ms-Button\">Read CustomXml</button>\n</section>"
language: html
style:
content: |-
section.samples {
margin-top: 20px;
}
section.samples .ms-Button, section.setup .ms-Button {
display: block;
margin-bottom: 5px;
margin-left: 20px;
min-width: 80px;
}
language: css
libraries: |-
https://appsforoffice.microsoft.com/lib/1/hosted/office.js
@types/office-js
[email protected]/dist/css/fabric.min.css
[email protected]/dist/css/fabric.components.min.css
[email protected]/client/core.min.js
@types/core-js
[email protected]
@types/[email protected]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment