Search code examples
pythonadobe-indesign

Python InDesign scripting: Get overflowing textbox from preflight for automatic resizing


Thanks to this great answer I was able to figure out how to run a preflight check for my documents using Python and the InDesign script API. Now I wanted to work on automatically adjusting the text size of the overflowing text boxes, but was unable to figure out how to retrieve a TextBox object from the Preflight object.

I referred to the API specification, but all the properties only seem to yield strings which do not uniquely define the TextBoxes, like in this example:

Errors Found (1):

  Text Frame (R=2)

Is there any way to retrieve the violating objects from the Preflight, in order to operate on them later on? I'd be very thankful for additional input on this matter, as I am stuck!


Solution

  • If all you need is to find and to fix the overset errors I'd propose this solution:

    Here is the simple Extendscript to fix the text overset error. It decreases the font size in the all overflowed text frames in active document:

    var doc = app.activeDocument;
    
    var frames = doc.textFrames.everyItem().getElements();
    var f = frames.length
    
    while(f--) {
        var frame = frames[f];
        if (frame.overflows) resize_font(frame)
    }
    
    function resize_font(frame) {
        app.scriptPreferences.enableRedraw = false;
        while (frame.overflows) {
            var texts = frame.parentStory.texts.everyItem().getElements();
            var t = texts.length;
            while(t--) {
                var characters = texts[t].characters.everyItem().getElements();
                var c = characters.length;
                while (c--) characters[c].pointSize = characters[c].pointSize * .99;
            }
        }
        app.scriptPreferences.enableRedraw = true;
    }
    

    You can save it in any folder and run it by the Python script:

    import win32com.client
    
    app = win32com.client.Dispatch('InDesign.Application.CS6')
    doc = app.Open(r'd:\temp\test.indd')
    
    profile = app.PreflightProfiles.Item('Stackoverflow Profile')
    print('Profile name:', profile.name)
    
    process = app.PreflightProcesses.Add(doc, profile)
    process.WaitForProcess()
    errors = process.processResults
    print('Errors:', errors)
    
    if errors[:4] != 'None':
        script = r'd:\temp\fix_overset.jsx'  # <-- here is the script to fix overset
        print('Run script', script)
        app.DoScript(script, 1246973031)     # run the jsx script
    
        # 1246973031 --> ScriptLanguage.JAVASCRIPT
        # https://www.indesignjs.de/extendscriptAPI/indesign-latest/#ScriptLanguage.html
    
        process = app.PreflightProcesses.Add(doc, profile)
        process.WaitForProcess()
        errors = process.processResults
        print('Errors:', errors)             # it should print 'None'
        if errors[:4] == 'None':
            doc.Save()
    
    doc.Close()
    
    input('\nDone... Press <ENTER> to close the window')