I need an Adobe Script that do this:
I've been doing this typesetting job and I came across this Typesetterer for Photoshop, went on a journey to find a similar script/application for inDesign and I found this this solution, tried it and worked, boosting my productivity by at least 2x. Tried this split one but it takes way longer to resize and move all the generated TextFrames. But it was really useful in developing my final code.
The main problem with this approach is that it required the typesetting script to be in a .txt file, which breaks all Bold and Italic from the original script.
main();
function main() { // Main() just to keep it organized
try {
var myMeasuringUnit = app.scriptPreferences.measurementUnit;
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
} catch (exception) {
alert(exception.description);
exit();
}
var myTextFrameSelection = app.activeDocument.selection;
cutAndPaste(myTextFrameSelection);
try {
app.scriptPreferences.measurementUnit = myMeasuringUnit;
} catch (exception) {}
}
function cutAndPaste(myTextFrameSelection) {
for (elementsInSelection = 0; elementsInSelection < myTextFrameSelection.length; elementsInSelection++) {
if (myTextFrameSelection[elementsInSelection].constructor.name == "TextFrame") {
var myParagraphs = myTextFrameSelection[elementsInSelection].texts[0].paragraphs;
var isCopied = true;
for (var i = 0; i < myParagraphs.length; i++) {
try {
myParagraphs[i].insertionPoints.itemByRange(0, -2).select();
app.cut();
isCopied = true;
} catch (exception) {
isCopied = false;
}
if (isCopied) {
/*
Attempt at adding a way to select another TextFrame and app.paste() the previously app.cut() line in it
var doc = app.activeDocument.selection[0];
doc.addEventListener('afterSelectionChanged', selectionChanged);
function selectionChanged() {
if (doc.selection[0] instanceof TextFrame && doc.selection[0].contents == '' && doc.selection[1] == null) {
if (doc.selection[0] instanceof TextFrame) {
doc.selection[0].contents = app.paste();
}
}
*/
app.paste(); // This just pastes it in the same folder
}
}
}
}
} // For now, what it does it "cut paragraph from the TextFrame but also paste in the same TextFrame"
So far, it just cut from the TextFrame, paragraph after paragraph, and it pastes on the same TextFrame. It's close to doing what I need, but I can't seem to find a way to select a new Frame while in the main loop. I commented out the possible solution that I'm struggling to get to work.
Maybe I'm using the wrong cut/paste functions too? Maybe it is easier to modify the 2nd link solution to accept .docx?
Important difference between RisingFog's solution and Eugeny Budantsev solition is the interaction with user. Former script shows the dialog window and keep it running until you close the window. Later runs just once and can't keep tracking user manipulations.
So if you want to keep your script running (and doing something as reaction on user manipulations) you need to show a some window even if the window will be empty. Something like this:
#targetengine session
var dialog = new Window("palette", undefined, undefined);
dialog.preferredSize.width = 200;
dialog.preferredSize.height = 50;
dialog.text = "Select next frame";
dialog.onClose = function() {
doc.removeEventListener('afterSelectionChanged', selectionChanged);
}
dialog.show();
var doc = app.activeDocument;
doc.addEventListener('afterSelectionChanged', selectionChanged);
function selectionChanged() {
// here is the code that will run wenever you change selection
if (doc.selection[0] instanceof TextFrame
&& doc.selection[0].contents == ''
&& doc.selection[1] == null) {
alert('Next empty text frame is selected!')
}
}
Of course you can fill the window with some texts or buttons.
Update
Here is the example how you can cut first paragraph from selected non-empty text frame (suppose it's the Text Script) and paste this paragraph automatically into next selected empty frame:
#targetengine session
var dialog = new Window("palette", undefined, undefined);
dialog.preferredSize.width = 300;
dialog.preferredSize.height = 50;
dialog.text = "Please, select next frame";
dialog.onClose = function() {
doc.removeEventListener('afterSelectionChanged', selectionChanged);
}
dialog.add("statictext", undefined, "Last cutted text:");
var msg = dialog.add("edittext");
msg.text = "";
msg.characters = 40
dialog.show();
var doc = app.activeDocument;
doc.addEventListener('afterSelectionChanged', selectionChanged);
function selectionChanged() {
var sel = doc.selection[0];
if (sel instanceof InsertionPoint) sel = sel.parent.textContainers[0];
if (sel instanceof TextFrame || sel instanceof Story) {
if (sel.contents != '') {
app.select(sel.paragraphs[0], SelectionOptions.REPLACE_WITH);
msg.text = sel.paragraphs[0].contents;
app.cut();
app.selection = null;
}
else {
sel.texts.everyItem().select();
app.paste();
app.selection = null;
// remove '\r' at the very end of text in the frame
app.findGrepPreferences.findWhat ="\r$";
app.changeGrepPreferences.changeTo = "";
sel.changeGrep();
}
}
}
Update 2
Here is the same script. Only difference, you don't need click on Text Script frame anymore. You need select the text frame before you run the script and then the script will cut first paragraph from this frame automatically every time when you click on any empty text frame.
#targetengine session
var dialog = new Window("palette", undefined, undefined);
dialog.preferredSize.width = 300;
dialog.preferredSize.height = 50;
dialog.text = "Please, select next frame";
dialog.onClose = function() {doc.removeEventListener('afterSelectionChanged', selectionChanged)}
dialog.add("statictext", undefined, "Last copied text:");
var msg = dialog.add("edittext");
msg.text = "";
msg.characters = 40;
// --- here is the Pause button
var pause = false;
var pause_btn = dialog.add("button", [10,10,300,30], "Pause");
pause_btn.onClick = function() {
pause = !pause;
// if (pause) msg.text = "[PAUSED] " + msg.text; // it can be done better, but it works, too
// if (!pause) msg.text = msg.text.replace(/^\[PAUSED\] /, "");
pause_btn.text = pause ? "Resume" : "Pause"; // this is way better
};
// ---
var doc = app.activeDocument;
var master_frame = app.selection[0]; // <-- the Text Script frame
if (master_frame instanceof TextFrame || master_frame instanceof Story) {
dialog.show();
app.selection = null;
doc.addEventListener('afterSelectionChanged', selectionChanged);
} else {
alert("Please, select a frame with text before run the script!");
exit();
}
function selectionChanged() {
if (pause) return; // <-- here you check the state of the button
var sel = doc.selection[0];
if (sel instanceof InsertionPoint) sel = sel.parent.textContainers[0];
if (sel instanceof TextFrame || sel instanceof Story) {
if (sel.contents == '' && master_frame.contents != '') {
app.select(master_frame.paragraphs[0], SelectionOptions.REPLACE_WITH);
msg.text = master_frame.paragraphs[0].contents;
app.cut();
app.selection = null;
sel.texts.everyItem().select();
app.paste();
app.selection = null;
// remove '\r' at the end
app.findGrepPreferences.findWhat ="\r$";
app.changeGrepPreferences.changeTo = "";
sel.changeGrep();
}
if (master_frame.contents == '') alert ("No text to paste anymore!")
}
}
I've added 'Pause' button to the window.