Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Experiment to create a document map for Google Docs using Google Apps Script
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>";
}
html += Utilities.formatString("<li><a href='%s'>%s</a></li>", tocDat[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));
}
@areee

This comment has been minimized.

Copy link

@areee areee commented Jan 9, 2016

Thank you, this script seems to be useful!
The only problem is that the code doesn't work nowadays. When running it I get an error message "Error: Not enough arguments (row 59, file Code)". Could you fix it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.