I am having trouble moving the cursor to bookmarked locations in Google script. Overview: I want episodically to update numbers in a Google doc via a Google apps script. Basically I’m trying to make a hacky alternative to one of RMarkdown’s virtues. Each formatted number in my Google doc, or target, corresponds to an r character variable exported into a Google sheet. Here’s what I have so far, though I’m open to other approaches.
One space back from the start of each target I place a bookmark. For matching the new value for each target, the target needs a name. But bookmarks in google docs apparently can’t be named. So at the end of the document I made a list. Each element of the list is a concatenation of a find string (“live.”) and the name of the target variable. Each element is linked back to the appropriate bookmark. It’s not ideal since I must insert some stray spaces but I can live with that. Here is a test document:
Text before first target[bookmark1] 77% text between targets in same paragraph [bookmark2] 1,234 and this goes on for several lines.
[bookmark3] 55 paragraph 2 must start with an unwanted space.
And skipping to the end,
live.formatted.number[linked to bookmark 2]
live.a.percent[linked to bookmark1]
live.plain.number[linked to bookmark 3]
The Google sheet with updates has in column A “formatted.number”, “plain.number”, “a.percent” and in column B “4,321”, “54.5”, “71%”.
The following script retrieves the bookmark id for each target. Then I build a url to the bookmark. If I manually copy the url and paste it into a browser window, the document opens with the cursor at the bookmark. But I haven’t figured out how to move the cursor to the bookmark using the script. A couple attempts that don't work are shown. In case it helps to know, my intent after I move the cursor is to define a range that starts at the bookmark and includes a leading space plus the target which has no spaces plus a trailing space. I will pad the matching replacement string with a space on either end and use it to replace the old version of each target.
function updateNumbers () {
var doc = DocumentApp.getActiveDocument()
bodyText = doc.getBody();
foundElement = bodyText.findText ("Live."); // Uses tag I chose to index dynamic text
while (foundElement !== null) {
var foundText = foundElement.getElement().asText();
var bkMarkUrl = foundText.getLinkUrl();
foundBkMark = doc.getBookmark(bkMarkUrl); //fails: returns null
Logger.log("foundBkMark " + foundBkMark)
var bkMarkLink = “https://docs.google.com/document/d/${doc.getId()}/${bkMarkUrl}”;
Logger.log("bkMarkLink " + bkMarkLink); // works only pasted into browser manually
var cursor = DocumentApp.getActiveDocument().getCursor();
var position = doc.newPosition(bkMarklink, 2); // Generates error.
doc.setCursor(position);
var sometext = cursor.insertText("test");
// Find the next match
foundElement = bodyText.findText("Live.", foundElement);
}
}
More options that don’t work:
The document is too complicated to turn it into a form.
I don’t want to assume that either the list of bookmark links or the Google sheet has the targets in any particular order. The document will go through numerous revisions and wrong order is exactly the kind of error opportunity I'm trying to minimize by automating updates. So I can’t just cycle through the bookmarks in order.