Google Apps Script---Replace Straight Quotation Marks with Curly Ones - javascript

When I was typing a novel on my Google Docs iPad app, it used straight up-and-down quotation marks, like this: ". Now, I want to change all of these quotes to the curly kind, without having to change all of them by hand.
I wrote a simple Google Apps Script file to deal with the issue, but when I run it, it seems to say "Running function myFunction..." indefinitely.
Here is my code. The first few lines deal with quotes in the middle of the sentence, using a simple replaceText method. Meanwhile, the while statement tests if there is a line break (\n) before the quote, and uses that to determine whether to put a beginning or end quote.
function myFunction() {
var body = DocumentApp.getActiveDocument().getBody();
//Replace quotes that are not at beginning or end of paragraph
body.replaceText(' "', ' “');
body.replaceText('" ', '” ');
var bodyString = body.getText();
var x = bodyString.indexOf('"');
var bodyText = body.editAsText();
while (x != -1) {
var testForLineBreaks = bodyString.slice(x-2, x);
if (testForLineBreaks == '\n') { //testForLineBreaks determines whether it is the beginning of the paragraph
//Replace quotes at beginning of paragraph
bodyText.deleteText(x, x);
bodyText.insertText(x, '“');
} else {
//Replace quotes at end of paragraph
bodyText.deleteText(x, x);
bodyText.insertText(x, '”');
}
x = bodyString.indexOf('"');
}
}
I can't seem to find what's wrong with it. And to confuse things more, when I click the debugger, it says
Too many changes applied before saving document. Please save changes in smaller batches using Document.saveAndClose(), then reopen the document with Document.openById().
I appreciate all help with this. Thank you in advance!

I am not sure about the exact limit, but I think you can include a counter in your while loop, and for every 50 or 100, output that via Logger.log(); once you get hold of that limit count, you may do what being suggested,
i.e. when approaching the limit, flush/save the changes by calling Document.saveAndClose(), then start again with the main loop by reopening the document with Document.openById()

some1 was right about the error message, but unfortunately that did not get to the root of the problem:
At the end of my while loop, the variable bodyString was being used to find the location of quotation marks to change. The problem was that bodyString was just that, a string, and so I needed to update it each time I made a change to the document.
Another problem, albeit more basic, was that Google counts \n as one character, so I had to change the parameter in var testForLineBreaks = bodyString.slice(x-2, x); to x-1, x.
After tinkering with these issues, my finished code looked like this:
function myFunction() {
var body = DocumentApp.getActiveDocument().getBody();
//Replace quotes that are not at beginning or end of paragraph
body.replaceText(' "', ' “');
body.replaceText('" ', '” ');
var bodyString = body.getText();
var x = bodyString.indexOf('"');
var bodyText = body.editAsText();
while (x != -1) {
var testForLineBreaks = bodyString.slice(x-1, x);
if (testForLineBreaks == '\n') { //testForLineBreaks determines whether it is the beginning of the paragraph
//Replace quotes at beginning of paragraph
bodyText.deleteText(x, x);
bodyText.insertText(x, '“');
} else {
//Replace quotes at end of paragraph
bodyText.deleteText(x, x);
bodyText.insertText(x, '”');
}
body = DocumentApp.getActiveDocument().getBody();
bodyString = body.getText();
x = bodyString.indexOf('"');
bodyText = body.editAsText();
}
}
There is one remaining problem with the code. If the quote is at the very beginning of the document, as in the first character, then the script will insert the wrong quote style. However, I plan on fixing that manually.

Related

Form validation script using regex to check for multiple key words across line breaks

What I need is to check for several key words within a textarea before allowing my students to submit their lesson summaries.
The following regex works fine as long as they don't click enter to create a new paragraph.
/^(?=.*\bmodel|models\b)(?=.*\btheory|theories\b)(?=.*\blaw|laws\b)(?=.*\bscale\b)/i;
From what I've been reading, it would seem that the following modification to the regex should allow my validation script to read across line breaks, but I haven't had any success.
var ck_summary = /^(?=.[\S\s]*\bmodel|models\b)(?=.[\S\s]*\btheory|theories\b)(?=.[\S\s]*\blaw|laws\b)(?=.[\S\s]*\bscale\b)/i;
I'm (obviously) a beginner at this and eager to learn. Can anyone please explain what am I doing wrong? Many thanks!
Here's my entire summary validation script...
var ck_studentid = /^[0-9]{6,6}$/;
var ck_summary = /^(?=.[\S\s]*\bmodel|models\b)(?=.[\S\s]*\btheory|theories\b)(?=.[\S\s]*\blaw|laws\b)(?=.[\S\s]*\bscale\b)/i;
function validate(sumform){
var studentid = sumform.studentid.value;
var summary = sumform.summary.value;
var errors = [];
if (!ck_studentid.test(studentid)) {
errors[errors.length] = "Check your Student ID";
}
if (!ck_summary.test(summary)) {
errors[errors.length] = "Make sure you used all of the vocabulary terms AND you spelled them correctly.";
}
if (errors.length > 0) {
reportErrors(errors);
return false;
}
return true;
}
function reportErrors(errors){
var msg = "Uh oh, looks like we have a problem...\n";
for (var i = 0; i<errors.length; i++) {
var numError = i + 1;
msg += "\n" + numError + ". " + errors[i];
}
alert(msg);
}
From what I've been reading, it would seem that the following
modification to the regex should allow my validation script to read
across line breaks, but I haven't had any success.
var ck_summary = /^(?=.[\S\s]*\bmodel|models\b)(?=.[\S\s]*\btheory|theories\b)(?=.[\S\s]*\blaw|laws\b)(?=.[\S\s]*\bscale\b)/i;
This didn't work for you because you did not modify it very well.
.*: captures every character/word except a newline \n, that was why you were told to modify it to [\S\s]* which capture every character/word including a newline \n. But looking at your pattern, you didn't totally modify it, you should remove all the dots . before [\S\s]*.
Your new code should be like this
var ck_summary = /^(?=[\S\s]*\bmodel|models\b)(?=[\S\s]*\btheory|theories\b)(?=[\S\s]*\blaw|laws\b)(?=[\S\s]*\bscale\b)/i;

Removing last comma

I read content from a file and then write it another file after editing . While editing , for each read line i put a comma at the end of line and then write it to the file. For the last read line i do not want to write a comma. How should i do it.?
while(!inputFile.AtEndOfStream){
var readLine = inputFile.ReadLine();
var omitChars = new RegExp("#define").test(readLine);
if(omitChars==1){
var stringReadPosition = readLine.substr(8);
var finalString = stringReadPosition.replace(/\s+/g, ': ');
asd = outputFile.Write(finalString.replace(/^(_)/, "") + ",\r\n");
}
}
outputFile.Write("};\r\n");
inputFile.Close();
outputFile.Close();
}
You can use substring in order to remove the last character of the string after you have formed the string:
finalString = finalString.substring(0, finalString.length - 1);
An alternative would be the use of slice, taking into consideration that negative indices are relative to the end of the string:
finalString = finalString.slice(0,-1);
Take a look in this question for more.
UPDATE: For your case, you could check whether or not you have reached the EOF - meaning you have read the last line, and then apply slice or substring:
//....
var stringReadPosition = readLine.substr(8);
var finalString = stringReadPosition.replace(/\s+/g, ': ');
//Check if stream reached EOF.
if(inputFile.AtEndOfStream) {
finalString = finalString.slice(0,-1);
}
asd = outputFile.Write(finalString.replace(/^(_)/, "") + ",\r\n");
//....
try this asd = asd.replace(/,\s*$/, "");
this will remove last comma, I have tried this, its working .Check if it works in ur code.
Try this code inside while loop

check whether string contains a line break

So, I have to get HTML of textarea and check whether it contains line break. How can i see whether it contain \n because the string return using val() does not contain \n and i am not able to detect it. I tried using .split("\n") but it gave the same result. How can it be done ?
One minute, IDK why when i add \n to textarea as value, it breaks and move to next line.
Line breaks in HTML aren't represented by \n or \r. They can be represented in lots of ways, including the <br> element, or any block element following another (<p></p><p></p>, for instance).
If you're using a textarea, you may find \n or \r (or \r\n) for line breaks, so:
var text = $("#theTextArea").val();
var match = /\r|\n/.exec(text);
if (match) {
// Found one, look at `match` for details, in particular `match.index`
}
Live Example | Source
...but that's just textareas, not HTML elements in general.
var text = $('#total-number').text();
var eachLine = text.split('\n');
alert('Lines found: ' + eachLine.length);
for(var i = 0, l = eachLine.length; i < l; i++) {
alert('Line ' + (i+1) + ': ' + eachLine[i]);
}
You can simply use this
var numberOfLineBreaks = (enteredText.match(/\n/g)||[]).length;

removing BBcode from textarea with Javascript

I'm creating a small javscript for phpBB3 forum, that counts how much character you typed in.
But i need to remove the special characters(which i managed to do so.) and one BBcode: quote
my problem lies with the quote...and the fact that I don't know much about regex.
this is what I managed to do so far but I'm stranded:
http://jsfiddle.net/emjkc/
var text = '';
var char = 0;
text = $('textarea').val();
text = text.replace(/[&\/\\#,+()$~%.'":*?<>{}!?(\r\n|\n|\r)]/gm, '');
char = text.length;
$('div').text(char);
$('textarea').bind('input propertychange', function () {
text = $(this).val();
text = text.replace(/[&\/\\#,+()$~%.'":*?<>{}!?\-\–_;(\r\n|\n|\r)]/gm, '');
char = text.length;
$('div').text(char);
});
You'd better write a parser for that, however if you want to try with regexes, this should do the trick:
text = $('textarea').val();
while (text.match(/\[quote.*\[\/quote\]/i) != null) {
//remove the least inside the innermost found quote tags
text = text.replace(/^(.*)\[quote.*?\[\/quote\](.*)$/gmi, '\$1\$2');
}
// now strip anything non-character
text = text.replace(/[^a-z0-9]/gmi, '');
I'm not sure if this would work, but I think you can replace all bbcodes with a regex like this:
var withoutBBCodes = message.replace(/\[[^\]]*\]/g,"");
It just replaces everything like [any char != ']' goes here]
EDIT: sorry, didn't see that you only want to replace [quote] and not all bbcodes:
var withoutBBQuote = message.replace(/\[[\/]*quote[^\]]*\]/g,"");
EDIT: ok, you also want quoted content removed:
while (message.indexOf("[quote") != -1) {
message = message.replace(/\[quote[^\]]*\]((?!\[[[\/]*quote).)*\[\/quote\]/g,"");
}
I know you already got a solution thanks to #guido but didn't want to leave this answer wrong.

var paragraph is giving me "unterminated string constant" error

I have this file
var paragraph = "Abandon| give up or over| yield| surrender| leave| cede| let go| deliver| turn over| relinquish| depart from| leave| desert| quit| go away from| desert| forsake| jilt| walk out on | give up| renounce| discontinue| forgo| drop| desist| abstain from|
recklessness| intemperance| wantonness| lack of restraint| unrestraint|
abandoned |left alone| forlorn| forsaken| deserted| neglected| rejected| shunned| cast off | jilted| dropped| ";
with a lot of spacing, so it's giving me that error at the spacings.
then running a loop and alerting the output
var sentences = paragraph.split("|");
var newparagraph = "";
for (i = 0; i < sentences.length; i++) {
var words = sentences[i].split(" ");
if (words.length < 4) {
newparagraph += sentences[i] + "|";
}
}
alert(newparagraph);
how do I read from a file that doesn't get errors from spacing?
As the other answers noted, javascript automatically puts a semicolon at the end of (or what it thinks is) every statement. More about it here.
http://en.wikipedia.org/wiki/JavaScript_syntax#Whitespace_and_semicolons
It doesn't understand text with line-breaks in them. You could use the '\' character to signify your text contains line-breaks.
var text = "this is\
a very long\
sentence";
But the above practice is generally frowned upon. Best bet, define strings in one line or use concatenation (+) to break your strings into multiple lines. If your text must contain line-breaks, use '\n' character.
I can't see a quote character at the end of var paragraph = "... line.
You're missing a terminating quote and semi-colon at the end of the var paragraph assignment. You can use a tool like jslint (http://www.jslint.com/) to check your syntax, if in doubt.

Categories

Resources