Reputation: 55
I need to automatically delete all horizontal rules which are surrounded by 6 linebreaks (3 before and 3 after) on a google doc.
This piece of code seems to put in the logs the correct linebreaks I want to delete (that's a first step) :
function myFunction() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody().getText();
var pattern = /\s\s\s\s/g;
while (m=pattern.exec(body)) { Logger.log(m[0]); }
}
I have two questions :
What tool can I use to delete these linebreaks (I don't yet understand the subtilies of using replace or replaceText, all my attemps with these have failed) ?
How can I add to my var pattern (the pattern to be deleted) a horizontal rule ? I tried /\s\s\s\sHorizontalRule\s\s\s\s/g but of course it did not work.
Upvotes: 1
Views: 698
Reputation: 1165
Horizontal rule is an element inside a paragraph (or sometimes inside a list item). Since it is not text, it can not be found or replaced by means of a regular expression. We should search for objects which are specially arranged in the document body, and delete them if found.
Consider the following code example:
function deleteHR() {
var body = DocumentApp.getActiveDocument().getBody();
var hr = null, hrArray = [], countDeleted = 0;
// Collect all horizontal rules in the Document
while (true) {
hr = body.findElement(DocumentApp.ElementType.HORIZONTAL_RULE, hr);
if (hr == null) break;
hrArray.push(hr);
}
hrArray.forEach(function(hr) {
var p = hr.getElement().getParent();
// Get empty paragraphs as siblings (if any)
var prevSiblings = getSiblings(p, 3, true),
nextSiblings = getSiblings(p, 3, false);
// Define a short function for batch deleting items
function remove(e) {
e.removeFromParent();
}
// If empty paragraphs exist (3 before and 3 after)
if (prevSiblings.length == 3 && nextSiblings.length == 3) {
// then delete them as well as the rule itself
hr.getElement().removeFromParent();
prevSiblings.forEach(remove);
nextSiblings.forEach(remove);
countDeleted++;
}
});
// Optional report
Logger.log(countDeleted + ' rules deleted');
}
// Recursive search for empty paragraphs as siblings
function getSiblings(p, n, isPrevious) {
if (n == 0) return [];
if (isPrevious) {
p = p.getPreviousSibling();
} else {
p = p.getNextSibling();
}
if (p == null) return [];
if (p.getType() != DocumentApp.ElementType.PARAGRAPH) return [];
if (p.asParagraph().getText().length > 0) return [];
var siblings = getSiblings(p, n - 1, isPrevious);
siblings.push(p);
return siblings;
}
Main function deleteHR()
does all the work. However it appears helpful to use another separate function getSiblings()
for recursive search for empty paragraphs. May be, this way is not the only, but it works.
Upvotes: 2