Copy link to clipboard
Copied
As I am working on this catalogue, I am looking for a way to replace a string of text by an item in a given Library that I created.
Context: The purpose is to replace strings of text containing a product "color code" after a data merge (since it isn't very feasible before) by the corresponding formated string of text (ZapfDingbat color bullet + text with style + some text with different style)
As illustrated below, I have a library (on the left) made of each individual color text strings (the ones on the right), and would like to replace the middle ones (100color, 102color, etc) by the corresponding library item
If there is a simpler way to do this (without 3rd party plugin), please feel free to tell me, but I've thought & search about that for long with no success.
Any help on the script or direction that I should take would be welcome. I know a bit of javascript but I am completely new to Adobe scripting.
Oh that's all. The regex I use looks for strings that start and end a paragraph as in
/^\d+color$/
where ^stands for at the beginning of a sentence
and $ the end of this same sentence
replace
findWhat:"^\\d+color$",
with
findWhat:"\\d+color",
And it should be fine.
Copy link to clipboard
Copied
A possible approach :
var main = function() {
var doc = app.properties.activeDocument,
lib, asset, fgp = app.findGrepPreferences.properties, found, n, text, errors = [], str, ip;
if ( !doc ) return;
lib = app.libraries.itemByName ( "colors.indl" );
if ( !lib.isValid || !lib.assets.length ) {
alert("Script needs a \"colors\" library with assets loaded !" );
return;
}
app.findGrepPreferences = null;
app.findGrepPreferences.properties = {
findWhat:"^\\d+color$",
};
found = doc.findGrep();
n = found.length;
while ( n-- ) {
text = found
; str = text.contents
asset = lib.assets.itemByName ( str );
if ( !asset.isValid ) {
errors.push ( "Couldn't find "+ str +" asset" );
continue;
}
ip = text.insertionPoints[0];
text.contents = "";
asset.placeAsset ( text );
}
app.findGrepPreferences.properties = fgp;
alert( errors.length ? "Some errors occured:\r"+errors.join("\r" ) : "All went fine" );
}
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );
HTH
Loic
Copy link to clipboard
Copied
Thank you SO much Loic.
That worked perfectly for a single item, except if I have more than one color code in a paragraph the script alerts "All went fine" but it doesn't replace any of them.
As a test I tried:
- Making large paragraphs / text frames
- Running the script first with just a single "100color", then after it performed properly, adding a second piece of text "360color" for example, but nothing happens after that first change.
Damn I feel I am so close (well, YOU are 😉
I'm trying to look at the code but can't find the bit that wouldn't allow it to run each time until it went through the whole color list. If that helps, the max number of color number is 999, we don't have colors past that (maybe a for loop instead of while ?).
Note that there are colors that are not yet matched by an item (for example, there isn't any "101color" neither in my library nor my document). Maybe it stops for that reason ?
Thanks so much again for your help nonetheless.
Copy link to clipboard
Copied
Hi,
The script logic is quite simple. It looks at strings with a specific pattern such as [number one of several times from 1 to infinity] then once this string extracted, look at the library if there is any asset which name matches the string.
If the latter, then the asset is placed instead of text.
But I also included some find grep options in order to deal with locked and hidden layers.
var main = function() {
var doc = app.properties.activeDocument,
lib, asset, fgp = app.findGrepPreferences.properties, found, n, text, errors = [], str, ip,
fcgo = app.findChangeGrepOptions.properties;
if ( !doc ) return;
lib = app.libraries.itemByName ( "colors.indl" );
if ( !lib.isValid || !lib.assets.length ) {
alert("Script needs a \"colors\" library with assets loaded !" );
return;
}
app.findGrepPreferences = null;
app.findGrepPreferences.properties = {
findWhat:"^\\d+color$",
};
app.findChangeGrepOptions.properties = {
includeHiddenLayers:true,
includeLockedLayersForFind:true,
includeLockedStoriesForFind:true,
includeMasterPages:true,
};
found = doc.findGrep();
n = found.length;
while ( n-- ) {
text = found
; str = text.contents
asset = lib.assets.itemByName ( str );
if ( !asset.isValid ) {
errors.push ( "Couldn't find "+ str +" asset" );
continue;
}
ip = text.insertionPoints[0];
text.contents = "";
asset.placeAsset ( text );
}
app.findGrepPreferences.properties = fgp;
app.findChangeGrepOptions.properties = fcgo;
alert( errors.length ? "Some errors occured:\r"+errors.join("\r" ) : "All went fine" );
}
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );
Loic
Copy link to clipboard
Copied
I believe the issue is that it can't perform the placement if there is any other string of text inside a text frame apart from the color code it looks for. I tested with various items (including for example a tab or a single space before or after the "XXXcolor" string) and whenever there is some other text (or a 2nd color code), the action does not perform:
EDIT: Any string of text EXCEPT a return. When placed on 2 different lines on a single frame, the script executes properly for both.
Investigating further myself! Thanks for your help Loic, if you identify where the problem could be, feel free to let me know 😉
Copy link to clipboard
Copied
Hi there — I don’t one to run before I can walk but I am struggling to data merge images from a CC Library, and this script sounds like a possible answer. However, I wouldn’t know how to structure the regular expression? The path to the library (and a sample image name) is, for example:
CC Libraries: Schedule Visuals/Direction (1x5) - Suspended rod (SR)
Any help appreciated…
Copy link to clipboard
Copied
davidl86075527 wrote
Hi there — I don’t one to run before I can walk but I am struggling to data merge images from a CC Library, and this script sounds like a possible answer. …
Unfortunately there is no way to access CC Libraries by document object model (DOM) commands by scripting.
So the answer is no, it cannot be done. You have to do a InDesign library file with your assets to use the script.
Regards,
Uwe
Copy link to clipboard
Copied
Thanks, Uwe – I was afraid of this … Shame the strength of the library can’t be paired with data merge. Hey ho!
Regards
David
Copy link to clipboard
Copied
Oh that's all. The regex I use looks for strings that start and end a paragraph as in
/^\d+color$/
where ^stands for at the beginning of a sentence
and $ the end of this same sentence
replace
findWhat:"^\\d+color$",
with
findWhat:"\\d+color",
And it should be fine.
Copy link to clipboard
Copied
I don't know what to say. YOU ARE AWESOME ! thank you so much for this.
Copy link to clipboard
Copied
Loic is a real gentleman!