Copy link to clipboard
Copied
Hi there – I have a scripting problem outlined below but not sure if its even possible.
Is it possible use javascript to loop through all groups in a document and then target the group that contains the word “CALLOUT” with a find replace GREP to remove some pricing? And not touch the groups that don’t contain the “CALLOUT” . The callout text box and the text box with the pricing are independent of each other.
FIND was \$\d+(\.\d{2})? now \$\d+(\.\d{2})? & delete.
If possible what would that javascript look like
The group on the left does not contain the callout and the group items on the right does.
There could be many of these groups in a document.
Any help appreciated.
Hey - I think this might fix it - sorry don't have time to test it properly
// Undo the script if needed
app.doScript(searchCallout, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Search Callout');
function searchCallout() {
var res = getTextSearch("CALLOUT");
var pg, tf;
for (var i = 0; i < res.length; i++) {
// Check if the result has parent text frames and if its parent is a group
if (res[i].parentTextFrames.length > 0) {
pg = res[i].p
...
Copy link to clipboard
Copied
Hey
Give this a go
// Main function
function main() {
// Get the active document
var doc = app.activeDocument;
// Loop through all groups in the document
for (var i = 0; i < doc.allPageItems.length; i++) {
var group = doc.allPageItems[i];
// Check if the item is a group
if (group instanceof Group) {
// Check if the group contains a text frame with the word "CALLOUT"
if (groupContainsCallout(group)) {
// Perform GREP find and replace to remove pricing
removePricing(group);
}
}
}
alert("Pricing removal complete.");
}
// Function to check if a group contains a text frame with the word "CALLOUT"
function groupContainsCallout(group) {
for (var j = 0; j < group.allPageItems.length; j++) {
var item = group.allPageItems[j];
// Check if the item is a text frame
if (item instanceof TextFrame) {
// Check if the text frame contains the word "CALLOUT"
if (item.contents.indexOf("CALLOUT") !== -1) {
return true;
}
}
}
return false;
}
// Function to remove pricing using GREP find and replace
function removePricing(group) {
for (var j = 0; j < group.allPageItems.length; j++) {
var item = group.allPageItems[j];
// Check if the item is a text frame
if (item instanceof TextFrame) {
// Perform GREP find and replace to remove pricing
var grepFind = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
var grepReplace = "";
app.findGrepPreferences.findWhat = grepFind;
app.changeGrepPreferences.changeTo = grepReplace;
item.changeGrep();
// Clear GREP preferences
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
}
}
}
// Run the main function
main();
Copy link to clipboard
Copied
Another approach to the one used by @Eugene Tyson is that instead of looping all the groups in the document we can run a find query to find "Callout" then for the results see if the result is part of a textframe whose parent is a group.
Another change that could be done is iterate just the textframes of the group instead of allPageItems. Both these suggestions could speed up the process.
-Manan
Copy link to clipboard
Copied
Thanks @Eugene Tyson your script works great.
I have added smoe fuctionality to either proces the current document or all open documents.
// Main function
function main() {
var scope = userInput();
var foundCALLOUT = false;
// Loop through the selected scope
if (scope instanceof Array) {
for (var i = 0; i < scope.length; i++) {
foundCALLOUT = processDocument(scope[i]) || foundCALLOUT;
}
} else {
foundCALLOUT = processDocument(scope);
}
if (foundCALLOUT) {
alert("CALLOUT product pricing updated.");
} else {
alert("No CALLOUT product groups found.");
}
}
// Function to process a document
function processDocument(doc) {
var foundCALLOUT = false;
// Loop through all groups in the document
for (var i = 0; i < doc.allPageItems.length; i++) {
var group = doc.allPageItems[i];
// Check if the item is a group
if (group instanceof Group) {
// Check if the group contains a text frame with the word "CALLOUT"
if (groupContainsCallout(group)) {
foundCALLOUT = true;
// Perform GREP find and replace to remove pricing
removePricing(group);
}
}
}
return foundCALLOUT;
}
// Function to check if a group contains a text frame with the word "CALLOUT"
function groupContainsCallout(group) {
for (var j = 0; j < group.allPageItems.length; j++) {
var item = group.allPageItems[j];
// Check if the item is a text frame
if (item instanceof TextFrame) {
// Check if the text frame contains the word "CALLOUT"
if (item.contents.indexOf("CALLOUT") !== -1) {
return true;
}
}
}
return false;
}
// Function to remove pricing using GREP find and replace
function removePricing(group) {
for (var j = 0; j < group.allPageItems.length; j++) {
var item = group.allPageItems[j];
// Check if the item is a text frame
if (item instanceof TextFrame) {
// Perform GREP find and replace to remove pricing
var grepFind = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
var grepReplace = "";
app.findGrepPreferences.findWhat = grepFind;
app.changeGrepPreferences.changeTo = grepReplace;
item.changeGrep();
// Clear GREP preferences
app.findGrepPreferences = NothingEnum.nothing;
app.changeGrepPreferences = NothingEnum.nothing;
}
}
}
// Function to get user input for the scope
function userInput() {
var w = new Window('dialog', 'Select Scope', undefined, { closeButton: false });
w.alignChildren = 'right';
var p = w.add('panel {alignChildren: "left"}');
p.add('radiobutton {text: "Active document"}');
p.add('radiobutton {text: "All open documents"}');
var b = w.add('group');
b.add('button', undefined, 'Cancel');
b.add('button', undefined, 'OK');
// Set default selection
p.children[0].value = true;
if (w.show() == 1) {
if (p.children[0].value) {
w.close();
return [app.activeDocument]; // Return an array with the active document
} else {
w.close();
var allOpenDocs = [];
for (var i = 0; i < app.documents.length; i++) {
allOpenDocs.push(app.documents[i]);
}
return allOpenDocs; // Return all open documents
}
} else {
w.close();
exit(); // Close the script if Cancel is clicked
}
}
// Run the main function
main();
@Manan Joshi Thanks for your input.
Is it possible to see a version of the script using your approach?
We will be processing alot of documents at once sometimes so any speed efficiencies would be appreciated.
Copy link to clipboard
Copied
Is it possible to see a version of the script using your approach?
Hi @rickt38612460, In case Manan doesn’t reply right away, here is an example:
//undo
app.doScript(searchCallout, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Search Callout');
function searchCallout(){
var res = getTextSearch("CALLOUT")
var pg, tf;
for (var i = 0; i < res.length; i++){
//gets the parent group—this assumes there are no nested groups
pg = res[i].parentTextFrames[0].parent
if (pg.constructor.name == "Group") {
tf = pg.textFrames.everyItem().getElements()
app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
for (var j = 0; j < tf.length; j++){
app.findGrepPreferences.findWhat = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
app.changeGrepPreferences.changeTo = "";
tf[j].parentStory.changeGrep()
};
}
};
}
function getTextSearch(f){
app.findTextPreferences = app.changeTextPreferences = app.findChangeTextOptions = null;
app.findChangeTextOptions.properties = {includeHiddenLayers:true, includeLockedLayersForFind:true, includeLockedStoriesForFind:true, includeMasterPages:true}
app.findTextPreferences.findWhat = f;
return app.activeDocument.findText()
}
Copy link to clipboard
Copied
Thanks @rob day this works great and is alot faster but I am getting the error below – although the error didnt show up the first few time i ran it and the script still works?
JavaScript Error!
Error Number: 2
Error String: tf is undefined
Engine: main
File: Path to script
Callout findReplace.jsx
Line: 32
Source: tf[jl.parentStory.changeGrep;
Being able to undo the whole script in one go is a great addition.
Copy link to clipboard
Copied
Hey - I think this might fix it - sorry don't have time to test it properly
// Undo the script if needed
app.doScript(searchCallout, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Search Callout');
function searchCallout() {
var res = getTextSearch("CALLOUT");
var pg, tf;
for (var i = 0; i < res.length; i++) {
// Check if the result has parent text frames and if its parent is a group
if (res[i].parentTextFrames.length > 0) {
pg = res[i].parentTextFrames[0].parent;
if (pg.constructor.name == "Group") {
tf = pg.textFrames.everyItem().getElements();
if (tf.length > 0) {
app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
for (var j = 0; j < tf.length; j++) {
app.findGrepPreferences.findWhat = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
app.changeGrepPreferences.changeTo = "";
tf[j].parentStory.changeGrep();
}
}
}
}
}
}
function getTextSearch(f) {
app.findTextPreferences = app.changeTextPreferences = app.findChangeTextOptions = null;
app.findChangeTextOptions.properties = { includeHiddenLayers: true, includeLockedLayersForFind: true, includeLockedStoriesForFind: true, includeMasterPages: true };
app.findTextPreferences.findWhat = f;
return app.activeDocument.findText();
}
Copy link to clipboard
Copied
If Eugene’s fix doesn’t work, can you share the document that throws the error?
Copy link to clipboard
Copied
Thanks @Eugene Tyson @rob day This works and I have marked it as the correct answer.