Here’s how to sort bookmarks into position order in a document. We’ll use Advanced Array functions 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); } }