7

*I have a Google Document with a string like "text {logo} text" How do place an image where {logo} is? So far I tried:

var logoElement = s.findText("{logo}").getElement();
logoElement.getParent().insertInlineImage(0,logoBlob);
s.replaceText("{logo}", "");

But this inserts the image before the found paragraph (or with 1: after). How do I place it inside the paragraph at the exact location?

Rubén
  • 34,714
  • 9
  • 70
  • 166
wivku
  • 2,457
  • 2
  • 33
  • 42
  • Have you seen this post ? http://stackoverflow.com/questions/11211434/insert-image-into-a-specified-location – Serge insas Dec 11 '13 at 20:32
  • read also the comments. – Serge insas Dec 11 '13 at 21:18
  • 1
    Serge, the post (and comments) states the search string "MUST be alone" in a paragraph. My question is about a search string *in the middle* of a paragraph, where *only* that part is replaced. My example has no problem finding the search string, but it places the image before (or after) the whole paragraph instead of placing it in front of exactly the search string. – wivku Dec 11 '13 at 21:43
  • 2
    The idea is precisely to split your text where you want to create a paragraph at the right place since the inline image is always placed between paragraphs... couldn't that be a solution ? ( I wrote this as comment as it's only a suggestion :-) – Serge insas Dec 11 '13 at 21:58
  • Thanks Serge. The original post in the link you suggested was indeed helpful. Would you happen to know how to set tab positions for a paragraph? – wivku Dec 12 '13 at 11:17
  • I tried another approach, please see new answer. – Serge insas Dec 12 '13 at 13:53

3 Answers3

11

I hope will be helpful, The following code is fine to me.

function insertImage(doc) {
  // Retrieve an image from the web.
  var resp = UrlFetchApp.fetch("http://www.google.com/intl/en_com/images/srpr/logo2w.png");
  var image = resp.getBlob();
  var body = doc.getBody();
  var oImg = body.findText("<<Logo1>>").getElement().getParent().asParagraph();
  oImg.clear();
  oImg = oImg.appendInlineImage(image);
  oImg.setWidth(100);
  oImg.setHeight(100);
}
  • 1
    This answer is beautiful for a more generic problem. Congrats - and many thanks! - on beauty and fast code! – Vladimir Brasil Sep 16 '16 at 22:54
  • I have to say that this solved my more generic problem as well of easily finding tags across a template. Thank you for the best and clearest code that I've seen to solve this so far. <3 – Ender Jun 26 '19 at 00:08
3

Thanks to the comment from Serge and the original post of the link for pointing me in the right direction. Here's what I have now:

var s = d.getHeader();
var logoResult = s.findText("{logo}"); // search result
var logoElement = logoResult.getElement(); // the paragraph that contains the placeholder
var text = logoElement.getText();
var placeholderStart = logoResult.getStartOffset(); // character position start placeholder
var placeholderEnd = logoResult.getEndOffsetInclusive(); // char. position end placeholder
var parent = logoElement.getParent(); 
var parPosition = parent.getChildIndex(logoElement);

// add new paragraph after the found paragraph, with text preceding the placeholder
var beforeAndLogo = s.insertParagraph(parPosition+2, text.substring(0, placeholderStart));
var logo = beforeAndLogo.appendInlineImage(logoBlob); // append the logo to that new paragraph

// add new paragraph after the new logo paragraph, containing the text after the placeholder
var afterLogo = s.insertParagraph(parPosition+3, text.substring(placeholderEnd+1));
afterLogo.merge(); // merge these two paragraphs

// finally remove the original paragraph
parent.removeFromParent(); // remove the original paragraph

It is not complete, I should also copy all the attributes. More importantly, it does not copy the tab settings (e.g. center tab). Have not found a way to set tab positions.

wivku
  • 2,457
  • 2
  • 33
  • 42
  • Have you found a way to copy attributes? I have been working on this problem, and it seems that even getAttributes() doesn't apply them correctly. – John Targaryen Jul 20 '15 at 04:44
2

I tried a simpler version based on your answer that keeps the format of the original paragraph...

Give it a try, it's not "foolproof" but it works in my test and is (I think) an interresting trial ;-)

code here :

function test(){
  placeImage('{logo}','0B3qSFd3iikE3SkFXc3BYQmlZY1U');
//This is my page and I’d like to have a {logo} on it right here
}


function placeImage(placeHolder,imageId) {
  var logoBlob = DocsList.getFileById(imageId).getBlob();
  var d = DocumentApp.getActiveDocument()
  var s = d.getHeader();
  var logoResult = s.findText(placeHolder); 
  var placeholderStart = logoResult.getStartOffset(); 
  var par = s.getChild(0).asParagraph();
  var parcopy = par.copy();
  var parLen = par.editAsText().getText().length-1;
  Logger.log('placeholderStart = '+placeholderStart+'  parLen = '+parLen)
  par.editAsText().deleteText(placeholderStart, parLen);
  parcopy.editAsText().deleteText(0, placeholderStart+placeHolder.length);
  var img = s.getChild(0).appendInlineImage(logoBlob);
  s.appendParagraph(parcopy);
  parcopy.merge();
}

enter image description here

Serge insas
  • 45,904
  • 7
  • 105
  • 131