Copy link to clipboard
Copied
Hi,
Can somebody tell me how to get the conditional text name (if there is) of the insertion point.
Something like.
CondintionalTextName=insertionpoint.conditional.name
but written in Java Script instead of Gibberish!
1 Correct answer
Hi Trevor,
Probably sth like:
ConditionalTextName=insertionpoint.appliedConditions[0].name;
Note that appliedConditions is an array, because multiple conditions can be applied to the same text.
EDIT—To avoid errors with non-conditional text:
var conds = myText.appliedConditions;
var condName = conds.length ? conds[0].name : '[No Condition]';
@+
Marc
Copy link to clipboard
Copied
Hi Trevor,
Probably sth like:
ConditionalTextName=insertionpoint.appliedConditions[0].name;
Note that appliedConditions is an array, because multiple conditions can be applied to the same text.
EDIT—To avoid errors with non-conditional text:
var conds = myText.appliedConditions;
var condName = conds.length ? conds[0].name : '[No Condition]';
@+
Marc
Copy link to clipboard
Copied
Hi Marc,
Thanks for your answer, sorry for the long delay in my response . I had a couple of things to iron out (like how to return all the conditions for all the selected texts and other simple issues that I'm too embarrassed to write) and I have been exceptinaly busy with other things.
This is the code that I came up with based on your answer.
try {
var cl=app.selection[0];
var w = new Window ("dialog","");
array = [];
for (var j = 0; cl.length>j; j++){
var conds=app.selection[0].characters.appliedConditions;
var curletter=app.selection[0].characters.contents;
for (var i = 0; conds.length > (i); i++) {
array.push ("Letter "+(j+1)+" \""+curletter+"\""+"\tCondition "+i+" name is \t"+conds.name+" ");}
if (conds.length==0) {
var condName = conds.length ? conds[0].name : '[No Condition]';
array.push ("Letter "+(j+1)+" \""+curletter+"\""+"\tCondition "+i+" name is \t"+condName)
}
}
if (j==0){var i=0;}
array.push ("\r\tSelected text \""+app.selection[0].characters.itemByRange(0,-1).contents+"\"");
array.push ("\tIn total "+j+ " characters");
alert_scroll ("Conditional Texts Names of Selectect Characters", array,);
function alert_scroll (title, input) // string, string/array
{
// if input is an array, convert it to a string
if (input instanceof Array)
input = input.join ("\r");
var w = new Window ("dialog", title);
var list = w.add ("edittext", undefined, input, {multiline: true, scrolling: true});
// the list should not be bigger than the maximum possible height of the window
list.maximumSize.height = w.maximumSize.height - 300;
list.minimumSize.width = 450;
w.add ("button", undefined, "Close", {name: "ok"});
w.show ();
}}
catch (cl)
{
alert("First Select Text!");
}
It produces the following result:
I would like to know two more things about conditionals texts.
1) I would like to add a line at the bottom stating how many DIFFERENT conditions are used throughout all the selected texts. In the above example including [no condition] a total of 8 conditions are used 1) AppleScript 2) blue 3) Green 4) Nikud 5) Red 6) Violet 7) Yellow 8) No condition
2) To apply the "Red" condition to the selected text I would use
app.selection[0].applyConditions ( app.activeDocument.conditions.item("Red", true), true);
I can't figure out how to make the selection have no conditions
app.selection[0].applyConditions ( app.activeDocument.conditions.item("[Unconditional]", true), true); Does not work.
Any Ideas?
Copy link to clipboard
Copied
Trevor, I don't know, if it helps after such a long time ...
app.selection[0].applyConditions ( [], true );
Tobias
Copy link to clipboard
Copied
Tobias ,thanks
I appreciate a thought regardless of the time passed.
I did figure out some time ago that app.selection[0].applyConditions ( ["none"], true ); works but I guess the app.selection[0].applyConditions ( [], true ); is shorter
I do have another question.
How does one make the a condition is removed from a selection.
For example:
A selection has any combination of the conditions "Bold" "Red" "Apple" and "Fred"
I want to remove from my selection the "Red" condition but keep any other conditions there.
I do not want to affect the "Red" condition that is outside my selection.
any ideas
Trevor
Copy link to clipboard
Copied
Trevor!
~ Trevor ~ wrote:
I did figure out some time ago that app.selection[0].applyConditions ( ["none"], true ); works but I guess the app.selection[0].applyConditions ( [], true ); is shorter
The best of it: It's language independant!
~ Trevor ~ wrote:
How does one make the a condition is removed from a selection.
Thank'd be nice to know, if someone has a better method. Up to now I'd use something like:
#target InDesign
var theSelection = app.selection[0]
theSelection.applyConditions(removeCondition(theSelection.appliedConditions, 'Red'), true);
function removeCondition (condObject, condName) {
newCondObject = [];
for (var i = 0; i < condObject.length; i++) {
if (condObject.name != condName ) newCondObject.push(condObject);
}
return newCondObject;
}
Tobias
Copy link to clipboard
Copied
Sorry, this is a bit more logical:
#target InDesign
var theSelection = app.selection[0];
removeCondition(theSelection, 'Red');
function removeCondition (condObject, condName) {
condObject = theSelection.appliedConditions;
newCondObject = [];
for (var i = 0; i < condObject.length; i++) {
if (condObject.name != condName ) newCondObject.push(condObject);
}
theSelection.applyConditions(newCondObject, true);
return null;
}
Tobias
Copy link to clipboard
Copied
Thanks
This method is only efective if the entire selection should become the same
See the screenshot
(1) the original line
(2) the line after selecting the whole line and running the script
(3) & (4) after running the script on partial selections
to loop though each character is not practical.
A solution might be to use menu action calls, i.e. check if the condition exist in the selection (using grep preference) then if found apply the "Red" condition twice through menu call.
I shall give this a go but was hoping for a better solution
Regards
Trevor
Copy link to clipboard
Copied
You can a grep to find all occurences and run my script snippet on every found character.
Tobias
Copy link to clipboard
Copied
No luck so far
1) Can't search for presence of a particular condition can only search for an entire array of conditions
in other word if I search for "Red" I will only find text which has just the "Red" condition applied to it but if it also has the "Apple" condition applied to it the it won't find it.
2) Don't now how to invoke a particular condition with a menu action. Oh well
By the way "None" it not necessarily a localized name see Marc's comment here http://forums.adobe.com/message/4455559#4455559
But [] is shorter
Copy link to clipboard
Copied
Hi Trevor,
indeed, the InDesign search fails on this demand. Hm.
Alternatively you have to build your own search function for conditions (sorry, a bit in a hurry):
#target InDesign
var theDoc = app.activeDocument;
var theSelection = app.selection[0];
var allRanges = theSelection.textStyleRanges;
// collect conditioned ranges
var conditionedRanges = [];
for (m=0;m<allRanges.length;m++) {
if ( allRanges
.appliedConditions.length > 0 ) { conditionedRanges.push(allRanges
); }
}
// remove single condition
for (n=0;n<conditionedRanges.length;n++) {
removeCondition(conditionedRanges
, 'Red'); }
function removeCondition (selectedObject, condName) {
var condObject = selectedObject.appliedConditions;
newCondObject = [];
for (var i = 0; i < condObject.length; i++) {
if (condObject.name != condName ) newCondObject.push(condObject);
}
selectedObject.applyConditions(newCondObject, true);
return null;
}
I think the textStyleRanges are the best choice for this demand, because they contain the larged cluster of characters with similar formating.
Tobias
Copy link to clipboard
Copied
Hi Tobias,
I deleted the last post that I wrote because the changes I made in your code were rubbish
Bellow is the "correct" code
Has 2 changes from yours besides the doscript.
your script didn't work because changes to text objects must me made in reverse order (change #1 VERY IMPORTANT)
I also added a check that only if the text range had a "Red" condition the conditions are applied (less changes to the document)
Once again thanks for all your efforts and I'll let you know if I get a better way.
Trevor
#target InDesign
app.scriptPreferences.enableRedraw =0;
app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Red Condition");
function main(){
var theDoc = app.activeDocument;
var theSelection = app.selection[0];
var allRanges=[];
var allRanges = theSelection.textStyleRanges;
// collect conditioned ranges
conditionedRanges = [];
for (var m=0;m<allRanges.length;m++) {
if (allRanges
.appliedConditions.length > 0 ) { conditionedRanges.push(allRanges
); }
}
// remove single condition
for (var n=conditionedRanges.length-1;n>=0; n--) // Have to go backwards!!!
{
removeCondition(conditionedRanges
, 'Red') }
}
function removeCondition (selectedObject, condName) {
var hasRedCondition=0;
var condObject = selectedObject.appliedConditions;
var newCondObject = [];
for (var i = 0; i < condObject.length; i++)
{
(condObject.name != condName) ? newCondObject.push(condObject) : hasRedCondition=1;
}
if (hasRedCondition==1) selectedObject.applyConditions(newCondObject, true) // This way the condtions are only changed if there is a "Red" condtion
return null;
}
Copy link to clipboard
Copied
Hi Trevor,
I gave you no bullet proof rock solid script, but only some quick thoughts for a solution. I like your changes. (Personally I'd change a bit more ... see below ...) I'm glad you now found your way through the conditions jungle.
In my eyes scripting conditions is a bit tricky and not as self explanatory. The fact that you could not find a text, that has multiple conditions applied, via a single condition search in an easy way makes it even more tricky. (I'd say, that's worth a feature request ...)
I optimized your code a bit:
#target InDesign
app.scriptPreferences.enableRedraw = 0;
app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Red Condition");
function main() {
var theCondition = 'Red';
var theSelection = app.selection[0];
var allRanges = [];
var theRange = '';
var allRanges = theSelection.textStyleRanges;
for ( var m = 0; m < allRanges.length; m++ ) {
theRange = allRanges
; if ( theRange.appliedConditions.length > 0 ) {
for ( var n = theRange.length-1; n >= 0; n-- ) {
removeCondition(theRange, theCondition); // remove condition
}
}
}
}
function removeCondition ( selectedObject, condName ) {
var hasCondition = false;
var condObject = selectedObject.appliedConditions;
var newCondObject = [];
for ( var i = 0; i < condObject.length; i++ ) {
(condObject.name != condName) ? newCondObject.push(condObject) : hasCondition = true;
}
if ( hasCondition ) selectedObject.applyConditions( newCondObject, true ); // condtions are only changed if there is a "Red" condtion
return null;
}
Some more ideas for you:
- To increase readability take some parts of the for - if - for - construction in main() and build further functions with them.
- You can extend the script's functionality by adding a drop down dialog window so the user can choose the condition by name.
- You can widen the selection part with some checks to focus the functionality on selections that make sense in this context (character, paragraph, text, ...).
Tobias
Copy link to clipboard
Copied
Very good Tobias
One a page document with a lot of conditions applied your optimized code took about 5.5 seconds as apposed to the about 17.5 that my one took!!
Note
Still not bulletproof
The line in the optimized code
for ( var m = 0; m < allRanges.length; m++ ) {
need to be changed to
for ( var m = allRanges.length-1 ; m >=0; m-- ) {
without the change does not work properly
Please edit your code post above and I will delete this note on changing the code.
tobias.wantzen wrote:
- You can extend the script's functionality by adding a drop down dialog window so the user can choose the condition by name.
The purpose ot the script is to be able to delete a condition as a function within another script without a user interface.
For a user to perform the task he just goes to the conditional text panel and unticks the Red condition Easy and Instant!
That's why I thought to use menu action, but it doesn't seem possible I would like to be proven wrong on this point !!
My Idea to use a search was silly as the condition can be taken off the whole selection.
Your right about the feature request it is really dumb that one can't search for a particlar condition that is part of an array of conditions.
Trevor
Copy link to clipboard
Copied
5.5 to 17.5 sec.? Nice improvement.
Corrected Script:
#target InDesign
app.scriptPreferences.enableRedraw = 0;
app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Red Condition");
function main() {
var theCondition = 'Red';
var theSelection = app.selection[0];
var allRanges = [];
var theRange = '';
var allRanges = theSelection.textStyleRanges;
for ( var m = allRanges.length-1; m >= 0; m-- ) {
theRange = allRanges
; if ( theRange.appliedConditions.length > 0 ) {
for ( var n = theRange.length-1; n >= 0; n-- ) {
removeCondition(theRange, theCondition); // remove condition
}
}
}
}
function removeCondition ( selectedObject, condName ) {
var hasCondition = false;
var condObject = selectedObject.appliedConditions;
var newCondObject = [];
for ( var i = 0; i < condObject.length; i++ ) {
(condObject.name != condName) ? newCondObject.push(condObject) : hasCondition = true;
}
if ( hasCondition ) selectedObject.applyConditions( newCondObject, true ); // condtions are only changed if there is a "Red" condtion
return null;
}
(I can only edit my post so long as no one has answered to it ...)
I didn't get the point of your menu action suggestion: What do you want to achieve with it? Can you verbose your idea?
Tobias
Copy link to clipboard
Copied
Sorry, I didn't know that limitation to the Edit, I see there is some logic to that.
You meant to say
"17.5 to 5.5 sec.? Nice improvement"
Sure is.
Regarding the menu actions I meant as follows
app.menuActions.item("$ID/#CondTextUI_PanelName").invoke();
opens the menu panel
The text is already selected
If one clicks on the box to the left of the word Red then the Red condition will be applied to the entire selection (providing it wasn't already applied to the whole selection)
Now that it has been applied to the whole selection if one clicks on that box a second time it gets rid of the Red condition from the selection
note the Red / Cyan by the letters E25 has now gone.
The problem is that I don't think there's a way of invoking this clicking action with a menuaction.
In other words there does not seem to be away of simulating the clicking of the box to the left of the word Red.
No equivalent of
app.menuActions.item("$ID/#CondText_Item_Red").invoke();
If there was the the scipt could be speed up very considerably.
Hope it's clear what I meant
Trevor
Copy link to clipboard
Copied
Hi Trevor,
maybe this is a job for UI scripting of MacOS. But in my knowledge you could only do this with AppleScript:
http://www.mactech.com/articles/mactech/Vol.21/21.06/UserInterfaceScripting/index.html
http://www.macosxautomation.com/applescript/uiscripting/index.html
You could try to work out the correct AppleScript code and integrate it into JS.
You can doScript that like:
var chs="tell application \"finder\"\r";
chs+="activate\r"
chs+="set myPath to (choose file with prompt \"Choose\")\r";
chs+="set myPath to POSIX path of myPath as text\r"
chs+="return myPath\r"
chs+="end tell";
var myResults = app.doScript(chs,ScriptLanguage.APPLESCRIPT_LANGUA GE);
alert( myResults );
But personally I'd avoid using UI scripting. It's not platform independant and I'm not sure, if it's even quicker ...
Tobias
Copy link to clipboard
Copied
Having a windows system I also avoid Apple Script
Thanks for all your effort, best left as is.
Trevor
Copy link to clipboard
Copied
Well Tobias I did warn you last week
Trevor wrote:
You shall be hearing from me soon !
I used Marc's script (slightly adapted) http://forums.adobe.com/message/4502873#4502873 for this problem and came up with Interesting results.
On a real life 36 page document with 4 conditions not including unconditional, with approximately 180 occurrences of "Red" and a total of about 420 conditional occurrences in total your script took approximately 3037.674 Seconds, Just over 50 minutes. The following script to approximately .53 of a second.
That's an increase in speed of about 5730 times !!! not bad
The weakness of your script is that it if affected by all changes in formats i.e. bold, italics, font and any thing else. That slows it down considerably.
My script also has an Archimedes heal. If there are more than about 13 different conditions it starts getting significantly slower at a square rate.
On one page tests the difference is much smaller but still very significant (depending on the contents of the page)
Regards
Trevor
#target indesign
app.scriptPreferences.enableRedraw =0;
startTime = new Date().getTime();
app.doScript("TrevorsBasedOnMarcs()", ScriptLanguage.javascript, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "Remove Condtion by Grep");
alert ((new Date().getTime()-startTime)/1000+" seconds");
function TrevorsBasedOnMarcs ()
{
try {
var theCondition = [(app.activeDocument.conditions.item("Red"))];
var theSelection = app.selection[0];
var myOtherConditions =[]
var myConditions=app.activeDocument.conditions;
var m=0
for(var n=0;n<myConditions.length;n++)
{
if (myConditions
!=theCondition) {
myOtherConditions
=myConditions ; m++
}
}
var myConditionCombos=[];
grepFindCondition=[];
(myConditionCombos= arrayParts(myOtherConditions));
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.appliedConditions=theCondition;
app.changeGrepPreferences.appliedConditions=[];
try {theSelection.changeGrep()} catch (noFind) {}
for (var x=0; x<myConditionCombos.length;x++)
{
try
{
app.findGrepPreferences.appliedConditions= (myConditionCombos
.concat (theCondition)); app.changeGrepPreferences.appliedConditions=myConditionCombos
; theSelection.changeGrep();
} catch(noFind) {}
}
} catch (noConds) {}
}
function arrayParts(/*arr*/a, r,i,j,t,s,p) // by Marc Auret
// -------------------------------------
// Note: a is supposed to contain unique items
// [if necessary, apply a makeUnique routine first]
{
if(! (i = Math.pow(2,a.length)-1) ){ return null; }
(r=[]).toString = function(){return this.join('\t');};
while(i--)
{
r = t = [];
s = (1+i).toString(2);
p = (j=s.length) - 1;
while( j-- ) '1'==s
&& t[t.length]=a[p-j]; }
return r;
}
Copy link to clipboard
Copied
Hi Trevor,
Very nice!
I'm working a lot with Conditions!
This amazing script is totally beyond my current [JS] understanding but I'm studying it with a great interest!
How could it be modified to deal with the "entire document", not only a text selection?
Thank you in advance !
(^/)
Copy link to clipboard
Copied
Obi-wan,
change line 12 to
var theSelection = app.activeDocument;
Tobias
Copy link to clipboard
Copied
Oups! Of course!
Thanks a lot Tobias!
(^/)
Copy link to clipboard
Copied
Hi,
I want find the grep of "[\l\u]+-" and want to find and apply the condition text "Red", is this possible by script?
thanks in advance.
by
hasvi

