heavily here.
First we get the bookmarks positions and the elements they refer to, and add a path to them to identify where they occur in the document. These paths will look something like this - here they are sorted. I make use of the childIndex method to get where an element is relative to its parent, and recursively go back up through the document to create a sortable index for each bookmark in the document, and then sort it using this generated path. Finally I get rid of the sorting aid, and get back to an array of bookMarks - this time sorted in the order they appear in the document.
0000.0000.0000.
0000.0004.0000.
0000.0006.0000.0001.0000.0000.
0000.0008.0000.
0000.0010.0000.
0000.0012.0000.
0000.0012.0000.
The code
function sortBookMarks () {
return DocumentApp.getActiveDocument().getBookmarks().map( function (b) {
return { path : pathInDocument(b.getPosition().getElement()), bookMark:b } ;
})
.sort ( function (a,b) {
return ( a.path>b.path ? 1 : (a.path < b.path ? -1 : 0));
})
.map ( function (b) {
return b.bookMark;
});
function pathInDocument(element,path) {
path = path || "" ;
var parent = element.getParent();
if (parent) {
path = pathInDocument( parent , Utilities.formatString ( '%04d.%s', parent.getChildIndex(element),path ));
}
return path;
}
}
The test
To use this create a document with various paragraphs, list items, tables etc, some of which contain the target words or phrases, run this and check the log to ensure the bookmarks get sorted according to document order.
function testBookMarkData() {
// delete all current bookmarks
DocumentApp.getActiveDocument().getBookmarks().forEach( function (b) {
b.remove();
});
// add some test ones
insertSomeBookMarks ("google");
insertSomeBookMarks ("script");
insertSomeBookMarks ("apps");
// show order before
var bookMarks = DocumentApp.getActiveDocument().getBookmarks();
bookMarks.forEach( function (b) {
Logger.log(b.getId() + ':' + b.getPosition().getElement().asText().getText());
});
// show order after
var sortedBookMarks = sortBookMarks();
sortedBookMarks.forEach( function (b) {
Logger.log(b.getId() + ':' + b.getPosition().getElement().asText().getText());
});
}
function insertSomeBookMarks(searchItem) {
// insert bookmarks for all the searchitems
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var rangeElement = body.findText (searchItem);
while (rangeElement !== null) {
var position = doc.newPosition(rangeElement.getElement(),rangeElement.getStartOffset());
var bookMark = position.insertBookmark();
rangeElement = body.findText(searchItem, rangeElement);
}
}
For help and more information join our forum, follow the blog, follow me on twitterYou want to learn Google Apps Script?
Learning Apps Script, (and transitioning from VBA) are covered comprehensively in my my book, Going Gas - from VBA to Apps script, available All formats are available now from O'Reilly,Amazon and all good bookshops. You can also read a preview on O'Reilly.
If you prefer Video style learning I also have two courses available. also published by O'Reilly.
Google Apps Script for Developers and Google Apps Script for Beginners.