Indesign JavaScript Creating Text&书中的博士内超链接 - 速度极慢

时间:2012-03-07 18:37:28

标签: javascript scripting adobe adobe-indesign extendscript

  1. 第一次发帖
  2. 第一次用JavaScript编写,虽然我有其他语言的经验。
  3. 我在Adobe InDesign CS5.5中工作。我在ID Book中有多个文件,每个文件包含不同数量的“章节”。该书包括一个索引文件,主题标题以缩写形式引用章节(例如,“第125章”变成“ch 125 no 3” - 注意“no x”部分是无关紧要的)。我的脚本的目标是创建文档间链接,这些链接将在将ID Book导出到PDF时添加重要功能。用户将能够从索引跳到章节,反之亦然。我认为脚本和我正在处理的问题对其他人有用,但还没有发现任何帖子来解决我的问题。

    特定章节(“第125章”)索引中的所有引用(如“ch 125 no 1”)都会获得指向该章首部位置的超链接。脚本的这一部分工作得很好并且运行得很快。

    另一半将在每章文本的末尾插入相应的主题标题,并使这些段落链接回索引中相应的主题头。 (换句话说,它们是交叉引用,但在ID术语中不是真正的x-refs,因为我想要更多地控制它们,我对该主题的阅读告诉我要避开真正的x-refs。)这是脚本的一部分那让我把头撞在墙上。它运行了几个小时而没有完成一本200章的书。请注意,出于测试目的,我只是在每个章节下的所需位置插入一段文本,而不是所有主题标题和链接。我知道从较小的文本集和我的调试打印到控制台,脚本正在工作,而不是陷入无限循环。然而,它运行时间过长,如果我打断它,InDesign没有响应,我必须杀死它,所以甚至无法检查部分结果。

    基于搜索/阅读论坛:我禁用了飞行前检查;禁用自动更新图书页码;将实时预览设置更改为延迟。我仍然怀疑缓慢可能与InDesign开销有关,但我不知道还有什么可以尝试。

    我对这个JS代码的风格有多糟糕感到尴尬但是目前我只是需要它才能工作,然后我可以改进它。

    var myBookFilePath = File.openDialog("Choose an InDesign Book File", "Indb files: *.indb");
    var myOpenBook = app.open(myBookFilePath);
    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.neverInteract;
    
    // Open up every file in the currently active Book
    app.open(app.activeBook.bookContents.everyItem().fullName)
    
    // TODO:  add error handling / user interaction here -- to pick which is Index file
    var strIndexFilename = "Index.indd";
    var objChapHeadsWeb = {};
    var myDoc = app.documents.item(strIndexFilename);
    
    $.writeln("\n\n~~~ " + myDoc.name + " ~~~");
    
    // REMOVED CODE - check for existing hyperlinks, hyperlink sources/destinations
    // loop to delete any pre-existing hyperlinks & associated objects
    // works w/o any problems
    
    // Ugly GREP to find the Main heading text (all caps entry and nothing beyond) in the index file
    app.findGrepPreferences = NothingEnum.nothing;
    app.changeGrepPreferences = NothingEnum.nothing;
    
    /// GREP:  ^[\u\d \:\;\?\-\'\"\$\%\&\!\@\*\#\,\.\(\)]+[\u\d](?=\.|,)
    app.findGrepPreferences.findWhat = "^[\\u\\d \\:\\;\\?\\-\\'\\\"\\$\\%\\&\\!\\@\\*\\#\\,\\.\\(\\)]+[\\u\\d](?=\\.|,)";
    app.findGrepPreferences.appliedParagraphStyle = "Main";
    
    var myFound = [];
    myFound = myDoc.findGrep();
    $.writeln("Found " + myFound.length + " Main headings.");
    
    for (var i = 0; i < myFound.length; i++)   {
        myDoc.hyperlinkTextDestinations.add(myFound[i], { name: myFound[i].contents });
    }
    
    $.writeln("There are now " + myDoc.hyperlinkTextDestinations.count() + " destinations.");
    
    
    myFound.length = 0;
    
    for (var j = app.documents.count()-1; j >= 0; j--) {
        app.findGrepPreferences = NothingEnum.nothing;
        app.changeGrepPreferences = NothingEnum.nothing;
    
        // set the variable to the document we are working with
        myDoc = null;
        myDoc = app.documents[j];
        myFound.length = 0;
    
        if (myDoc.name === strIndexFilename) {
            continue;       // we don't want to look for chapter heads in the Index file, so skip it
        }
    
        $.writeln("\n\n~~~ " + myDoc.name + " ~~~");
    
    // REMOVED CODE - check for existing hyperlinks, hyperlink sources/destinations
    // loop to delete any pre-existing hyperlinks & associated objects
    // works w/o any problems
    
        // Clear GREP prefs
        app.findGrepPreferences = NothingEnum.nothing;
        app.changeGrepPreferences = NothingEnum.nothing;
    
        app.findGrepPreferences.findWhat = "^CHAPTER \\d+";
        app.findGrepPreferences.appliedParagraphStyle = "chapter";
    
        myFound = myDoc.findGrep();
        var strTemp = "";
        $.writeln("Found " + myFound.length + " chapter headings.");
    
        for (var m = 0; m < myFound.length; m++)   {
            strTemp = myFound[m].contents;
    
            objChapHeadsWeb[strTemp] = {};
            objChapHeadsWeb[strTemp].withinDocName = myDoc.name;
            objChapHeadsWeb[strTemp].hltdChHead = 
                myDoc.hyperlinkTextDestinations.add(myFound[m], {name:strTemp});
            objChapHeadsWeb[strTemp].a_strIxMains = [];
            objChapHeadsWeb[strTemp].a_hltdIxMains = [];
            objChapHeadsWeb[strTemp].nextKeyName = "";
    
            objChapHeadsWeb[strTemp].nextKeyName = 
                ((m < myFound.length-1) ? myFound[m+1].contents : String(""));
        }
    
        $.writeln("There are now " + myDoc.hyperlinkTextDestinations.count() + " destinations.");
    }
    
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //
    //  Find the "ch" (chapter) references in the index file, link them
    //      back to the corresponding text anchors for the chapter heads
    //      in the text.
    // 
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    myDoc = app.documents.item(strIndexFilename);   // work with the Index file
    
    app.findGrepPreferences = NothingEnum.nothing;
    app.changeGrepPreferences = NothingEnum.nothing;
    
    // GREP to find the "ch" (chapter) references in the index file
    // like ch 151 no 1 OR ch 12 no 3
    app.findGrepPreferences.findWhat = "(ch\\s+\\d+\\s+no\\s+\\d+)";
    
    var strExpandedChap = "";
    var strWorkingMainHd = "";
    var arrFoundChapRefs = [];
    var myHyperlinkSource;
    var myHyperlinkDest;
    
    for (var x = 0; x < myDoc.hyperlinkTextDestinations.count(); x++)   {
        strWorkingMainHd = "";
        arrFoundChapRefs.length = 0;
    
        // the special case, where we are working with the ultimate hyperlinkTextDestination obj
        if (x === myDoc.hyperlinkTextDestinations.count()-1) {
            // This is selecting text from the start of one MAIN heading...
            myDoc.hyperlinkTextDestinations[x].destinationText.select();
            // This next line will extend the selection to the end of the story,
            //      which should also be the end of the document
            myDoc.selection[0].parentStory.insertionPoints[-1].select(SelectionOptions.ADD_TO);
        }
        // the regular case...
        else  {
            // This is selecting text from the start of one MAIN heading...
            myDoc.hyperlinkTextDestinations[x].destinationText.select();
            // ... to the start of the next MAIN heading
            myDoc.hyperlinkTextDestinations[x+1].destinationText.select(SelectionOptions.ADD_TO);
        }
    
        strWorkingMainHd = myDoc.hyperlinkTextDestinations[x].name;
        //arrFoundChapRefs = myDoc.selection[0].match(/(ch\s+)(\d+)(\s+no\s+\d+)/g);  //NOTE:  global flag
    
        arrFoundChapRefs = myDoc.selection[0].findGrep();
    
        for(y = 0; y < arrFoundChapRefs.length; y++)    {
            myHyperlinkSource = null;
            myHyperlinkDest = null;
            strExpandedChap = "";
    
            strExpandedChap = arrFoundChapRefs[y].contents.replace(/ch\s+/, "CHAPTER ");
            strExpandedChap = strExpandedChap.replace(/\s+no\s+\d+/, "");
    
            // if we found the chapter head corresponding to our chapter ref in the index
            //      then it is time to create a link
            if (strExpandedChap in objChapHeadsWeb)    {
                objChapHeadsWeb[strExpandedChap].a_strIxMains.push(strWorkingMainHd);
                objChapHeadsWeb[strExpandedChap].a_hltdIxMains.push(myDoc.hyperlinkTextDestinations[x]);
    
                myHyperlinkSource = myDoc.hyperlinkTextSources.add(arrFoundChapRefs[y]);
                myHyperlinkDest = objChapHeadsWeb[strExpandedChap].hltdChHead;
    
                myDoc.hyperlinks.add(myHyperlinkSource, myHyperlinkDest);
            }   else    {
                $.writeln("Couldn't find chapter head " + strExpandedChap);
            }
        }
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // NOW TIME FOR THE HARD PART...
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    myDoc = null;
    var strWorkingMainHd = "";
    var nextKey = "";
    var myParentStory = null;
    var myCharIndex = 0;
    var myCompareChar = null;
    var myLeftmostBound = 0;
    var myCurrentPara = null;
    
    for (var key in objChapHeadsWeb)   {
        myDoc = app.documents.item(objChapHeadsWeb[key].withinDocName);
        myCompareChar = null;   //recent addition
        $.writeln("Working on " + key + ".");   //debugging
    
        nextKey = objChapHeadsWeb[key].nextKeyName;
    
        objChapHeadsWeb[key].hltdChHead.destinationText.select();
        myLeftmostBound = myDoc.selection[0].index;
        myParentStory = myDoc.selection[0].parentStory;
    
        if( (nextKey === "") || (myDoc.name !== objChapHeadsWeb[nextKey].withinDocName) )
        {
            //// Need to find end of story instead of beginning of next chapter
            //myDoc.selection[0].parentStory.insertionPoints[-1].select(SelectionOptions.ADD_TO);
            myParentStory.insertionPoints[-1].select();
            //myCharIndex = myDoc.selection[0].index;           /recently commented out
    
            myCharIndex = myDoc.selection[0].index - 1;     //testing new version
            myCompareChar = myParentStory.characters.item(myCharIndex);     //recenttly added/relocated from below
        }   else    {
            /////
            //objChapHeadsWeb[nextKey].hltdChHead.destinationText.select(SelectionOptions.ADD_TO);
            objChapHeadsWeb[nextKey].hltdChHead.destinationText.select();
    
            //myParentStory.characters.item(myDoc.selection[0].index -1).select();
    
            myParentStory.characters.item(myDoc.selection[0].index -2).select();  //temp test *****
    
            myCharIndex = myDoc.selection[0].index;
            myCompareChar = myParentStory.characters.item(myCharIndex);
    
            if (myCompareChar.contents === "\uFEFF") {
                $.writeln("Message from inside the \\uFEFF check.");     //debugging
    
                myParentStory.characters.item(myDoc.selection[0].index -1).select();
    
                myCharIndex = myDoc.selection[0].index;
                myCompareChar = myParentStory.characters.item(myCharIndex);
            }
    
            if( (myCompareChar.contents !== SpecialCharacters.PAGE_BREAK) &&
                (myCompareChar.contents !== SpecialCharacters.ODD_PAGE_BREAK) &&
                (myCompareChar.contents !== SpecialCharacters.EVEN_PAGE_BREAK) &&
                (myCompareChar.contents !== SpecialCharacters.COLUMN_BREAK) &&
                (myCompareChar.contents !== SpecialCharacters.FRAME_BREAK)) 
            {
                $.writeln("Possible error finding correct insertion point for " + objChapHeadsWeb[key].hltdChHead.name + ".");
            }
        }
    
        if(myCharIndex <= myLeftmostBound)  {   // this shouldn't ever happen
            alert("Critical error finding IX Marker insertion point for " + objChapHeadsWeb[key].hltdChHead.name + ".");
        }
    
        if(myCompareChar.contents !== "\r") {
            myDoc.selection[0].insertionPoints[-1].contents = "\r";
        }
    
        myDoc.selection[0].insertionPoints[-1].contents = "TESTING text insertion for:  " + objChapHeadsWeb[key].hltdChHead.name + "\r";
        myDoc.selection[0].insertionPoints.previousItem(myDoc.selection[0].insertionPoints[-1]).select();
    
    //myDoc.selection[0].insertionPoints[-1].contents = "<Now I'm here!>";
    
        myCurrentPara = myDoc.selection[0].paragraphs[0];
    
        myCurrentPara.appliedParagraphStyle = myDoc.paragraphStyles.item("IX Marker");
    
        // TODO:
        //      need error handling for when style doesn't already exist in the document
    }   // end big for loop
    
    
    //TODO:  add error handling support to carry on if user cancels
    //close each open file; user should be prompted to save changed files by default
    
    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
    app.documents.everyItem().close();
    
    // Cleanup
    app.findGrepPreferences = NothingEnum.nothing;
    app.changeGrepPreferences = NothingEnum.nothing;
    

2 个答案:

答案 0 :(得分:0)

尝试打开交叉引用的所有文件链接到它们。

答案 1 :(得分:0)

我可以建议一些改进可能会加速一些事情。 首先,你在这里有大量的全局变量,你可以使用函数集中在更少的范围内。拥有许多全局变量在性能方面成本很高。

说完之后,我不会立即打开书中的每一个文档,而是一个一个地处理它们。请注意,grep调用非常昂贵,因此您可能会尝试查看模式。

另一个是广泛使用$ .writeln命令。特别是在循环中避免它。首选易于设置的报告库。

最后,我尝试在&#34;更好的&#34;中重写代码。方式,但很难构建整个脚本,清楚地了解您的需求,没有要处理的文件。但我希望以下代码片段可以帮助您开始重写代码并说明重要的时间改进。

&#13;
&#13;
var debug = true;

var log = function(msg) {
	
	var l = File (Folder.desktop+"/log.txt" );
	
	if ( !debug ) return;
	
	l.open('a');
	l.write(msg);
	l.close();
};

var main = function() {
	
	var bookFile, uil = app.scriptPreferences.userIntercationLevel;
	
	log("The party has started");
	
	bookFile = File.openDialog("Choose an InDesign Book File", "Indb files: *.indb");
	
	if (!bookFile) return;
	app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
	
	try {
		processBookFile ( bookFile );
	}
	catch(err) {
		alert(err.line+"///"+err.message);
	}

	app.scriptPreferences.userInteractionLevel = uil;
};

function processBookFile ( bookFile ) {
	var book = app.open ( bookFile ),
	bks = book.bookContents,
	n = bks.length;
	
	while ( n-- ) {
		File(bks[n].name)!="Index.indd" && processBookContent ( bks[n] );
	}
}

function processBookContent ( bookContent ) {
	var bcf = bookContent.fullName,
	doc = app.open ( bcf, debug );
	
	//DEAL WITH HEADINGS
	processHeadings ( doc );
	
	//DEAL WITH CHAPTERS
	processHeadings ( doc );
	
	//add hyperlinks
	addHyperlinks( doc);
}



function processHeadings (doc){
	var props = {
		findWhat : "^[\\u\\d \\:\\;\\?\\-\\'\\\"\\$\\%\\&\\!\\@\\*\\#\\,\\.\\(\\)]+[\\u\\d](?=\\.|,)",
		appliedParagraphStyle : "Main"
	},
	found = findGrep(doc, props),
	n = found.length;
	
	while ( n-- ) {
		doc.hyperlinkTextDestinations.add(doc, { name: found[i].contents });
	}
};

function processChapters (doc ) {
	var props = {
		findWhat : "^CHAPTER \\d+",
		appliedParagraphStyle : "chapter"
	},
	found = findGrep(doc, props),
	n = found.length;
	
	while ( n-- ) {
		doc.hyperlinkTextDestinations.add(found[n], found[n].contents);
	}
}

function findGrep(doc, props){
	app.findGrepPreferences = app.changeGrepPreferences = null;	
	app.findGrepPreferences.properties = props;
	return doc.findGrep();
}

function addHyperlinks (doc){
	//a logic of yours
};


main();
&#13;
&#13;
&#13;