Changing bullet to dash ( -) in Google Document - google-apps-script

We have a function to set a glyphType to DocumentApp.GlyphType.BULLET.
listItem.setGlyphType(DocumentApp.GlyphType.BULLET)
However, is there any way to set the glyphType to dash (-)?
For example, our list is below.
- Item 1
- Item 2
- Item 3
Ref: https://developers.google.com/apps-script/reference/document/list-item#setGlyphType(GlyphType)

The dash is not listed as a glyph type. But here is a work around. You could make you own pre-filled list with place holder items in a master document, copy the list and replace the items into the target document. Perhaps this is a lot of effort for styling bullets, but it could work.

Yes #Jason Allshorn is correct. I was able to set a custom bullet using apps script. I have a template doc that I copy to make a new doc. In this template I created a list item, text "list item", with my custom bullet glyph. Google, what is up with those giant dots? Ugly! I find that list item in the doc, copy it, and remove it. Code below:
function getListItem(ss, doc) {
var body = doc.getBody();
for (var i = 0; i < body.getNumChildren(); i++) {
var child = body.getChild(i);
var childType = child.getType();
if (childType == DocumentApp.ElementType.LIST_ITEM && child.getText() == 'list item') {
var customBulletListItem = child.copy();
body.removeChild(child);
break;
}
}
return customBulletListItem;
}
... then when I add a list item (li), I do the following:
body.insertListItem(i, li.copy());
body.getChild(i).replaceText("list item", "My new list item text");
body.getChild(i).setIndentFirstLine(0).setIndentStart(15);
body.getChild(i).editAsText().setBold(true);
This gets me my custom bullet glyph. The last two lines fix the huge indent on list items and bold the line. Google, what is up with the huge indents? Ugly!

Related

Chrome extension: Add style to element if it contains particular text

I want to add styling to an element only if it contains a particular string. i.e. if(el contains str) {el:style}.
If I wanted just the links containing w3.org to be pink, how would I find <a href="http://www.w3.org/1999/xhtml">article < /a> inside the innerHTML and then style the word "article" on the page.
So far, I can turn ALL the links pink but I can't selectively target the ones containing "www.w3.org".
var links = [...document.body.getElementsByTagName("a")];
for (var i = 0; i < links.length; i++) {
links[i].style["color"] = "#FF00FF";
}
How would I apply this ONLY to the elements containing the string "w3.org"?
I thought this would be so simple at first! Any and all help is appreciated.
While you can't filter by non-exact href values when finding the initial list, and you can't filter by contained text then either, you can filter the list after the fact using plain javascript:
var links = [...document.body.getElementsByTagName("a")];
for (var i = 0; i < links.length; i++) {
if (links[i]['href'].indexOf('www.w3.org') == -1) { continue };
links[i].style["color"] = "#FF00FF";
}
Assuming you want to filter by the href, that is. If you mean the literal text, you would use links[i]['text'] instead.

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.

Can Google App Scripts access the location of footnote superscripts programmatically?

Is it possible to use DocumentApp to find the location of footnote references in the body?
Searching the body or an element using editAsText() or findText() does not show the superscript footnote markers.
For example, in the following document:
This is a riveting story with statistics!1 You can see other stuff here too.
body.getText() returns 'This is a riveting story with statistics! You can see other stuff here too.' No reference, no 1
If I want to replace, edit, or manipulate text around the footnote reference (e.g. 1 ), how can I find its location?
It turns out that the footnote reference is indexed as a child in the Doc. So you can get the index of the footnote reference, insert some text at that index, and then remove the footnote from its parent.
function performConversion (docu) {
var footnotes = docu.getFootnotes() // get the footnote
var noteText = footnotes.map(function (note) {
return '((' + note.getFootnoteContents() + ' ))' // reformat text with parens and save in array
})
footnotes.forEach(function (note, index) {
var paragraph = note.getParent() // get the paragraph
var noteIndex = paragraph.getChildIndex(note) // get the footnote's "child index"
paragraph.insertText(noteIndex, noteText[index]) // insert formatted text before footnote child index in paragraph
note.removeFromParent() // delete the original footnote
})
}
You can use getFootnotes() to edit footnotes. getFootnotes() returns an arrays of objects , you need to iterate over them.
You can list the locations (i.e Parent Paragraphs) of footnotes in Logger.log(), in the following fashion:
function getFootnotes(){
var doc = DocumentApp.openById('...');
var footnotes = doc.getFootnotes();
var textLocation = {};
for(var i in footnotes ){
textLocation = footnotes[i].getParent().getText();
Logger.log(textLocation);
}
}
To get the paragraph truncated right upto the footnote superscript. You can use:
textLocation = footnotes[i].getPreviousSibling().getText();
in your case it should return: This is a riveting story with statistics! only this portion, because [1] is just after the word statistics!

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 )

get itemrenderer by list item in flex

I've a Tree with checkbox with dataprovider as an xmlList. Now I need to get the item renderer of the list item without click on item and by search the from outside.
protected function btnSearch_clickHandler():void
{
var searchString:String = txtInputSearch.text;
if(searchString != "")
{
StyleItemsArray.removeAll();
var conaintList:XMLList = (treeSource.node.(#label.search(searchString) > -1) as XMLList);
for each(var xmlItem:XML in conaintList)
{
// trigger the checkbox click event here
}
}
}
Sorry for delayed:
I tried the solution given but it seems datagroup is used in Flex 4 but I'm still in flex 3 version.
I tried couple of other way (e.g. itemToItemRenderer())but no luck.
Could someone please help me out?
you can retrieve all item-render of list by just using for getElementAt.
for(var i:int=0; i < youListVariable.dataProvider.length; i++)
{
var render:CustomFieldRenderer = youListVariable.dataGroup.getElementAt(i) as CustomFieldRenderer
//put Your comparison condition and if condition matched then break
}
CustomFieldRenderer is your itemRender.
youListVariable is your list's id i.e. list's variable.