Skip to content

Instantly share code, notes, and snippets.

@matharden
Forked from mvogelgesang/richText2HTMLExample.js
Created August 13, 2021 17:07
Show Gist options
  • Save matharden/f24a475d274d549dbdd3c09636fb7582 to your computer and use it in GitHub Desktop.
Save matharden/f24a475d274d549dbdd3c09636fb7582 to your computer and use it in GitHub Desktop.
Converts Google AppScript RichTextValue to HTML encoded strings.
/**
* 2019 @mvogelgesang
* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Gist: https://gist.github.com/mvogelgesang/8fe14931d79ed79d73154d969f02aada
*/
// Builds the new menu
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({name: "Run Script", functionName: "runScript"});
ss.addMenu("RichText2HTML", menuEntries);
}
function runScript() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CONFIG");
var toEmail = sheet.getRange("b1").getValue();
// simple error handling for e-mail address
if (toEmail === "") {
var ui = SpreadsheetApp.getUi();
var response = ui.alert("Hey, an e-mail address is needed. Set the desired to address in CONFIG, cell B1");
sheet.getRange("b1").activate();
return;
}
var range = sheet.getRange("b2");
var richText = range.getRichTextValue();
MailApp.sendEmail({
to: toEmail,
subject: "I am trying out Apps Script!",
htmlBody: htmlEncodeRichText(richText),
body: richText.getText()
});
}
/**
* Given a RichTextValue Object, iterate over the individual runs
* and call out to htmlStyleRtRun() to return the text wrapped
* in <span> tags with specific styling.
* @param {RichTextValue} richTextValue a RichTextValue object
* from a given Cell.
* @return {string} HTML encoded text
*/
function htmlEncodeRichText(richTextValue) {
// create an empty string which will hold the html content
var htmlString = "";
// get an array of Runs for the given Rich Text
var rtRuns = richTextValue.getRuns();
// loop the array
for (var i = 0; i < rtRuns.length; i++) {
// return html version of a given run, append to existing string
htmlString += htmlStyleRtRun(rtRuns[i]);
Logger.log("Run # " + i + " plain text: ");
Logger.log(rtRuns[i].getText());
Logger.log("Run # " + i + " Output:");
Logger.log(htmlString);
}
return htmlString;
}
/**
* Given a RichTextValue Run, evaluates for style attributes and
* builds a <span> tag with in-line styles.
* For instance:
* <span style="color: cyan">text</span>
*
* @param {RichTextValue} richTextRun an instance of a
* RichTextValue run
* @return {string} inputted text wrapped in <span> tag with
* applicable styling.
*/
function htmlStyleRtRun(richTextRun) {
// string to hold the inline style key value pairs
var styleString = "";
// evaluate the attributes of a given Run and construct style attributes
if (richTextRun.getTextStyle().isBold()) {
styleString += "font-weight:bold;"
}
if (richTextRun.getTextStyle().isItalic()) {
styleString += "font-style:italic;"
}
// fetch values for font family, size, and color attributes
styleString += "font-family:" + richTextRun.getTextStyle().getFontFamily() +
";";
styleString += "font-size:" + richTextRun.getTextStyle().getFontSize() +
"px;";
styleString += "color:" + richTextRun.getTextStyle().getForegroundColor() +
";";
// underline and strikethrough use the same style key, text-decoration, must evaluate together, otherwise, the styling breaks.
// both false
if (!richTextRun.getTextStyle().isUnderline() && !richTextRun.getTextStyle().isStrikethrough()) {
// do nothing
}
// underline true, strikethrough false
else if (richTextRun.getTextStyle().isUnderline() && !richTextRun.getTextStyle()
.isStrikethrough()) {
styleString += "text-decoration: underline;";
}
// underline false, strikethrough true
else if (!richTextRun.getTextStyle().isUnderline() && richTextRun.getTextStyle()
.isStrikethrough()) {
styleString += "text-decoration: line-through;";
}
// both true
else {
styleString += "text-decoration: line-through underline;";
}
// line breaks don't get converted, run regex and insert <br> to replace \n
var richText = richTextRun.getText();
var re = new RegExp("\n", "g");
var richText = richText.replace(re, "<br>");
// bring it all together
var formattedText = '<span style="' + styleString + '">' + richText +
'</span>';
return formattedText;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment