├── .gitignore ├── image ├── 128x128.png ├── 16x16.png ├── 24x24.png ├── 256x256.png ├── 32x32.png ├── 48x48.png ├── 512x512.png ├── 64x64.png ├── 96x96.png ├── StoreExample.png ├── StoreExample2.png ├── Example1400by560.png ├── Example1400by560.xcf ├── Example440by280.png ├── Example440by280.xcf ├── Example920by680.png ├── Example920by680.xcf ├── logoSquare64by64.png ├── logoNoBackground64by64.png ├── logo.svg └── logoSquare.svg ├── readmeImages ├── diagram └── diagram.png ├── ElmBuild.bash ├── elm-package.json ├── Code.gs ├── helpLogo.svg ├── SavedProperties.gs ├── imageLogic.gs ├── README.md ├── index.html └── SelectInput.elm /.gitignore: -------------------------------------------------------------------------------- 1 | /elm-stuff 2 | -------------------------------------------------------------------------------- /image/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/128x128.png -------------------------------------------------------------------------------- /image/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/16x16.png -------------------------------------------------------------------------------- /image/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/24x24.png -------------------------------------------------------------------------------- /image/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/256x256.png -------------------------------------------------------------------------------- /image/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/32x32.png -------------------------------------------------------------------------------- /image/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/48x48.png -------------------------------------------------------------------------------- /image/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/512x512.png -------------------------------------------------------------------------------- /image/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/64x64.png -------------------------------------------------------------------------------- /image/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/96x96.png -------------------------------------------------------------------------------- /image/StoreExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/StoreExample.png -------------------------------------------------------------------------------- /readmeImages/diagram: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/readmeImages/diagram -------------------------------------------------------------------------------- /image/StoreExample2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/StoreExample2.png -------------------------------------------------------------------------------- /readmeImages/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/readmeImages/diagram.png -------------------------------------------------------------------------------- /image/Example1400by560.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/Example1400by560.png -------------------------------------------------------------------------------- /image/Example1400by560.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/Example1400by560.xcf -------------------------------------------------------------------------------- /image/Example440by280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/Example440by280.png -------------------------------------------------------------------------------- /image/Example440by280.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/Example440by280.xcf -------------------------------------------------------------------------------- /image/Example920by680.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/Example920by680.png -------------------------------------------------------------------------------- /image/Example920by680.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/Example920by680.xcf -------------------------------------------------------------------------------- /image/logoSquare64by64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/logoSquare64by64.png -------------------------------------------------------------------------------- /image/logoNoBackground64by64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brendena/MathEquationsGoogleSlide/HEAD/image/logoNoBackground64by64.png -------------------------------------------------------------------------------- /ElmBuild.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "BuildScript" 3 | 4 | elm-make SelectInput.elm --output=SelectInput.js 5 | 6 | mv SelectInput.js SelectInput.html 7 | 8 | sed -i '1s/^/" >> SelectInput.html 10 | 11 | git add --all -------------------------------------------------------------------------------- /elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "5.1.1 <= v < 6.0.0", 12 | "elm-lang/html": "2.0.0 <= v < 3.0.0" 13 | }, 14 | "elm-version": "0.18.0 <= v < 0.19.0" 15 | } 16 | -------------------------------------------------------------------------------- /Code.gs: -------------------------------------------------------------------------------- 1 | /* 2 | Notes 3 | https://developers.google.com/apps-script/guides/slides/presentations 4 | 5 | https://developers.google.com/apps-script/reference/slides/slides-app 6 | */ 7 | /* 8 | very cool example 9 | https://chrome.google.com/webstore/detail/equatio-math-made-digital/hjngolefdpdnooamgdldlkjgmdcmcjnc 10 | */ 11 | 12 | function PropertiesTypes(){ 13 | 14 | return { 15 | "imageProperties":{} 16 | } 17 | } 18 | 19 | function onOpen() { 20 | SlidesApp.getUi().createMenu('Math Equations') 21 | .addItem('Menu', 'showSidebar') 22 | //.addItem('Refresh Data', 'loadDataToSpreadSheet') 23 | .addToUi(); 24 | Logger.log("started"); 25 | } 26 | 27 | 28 | function showSidebar() { 29 | 30 | var html = doGet().setTitle('Math Equations UI').setWidth(300); 31 | SlidesApp.getUi() // Or DocumentApp or FormApp. 32 | .showSidebar(html); 33 | } 34 | 35 | function onInstall(){ 36 | onOpen(); 37 | } 38 | 39 | 40 | function doGet() { 41 | return HtmlService 42 | .createTemplateFromFile('index') 43 | .evaluate(); 44 | } 45 | 46 | function include(filename) { 47 | return HtmlService.createHtmlOutputFromFile(filename) 48 | .getContent(); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /helpLogo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Svg Vector Icons : http://www.onlinewebfonts.com/icon 6 | 7 | -------------------------------------------------------------------------------- /SavedProperties.gs: -------------------------------------------------------------------------------- 1 | // array for document ids 2 | var nameGlobalProperties = "savedProperties"; 3 | 4 | 5 | 6 | function getAllSavedProperties(){ 7 | var savedPropertiesString = getUserProperties().getProperty(nameGlobalProperties); 8 | //Logger.log(savedPropertiesString); 9 | var savedPropertiesJson = JSON.parse(savedPropertiesString) 10 | if(savedPropertiesJson == null || typeof(savedPropertiesJson) !== "object" ||savedPropertiesJson == 'undefined' || Array.isArray(savedPropertiesJson) === true){ // typeof(savedPropertiesJson) === "Object" || 11 | savedPropertiesJson = {}; 12 | } 13 | return savedPropertiesJson; 14 | } 15 | 16 | function getSpecificSavedProperties(properties){ 17 | var savedProperties = getAllSavedProperties(); 18 | var returnProperties = undefined; 19 | if(Array.isArray(properties)){ 20 | returnProperties = {}; 21 | properties.forEach(function(property){ 22 | returnProperties[property] = checkDefaultValue(properties, savedProperties[property]); 23 | }); 24 | } 25 | else{ 26 | returnProperties = checkDefaultValue(properties, savedProperties[properties]); 27 | } 28 | return returnProperties; 29 | } 30 | 31 | function savePropertie(propertyName, value){ 32 | try { 33 | var savedProperties = this.getAllSavedProperties(); 34 | savedProperties[propertyName] = value 35 | saveProperties(savedProperties); 36 | } catch (f) { 37 | Logger.log(f.toString()); 38 | } 39 | } 40 | 41 | function saveProperties(JsonProperties){ 42 | getUserProperties().setProperty(nameGlobalProperties, JSON.stringify(JsonProperties)); 43 | } 44 | 45 | 46 | 47 | function resetProperties() { 48 | saveProperties({}); 49 | } 50 | 51 | 52 | 53 | function getUserProperties(){ 54 | return PropertiesService.getUserProperties(); 55 | } 56 | 57 | function setSavedPropertiesValues(value){ 58 | savePropertie(nameGlobalPropertiesTypes, value); 59 | } 60 | 61 | function checkDefaultValue(propertyName, propertyValue){ 62 | var propertiesTypes = PropertiesTypes(); 63 | if(propertyValue == undefined){ 64 | return propertiesTypes[propertyName]; 65 | } 66 | return propertyValue; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /imageLogic.gs: -------------------------------------------------------------------------------- 1 | function setImage(jsonImageData){ 2 | var imageSlide = undefined; 3 | 4 | //var imageProperties = getSpecificSavedProperties("imageProperties"); 5 | 6 | var image = createImageFromBlob(jsonImageData["image"]); 7 | var slide = SlidesApp.getActivePresentation().getSelection().getCurrentPage(); 8 | 9 | // if the equation was not linked 10 | if(jsonImageData["linkedMathEquation"] != ""){ 11 | var imageObjectId = jsonImageData["linkedMathEquation"]; 12 | 13 | imageSlide = findImageSlide(imageObjectId) 14 | imageSlide.replace(image) 15 | } // if the equation was linked 16 | else{ 17 | Logger.log("New Image") 18 | imageSlide = slide.insertImage(image); 19 | 20 | 21 | 22 | } 23 | 24 | //set Image size 25 | var sizeEquationHeight = jsonImageData["mathEquationSize"]; 26 | 27 | imageSlide.setWidth(sizeEquationHeight * jsonImageData["ratio"] ); 28 | imageSlide.setHeight(sizeEquationHeight ); 29 | 30 | return imageSlide.getObjectId(); 31 | 32 | } 33 | 34 | function addAltText(jsonImageData, objectId) 35 | { 36 | var image = findImageSlide(objectId); 37 | 38 | var requests = [{ 39 | updatePageElementAltText: 40 | { 41 | objectId: image.getObjectId(), 42 | title: createAltTitle(jsonImageData), 43 | description: jsonImageData["mathEquation"], 44 | } 45 | 46 | }]; 47 | try { 48 | var batchUpdateResponse = Slides.Presentations.batchUpdate({ 49 | requests: requests 50 | },SlidesApp.getActivePresentation().getId()); 51 | setImage = true; 52 | } catch (e) { 53 | throw ("BatchUpdateError - " + e); 54 | } 55 | } 56 | 57 | function createImageFromBlob(blob){ 58 | return Utilities.newBlob(Utilities.base64Decode(blob), MimeType.PNG); 59 | } 60 | 61 | function findImageSlide(imageObjectId){ 62 | var slide = SlidesApp.getActivePresentation().getSelection().getCurrentPage(); 63 | var allImage = slide.getImages(); 64 | var imageSlide = undefined; 65 | for(var i = 0; i < allImage.length; i++){ 66 | if(allImage[i].getObjectId() == imageObjectId){ 67 | imageSlide = allImage[i] 68 | } 69 | } 70 | if(imageSlide == undefined){ 71 | throw "couldn't find the id on this slide" 72 | } 73 | return imageSlide; 74 | } 75 | 76 | function getLinkedToImage(){ 77 | var imageProperties = getSpecificSavedProperties("imageProperties"); 78 | var selection = SlidesApp.getActivePresentation().getSelection(); 79 | var selectionRange = selection.getPageElementRange(); 80 | 81 | if(selectionRange == null) 82 | throw "you need to select a image to reload the equation back into the text box" 83 | 84 | var pageElements = selectionRange.getPageElements(); 85 | 86 | if(pageElements.length <= 0) 87 | throw "please select a item" 88 | else if(pageElements.length >= 2) 89 | throw "can only select one item" 90 | 91 | 92 | var image = pageElements[0].asImage() 93 | 94 | 95 | var imageProperties; 96 | { 97 | //old way of loading image 98 | imageProperties = imageProperties[image.getObjectId()] 99 | if(imageProperties == undefined) 100 | { 101 | 102 | var altTextTitle = image.getTitle(); 103 | imageProperties = getAltTextData(altTextTitle); 104 | imageProperties["equation"] = image.getDescription(); 105 | } 106 | } 107 | 108 | if (imageProperties["equationColor"] == undefined && 109 | imageProperties["equationColor"] == null){ 110 | imageProperties["equationColor"] = "#000000"; 111 | } 112 | return { 113 | "objectId": image.getObjectId(), 114 | "equation": imageProperties["equation"], 115 | "equationColor": imageProperties["equationColor"], 116 | "equationSize": image.getHeight() 117 | } 118 | } 119 | 120 | 121 | function test(){ 122 | Logger.log(getSpecificSavedProperties("imageProperties")) 123 | } 124 | 125 | function createAltTitle(jsonImageData){ 126 | return "MathEquation,"+ jsonImageData["mathEquationColor"]; 127 | } 128 | 129 | function getAltTextData(altTextTitle){ 130 | if(altTextTitle.search("MathEquation") == -1){ 131 | throw "Alt Text data doesn't match"; 132 | } 133 | var splitData = altTextTitle.split(","); 134 | 135 | return { 136 | "equationColor": splitData[1] 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Project is outdated 2 | 3 | This project needed to be rewritten, so i made a [new repo](https://github.com/brendena/MathEquationsGoogleSlideV2) with the redesized extension 4 | 5 | * https://github.com/brendena/MathEquationsGoogleSlideV2 6 | # ______________________________ 7 | 8 | ![Master Google sheets documents icon](https://github.com/brendena/MathEquationsGoogleSlide/blob/master/image/96x96.png?raw=true) 9 | 10 | # [MathEquationsGoogleSlide](https://chrome.google.com/webstore/detail/math-equations/edbiogkpgmbdkmgmdcdmgminoahbcdml) 11 | Allows you to create beatiful images from layout scripting languages. 12 | 13 | ## Supported Languages 14 | * Latex 15 | * AsciiMath 16 | * MathML 17 | 18 | ![Example UI Layout](https://github.com/brendena/MathEquationsGoogleSlide/blob/master/image/StoreExample2.png?raw=true) 19 | 20 | ## How it works 21 | 22 | ![diagram on how it works](https://github.com/brendena/MathEquationsGoogleSlide/blob/master/readmeImages/diagram.png?raw=true) 23 | 24 | 25 | ### Elm version - 0.18 26 | 27 | * **Compilling** Elm code its compiled to SelectInput.js. Then i use a bash script to convert it to SelectInput.html which i include in index.html 28 | 29 | Good Resources on Elm 30 | * [quick examples](http://elm-lang.org/examples) 31 | * [great book](https://www.elm-tutorial.org/en/05-resources/02-models.html) 32 | 33 | ### Index.html 34 | * **css** - All css is inside of the index.html page. This is because for the size of the app, it was easier to have it inside of the index.html page then to have it inside of elm. It is inside of the html page because you can't import css style sheets in google extensions. So the styles would need to be in a html page and included with a ["google appscript Scriptlets"](https://developers.google.com/apps-script/guides/html/templates) which would make it impossible to test the app local. 35 | * **MathJax** - Elm can't handle normal javascript so all the code that hanldes mathJax has to be handled handled inside of the index.html 36 | * **Canvas'/creating image** - There are two canvas. One to display the equation to the user. This is inside of the elm code. Then there is a canvas outside of the elm script. This secondary canvas is used to create a image that you will be send to google app script. This canvas is hidden and is large, so when you convert it to a image it will look sharp on your slide. 37 | 38 | 39 | ### Google app script 40 | * **image** - the image is send as a blob and this can be easily converted to a image with this Utilities.newBlob(Utilities.base64Decode(blob), MimeType.PNG); 41 | * **reloading images** - To reload a equation, so you can edit it you have load it into a saved property. I have a dictonary in the saved property called **imageProperties** where they key is the ObjectId and the value is a string of the equation. You have to save the information as a saved property because there is no way of storing data inside of the image. There no alternative text section or attribute to put the equation data into so the only way, so saving it inside of saved property was the second best option. 42 | * **savedProperties** - i have a seperate file to make using saved propertys easier. I save all the properties into a single key called **savedProperties** which is also a dictionary which make working with saved data as easy as working with a dictionary object. 43 | 44 | 45 | 46 | ## Build 47 | ### Local Development 48 | * remove any **<\?!= include('Text'); ?>** -index.html 49 | * make sure **** is included -index.html 50 | * **elm-make** SelectInput.elm --output=SelectInput.js 51 | * Then you can open the index.html page 52 | 53 | ### Google Extension Development 54 | * Use this [extension](https://chrome.google.com/webstore/detail/google-apps-script-github/lfjcgcmkmjjlieihflfhjopckgpelofo) to pull the latest code from a github repo 55 | * add **<\?!= include('Text'); ?>** -index.html 56 | * remove **** -index.html 57 | 58 | ## Pushing Code 59 | ### Local Development 60 | 1. bash ./ElmBuild.bash 61 | 2. git push 62 | ### Google Extension Development 63 | 1. use this [extension](https://chrome.google.com/webstore/detail/google-apps-script-github/lfjcgcmkmjjlieihflfhjopckgpelofo) and hit the push button. 64 | 65 | ## ToDo 66 | - Cleaner Error Messages 67 | - Minify the output of the elm script 68 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | 204 | 205 | 206 |
207 |