Sunday, September 09, 2007
Placing Snippets Inline/Anchored
I've found InDesign's snippets feature to be a constant source of frustration because you simply can't place them as inline or anchored objects. So much of my work involves inline/anchored objects that this makes snippets just about useless. But the alternative of using library items isn't that great either. Library panels take up space on screen and they clutter up the the Open Recent menu. Also, in the past, they've been a source of frustration when crashes occur and they have to be recovered. Untitled assets seem to pop into existence in a recovered library, or worse yet, a previously named asset suddenly loses its name.
Snippets do not take up space on screen, are impervious to crash/recovery issues, and they do not appear on the Open Recent menu. So, how to work around the inability to place them inline? Whats more, how to do it without using the clipboard which might or might not have important information on it at any point in time.
I came up with the idea of using a temporary library. Even on a G4, creating a library, putting something into it, pulling it back out again and deleting the library is pretty swift, while on a MacIntel it positively flies. So, I wrote this function to do the work:
To turn the above function into a complete script I added this front-end:
Snippets do not take up space on screen, are impervious to crash/recovery issues, and they do not appear on the Open Recent menu. So, how to work around the inability to place them inline? Whats more, how to do it without using the clipboard which might or might not have important information on it at any point in time.
I came up with the idea of using a temporary library. Even on a G4, creating a library, putting something into it, pulling it back out again and deleting the library is pretty swift, while on a MacIntel it positively flies. So, I wrote this function to do the work:
function placeSnipInline( mySnipFile, text ) {One odd thing here might leap out at you. Why did I not take advantage of the returned object from the place() call to get a reference to the placed object rather than rely on myDoc.pageItems[0] in the store call? The reason is that I have just this morning discovered that if you place a snippet that consists of just a text frame, what's returned by place() is the story, not the text frame.
var myDoc = app.documents.add(false);
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.neverInteract;
myDoc.pages[0].place(mySnipFile);
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
myLib = app.libraries.add(File("~/Desktop/templib.indl"));
myLib.store(myDoc.pageItems[0]);
myDoc.close(SaveOptions.no);
myLib.assets[0].placeAsset(text);
myLib.close();
File("~/Desktop/templib.indl").remove();
}
To turn the above function into a complete script I added this front-end:
//DESCRIPTION: Place Snippet Inline/Anchored
if (app.documents.length > 0 &&
app.selection.length > 0 &&
app.selection[0].hasOwnProperty("baseline")) {
placeSnippet(app.selection[0]);
} else {
alert("There must be a text selection to run this script");
}
function placeSnippet(sel) {
if (File.fs == "Windows") {
var Filter = "Snippet files: *.inds";
} else {
var xmlFilter = function(file) {
while(file.alias){
file = file.resolve();
if (file == null) return false;
}
if (file instanceof Folder) return true;
return (file.name.slice(file.name.lastIndexOf(".")).toLowerCase() == ".inds");
}
var Filter = xmlFilter
}
var myFile = File.openDialog("Choose a snippet file", Filter);
if (myFile == null) { return }
placeSnipInline(myFile, app.selection[0]);
}