I am trying to write a script to perform a data merge, followed by a find/replace, page add, and finally export. I can get it to perform the merge and find/replaces that are needed. When I add a new page manually I normally select the first page in the pages window then click add a new page at the bottom. Doing that makes every page after that go to 2 pages. I don't know how to do this in the script, what I tried below didn't work. It adds a new page at the end of the document.
app.activeDocument.pages.item(0).select();
app.activeDocument.pages.add();
After the merge, editing gets really slow, taking 15-20 per letter I add or delete.The only way i've found to have it edit like you'd expect is by exporting it to the IDML format then reopening that file in InDesign. I haven't been able to find much on exporting via a script in javascript. What I plan to try next is: app.activeDocument.exportFile(ExportFormat.INDESIGN_MARKUP, newDoc, false);
But I don't know if that will work or not. I'm very new to scripting in InDesign. I'm using InDesign CS5.5 and here is the whole script thus far:
main();
function main()
{
//Possibly let the user go find and choose a file
//var mergeTemplate = File.openDialog();
//var myDocument = app.open(mergeTemplate);
//Open the template file to be used by the data merge.
var myDocument = app.open(File("Macintosh HD/Users/Christian/Desktop/InDesign_Data_Merge/MMM14 Template_v1.indd"));
//Load the data source
var myDataSource = File("Macintosh HD/Users/Christian/Desktop/InDesign_Data_Merge/MMM v1.mer");
myDocument.dataMergeProperties.selectDataSource(myDataSource);
myDocument.dataMergeProperties.mergeRecords();
//Save the document under a new name for later use.
app.activeDocument.save(File("Macintosh HD/Users/Christian/Desktop/InDesign_Data_Merge/DataMerge_MMM.indd"));
//Close the document, NOT saving original template, so the original file is not destroyed or overwritten.
myDocument.close(SaveOptions.no);
//Find line break placeholder and replace with line break
findReplace ("$$", "^n");
//Find the tab placeholder and replace with tab
findReplace ("##", "^t");
//Select the first page of the document
//app.activeDocument.pages.item(0).select();
//Add another page to make the document print on both sides, like an open book
//app.activeDocument.pages.add();
//export to IDML
//exportIDML();
}
function findReplace(findVal,replaceVal)
{
// Clear the find/change text preferences.
app.findTextPreferences = NothingEnum.NOTHING;
app.changeTextPreferences = NothingEnum.NOTHING;
// Set the find options
app.findChangeTextOptions.caseSensitive = false;
app.findChangeTextOptions.includeFootnotes = false;
app.findChangeTextOptions.includeHiddenLayers = false;
app.findChangeTextOptions.includeLockedLayersForFind = false;
app.findChangeTextOptions.includeLockedStoriesForFind = false;
app.findChangeTextOptions.includeMasterPages = false;
app.findChangeTextOptions.wholeWord = false;
// Search the document for the string findVal
app.findTextPreferences.findWhat = findVal;
// Change it to the string replaceVal
app.changeTextPreferences.changeTo = replaceVal;
// Perform the search-and-replace operation
app.activeDocument.changeText();
}
function exportIDML()
{
var newDoc = app.open(File("Macintosh HD/Users/Christian/Desktop/InDesign_Data_Merge/DataMerge_MMM.indd"));
app.activeDocument.exportFile(ExportFormat.INDESIGN_MARKUP, newDoc, false);
}
Edit: Another post led me to this site jongware.mit.edu but i'm not sure how to start searching for what I need here?
Instead of
app.activeDocument.pages.add();
you can use a handy parameter in the Pages.add
function:
app.activeDocument.pages.add(LocationOptions.AT_END);
You don't need the second parameter "reference", because AT_END
already tells ID precisely where the new page must come (ie, if you want to always add a page after the first one, you'd use AFTER
for at and app.activeDocument.pages[0]
for reference ).
That, however, only adds a page. To make your text flow onto it, you need to manually add a new text frame and "thread" (link) the one from the previous page:
newframe = newpage.textFrames.add(..)
startframe.nextTextFrame = newframe; // <- thread
Unfortunately, only adding a new text frame to a page does not automatically size it to its parent page's margins. All you get is a tiny new frame in the top left. So you have to read out the page size (using its bounds
property) and the current margins
, and then you can resize the frame. Another snag awaits you, if your margins are mirrored : for some reason, the MarginPreferences object does not "see" whether you are on a left or a right hand sided page. So I use page.index
to check if it's odd, and if so, reverse left
and right
margins.
Another possible pitfall is when your text contains Continuously Overset items -- text that will not fit on a page, whatever you do. That may happen with a large table, a large image, or text with some weird attribute such as a huge left indent or No-Break applied to more text than can fit on a single line. If not checked, this script would keep on checking for overflow, detect it, create a new page and text frame, which then will also overflow and so on and so forth. A quick check is to add a new text frame and check if it actually contains anything -- a Continuously Overflowing frame will always be entirely empty.
With that out of the way, here is the part that you can use instead of your own commented-out code. It assumes the to be added text is in an overset text frame on the very last page (index -1
) of your current document. It also assumes this text frame is the only one on that page(!).
startframe = app.activeDocument.pages[-1].textFrames[0];
while (startframe.overflows)
{
newpg = app.activeDocument.pages.add(LocationOptions.AT_END);
newframe = newpg.textFrames.add();
if (newpg.index & 1)
newframe.geometricBounds = [newpg.bounds[0]+newpg.marginPreferences.top,
newpg.bounds[1]+newpg.marginPreferences.left,
newpg.bounds[2]-newpg.marginPreferences.bottom,
newpg.bounds[3]-newpg.marginPreferences.right];
else
newframe.geometricBounds = [newpg.bounds[0]+newpg.marginPreferences.top,
newpg.bounds[1]+newpg.marginPreferences.right,
newpg.bounds[2]-newpg.marginPreferences.bottom,
newpg.bounds[3]-newpg.marginPreferences.left];
startframe.nextTextFrame = newframe;
startframe = newframe;
// Check for Continuous Overflow!
if (startframe.contents.length == 0)
{
alert ("Continuous Overflow detected, cannot continue");
break;
}
}
That is an annoying issue you got, with ID slowing down after a Data Merge. I can't recall if that has been reported before; you might want to ask on the Adobe InDesign forum . Only maybe : perhaps you can manually try this. Directly after doing your merge, don't use "Save" but do a "Save As", and overwrite your old file. "Save As" cleans up and reallocates memory; I've found it sometimes helps. If that doesn't work, I cannot recommend anything else than, indeed, export to IDML and re-open that.
Your attempt to exporting to IDML is a fair one, but it contains a few mistakes!
First off, you should not use app.open
-- this does what it says, it opens a previously saved file. You want to create a new file here; the parameter to in exportFile
refers to the file that it will create . With your code, it would overwrite an existing file -- unless ID notices you already have it open and so complains about that. Not a statement I would be willing to test for correctness.
Second, you need to set its file extension correctly to .idml
:)
A third, minor, point: the Folder
object provides a handy shortcut to your Desktop folder.
var newDoc = new File(Folder.desktop+"/DataMerge_MMM.idml");
app.activeDocument.exportFile(ExportFormat.INDESIGN_MARKUP, newDoc);
I don't have a CS5 at hand, I tested with my CS6. If you get errors on "unknown properties" and their ilk, call back in the morning and I will see what I can do.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.