Ghesio
Ghesio

Reputation: 89

Insert a block of preformatted text at cursor

I'm trying to automate some boring action in a documentation I'm writing.

I would like to be able to insert at cursor position something like this:

HEADING3

Some Text

BOLD_TEXT1

2x2 table

BOLD_TEXT2

2x2 table

BOLD_TEXT2

2x2 table

Where BOLD_TEXT has the same style (i.e. text dimension 14, grey color and all caps) and the table is page-wide and has the first row colored (i.e green) while the second column has second row with background color.

Is it possible without getting mad? I have not found some valid example in GAS docs.

Upvotes: 1

Views: 1758

Answers (2)

Cooper
Cooper

Reputation: 64032

Inserting text with formatting

This is a simple solution for inserting formatted text into a document. It also includes the html for a simple side bar with a text area and submit button.

Here's the gs code:

function insertTextAtCursor(txt)
{
  var retAddrStyle={};
  retAddrStyle[DocumentApp.Attribute.FONT_FAMILY] = 'Calibri';
  retAddrStyle[DocumentApp.Attribute.FONT_SIZE] = 14;
  retAddrStyle[DocumentApp.Attribute.BOLD] = true;
  retAddrStyle[DocumentApp.Attribute.LINE_SPACING]=1;
  retAddrStyle[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT]=DocumentApp.HorizontalAlignment.LEFT;
  retAddrStyle[DocumentApp.Attribute.MARGIN_TOP]=0;
  var doc=DocumentApp.getActiveDocument().getCursor().insertText(txt).setAttributes(retAddrStyle);
  return true;
}

This will display the sidebar:

function loadParagraphSidebar()
{
  var html=HtmlService.createHtmlOutputFromFile('inserttext').setTitle('Insert Text');
  DocumentApp.getUi().showSidebar(html);
}

This is the html for sidebar (inserttext.html):

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script>
    function sendText()
    {
      var txt=$('#txt1').val();
      $('#txt1').css('background-color','#ffff00');
      google.script.run
        .withSuccessHandler(clearText)
        .insertTextAtCursor(txt);
    }
    function clearText()
    {
      $('#txt1').val('');
      $('#txt1').css('background-color','#ffffff');
    }
    console.log("My code");
  </script>
  </head>
  <body>
  <br />Text:<br /><textarea id="txt1" rows="12" cols="35"></textarea>
  <br /><input id="btn1" type="button" value="submit" onClick="sendText();" />    
  </body>
</html>

The Sidebar:

enter image description here

Before insertion:

enter image description here

After insertion:

enter image description here

Upvotes: 1

user6655984
user6655984

Reputation:

Yes, it's possible without getting mad. Here is a function that locates the current element and then inserts a bunch of stuff after it.

Locate current element

First, get the element at the location of the cursor, and then recursively get its parent until we reach Body level. This is necessary because new paragraphs and tables must be inserted in the Body.

Define a style

Create an empty object and then define its properties like DocumentApp.Attribute.BACKGROUND_COLOR, which are listed here. Apply to an element with setAttributes method.

Insert elements

Done with Body methods insertParagraph and insertTable. Since the table involves a bit of custom formatting, it is separated into a function insertMyTable. Apparently one can't apply background color to a row, so this is done at cell level. The row/column index of cells is 0-based.

Full-page table

The only way I found to make a table full-width is by computing the required cell width from page width and margins, and setting this width on cells. This may be slightly off because cell borders have width, but I decided not to care.

End result:

screenshot

For convenience of use, the function onOpen will create a menu item Custom > Insert Stuff every time the document is open.

function insertStuff() {
  var body = DocumentApp.getActiveDocument().getBody();
  var cursor = DocumentApp.getActiveDocument().getCursor();
  if (cursor) {
    var element = cursor.getElement();
    while (element.getParent().getType() != DocumentApp.ElementType.BODY_SECTION) {
      element = element.getParent();
    }
    var index = body.getChildIndex(element);
  }
  else {
    DocumentApp.getUi().alert("Could not find current position");
    return;
  }

  var boldStyle = {};
  boldStyle[DocumentApp.Attribute.BOLD] = true;
  boldStyle[DocumentApp.Attribute.FOREGROUND_COLOR] = "#555555";
  boldStyle[DocumentApp.Attribute.FONT_SIZE] = 14;

  body.insertParagraph(index + 1, "Heading3").setHeading(DocumentApp.ParagraphHeading.HEADING3);
  body.insertParagraph(index + 2, "some text");
  body.insertParagraph(index + 3, "bold text 1").setAttributes(boldStyle);
  insertMyTable(body, index + 4);
  body.insertParagraph(index + 5, "bold text 2").setAttributes(boldStyle);
  insertMyTable(body, index + 6);
  body.insertParagraph(index + 7, "bold text 3").setAttributes(boldStyle);
  insertMyTable(body, index + 8);
}

function insertMyTable(body, index) {
  var topCellStyle = {};
  topCellStyle[DocumentApp.Attribute.BACKGROUND_COLOR] = "#00FF00";
  var bottomRightCellStyle = {};
  bottomRightCellStyle[DocumentApp.Attribute.BACKGROUND_COLOR] = "#0000FF";

  var table = body.insertTable(index, [["", ""], ["", ""]]);
  table.getCell(0, 0).setAttributes(topCellStyle);
  table.getCell(0, 1).setAttributes(topCellStyle);
  table.getCell(1, 1).setAttributes(bottomRightCellStyle);
  var cellWidth = (body.getPageWidth() - body.getMarginLeft() - body.getMarginRight())/2;
  table.getCell(0, 0).setWidth(cellWidth);
  table.getCell(0, 1).setWidth(cellWidth);
}


function onOpen() {
  DocumentApp.getUi().createMenu("Custom").addItem("Insert stuff", "insertStuff").addToUi();
}

Upvotes: 2

Related Questions