Hi all,
First of all, I want to thank you, Kris, for your detailed explanation on my question. I thanked you in my previous post here about a month ago, but for some unknown reason, it's not here.
Now after a break, I'd like to get back to my issue.
For beginning, a little 'background' information to show you what I am trying to achieve.
I wrote a script for my client that creates cross-references by converting tags to x-refs sources and destinations from tagged text.
There are two kinds of tags that look like so:
<s=Anchor 1> -- for sources
<d=Anchor 1> -- for destinations
The tags and their numbers are generated by the clients software. The tagged text is imported to InDesign via xTags plug-in (by Em software), because, in addition to text, images are imported and placed as in line objects. A destination tag always follows the inline image it points to.
But my client wanted the destination marker to always stick with the image, so that when it is cut and pasted onto another page, the destination marker goes with it.
To achieve this I wrote a function that creates a text frame inside a graphic frame holding the image and moves the destination tag into it:
Code:function MoveDestinationTags() {
app.findGrepPreferences = app.changeGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "<d=Anchor\\s\\d+>";
var myFinds = myDoc.findGrep();
if (myFinds.length == 0) ErrorExit("No destination tags have been found.");
WriteToFile("\rMoving destination tags into images:\n");
var myPrBarWin = new Window ( "window", "Creating Cross-References" );
var myPrBar = myPrBarWin.add ("progressbar", [12, 12, 350, 24], 0, myFinds.length);
var myPrBarText = myPrBarWin.add("statictext");
myPrBarText.bounds = [0, 0, 340, 20];
myPrBarText.alignment = "left";
myPrBarWin.show();
var myPrBarCounter = 1;
for ( var j = myFinds.length-1; j >= 0; j-- ) {
try {
var myFound = myFinds[j];
var myTagName = myFound.contents + "";
myPrBar.value = myPrBarCounter;
myPrBarText.text = String("Moving destination tags \"" + myTagName + "\" (" + myPrBarCounter + " out of " + myFinds.length + ")");
$.writeln("MoveDestinationTags - " + j + " - " + myFound.contents);
var myPrevChar = myFound.characters.previousItem(myFound.characters[0]);
var myRectangle = myPrevChar.rectangles.everyItem().getElements()[0];
if (myRectangle != null) {
var myTextFrame = myRectangle.textFrames.add({geometricBounds:myRectangle.geometricBounds});
myFound.move(LocationOptions.BEFORE, myTextFrame);
WriteToFile(myPrBarCounter + " - " + myTagName + " -- Ok\n");
}
}
catch(e) {
$.writeln(e);
WriteToFile(myPrBarCounter + " - ERROR -- Can't move destination tag \"" + myFound.contents + "\"\n");
}
myPrBarCounter++;
}
myPrBarWin.close();
}
However, here comes a problem: the script works normally on a test document containing 3 pairs of tags, but works very slowly on a real document containing 59 pairs of tags (it takes about 40 minutes to complete).
Here is an excerpt from a log file:
MoveDestinationTags - 58 - <d=Anchor 59>
myDuration2-58= 101.506
MoveDestinationTags - 57 - <d=Anchor 58>
myDuration2-57= 98.782
MoveDestinationTags - 56 - <d=Anchor 57>
myDuration2-56= 95.828
......
MoveDestinationTags - 2 - <d=Anchor 3>
myDuration2-2= 6.599
MoveDestinationTags - 1 - <d=Anchor 2>
myDuration2-1= 5.819
MoveDestinationTags - 0 - <d=Anchor 1>
myDuration2-0= 4.476
myDuration1 = 2648.399All tags are processed backwards: from #58 (Anchor 59) to #0 (Anchor 1).
myDuration1 is a variable showing the total time for processing all tags in secs.
myDuration2 shows time for every particular tag. Notice that it takes 101.5 secs to complete MoveDestinationTags function for the first tag in the loop, then the time gradually reduces and it takes just about 4.5 secs for the last tag.
Why the duration is so different? Can I somehow reduce the time required to complete the function?As a workaround, I want to use what I've learned from Kris's posts to make a new scripted plug-in and rework the original script. My idea is to create a text frame only when an image is being cut, instead of creating it for every image. The script will mark every image with the name of the corresponding tag using
setDataStore method. When a user cuts an image, the plug-in temporarily pastes it back into the document, creates a text frame inside the image, removes the corresponding destination marker and recreates it inside the text frame and finally cuts it. I believe the user won’t notice anything on a fast computer.
Here is a code to illustrate what I mean:
List of Subjects: *
Event Filter: subjectDelete
Code:if (app.documents[0].undoName == "Cut" ) {
var theValue = theItem.getDataStore("kas",0,0);
if (theValue.indexOf("Anchor") == 0) {
app.pasteInPlace();
var theObj = app.selection[0];
var tf = theObj.textFrames.add({geometricBounds:theObj.geometricBounds});
tf.contents = theValue; // x-ref destination will be created here
app.cut();
}
}
(I am on CS3 at the moment, so I'm not creating the x-ref destination -- just adding anchor's name to the contents of the text frame)
Do you foresee any pitfalls of using this approach?Thank you in advance.
Kasyan