【问题标题】:Extendscript batch save PDFsExtendscript 批量保存 PDF
【发布时间】:2014-05-21 11:12:50
【问题描述】:

我需要一点帮助。我想要一个脚本,将所有子文件夹中的所有 AI 文件转换为 PDF 并将它们放在根目录的单个文件夹中,我希望它跳过任何名为“资源”的文件夹。我找到了一个脚本,它主要完成我需要它做的事情,并且我已经对其进行了进一步修改以满足我们的确切需求。不过,我正在努力解决其中的两个部分。具体来说,第 33 行和第 80 行是我现在的问题。

#target illustrator

main();

//
function main() {

          var topLevel = Folder.selectDialog( 'Select the top level folder to start converting AI files to PDFX files' );

          var proofFolder = new Folder( topLevel + '/Proofs2/');
                    proofFolder.create();


          if ( topLevel != null ) {

                    processDocs( recursiveFolders( topLevel, /\.ai$/i ), getPDFOptions() );

          };

};

//
function processDocs( aiFiles, opts ) {

          var i, baseName, doc, saveFile;

          for ( i = 0; i < aiFiles.length; i++ ) {

                    doc = app.open( aiFiles[i] );

                    baseName = decodeURI( doc.name.match( /(.*)\.[^\.]+$/ )[1] );

//这是第 33 行// saveFile = File(proofFolder.path + baseName + '.pdf');

                    doc.saveAs( saveFile, opts );

                    doc.close( SaveOptions.DONOTSAVECHANGES );

          };

};

//
function getPDFOptions() {

    var pdfSaveOpts = new PDFSaveOptions();

    pdfSaveOpts.acrobatLayers = true;
    pdfSaveOpts.colorBars = false;
    pdfSaveOpts.colorCompression = CompressionQuality.AUTOMATICJPEGHIGH;
    pdfSaveOpts.compressArt = true;
    pdfSaveOpts.embedICCProfile = true;
    pdfSaveOpts.enablePlainText = true;
    pdfSaveOpts.generateThumbnails = true;
    pdfSaveOpts.optimization = true;
    pdfSaveOpts.pageInformation = true;
    pdfSaveOpts.preserveEditability = true;
    pdfSaveOpts.pDFXStandard = PDFXStandard.PDFX1A2001;
    pdfSaveOpts.viewAfterSaving = false;


    return pdfSaveOpts;

};

//
function recursiveFolders( fold, exp ) {

          var fileList = Array(); // Our matching files…

          getFiles( fold, exp, fileList );

          return fileList;

};

//
function getFiles( fold, exp, array ) {

//这是第 80 行 // if (Folder.name !== /\Resources$/){

          var i, temp;

          temp = Folder( fold ).getFiles(); // All files and folders…

          for ( i = 0; i < temp.length; i++ ) {

                    if ( temp[i] instanceof File && RegExp( exp ).test( temp[i].fsName ) ){

                              array.push( temp[i] );

                    };


                    if ( temp[i] instanceof Folder ) {

                              getFiles( temp[i].fsName, exp, array );

                    };

          };

          return array;

        };

};

【问题讨论】:

  • Errrr...没有行号,使得第 33 行和第 80 行很难找到...
  • 如何将代码与行号一起粘贴?
  • 如果在 Linux 上,执行“cat -n yourfile > file2paste”并粘贴。否则,请在有问题的代码中进行注释。
  • 好的,我在这两行中添加了注释。
  • 根据 proofFolder.path 的值,您可能需要在它和文件名之间使用分隔符,例如 Mac OSX 上的“/”或 Windows 中的第 33 行的“\”。或者尝试将其硬编码为“fred.pdf”现在看看是否有效。

标签: javascript directory adobe-illustrator extendscript


【解决方案1】:

第 33 行:

Javascript 中的变量对于定义它们的函数是本地的。也就是说,如果你尝试

a();

function a()
{
    var a1 = 1;
    b();
}

function b()
{
    alert ("var a1 = "+a1);
}

你会发现a1 在函数b 内部是undefined。两种常见的解决方案(可能还有更多)是将变量放在函数定义中:

b(a1);
..
function b (myVarArg)
{
    alert ("var a1 = "+myVarArg);
}

或 -- 简单但容易出错 -- 在程序最顶部 main 之前声明变量:

var a1;

这是一个快速简单的解决方案;该变量将在所有函数中“可见”,并且在任何地方分配一个新值都可以。它“有点容易出错”,因为具有相同名称的 local 变量(在函数内定义)将有效地“隐藏”原始。因此,如果不小心使用,您最终可能会得到这样的结构:

var a1 = 1;
a();
alert ("var a1 = "+a1);

function a()
{
    var a1 = 2;
    b();
    alert ("var a1 = "+a1);
}

function b()
{
    alert ("var a1 = "+a1);
}

幸运的是,您使用清晰、描述性的变量名会帮助您。


第 80 行

if (Folder.name !== /\Resources$/) ...

不当使用正确的 Javascript 语法☺

  1. !== 不是有效的比较运算符。使用==(测试是否相等)或===(测试是否非常相等——请参阅Does it matter which equals operator (== vs ===) I use in JavaScript comparisons? 了解一些重要细节)和!= 测试是否不相等。

  2. 您可以将字符串与另一个字符串进行比较,但不能与 GREP 表达式进行比较。符号 /.../ 保留用于 GREP 表达式,对于您需要 "..."'...' 的字符串。 一些函数确实可以接受 GREP 和常规字符串,但这个测试不接受。

  3. 要在比较中使用 GREP 字符串,请使用字符串函数 match

    if (Folder.name.match(/\\Resources$/)) ...
    

    注意双端括号(一个用于封闭的if,一个用于match 函数)和double 反斜杠,因为反斜杠是GREP 字符串中的“特殊字符”。 (它在 Javascript 字符串中也很特殊,所以无论你打算使用什么,它都可能被称为不正确的语法 #4。)


这会解决所有问题并使其正常工作吗?

未经测试。如果没有这些更正,您的脚本将无法运行。有了它们,它至少应该做一些事情(如果你的逻辑是合理的,你的路径存在,你的输入是正确的并且你的 Illustrator 常量有正确的名称)。

暂时,我不敢说它应该可以工作。


附录

花了一些调试才发现真正的问题.. 调试策略:在可疑行之前插入alert,显示重要变量的值。运行,等待结果,冲洗,重复。

首先:将array 作为函数参数传递似乎不是一个好主意。我发现数组被一遍又一遍地复制到自己身上(或者也许这只是我修补的结果)。我认为更安全的方法是让getFiles 返回 only 新添加的文件,并将结果连接到它的 current 版本(即,从你从哪里调用getFiles,不管它是否是getFiles的前一个化身)。请参阅(我认为!)我在上面修改“本地”、“全局”和/或“通过”变量的警告。

function getMyFiles( fold, exp ) {
//This is line 80//
    if (!fold.name.match (/(\\|\/)Resources$/)) {

          var i, temp;
          var array = [];

          temp = Folder( fold ).getFiles(); // All files and folders…

          for ( i = 0; i < temp.length; i++ ) {

                    if ( temp[i] instanceof File && RegExp( exp ).test( temp[i].fsName ) ){
                        //  alert ('path '+fold+', adding '+temp[i]);
                              array.push( temp[i] );

                    };


                    if ( temp[i] instanceof Folder ) {

                             array = array.concat (getFiles( temp[i], exp ));

                    };

          };
        //  alert ('array is '+array.length+'\n'+array.join('\n'));

          return array;

        };
        return [];
};

您可以像以前一样在原来的 recursiveFolders 函数中调用此函数,但这次不要传递数组而是 分配它:

function recursiveFolders( fold, exp )
{
          var fileList = Array(); // Our matching files…
          fileList = getFiles( fold, exp );
    // alert ('Filelist is '+fileList.length+'\n'+fileList.join ('\n'));
          return fileList;

};

只有当我得到 部分工作时,我才遇到与您相同的错误,根据您的评论“fold.match 不是函数”。这花了一分钟左右的时间。事实证明,Javascript 解析器是正确的。 最初fold 参数是Folder,要获得它的名称,您需要fold.name。但是看看你自己的代码:你在 recursive 调用中使用了参数temp[i].fsName,它是一个String!因此,没有name,因此,错误。

首先,我使用fold.toStringfold 直接转换为always-a-String(适用于文件夹和字符串),但后来我改变主意并使用fold.name 保持一致性,并调用getFiles使用“正确”参数:temp[i] 而不是 temp[i].fsName。现在它似乎起作用了——真的。 (稍微更有信心地说。)

【讨论】:

  • 感谢您花时间给出详细的解释。在得到您的答案之前,我确实将变量设为全局变量并且它有效。我见过人们说这并不总是最好的解决方案,但它确实适用于这种情况,我认为我的脚本足够简单,不会造成问题。对于文件夹名称匹配,我已经输入了正确的语法,但它仍然没有跳过这些文件夹。我把它放错地方了吗?这就是我现在对该行的内容:if (!(Folder.name.match(/\\Resources$/))){
  • 啊——语法是正确的,但前提是“我们现在正在查看Folder.name”不是。文件夹名称此时存储在函数参数fold 中。试试if (fold.name.match ..
  • 使用 (fold.name.match... 会导致“未定义”错误。
  • 对不起,我无法远程调试这个。试试if (fold.match(也许fold 不再是Folder 名称,而只是一个简单的字符串)。
  • 不。现在它说“折叠不是一个函数”。很抱歉很痛苦。
猜你喜欢
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2011-05-28
  • 2021-05-02
  • 2018-09-24
  • 2013-06-29
  • 2019-02-02
相关资源
最近更新 更多