0

I'm writing a function that will duplicate the current document by moving every element into a new document -- it's part of a larger project.

However, when there is a footnote in the document, the function fails, with this error.

Service Documents failed while accessing document with id [id of target doc]

Now, I have no problem with the function not being able to transfer the footnote into a new document -- or at least transferring just the text of the footnote. However, this error stops my entire function from running (none of the elements in the doc get transferred over).

Is it possible to ignore footnotes or convert them to text, and allow the function to transfer all other elements into the new document?

Here's a sample document with a footnote

Here's my code:

function duplicateDocument() {
  var currentDoc = DocumentApp.getActiveDocument().getBody();
  var targetDoc = DocumentApp.create('New Doc');
  var totalElements = currentDoc.getNumChildren();
  
  //Goes through each type of element to preserve formatting
  for( var index = 0; index < totalElements; ++index ) {
    var body = targetDoc.getBody();
    var element = currentDoc.getChild(index).copy();
    var type = element.getType();
    
    if( type == DocumentApp.ElementType.PARAGRAPH ){
      body.appendParagraph(element);
    }
    else if( type == DocumentApp.ElementType.TABLE){
      body.appendTable(element);
    }
    else if( type == DocumentApp.ElementType.LIST_ITEM){
      body.appendListItem(element);
      
    } else if( type == DocumentApp.ElementType.BOOKMARK ){
      body.appendBookmark(element);
      
    } else if( type == DocumentApp.ElementType.INLINE_IMAGE ){
      body.appendImage(element);
      
    } else if( type == DocumentApp.ElementType.HORIZONTAL_RULE ){
      body.appendHorizontalRule();
      
    } else if( type == DocumentApp.ElementType.PAGE_BREAK ){
      body.appendPageBreak();
      
    }
  } 
}
Matt K
  • 51
  • 7
  • Can I ask you about your question? 1. In the case of your script, can I ask you about the reason that you don't want to use the script like `DriveApp.getFileById(DocumentApp.getActiveDocument().getId()).makeCopy()`? 2. Does your sample Document include all patterns you want to use? Because when you modified the sample Document by including other patterns from the current one after your script was modified, the script might not be able to be used. I'm worry about this. So I would like to confirm about this. 3. Is your goal to copy the text by ignoring the footnotes? – Tanaike Jul 19 '20 at 05:43
  • For #1: I'm not sure how that works and what the difference is, would you mind explaining? For #2: yes, everything in the document is what I want to use... I'm not sure I understand your question. For #3: my goal is to either copy the footnotes into the other document, or ignore them and allow the rest of the elements to be copied over – Matt K Jul 20 '20 at 01:59
  • Thank you for replying. I have to apologize for my poor English skill. About A1, I understood you might want to copy the Google Document from your script. So I proposed about this using the simple script. How about this? About A2, I thought that your shared sample Document might be a simpler than your actual document. So, even when I proposed a modified script, the script might not work. I'm worry about this. In your case, when a modified script can use your sample Document, there are no additional functions. Is my understanding correct? – Tanaike Jul 20 '20 at 02:30
  • About A3, I can understand about `ignore them and allow the rest of the elements to be copied over`. But I cannot understand about `copy the footnotes into the other document`. – Tanaike Jul 20 '20 at 02:30
  • 1
    What @Tanaike is saying is that if you want to make a copy of your document (rather than appending content to an already existing document it can be easilty done with the one-line script `function duplicateDocument() {DriveApp.getFileById(DocumentApp.getActiveDocument().getId()).makeCopy()}` instead of your script. Did you try it? – ziganotschka Jul 21 '20 at 12:42
  • Yes, that is a good suggestion, however, I intend to change the script later. This is only a starting point. In the future I want the script to only copy over what the user is selecting, or specific elements in the document, which means I can't always just make a copy of the doc. – Matt K Jul 21 '20 at 18:01
  • @ziganotschka Thank you for your always support. – Tanaike Jul 21 '20 at 23:03
  • @Matt K Can I ask you about your answer for my questions? [this](https://stackoverflow.com/questions/62973123/cant-transfer-footnote-into-new-document-entire-function-fails?noredirect=1#comment111386185_62973123) and [this](https://stackoverflow.com/questions/62973123/cant-transfer-footnote-into-new-document-entire-function-fails?noredirect=1#comment111386188_62973123) If you cannot understand my English, please tell me. – Tanaike Jul 21 '20 at 23:05
  • 1) I answered this in my response to @ziganotshka. 2) My sample document is not simpler than my actual document, it's the same thing. 3) I would just like to transfer everything EXCEPT footnotes into the other document, without having to delete them first – Matt K Jul 22 '20 at 20:47
  • The [tag:google-docs-api] / Advanced Document Service supports adding footnotes --> https://stackoverflow.com/q/71959274/1595451 – Rubén Apr 22 '22 at 22:36

1 Answers1

0

At current stage it's unfortunately not possible to create footnotes programmatically with Apps Script

  • A related feature request already exists, but it has not been implemented yet
  • This must be the reason tht copying a paragraph with foot notes (so trying to create a footnote in the new document) results in buggy behavour
  • This issue seems also to be still in investigation
  • In the mean time - if we can live with copying the document without the footnotes - the best workaround would be to remove the footnotes programmatically
  • This you can do by looping through all the children of a paragraph, and if you encounter a footnote - remove it

Sample:

    if( type == DocumentApp.ElementType.PARAGRAPH){
      var num = element.asParagraph().getNumChildren();
      for( var i = 0; i < num; i++ ) {
        var child = element.asParagraph().getChild(i);
        var childType = child.getType();        
        if( childType == DocumentApp.ElementType.FOOTNOTE){
          child.removeFromParent();
        }
      }
      body.appendParagraph(element);
    }
ziganotschka
  • 25,866
  • 2
  • 16
  • 33