I'm using DocumentApp.Attribute with mixed results. Here is an example:
var underline = {};
underline[DocumentApp.Attribute.UNDERLINE] = true;
underline[DocumentApp.Attribute.WIDTH] = 100;
underline[DocumentApp.Attribute.MARGIN_LEFT] = 10;
doc.appendParagraph("Paragraph text").setAttributes(underline);
The paragraph is created, and underlined, but the other two attributes don't get applied.
I think that you will find that a paragraph cannot have either Margin or width attributes ... they apply to the page or document as a whole. You might get the effect that you wish by using the Indent set of attributes.
This begs the next question "how do you set page attributes?"
MARGIN-LEFT appears as an attribute of the Body section so getActiveSection().setAttributes(style)
I am not sure what width refers to but you can do a getAttributes for each element type to track it down PAGE-WIDTH is an attribute of Body Section again. Play around with this code ...
function myFunction() {
var doc = DocumentApp.openById("1lqjkdfdsafgdsafsdaQI3kjtY");
var docele = doc.getActiveSection();
Logger.log(docele.getAttributes());
var para = doc.getParagraphs()[0];
var atts = para.getAttributes();
Logger.log(atts)
// Define a custom paragraph style.
var style = {};
style[DocumentApp.Attribute.WIDTH] = 100;
style[DocumentApp.Attribute.MARGIN_LEFT] = 200;
docele.setAttributes(style);
}
For me this gave body section attributes of {UNDERLINE=null, MARGIN_BOTTOM=72.0, PAGE_HEIGHT=792.0, BOLD=null, BACKGROUND_COLOR=null, FONT_SIZE=null, FONT_FAMILY=null, STRIKETHROUGH=null, MARGIN_LEFT=10.0, PAGE_WIDTH=612.0, LINK_URL=null, ITALIC=null, MARGIN_RIGHT=72.0, MARGIN_TOP=72.0, FOREGROUND_COLOR=null}
and paragraph attributes of {UNDERLINE=null, INDENT_END=8.25, LEFT_TO_RIGHT=true, BOLD=null, BACKGROUND_COLOR=null, FONT_SIZE=12, FONT_FAMILY=Comic Sans MS, SPACING_BEFORE=null, SPACING_AFTER=null, STRIKETHROUGH=null, INDENT_START=0.0, LINE_SPACING=null, LINK_URL=null, ITALIC=null, INDENT_FIRST_LINE=0.0, HORIZONTAL_ALIGNMENT=null, HEADING=null, FOREGROUND_COLOR=null}
This gives a clue to the alternative form for setting of attributes
docele.setAttributes({"FOREGROUND_COLOR":"#ff0000"})
Related
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);
I am hoping to re-define the heading styles for a document. My understanding is that getHeadingAttributes and setHeadingAttributes would let me do this
https://developers.google.com/apps-script/reference/document/body#setheadingattributesparagraphheading-attributes
This is how I'm going about testing this --
function main() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
styledef=body.getHeadingAttributes(DocumentApp.ParagraphHeading.HEADING1);
Logger.log("Before: \n" + JSON.stringify(styledef) );
styledef[DocumentApp.Attribute.UNDERLINE] = true;
styledef[DocumentApp.Attribute.BACKGROUND_COLOR] = '#ffff00';
body.setHeadingAttributes(DocumentApp.ParagraphHeading.HEADING1, styledef);
styledef=body.getHeadingAttributes(DocumentApp.ParagraphHeading.HEADING1);
Logger.log("After: \n" + JSON.stringify(styledef));
}
This Body has its headings attributes modified, as revealed by the Logger output:
[17-10-04 09:20:53:379 MDT] Before:
{"FONT_SIZE":18,"ITALIC":false,"HORIZONTAL_ALIGNMENT":{},"INDENT_END":0,"INDENT_START":0,"LINE_SPACING":1,"UNDERLINE":false,"BACKGROUND_COLOR":null,"INDENT_FIRST_LINE":0,"SPACING_BEFORE":12,"SPACING_AFTER":0,"STRIKETHROUGH":false,"FOREGROUND_COLOR":"#000000","BOLD":true,"FONT_FAMILY":"Arial","VERTICAL_ALIGNMENT":{}}
[17-10-04 09:20:53:382 MDT] After:
{"FONT_SIZE":18,"ITALIC":false,"HORIZONTAL_ALIGNMENT":{},"INDENT_END":0,"INDENT_START":0,"LINE_SPACING":1,"UNDERLINE":true,"BACKGROUND_COLOR":"#ffff00","INDENT_FIRST_LINE":0,"SPACING_BEFORE":12,"SPACING_AFTER":0,"STRIKETHROUGH":false,"FOREGROUND_COLOR":"#000000","BOLD":true,"FONT_FAMILY":"Arial","VERTICAL_ALIGNMENT":{}}
UNDERLINE changed from false to true
BACKGROUND_COLOR changed from null to #ffff00
But in my document to which this script is bound, the styling of Heading 1 has not changed for existing paragraphs with that Heading. Nor are new paragraphs marked Heading 1 styled with the changes I've tried to make.
Incidentally, when I run that same function on NORMAL instead of HEADING1, the changes are instantly visible: Every Heading (Normal, Title, Subtitle, Heading 1, etc...) has the underline and background color applied.
I feel like I've fundamentally misunderstood the purpose of these methods (getHeadingAttributes, setHeadingAttributes). If not these methods, I'd like to find the correct way to re-define Heading stylings for a document. Can you point me in the right direction?
Many Thanks,
Haven't played around much of this yet, but check the Enum ParagraphHeading as it seems close to what you're getting at.
Use the ParagraphHeading enumeration to configure the heading style for ParagraphElement.
var body = DocumentApp.getActiveDocument().getBody();
// Append a paragraph, with heading 1.
var par1 = body.appendParagraph("Title");
par1.setHeading(DocumentApp.ParagraphHeading.HEADING1);
// Append a paragraph, with heading 2.
var par2 = body.appendParagraph("SubTitle");
par2.setHeading(DocumentApp.ParagraphHeading.HEADING2);
// Append a paragraph, with normal heading.
var par3 = body.appendParagraph("Text");
par3.setHeading(DocumentApp.ParagraphHeading.NORMAL);
I want to replace a word "allowance" with "Some text", after running the code, It will remove word allowance and apply "Some text" with same formatting as that of "allowance" but foreground color property is not getting set as that of original.I want Some text also in red color as shown in the screenshot
function retainFormatting() {
var doc = DocumentApp.getActiveDocument();
var textToHighlight = 'allowance';
var highlightStyle;
var paras = doc.getParagraphs();
var textLocation = {};
var i;
for (i=0; i<paras.length; ++i) {
textLocation = paras[i].findText(textToHighlight);
if (textLocation != null && textLocation.getStartOffset() != -1) {
highlightStyle = textLocation.getElement().getAttributes(textLocation.getStartOffset());
textLocation.getElement().deleteText(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive());
textLocation.getElement().insertText(textLocation.getStartOffset(),"Some text");
textLocation.getElement().setAttributes(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
}
}
}
before setting attribute at offset
after setting attribute it turns out to be
getForegroundColor(offset)
Retrieves the foreground color at the specified character offset.
And
setForegroundColor(startOffset, endOffsetInclusive, color)
Sets the foreground color for the specified character range.
Here is a sample code :
Getting Color from text
highlightColor = textLocation.getElement().getForegroundColor(textLocation.getStartOffset());
Applying color to text
textLocation.getElement().setForegroundColor(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
I hope it helps. Goodluck :)
Try
textLocation.getElement().editAsText().deleteText(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive());
textLocation.getElement().editAsText().insertText(textLocation.getStartOffset(),"Some text");
The .editAsText() puts you into editing the contents of the rich text leaving the existing attributes as a 'wrapper'
Alternatively, try replacing the text rather than deleting and inserting
paras[i].replaceText("allowance", "some text") // the first attribute is a regular expression as string
I have just tested this and it seems that setting LINK_URL alongside other attributes interferes with FOREGROUND_COLOR.
The following results in a black text color:
var attrs = {
"FOREGROUND_COLOR": "#ff0000", // should be red
"LINK_URL": null
};
text.setAttributes(start, end, attrs);
The following results in a red text color:
var attrs = {
"FOREGROUND_COLOR": "#ff0000" // should be red
};
text.setAttributes(start, end, attrs);
In effect, if you don't need to set the link, remove the LINK_URL from the list of formatting options.
#JSDBroughton Gave me an idea, which worked.
Try setting the attributes of the rich text object you get when calling editAsText. So instead of:
highlightStyle = textLocation.getElement().getAttributes(textLocation.getStartOffset());
textLocation.getElement().setAttributes(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
Do:
// Make sure you replace `asParagraph` with what you actually need
highlightStyle = textLocation.getElement().asParagraph().editAsText().getAttributes(textLocation.getStartOffset());
textLocation.getElement().asParagraph().editAsText().setAttributes(textLocation.getStartOffset(),textLocation.getEndOffsetInclusive(), highlightStyle);
Edit: after playing around with this, seems like this only sometimes works. I still haven't figured out the pattern for when it does work and when it doesn't.
I'm writing a script that picks the paragraph where the cursor is contained, set the text to uppercase and change the paragraph heading to HEADING1.
However, the paragraph is set to the 'global' HEADING1, not to HEADING1 as it is defined in the current document. Here is the code.
function SetSceneHeading() {
var cursor = DocumentApp.getActiveDocument().getCursor();
var element = cursor.getElement();
var paragraph = [];
if (element.getType() != 'PARAGRAPH') {
paragraph = element.getParent().asParagraph();
}
else paragraph = element.asParagraph();
var txt = paragraph.getText();
var TXT = txt.toUpperCase();
paragraph.setText(TXT);
paragraph.setHeading(DocumentApp.ParagraphHeading.HEADING1);
}
Is there a way to set a paragraph to the 'current' HEADING1? Thanks.
I found a workaroud to set a paragraph to a user defined heading. Basically, you first set the heading using setHeading(), then you set to "null" the attributes that the previous operation messed up. This way the paragraph is set according to the user defined heading.
function MyFunction ()
var paragraph = ....
paragraph.setHeading(DocumentApp.ParagraphHeading.HEADING1);
paragraph.setAttributes(ResetAttributes());
function ResetAttributes() {
var style = {};
style[DocumentApp.Attribute.FONT_SIZE] = null;
style[DocumentApp.Attribute.BOLD] = null;
style[DocumentApp.Attribute.SPACING_BEFORE] = null;
style[DocumentApp.Attribute.SPACING_AFTER] = null;
return style;
}
I made a few tests, FONT_SIZE BOLD SPACING_BEFORE SPACING_AFTER seem to be the attributes that need to be reset. They may be more, according to the cases.
Unfortunately it seems that this won't be possible for now, there is an open issue that I think is relevant : issue 2373 (status acknowledged) , you could star it to get informed of any enhancement.
I have a page and I'm using chrome console to add an SVG element which covers the whole body.
I typed the following commands in the console,
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.style.position = "absolute";
svg.style.left = svg.style.right = svg.style.top = svg.style.bottom = "0px";
svg.style.opacity = 0.5;
svg.style['z-index'] = 100;
svg.style.width = "100%";
svg.style.height = "100%";
document.body.appendChild(svg);
But the SVG element only covers the part of page that is displayed, i.e., if the page is long enough so that we have to scroll down, the whole page is not covered.
Any suggestions?
If you want to fix the element at the viewport, use position:fixed; instead.
Otherwise, do not use 100%, but:
svg.style.height = Math.max(document.body.scrollHeight,
document.documentElement.scrollHeight) + 'px';