javascript Indesign -错误27“堆栈溢出”与app.doScript

e3bfsja2  于 2023-06-20  发布在  Java
关注(0)|答案(1)|浏览(135)

我试图将我的大部分工作任务自动化,但不知何故我被卡住了。
工作的一部分包括将各种照片放入InDesign文档中进行嵌套,并创建要在特殊的自定义机器上打印的PDF。
每张照片都附有一张纸质订单,上面标有5至8位数字不等的订单号,以及包含此订单号和其他信息的条形码。
图像的文件名包含订单号,我必须手动放置它们。
由于这是一个非常耗时的任务,我想我会使用条形码扫描仪输入订单条形码(删除我不需要的信息,只保留订单号),并在照片文件夹中搜索相应的图像,以自动插入它。
为了使它更快,我想不断地重新启动脚本,以便一个接一个地插入它们,但在插入39张图像后,这给了我错误27:堆栈溢出。
有没有办法解决这个错误?如果我不得不重写整个剧本,你建议我怎么做?
这是脚本:

#target "InDesign"
    #targetengine "session"
    if (app.documents.length == 0) {MyImages
        alert ("Open a document first");
        exit ();
        }

//  I've made some research on internet and apparently some user solved the problem increasing the memCache, but it doesn't work in my case

    $.memCache = 9999999999;
    app.scriptPreferences.enableRedraw = false;
    var MyDoc = app.activeDocument;
    MyDoc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.millimeters;
    MyDoc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.millimeters;
    app.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;
    MyDoc.viewPreferences.rulerOrigin = RulerOrigin.PAGE_ORIGIN;
    MyDoc.zeroPoint = [0,0];
    var MyFolder, MyImages, ImgNumber;

//  RestartScript is used to prevent the script from restarting with app.doScript (line 70) if the cancel button is pressed

    var RestartScript = 0;
    var MyPanel = new Window ("dialog", "Enter the barcode");
    var MyText = MyPanel.add ("edittext");
    MyText.preferredSize.width = 150;
    MyText.onChanging = function () {
        MyText.text = MyText.text.replace (/[^0-9]/g, "");

//  This part allows the script to continue automatically once the barcode scanner enters the code which is 15 characters long

        if (MyText.text.length >= 15) {
            BarcodeConversion ();
            MyPanel.close ();
            }
        }

//  The EventListener allows a manual insertion of the image number (if the barcode is not present on the order)

    MyText.addEventListener ("keydown", function (KeyEvent) {
        if (KeyEvent.keyName == "Enter") {
            if (MyText.text != "") {
                ImgNumber = MyText.text;
                MyPanel.close ();
                }
            }
        });

//  The focus is on the edittext for practical purposes

    MyText.active = true;
    var Browse = MyPanel.add ("button", undefined, "Browse");
    Browse.onClick = function () {
        MyFolder = Folder.selectDialog ("Select a folder", " ");
        MyImages = MyFolder.getFiles (/.+\.(?:gif|jpe?g|eps|tiff?|psd|pdf|bmp|png)$/i);
        if (MyImages.length <= 0) {
            alert ("There are no images in this folder");
            return;
            }

//  This is for focusing on the edittext automatically after clicking the browse button, but it doesn't work (I don't know why)

        MyText.active = true;
        }
    var Cancel = MyPanel.add ("button", undefined, "Cancel");
    Cancel.onClick = function () {
        MyPanel.close ();
        }
    MyPanel.show ();
    if (ImgNumber != undefined) {
        Search ();
        }

//  I'm using app.doScript to restart the same script and automatically insert multiple images in a continuous way (I've tried with MyPanel.show() instead of this to reopen the input panel but it doesn't display well)
//  This is what causes the stack overrun error

    if (RestartScript == 1) {
        app.doScript (new File (app.activeScript.parent.fsName + "\\" + app.activeScript.name) ,ScriptLanguage.JAVASCRIPT);
        }

    function BarcodeConversion () {
        if (MyFolder == undefined) {
            alert ("Folder not selected");
            MyText.text = "";
            return;
            }

//  Here I use slice to remove the part of the barcode I don't need, obtaining the order's number

        ImgNumber = MyText.text.slice (4, 12);
        }

    function Search () {

//  In this function I'm placing all the images with the filename who correspond to the order's number in an array (in case I have multiple images with the same number)

        var ImgFound = [];
        for (var a = 0; a < MyImages.length; a++) {
            if (MyImages[a].name.toLowerCase ().indexOf (ImgNumber.toString ()) != -1) {
                ImgFound.push (MyImages[a]);

//  If there are more images with the same number an alert is triggered and the manual selection is done with openDlg (with the * wildcard character as I work on windows )

                if (ImgFound.length > 1) {

//  A sound alert is triggered, but the volume is too low and doesn't work properly on windows 11 (if someone kwow how to do it in a different way, feel free to share the method)

                    beep ();
                    alert ("There are multiple images with the number " + ImgNumber);
                    var ManualSelection = (File (MyFolder + "/*" + ImgNumber + "*")).openDlg ("Place", undefined, true);
                    if (ManualSelection == null) {
                        Reset ();
                        return;
                        }
                    ImgFound = [];
                    for (var b = 0; b < ManualSelection.length; b++) {
                        ImgFound.push (ManualSelection[b]);
                        }
                    break;
                    }
                }
            }

//  Here i place all the images from the array in the current page and center them

        for (var c = 0; c < ImgFound.length; c++) {
            app.activeWindow.activePage.place (ImgFound[c]);
            MyDoc.align (app.activeWindow.activePage.rectangles[0], AlignOptions.VERTICAL_CENTERS, AlignDistributeBounds.PAGE_BOUNDS);
            MyDoc.align (app.activeWindow.activePage.rectangles[0], AlignOptions.HORIZONTAL_CENTERS, AlignDistributeBounds.PAGE_BOUNDS);
            }
        if (ImgFound == 0) {
            alert ("Image " + ImgNumber + " not present");
            }
        Reset ();
        }

    function Reset () {

//  This function serves to reset the variables to avoid conflicts / errors

        ImgNumber = undefined;
        ImgFound = 0;
        RestartScript = 1;
        }
jmo0nnb3

jmo0nnb31#

我会尝试用调色板代替对话。下面是一个简短的工作示例:

#target "InDesign"
#targetengine "session"

var palette = new Window('palette', 'Enter the barcode');

palette.add('statictext', undefined, 'Folder:');
var folder = palette.add('edittext');
folder.text = 'd:\\temp';
folder.characters = 30;

palette.add('statictext', undefined, 'File:');
var file = palette.add('edittext');
file.characters = 30;
file.active = true;

file.onChanging = function() {
    file.text = file.text.replace(/\D/g, '');
}

file.addEventListener('keydown', function(k) {
    if (k.keyName == 'Enter' && file.text != '') {
        place_image(folder.text, file.text);
        file.text = '';
    }
});

palette.addEventListener('keydown', function(k) {
    if (k.keyName === 'Escape') {
        palette.close();  
        // palette = null // for Win CS6
    }
});

palette.show();
// palette.onClose = function() { palette = null } // for Win CS6

//------------------------------------------------------------------
function place_image(folder_name, file_name) {
    var folder = Folder(folder_name);
    var file = File(folder + '/' + file_name + '.jpg');
    if (file.exists) app.activeWindow.activePage.place(file);
}

它会显示一个像这样的调色板:

您可以在第二个字段中输入文件名,按Enter键,它会将给定文件夹中具有此名称的jpeg图像放入您的文档中。
据我所知,它对这个案子很有效。不需要doScript笨拙的技巧。至少在我以这种方式放置了大约一百张图像后,它没有让我出错。
您可以自己添加任何其他功能。

相关问题