Instantly share code, notes, and snippets.
Last active
August 10, 2023 23:00
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save akrantz/93f3da3865bd8c0583f3e3ecbc258b4a to your computer and use it in GitHub Desktop.
Use tags to process subsets of slides.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Work with tags | |
description: Use tags to process subsets of slides. | |
host: POWERPOINT | |
api_set: {} | |
script: | |
content: > | |
$("#add-selected-slide-tag").click(() => tryCatch(addTagToSelectedSlide)); | |
$("#delete-slides-by-audience").click(() => | |
tryCatch(deleteSlidesByAudience)); | |
$("#add-slide-tags").click(() => tryCatch(addMultipleSlideTags)); | |
$("#add-shape-tag").click(() => tryCatch(addShapeTag)); | |
$("#add-presentation-tag").click(() => tryCatch(addPresentationTag)); | |
$("#delete-presentation-tag").click(() => tryCatch(deletePresentationTag)); | |
$("#enumerate-tags").click(() => tryCatch(enumerateTags)); | |
async function addTagToSelectedSlide() { | |
await PowerPoint.run(async function(context) { | |
let selectedSlideIndex = await getSelectedSlideIndex(); | |
// Decrement because the getSelectedSlideByIndex method is 1-based, | |
// but the getItemAt method is 0-based. | |
selectedSlideIndex = selectedSlideIndex - 1; | |
const slide = context.presentation.slides.getItemAt(selectedSlideIndex); | |
slide.tags.add("CUSTOMER_TYPE", "Premium"); | |
await context.sync(); | |
const audienceTag = slide.tags.getItem("CUSTOMER_TYPE"); | |
audienceTag.load("key, value"); | |
await context.sync(); | |
console.log("Added key " + JSON.stringify(audienceTag.key) + " with value " + JSON.stringify(audienceTag.value)); | |
}); | |
} | |
function getSelectedSlideIndex() { | |
// Wrap a call of one of the Common APIs in a Promise-returning | |
// function, so that it can be easily called within a run() function | |
// of an application-specific API. | |
return new OfficeExtension.Promise<number>(function(resolve, reject) { | |
Office.context.document.getSelectedDataAsync(Office.CoercionType.SlideRange, function(asyncResult) { | |
try { | |
if (asyncResult.status === Office.AsyncResultStatus.Failed) { | |
reject(console.error(asyncResult.error.message)); | |
} else { | |
const result = asyncResult.value as any; | |
resolve(result.slides[0].index); | |
} | |
} catch (error) { | |
reject(console.log(error)); | |
} | |
}); | |
}); | |
} | |
async function deleteSlidesByAudience() { | |
await PowerPoint.run(async function(context) { | |
const slides = context.presentation.slides; | |
slides.load("tags/key, tags/value"); | |
await context.sync(); | |
for (let i = 0; i < slides.items.length; i++) { | |
let currentSlide = slides.items[i]; | |
for (let j = 0; j < currentSlide.tags.items.length; j++) { | |
let currentTag = currentSlide.tags.items[j]; | |
if (currentTag.key === "CUSTOMER_TYPE" && currentTag.value === "Premium") { | |
currentSlide.delete(); | |
} | |
} | |
} | |
await context.sync(); | |
}); | |
} | |
async function addMultipleSlideTags() { | |
await PowerPoint.run(async function(context) { | |
const slide = context.presentation.slides.getItemAt(0); | |
slide.tags.add("OCEAN", "Indian"); | |
slide.tags.add("PLANET", "Jupiter"); | |
slide.tags.add("CONTINENT", "Antarctica"); | |
await context.sync(); | |
slide.tags.load("key, value"); | |
await context.sync(); | |
for (let i = 0; i < slide.tags.items.length; i++) { | |
console.log( | |
"Added key " + | |
JSON.stringify(slide.tags.items[i].key) + | |
" with value " + | |
JSON.stringify(slide.tags.items[i].value) | |
); | |
} | |
}); | |
} | |
async function addShapeTag() { | |
await PowerPoint.run(async function(context) { | |
const slide = context.presentation.slides.getItemAt(0); | |
const shape = slide.shapes.getItemAt(0); | |
shape.tags.add("MOUNTAIN", "Denali"); | |
await context.sync(); | |
const myShapeTag = shape.tags.getItem("MOUNTAIN"); | |
myShapeTag.load("key, value"); | |
await context.sync(); | |
console.log("Added key " + JSON.stringify(myShapeTag.key) + " with value " + JSON.stringify(myShapeTag.value)); | |
}); | |
} | |
async function addPresentationTag() { | |
await PowerPoint.run(async function(context) { | |
let presentationTags = context.presentation.tags; | |
presentationTags.add("COLOR", "blue"); | |
await context.sync(); | |
const tag = presentationTags.getItem("COLOR"); | |
tag.load("key, value"); | |
await context.sync(); | |
console.log("Added key " + JSON.stringify(tag.key) + " with value " + JSON.stringify(tag.value)); | |
}); | |
} | |
async function deletePresentationTag() { | |
await PowerPoint.run(async function(context) { | |
let presentationTags = context.presentation.tags; | |
presentationTags.delete("COLOR"); | |
await context.sync(); | |
console.log(JSON.stringify(presentationTags)); | |
}); | |
} | |
/** 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: ${error}`); | |
} | |
} | |
async function loadTags(tags: PowerPoint.TagCollection) { | |
// for each tag in tag collection, log the tag key and value to the console | |
for (let index = 0; index < tags.items.length; ++index) { | |
const tag = tags.items[index]; | |
tag.load(); | |
} | |
} | |
async function logTags(context: PowerPoint.RequestContext, tags: | |
PowerPoint.TagCollection) { | |
for (let index = 0; index < tags.items.length; ++index) { | |
const tag = tags.items[index]; | |
console.log(`Tag [${index}] key: ${tag.key}, Tag value: ${tag.value}`); | |
} | |
} | |
async function enumerateTags() { | |
return PowerPoint.run(async (context) => { | |
// load for presentation | |
context.presentation.load(["slides", "tags"]); | |
context.presentation.slides.load(["items"]); | |
context.presentation.tags.load(["items"]); | |
loadTags(context.presentation.tags); | |
await context.sync(); | |
// load for each slide | |
for (let slideIndex = 0; slideIndex < context.presentation.slides.items.length; ++slideIndex) { | |
const slide = context.presentation.slides.items[slideIndex]; | |
slide.load(["shapes", "tags"]); | |
slide.shapes.load("items"); | |
slide.tags.load("items"); | |
loadTags(slide.tags); | |
} | |
await context.sync(); | |
// load for each shape on each slide | |
for (let slideIndex = 0; slideIndex < context.presentation.slides.items.length; ++slideIndex) { | |
const slide = context.presentation.slides.items[slideIndex]; | |
for (let shapeIndex = 0; shapeIndex < slide.shapes.items.length; ++shapeIndex) { | |
const shape = slide.shapes.items[shapeIndex]; | |
shape.load(["tags"]); | |
shape.tags.load("items"); | |
} | |
} | |
await context.sync(); | |
// log presentation tags | |
logTags(context, context.presentation.tags); | |
for (let slideIndex = 0; slideIndex < context.presentation.slides.items.length; ++slideIndex) { | |
const slide = context.presentation.slides.items[slideIndex]; | |
console.log(`Slide ${slideIndex}: ${slide.tags.items.length} tags.`); | |
logTags(context, slide.tags); | |
for (let shapeIndex = 0; shapeIndex < slide.shapes.items.length; ++shapeIndex) { | |
const shape = slide.shapes.items[shapeIndex]; | |
if (shape.tags.items.length > 0) { | |
console.log(`Shape ${shapeIndex}: ${shape.tags.items.length} tags.`); | |
logTags(context, shape.tags); | |
} | |
} | |
} | |
}); | |
} | |
language: typescript | |
template: | |
content: "<section class=\"ms-font-m\">\n <p>These snippets show how to use tags with the presentation and its slides and shapes.</p>\n\n<section class=\"samples ms-font-m\">\n <h3>Try it out</h3>\n\n <p>1. Add several slides to the deck. Add content to each so they are visually distinct in the thumbnail pane.</p>\n\n <p>2. Select a <i>single</i> slide and press <b>Add tag</b> to tag the slide to be shown only to premium customers.</p>\n <button id=\"add-selected-slide-tag\" class=\"ms-Button\">\n <span class=\"ms-Button-label\">Add tag</span>\n </button>\n\n <p>3. Repeat step 2 for another slide.</p>\n\n <p>4. Press <b>Delete premium customer slides</b> to remove from the presentation slides that should only be shown to premium customers.</p>\n <button id=\"delete-slides-by-audience\" class=\"ms-Button\">\n <span class=\"ms-Button-label\">Delete premium customer slides</span>\n </button>\n\n <p>5. Press <b>Add slide tags</b> to add mulitiple tags to the first slide of the presentation.</p>\n <button id=\"add-slide-tags\" class=\"ms-Button\">\n <span class=\"ms-Button-label\">Add slide tags</span>\n </button>\n\n <p>6. Select the first slide and on the ribbon, navigate <b>Insert</b> > <b>Illustrations</b> > <b>Shapes</b> to add a shape to it. Press <b>Add shape tag</b>.</p>\n <button id=\"add-shape-tag\" class=\"ms-Button\">\n <span class=\"ms-Button-label\">Add shape tag</span>\n </button>\n\n <p>7. Press <b>Add presentation tag</b>.</p>\n <button id=\"add-presentation-tag\" class=\"ms-Button\">\n <span class=\"ms-Button-label\">Add presentation tag</span>\n </button>\n\n <p>8. Press <b>Delete presentation tag</b>.</p>\n <button id=\"delete-presentation-tag\" class=\"ms-Button\">\n <span class=\"ms-Button-label\">Delete presentation tag</span>\n </button>\n\n\t <p>8. Press <b>Enumerate tags</b>.</p>\n\t <button id=\"enumerate-tags\" class=\"ms-Button\">\n\t <span class=\"ms-Button-label\">Enumerate tags</span>\n\t </button></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