appendParagraph - Adding Blank Space on the First Line - google-apps-script

I am new to Google Apps Script and trying to generate a document using Excel Data.
I am able to successfully create the document and add tables and paragraphs.
I see some odd behavior with appendParagraph.
It adds a space (blank like) when adding the first paragraph. The the paragraphs that follow are fine.
I tried replacing the new line (\n) with '', but did not work.
Any suggestion how to get rid of the line or add a paragraph without the blank line for the first paragraph (Sample Code below).
titleStyle[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT] = DocumentApp.HorizontalAlignment.CENTER
titleStyle[DocumentApp.Attribute.FONT_SIZE] = 19
titleStyle[DocumentApp.Attribute.FONT_FAMILY] = 'Arial'
titleStyle[DocumentApp.Attribute.BOLD] = true
const compTitle = cell.appendParagraph('TITLE PARAGRAPH')
compTitle.setAttributes(titleStyle)
const contentStyle = {}
contentStyle[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT] = DocumentApp.HorizontalAlignment.CENTER
contentStyle[DocumentApp.Attribute.FONT_SIZE] = 11
contentStyle[DocumentApp.Attribute.FONT_FAMILY] = 'Arial'
contentStyle[DocumentApp.Attribute.BOLD] = false
const content = cell.appendParagraph('CONTENT PARAGRAPH')
content.setAttributes(contentStyle)

As Cooper mentioned, your documents start off with a blank paragraph. If you want to remove it programmatically, run the following function:
function removeEmptyPara() {
const paras = DocumentApp.getActiveDocument().getBody().getParagraphs();
const firstPara = paras[0];
if (paras.length > 1 && !firstPara.getText()) firstPara.removeFromParent()
}
Let me know if this helps.

Related

Pasting Bold text into a doc after being taken form Spreadsheet

So I've been working through a problem of pulling structured data from a spreadsheet and them using App Script to insert it into a Template Google Doc.
I have it working simply as concatenated strings, but I'm trying to do it with the BODY class so if I want to put the end product into Gmail it could be easier. Or if I want to retain table structure....
So, everything is fine and dandy, except for this one bit of code. I'm struggling with setBold. It's a weird syntax in that it's a boolean operation, right?
So here is what I have and it's pretty easy to grok I think:
for(var i = 0; i < num; i++) {
var songName = String(dataArray[i][1]);
var sWs = String(dataArray[i][2]);
var pub = String(dataArray[i][3]);
newText.editAsText().appendText('SONG NAME:'+ nLi).setBold(true);
newText.editAsText().appendText(songName + brk).setBold(false);
newText.editAsText().appendText('SONGWRITER(S):' + nLi);
But it's coming out as:
SONG NAME:
I have also tried this code:
newText.editAsText().setBold(true);
newText.editAsText().appendText('SONG NAME:'+ nLi);
newText.editAsText().setBold(true);
newText.editAsText().appendText(songName + brk);
newText.editAsText().appendText('SONGWRITER(S):' + nLi);
Thinking of the setBold as setting then unsetting a flag.
Neither worked.
I prefer using styles:
function addboldtext() {
const doc=DocumentApp.getActiveDocument();
const body=doc.getBody();
const style1={};
style1[DocumentApp.Attribute.BOLD]=true;
style1[DocumentApp.Attribute.FOREGROUND_COLOR]='#000000';//you can add all of the attributes that you wish
body.appendParagraph("This is text").setAttributes(style1)
}

Centering in a gDoc after a replace

I am looking to replace a string within a Google Doc via an app script. The string will exist on a line, but after the replace, I want it to have a specific font, size and justification.
I've created a style to address all these attributes (I included both Horiz. and Vert. alignment) and most of it works fine. When the string is replaced, the replacement has the right font, size and bold attributes. For some reason, I cannot get the justification to get changed.
// Define the style for the replacement string.
var hdrStyle = {};
hdrStyle[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT] =
DocumentApp.HorizontalAlignment.CENTER;
hdrStyle[DocumentApp.Attribute.VERTICAL_ALIGNMENT] =
DocumentApp.VerticalAlignment.CENTER;
hdrStyle[DocumentApp.Attribute.FONT_FAMILY] = 'Calibri';
hdrStyle[DocumentApp.Attribute.FONT_SIZE] = 24;
hdrStyle[DocumentApp.Attribute.BOLD] = true;
{ then later }
documentBody = DocumentApp.openById(fileId).getBody();
hdrElem = documentBody.findText("old string").getElement();
hdrText = hdrElem.asText().setText("new string");
// Force our 'header style':
hdrElem.setAttributes(hdrStyle);
I've tried setting the style after the findText and (as here) after, but no change in centering.
I see there is a paragraph centering, but I am not clear how to 'get' the paragraph associated with the element that is returned on the find.
I'm hoping this is some simple set of calls - but have run out of ideas (and patience)..!
Any help would be appreciated!
You can use getParent() on hdrElem to get the parent paragraph to apply the styling to.
https://developers.google.com/apps-script/reference/document/text#getParent()
documentBody = DocumentApp.openById(fileId).getBody();
hdrElem = documentBody.findText("old string").getElement();
hdrText = hdrElem.asText().setText("new string");
var hdrParent = hdrElem.getParent()
// Force our 'header style':
hdrParent.setAttributes(hdrStyle);

How to set a certain number of spaces or indents before a Paragraph in Google Docs using Google Apps Script

I have a 20 line script, and I want to make sure that each paragraph is indented exactly once.
function myFunction() {
/*
This function turns the document's format into standard MLA.
*/
var body = DocumentApp.getActiveDocument().getBody();
body.setFontSize(12); // Set the font size of the contents of the documents to 9
body.setForegroundColor('#000000');
body.setFontFamily("Times New Roman");
// Loops through paragraphs in body and sets each to double spaced
var paragraphs = body.getParagraphs();
for (var i = 3; i < paragraphs.length; i++) { // Starts at 3 to exclude first 4 developer-made paragraphs
var paragraph = paragraphs[i];
paragraph.setLineSpacing(2);
// Left align the first cell.
paragraph.setAlignment(DocumentApp.HorizontalAlignment.LEFT);
// One indent
paragraph.editAsText().insertText(0, "\t"); // Adds one tab every time
}
var bodyText = body.editAsText();
bodyText.insertText(0, 'February 3, 1976\nMrs. Smith\nYour Name Here\nSocial Studies\n');
bodyText.setBold(false);
}
The code I have tried doesn't work. But my expected results are that for every paragraph in the for loop in myFunction(), there are exactly 4 spaces before the first word in each paragraph.
Here is a sample: https://docs.google.com/document/d/1sMztzhOehzheRdqumC6PLnvk4qJgUCSE0irjTZ0FjTQ/edit?usp=sharing
If the user uses Autoformat, but already has the paragraphs indented...
Update
I have investigated use of the Paragraph.setIndentFirstLine() method. When I set it to four, it sets it to 1 space. Now I realize this is because points and spaces are not the same thing. What number do I need to multiply by to get four spaces in points?
Let us consider a few basic identing operations: manual and by script.
The following image shows how to indent current paragraph (cursor stays inside this one).
Please note, the units are centimetres. Also note, that the paragraph does not include leading spaces or tabs, we have no need of them.
Suppose we would like to get the indent values in the script and apply them to the next paragraph. Look at the code below:
function myFunction() {
var ps = DocumentApp.getActiveDocument().getBody().getParagraphs();
// We work with the 5-th and 6-th paragraphs indeed
var iFirst = ps[5].getIndentFirstLine();
var iStart = ps[5].getIndentStart();
var iEnd = ps[5].getIndentEnd();
Logger.log([iFirst, iStart, iEnd]);
ps[6].setIndentFirstLine(iFirst);
ps[6].setIndentStart(iStart);
ps[6].setIndentEnd(iEnd);
}
If you run and look at the log, you will see something like this: [92.69291338582678, 64.34645669291339, 14.173228346456694]. No surprise, we have typographic points instead of centimetres. (1cm=28.3465pt) So we can measure and modify any paragraph indent values precisely.
Addition
For some reasons you might want to control spaces number at the beginning of the paragraph. It is also possible by scripting, but it has no effect on the paragraph's "left" or "right" indents.
Sample code below is for similar task: count leading spaces number of the 5-th paragraph and make the same number of spaces at the beginning of the next one.
function mySpaces() {
var ps = DocumentApp.getActiveDocument().getBody().getParagraphs();
// We work with the 5-th and 6-th paragraphs indeed
var spacesCount = getLeadingSpacesCount(ps[5]);
Logger.log(spacesCount);
var diff = getLeadingSpacesCount(ps[6]) - spacesCount;
if (diff > 0) {
ps[6].editAsText().deleteText(0, diff - 1);
} else if (diff < 0) {
var s = Array(1 - diff).join(' ');
ps[6].editAsText().insertText(0, s);
}
}
function getLeadingSpacesCount(p) {
var found = p.findText("^ +");
return found ? found.getEndOffsetInclusive() + 1 : 0;
}
We have used methods deleteText() and insertText() of the class Text for proper corrections and findText() to locate the spaces if any. Note, the last method argument is a string, representing a regular expression. It matches "all leading spaces", if they exist. See more details about regular expression syntax.

Google Apps Script: weird page layout in a script formatted document

I'm working on a script that applies custom headings to a plain text document imported in Google Docs. The scripts works pretty much as it should. However the resulting document has a weird layout, as if random page breaks were inserted here and there. But there are no page breaks and I can't understand the reason of this layout. Checking the paragraph attributes give me no hints on what is wrong.
Here is the text BEFORE the script is applied:
https://docs.google.com/document/d/1MzFvlkG13i3rrUcz5jmmSppG4sBH6zTXr7RViwdqaIo/edit?usp=sharing
You can make a copy of the document and execute the script (from the Scripts menu, choose Apply Headings). The script applies the appropriate heading to the scene heading, name of the character, dialogue, etc.
As you can see, at the bottom of page 2 and 3 of the resulting document there is a big gap and I can't figure out why. The paragraph attributes seem ok to me...
Here is a copy of the script:
// Apply headings to sceneheadings, actions, characters, dialogues, parentheticals
// to an imported plain text film script;
function ApplyHeadings() {
var pars = DocumentApp.getActiveDocument().getBody().getParagraphs();
for(var i=0; i<pars.length; i++) {
var par = pars[i];
var partext = par.getText();
var indt = par.getIndentStart();
Logger.log(indt);
if (indt > 100 && indt < 120) {
var INT = par.findText("INT.");
var EXT = par.findText("EXT.");
if (INT != null || EXT != null) {
par.setHeading(DocumentApp.ParagraphHeading.HEADING1);
par.setAttributes(ResetAttributes());
}
else {
par.setHeading(DocumentApp.ParagraphHeading.NORMAL);
par.setAttributes(ResetAttributes());
}
}
else if (indt > 245 && indt < 260) {
par.setHeading(DocumentApp.ParagraphHeading.HEADING2);
par.setAttributes(ResetAttributes());
}
else if (indt > 170 && indt < 190) {
par.setHeading(DocumentApp.ParagraphHeading.HEADING3);
par.setAttributes(ResetAttributes());
}
else if (indt > 200 && indt < 240) {
par.setHeading(DocumentApp.ParagraphHeading.HEADING4);
par.setAttributes(ResetAttributes());
}
}
}
// Reset all the attributes to "null" apart from HEADING;
function ResetAttributes() {
var style = {};
style[DocumentApp.Attribute.STRIKETHROUGH] = null;
style[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT] = null;
style[DocumentApp.Attribute.INDENT_START] = null;
style[DocumentApp.Attribute.INDENT_END] = null;
style[DocumentApp.Attribute.INDENT_FIRST_LINE] = null;
style[DocumentApp.Attribute.LINE_SPACING] = null;
style[DocumentApp.Attribute.ITALIC] = null;
style[DocumentApp.Attribute.FONT_SIZE] = null;
style[DocumentApp.Attribute.FONT_FAMILY] = null;
style[DocumentApp.Attribute.BOLD] = null;
style[DocumentApp.Attribute.SPACING_BEFORE] = null;
style[DocumentApp.Attribute.SPACING_AFTER] = null;
return style;
}
A couple of screenshots to make the problem more clear.
This is page 2 of the document BEFORE the script is applied.
This is page two AFTER the script is applied. Headings are applied correctly but... Why the white space at the bottom?
Note: if you manually re-apply HEADING2 to the first paragraph of page 3 (AUDIO TV), the paragraph will jump back to fill the space at the bottom of page 2. This action, however, doesn't change any attribute in the paragraph. So why the magic happens?
Thanks a lot for your patience.
That was an interesting problem ;-)
I copied your doc, ran the script and had a surprise : nothing happened !
It took me a few minutes to realize that the copy I just made had no style defined for headings, everything was for some reason in courrier new 12pt, including the headings.
I examined the log and saw the indent values, played with that a lot to finally see that the headings were there but not changing the style.
So I went in the doc menu and set 'Use my default style and... everything looks fine, see screen capture below.
So now your question : it appears that there must be something wrong in your style definition, by "wrong" I mean something that changes more than just the font Style and size but honestly I can't see any way to guess what since I'm unable to reproduce it... Please try resetting your heading styles and re-define your default.... and tell us what happens then.
PS : here are my default heading styles : (and the url of my copy in view only :https://docs.google.com/document/d/1yP0RRCrRSsQc9zCk-sdfu5olNGDkoIrabXanII4qUG0/edit?usp=sharing )

How to split line of text (first half bold, second half not bold) when creating document using Google Script

Instead of:
doc.appendparagraph();
how do you add a line of text to your document without it returning to the next line?
I'm trying to break up a line of text and bold the first half the sentence with .setAttributes(bold);
bold which I've defined using....
var boldpl = {};
boldpl[DocumentApp.Attribute.BOLD] = true;.
Thank you.
I've figured out how to do this in a roundabout way using a merge feature, but how do you go about adding a new line instead of a new paragraph? There is no doc.appendText(); feature is there?
Also is there an easy way to make my document single spaced?
You've asked a lot of different questions there!
Given an existing paragraph, how can some portion of it be rendered in
bold while the rest remains normal?
A Document contains a Body, which can contain Paragraphs, each of which can contain other elements, including Text. You can get that Text either as a string - which you can't do much with - or as a Text Object. Here's an example of using the Text.setBold() method to change just some text in a paragraph to bold:
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var firstParagraph = body.getParagraphs()[0];
textElement = firstParagraph.editAsText();
textElement.setBold(0,6,true); // Set the 0th to 6th characters bold
Alternatively, you could use the Text.setAttributes() method with your custom attribute boldpl:
textElement.setAttributes(0,6, boldpl)
Starting with that building block, you could do things like:
Apply bold from the start of a paragraph until the first occurrence of a colon (:).
Apply bold to the first few words.
...or even apply bold to the first half!
textElement.setBold(0,
Math.floor((textElement.getText().length)/2),
true);
There is no doc.appendText(); feature is there?
No... but there is a Paragraph.appendText() method.
Also is there an easy way to make my document single spaced?
You can control the line spacing of text within paragraphs, by setting attributes on individual paragraphs. See Paragraph.setLineSpacing(). Here's a function that sets every paragraph in your document to single-spacing:
function singleSpace() {
var doc = DocumentApp.getActiveDocument();
var bodyElement = DocumentApp.getActiveDocument().getBody();
var paragraphs = bodyElement.getParagraphs();
// Set each paragraph to single-spaced
paragraphs.forEach( function( paragraph ) {
paragraph.setLineSpacing( 1.0 );
});
}