Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Script for show or hide conditional text in InDesign

Community Beginner ,
Feb 10, 2023 Feb 10, 2023

Hello everyone

I have a document that use a conditional text, and i need check how the text stay with or without the conditional, in many pages, today i do this showing and hiding the eye in conditional text panel, so, i am trying write a code for atutomate this task.

 

I am yet in begin

var delay = 50;
var stopCheck = false;

while (stopCheck == false){
    
    if (app.activeDocument.conditions.item("condition_name").visible == true) {
        
        app.activeDocument.conditions.item("condition_name").visible = false;
         $.sleep(delay);
         
        } else {
            app.activeDocument.conditions.item("condition_name").visible = true;
             $.sleep(delay);
             
             }
        
    }

 

the code worked, I know this because i see the eye in the panel changing, but in the document the text do not hide or show, I understand that InDesign freeze the view, while the script runs.

 

I try too use the invoke of menuActions, but the result is same

 

app.menuActions.itemByID(133136).invoke() // Hide
app.menuActions.itemByID(133135).invoke() // Show

 

somebody knows how i can resolve, or the reason for this

grateful for help

TOPICS
How to , Scripting
1.8K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Feb 10, 2023 Feb 10, 2023

Hi @cleitongoncalves and @brian_p_dts I actually couldn't get anything to work. In Illustrator we can do "app.redraw()" but Indesign doesn't seem to have that.

 

The best I could do is to set up an IdleTask, but the problem with that is that is the timing is unpredictable and sometimes hangs for long periods when (presumably) another task takes precedence. I hope an expert can tell us how to make the event fire with predictable timing.

- Mark

 

 

 

 

/**
 * Toggle conditional text in idle task.
...
Translate
Community Expert ,
Feb 10, 2023 Feb 10, 2023

Try adding app.activeDocument.recompose() at the end. Conditional text can be laggy/buggy

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 10, 2023 Feb 10, 2023

Hi @cleitongoncalves and @brian_p_dts I actually couldn't get anything to work. In Illustrator we can do "app.redraw()" but Indesign doesn't seem to have that.

 

The best I could do is to set up an IdleTask, but the problem with that is that is the timing is unpredictable and sometimes hangs for long periods when (presumably) another task takes precedence. I hope an expert can tell us how to make the event fire with predictable timing.

- Mark

 

 

 

 

/**
 * Toggle conditional text in idle task.
 * The aim is to get Indesign to redraw,
 * like in Illustrator you have "app.redraw()".
 * Note that due to this using idle tasks, the
 * timing is unpredictable, and often *terrible*.
 * Also none of the following worked for me:
 *   app.activeDocument.recompose();
 *   app.menuActions.itemByName("$ID/Recompose all stories").invoke();
 *   app.scriptMenuActions.itemByID(318).invoke(); // force redraw menu
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/script-for-show-or-hide-conditional-text-in-indesign/m-p/13570934
 */

//@targetengine 'toggler'

// settings
var conditionName = 'condition_name',
    maxCount = 10,
    delay = 500;

// internal vars
var myTaskName = 'myIdleTask';

if (app.idleTasks.itemByName(myTaskName).isValid)
    stopToggler();
else
    startToggler();


function startToggler() {

    alert('Starting ' + maxCount + ' toggles.');
    app.idleTasks.add({ name: myTaskName, sleep: delay })
        .addEventListener(IdleEvent.ON_IDLE, (function (counter) {
            return function () {
                if (--counter < 0)
                    stopToggler();
                else
                    app.activeDocument.conditions.item(conditionName).visible = !app.activeDocument.conditions.item(conditionName).visible;
            }
        })(maxCount));

};

function stopToggler() {
    app.idleTasks.itemByName("myIdleTask").remove();
    alert('Stopped');
};

 

 

 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 10, 2023 Feb 10, 2023

@m1b We do have recompose. I'm actually working on a doc/script for conditional text right now, and this works fine. I see the text disappearring and reappearing when running it. 

var main = function()  {
    var doc = app.activeDocument;
    var cons = doc.conditions;
    var conName = "RPS_Staff";
    var con = cons.itemByName(conName);
    if (con.visible) {
        con.visible = false;
        doc.recompose();
    } 
    else {
        con.visible = true;
        doc.recompose();
    }
}

main();

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 10, 2023 Feb 10, 2023

Thanks @brian_p_dts, but in my testing (ID 18.1 MacOS 13.2) recompose doesn't work. I believe this is because recompose has nothing to do with redrawing, but serves to re-apply the paragraph composer(s) to the text object(s), which I'd guess happens automatically when the app redraws.

 

Your script works perfectly because Indesign does redraw when the script ends. And when I remove the two recompose calls from your script, it still works fine, because they don't do anything there (but in a longer script you may still require them for other reasons, of course.)

 

The difference between @cleitongoncalves and your requirements is that @cleitongoncalves needs the redraw to happen while the script is still running.

 

(I might be wrong—I'm just learning this stuff!)

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 10, 2023 Feb 10, 2023

No I think you're 100% right. I just woefully misread everything 🙂

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 10, 2023 Feb 10, 2023

By the way, I tried lots of things relating to the document's layoutWindow to force a redraw, but nothing I tried worked. Toggling the presentation mode actually causes the window to redraw, but not the window's contents! I also made sure I used

app.scriptPreferences.enableRedraw = true;
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 12, 2023 Feb 12, 2023

Hey folks

first I would like to thank you for your contribution, the tips opened up new possibilities here, I bring the results of the tests I did

Before explaining, better use of conditional text here:

I have been using it to export a pdf for students and teachers, the answers for the teacher are with the conditional text, and i export the pdf for the student with the conditional text hidden.

These responses are in their own text boxes and anchored to the main text.

texto cond.pngexpand image

If there is only text on the page, the .recompose() approach works perfectly, but in some cases the response is a vector, a circle to mark an alternative, which I anchor to the text, and apply the condition to just the anchor character, in these cases recompose() interferes with the visualization of the main text.

 

response anchored.gifexpand image

 

Here if I unanchor the circle, the script does not interfere with the visualization of the main text, but precisely because it is no longer anchored, I lose the function of the conditional.

response no anchored.gifexpand image

 

I'm still doing tests here.

@m1b I was curious about the approach with idleTasks, but I can't get it to work here, the message "The requested action could not be completed because the object no longer exists". appears when run, I could not understand. I am use the ID 18.1

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 12, 2023 Feb 12, 2023

Thanks for the extra info. As for the idleTasks, can you share a small demo file that I can test with? Maybe it's not finding the condition or something. Very hard to know without reproducing the error. - Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 12, 2023 Feb 12, 2023

Oh, I also forgot to ask: are you running Indesign on Windows? I have some answers saying that recompose works (as you say it works for you) but it never refreshes the window for me. I'm running MacOS and I wonder if it is different. - Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 13, 2023 Feb 13, 2023

Of course, it is attached,
in the code I just added the .recompose();

var delay = 50;
var stopCheck = false;

while (stopCheck == false){
    
    if (app.activeDocument.conditions.item("TEACHER").visible == true) {
        app.activeDocument.conditions.item("TEACHER").visible = false;
        $.sleep(delay);
        app.activeDocument.recompose();
         
        } else {
            app.activeDocument.conditions.item("TEACHER").visible = true;
            $.sleep(delay);
            app.activeDocument.recompose();
             
             }
        
    }


and I use Windows

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 13, 2023 Feb 13, 2023

Interesting! That code doesn't work at all on my system. I tried my idleTask script on your demo file and it seemed to work okay. See video attached.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 13, 2023 Feb 13, 2023

I've learned a bit more about Events and I think the idleTasks script might benefit from running on it's own "targetengine" so I've added that to my script above. I'd be interested to see if it worked any better for you.

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 13, 2023 Feb 13, 2023

Really @m1b 

I tested it with //@target-engine 'toggler' at the beginning of the code,
did not work, the following message appears,

Captura de tela 2023-02-13 172400.pngexpand image

is it with // at the beginning of the line?

But it occurred to me to add the #targetengine "session",
and with that, it no longer presented the error "The requested action could not be completed because the object no longer exists", now the code is working.

Even today I'm going to do some more tests to check the conditional intermittency, and understand a little more about idleTasks.

but I'm glad we're making progress. thanks

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 13, 2023 Feb 13, 2023

Oops! that was a typo. I've edited it to be

//@targetengine 'toggler'

Note: you can also use "#targetengine", which is the older way to do it. Either should be fine.

 

Also I think the targetengine name 'toggler' or 'session' isn't important here—it can be any string. But I may be wrong. I don't know much about it yet.

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 13, 2023 Feb 13, 2023

By the way, when I make the delay too short, the event doesn't seem to fire. 500 milliseconds works fairly consistently in my testing.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 13, 2023 Feb 13, 2023
LATEST

Perfect
everything working, I'll keep studying idle tasks, to understand the best way to use it, thanks a lot for your help.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 13, 2023 Feb 13, 2023

I'm just brainstorming 😉 what if you change something in the text - to force InDesign to recompose it - then set the correct value back - like changing PointSize +1pt then -1pt? But not by using Undo. 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines