Skip to content

Instantly share code, notes, and snippets.

@abubelinha
Forked from mhawksey/gist:5599539
Last active December 17, 2017 00:11
Show Gist options
  • Save abubelinha/0c797f93a7fccf1896f36d4020f09fd6 to your computer and use it in GitHub Desktop.
Save abubelinha/0c797f93a7fccf1896f36d4020f09fd6 to your computer and use it in GitHub Desktop.
Experiment to create a document map for Google Docs using Google Apps Script
/* https://docs.google.com/document/d/1r68eiN0w_NGGjloTD2RL_91opnPfAfHR81MQloKVvTo/edit#heading=h.g9i813j0d54t
From https://mashe.hawksey.info/2013/05/playing-with-google-docs-sidebar-using-google-apps-script/
https://developers.google.com/apps-script/reference/document/table-of-contents
https://developers.google.com/apps-script/reference/document/body#getHeadingAttributes(ParagraphHeading)
https://opensourcehacker.com/2013/01/21/script-for-generating-google-documents-from-google-spreadsheet-data-source/
https://www.quora.com/How-do-I-find-and-replace-formatting-in-Google-Docs
*/
function onOpen() {
// Add a menu with some items, some separators, and a sub-menu.
DocumentApp.getUi().createMenu('Custom')
.addItem('Show Document Map', 'showDocumentMap')
.addToUi();
}
function showDocumentMap() {
// based on http://stackoverflow.com/a/12244248/1027723
var docmap = {};
var tocDat = {};
var doc = DocumentApp.getActiveDocument(); //get active document
for (var i = 0; i < doc.getNumChildren(); i++) { // loop all the document elements
var p = doc.getChild(i);
if (p.getType() == DocumentApp.ElementType.TABLE_OF_CONTENTS) { // if the element type is a TABLE_OF_CONTENTS extract item links
var toc = p.asTableOfContents();
for (var ti = 0; ti < toc.getNumChildren(); ti++) { // looping over each ToC item
var itemToc = toc.getChild(ti).asParagraph().getChild(0).asText();
var itemText = itemToc.getText();
var itemUrl = itemToc.getLinkUrl();
tocDat[itemText] = itemUrl; // create object array
}
}
// Doesn't appear to be any section level data in ToC so get this manually by going through document
if (p.getType() == DocumentApp.ElementType.PARAGRAPH){ // only need to get paragraphs
var heading = doc.getChild(i).asParagraph().getHeading();
var title = doc.getChild(i).asParagraph().asText().getText();
// if a heading map heading text to heading level
if (heading == DocumentApp.ParagraphHeading.HEADING1){
docmap[title] = 1;
} else if (heading == DocumentApp.ParagraphHeading.HEADING2){
docmap[title] = 2;
} else if (heading == DocumentApp.ParagraphHeading.HEADING3){
docmap[title] = 3;
} else if (heading == DocumentApp.ParagraphHeading.HEADING4){
docmap[title] = 4;
} else if (heading == DocumentApp.ParagraphHeading.HEADING5){
docmap[title] = 5;
} else if (heading == DocumentApp.ParagraphHeading.HEADING6){
docmap[title] = 6;
}
}
}
// build some html to render in sidebar (you can also use UIInstance for this)
var html = "";
var last_level = 0
for (i in docmap){
var level = docmap[i];
// not sure if this entirely works (basically want to nest subsections)
if(level > last_level)
html += "<ul>";
else if (level < last_level){
html += "</ul>";
}
// issue: https://gist.github.com/mhawksey/5599539#gistcomment-1666425
//html += Utilities.formatString("<li><a href='%s'>%s</a></li>", tocDat[i],i);
html += Utilities.formatString("<li><a href='%s'>%s</a></li>", docmap[i],i);
last_level = level;
}
html += "</ul>"; //close unorder list
html += "<p align='right'><a href='http://mashe.hawksey.info/'>MASHe blog</a></p>"; // add link to see if these actually render
// push out to sidebar
DocumentApp.getUi().showSidebar(
HtmlService
.createHtmlOutput(html)
.setTitle('Document Map')
.setWidth(250));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment