From 30d2d331a2e79a4389ea567e7bc8219896c778a4 Mon Sep 17 00:00:00 2001 From: TanmayB <110551323+happygoluckycodeeditor@users.noreply.github.com> Date: Thu, 27 Nov 2025 19:42:16 +0900 Subject: [PATCH 1/4] feature(slides): add enhanced translation with source language selection --- slides/translate/sidebarEnhanced.html | 180 +++++++++++++++++++++++++ slides/translate/translateAllSlides.gs | 162 ++++++++++++++++++++++ 2 files changed, 342 insertions(+) create mode 100644 slides/translate/sidebarEnhanced.html create mode 100644 slides/translate/translateAllSlides.gs diff --git a/slides/translate/sidebarEnhanced.html b/slides/translate/sidebarEnhanced.html new file mode 100644 index 000000000..a7b1afc67 --- /dev/null +++ b/slides/translate/sidebarEnhanced.html @@ -0,0 +1,180 @@ + + +
+ + + + + + + + + + + diff --git a/slides/translate/translateAllSlides.gs b/slides/translate/translateAllSlides.gs new file mode 100644 index 000000000..7285a7630 --- /dev/null +++ b/slides/translate/translateAllSlides.gs @@ -0,0 +1,162 @@ +/** + * Copyright Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @OnlyCurrentDoc Limits the script to only accessing the current presentation. + */ + +/** + * Create a open translate menu item. + * @param {object} event The open event. + */ +function onOpen(event) { + SlidesApp.getUi() + .createAddonMenu() + .addItem("Open Translate", "showSidebar") + .addToUi(); +} + +/** + * Open the Add-on upon install. + * @param {object} event The install event. + */ +function onInstall(event) { + onOpen(event); +} + +/** + * Opens a sidebar in the document containing the add-on's user interface. + */ +function showSidebar() { + const ui = + HtmlService.createHtmlOutputFromFile("sidebarEnhanced").setTitle( + "Translate", + ); + SlidesApp.getUi().showSidebar(ui); +} + +/** + * Recursively gets child text elements a list of elements. + * @param {GoogleAppsScript.Slides.PageElement[]} elements The elements to get text from. + * @return {GoogleAppsScript.Slides.TextRange[]} An array of text elements. + */ +function getElementTexts(elements) { + /** @type {GoogleAppsScript.Slides.TextRange[]} */ + let texts = []; + for (const element of elements) { + switch (element.getPageElementType()) { + case SlidesApp.PageElementType.GROUP: + for (const child of element.asGroup().getChildren()) { + texts = texts.concat(getElementTexts([child])); + } + break; + case SlidesApp.PageElementType.TABLE: { + const table = element.asTable(); + for (let r = 0; r < table.getNumRows(); ++r) { + for (let c = 0; c < table.getNumColumns(); ++c) { + texts.push(table.getCell(r, c).getText()); + } + } + break; + } + case SlidesApp.PageElementType.SHAPE: + texts.push(element.asShape().getText()); + break; + } + } + return texts; +} + +/** + * Translates selected slide elements to the target language using Apps Script's Language service. + * + * @param {string} targetLanguage The two-letter short form for the target language. (ISO 639-1) + * @return {number} The number of elements translated. + */ +function translateSelectedElements(targetLanguage) { + // Get selected elements. + const selection = SlidesApp.getActivePresentation().getSelection(); + const selectionType = selection.getSelectionType(); + /** @type {GoogleAppsScript.Slides.TextRange[]} */ + let texts = []; + switch (selectionType) { + case SlidesApp.SelectionType.PAGE: + for (const page of selection.getPageRange().getPages()) { + texts = texts.concat(getElementTexts(page.getPageElements())); + } + break; + case SlidesApp.SelectionType.PAGE_ELEMENT: { + const pageElements = selection.getPageElementRange().getPageElements(); + texts = texts.concat(getElementTexts(pageElements)); + break; + } + case SlidesApp.SelectionType.TABLE_CELL: + for (const cell of selection.getTableCellRange().getTableCells()) { + texts.push(cell.getText()); + } + break; + case SlidesApp.SelectionType.TEXT: + for (const element of selection.getPageElementRange().getPageElements()) { + texts.push(element.asShape().getText()); + } + break; + } + + // Translate all elements in-place. + for (const text of texts) { + text.setText( + LanguageApp.translate(text.asRenderedString(), "", targetLanguage), + ); + } + + return texts.length; +} + +/** + * Translates all text elements in all slides of the active presentation. + * + * @param {string} sourceLanguage The two-letter short form for the source language. (ISO 639-1) Use empty string for auto-detect. + * @param {string} targetLanguage The two-letter short form for the target language. (ISO 639-1) + * @return {number} The number of elements translated. + */ +function translateAllSlides(sourceLanguage, targetLanguage) { + // Get the active presentation and all slides + const presentation = SlidesApp.getActivePresentation(); + const slides = presentation.getSlides(); + + let totalTranslated = 0; + + // Loop through each slide + for (const slide of slides) { + // Get all text-containing elements from the slide + const texts = getElementTexts(slide.getPageElements()); + + // Translate all text elements in-place + for (const text of texts) { + const originalText = text.asRenderedString(); + if (originalText.trim().length > 0) { + const translatedText = LanguageApp.translate( + originalText, + sourceLanguage, + targetLanguage, + ); + text.setText(translatedText); + totalTranslated++; + } + } + } + + return totalTranslated; +} From 408c36ebe698d4ac0a386a52edb2c63d5c99342e Mon Sep 17 00:00:00 2001 From: TanmayB <110551323+happygoluckycodeeditor@users.noreply.github.com> Date: Thu, 27 Nov 2025 20:01:43 +0900 Subject: [PATCH 2/4] docs(slides): document enhanced translation feature --- slides/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/slides/README.md b/slides/README.md index 7be47c3fb..0e7e87a15 100644 --- a/slides/README.md +++ b/slides/README.md @@ -6,6 +6,14 @@ Sample Google Apps Script add-ons for Google Slides. This add-on translates selected text from one language to another. +### Enhanced Version Available + +An enhanced version is also available (`translateAllSlides.gs` and `sidebarEnhanced.html`) with additional features: +- Translate entire presentations with one click +- Source language selection with auto-detect option +- Expanded support for 30+ languages +- Two translation modes: selected elements or all slides +  ## [Progress Bars](https://developers.google.com/apps-script/guides/slides/samples/progress-bar) From fb93dbc99b4fa5046d648b75470d26de88944333 Mon Sep 17 00:00:00 2001 From: TanmayB <110551323+happygoluckycodeeditor@users.noreply.github.com> Date: Thu, 27 Nov 2025 20:27:14 +0900 Subject: [PATCH 3/4] fix(slides): address code review feedback on the code --- slides/translate/sidebarEnhanced.html | 17 +++++++++-------- slides/translate/translateAllSlides.gs | 13 ++++++++++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/slides/translate/sidebarEnhanced.html b/slides/translate/sidebarEnhanced.html index a7b1afc67..eef7f0662 100644 --- a/slides/translate/sidebarEnhanced.html +++ b/slides/translate/sidebarEnhanced.html @@ -43,12 +43,11 @@ Translate sample by Google - +