Copy link to clipboard
Copied
Hello
There is a routine issue i face when I try to make a specific script which seems to make undoing the script in one control z impossible.
Of note I ahve read the post about app.doScript(function()
So the script I am trying to make is to break a single text box with several columns inside into single text columns frames threaded the same way as the og text frame etc
when i tried to make one before I got it to work but couldnt undo
So i tried to make one again
it duplicates the 1st frame the an eqaual amount of times to columns in the 1st text frame and then changes all of the duplicated frames to 1 column
howwever it seems impossible to undo, and instead i have to watch indesign undoing every step
code below is a bit messy but potentially could anyone signpost me to solving this issue
I ahve made a script which allows for rules to be placed inbetween differnt columns of different lengths and its a very multi step process, which has to come up with particaular values for particular situtions yet that can undo in one go.
As always many thanks all.
Best
// Create a reference to the active document
var doc = app.activeDocument;
// Check if a text frame is selected
if (doc.selection.length === 1 && doc.selection[0] instanceof TextFrame) {
var selectedTextFrame = doc.selection[0];
// Get the number of columns in the selected text frame
var numColumns = selectedTextFrame.textColumns.length;
// Wrap the entire operation in a single undoable action
app.doScript("duplicateAndPositionTextBoxes()", ScriptLanguage.JAVASCRIPT);
// Function to duplicate and position the text boxes
function duplicateAndPositionTextBoxes() {
try {
var frameBounds = selectedTextFrame.geometricBounds;
for (var i = 0; i < numColumns; i++) {
// Duplicate the selected text frame
var duplicatedTextFrame = selectedTextFrame.duplicate(selectedTextFrame.parent);
duplicatedTextFrame.contents = "";
// Set the position of the duplicated text frame
var xOffset = i * (frameBounds[3] - frameBounds[1]);
duplicatedTextFrame.move(undefined, [xOffset, 0]); // Change the coordinates as needed
// Set the duplicated frame to a single column layout
duplicatedTextFrame.textFramePreferences.textColumnCount = 1;
}
} finally {
// Perform undo if there's an error
if (app.scriptPreferences.enableRedraw) {
app.scriptPreferences.enableRedraw = false;
app.undo();
app.scriptPreferences.enableRedraw = true;
}
}
}
} else {
alert("Please select a single text frame.");
}Hi @SmythWharf, you've made a great start on your script and you seem to be learning a lot, so that's awesome. One of the confounding factors with your script is your use of app.undo(). I would avoid that if at all possible.
Here's something to guide you—I've written a script to do the column separating, and also called the whole thing from app.doScript, which means that the whole thing will be undo-able in one go. Hope that shows you one approach to the problem—but there are many ways.
- Mark
...Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi @SmythWharf, you've made a great start on your script and you seem to be learning a lot, so that's awesome. One of the confounding factors with your script is your use of app.undo(). I would avoid that if at all possible.
Here's something to guide you—I've written a script to do the column separating, and also called the whole thing from app.doScript, which means that the whole thing will be undo-able in one go. Hope that shows you one approach to the problem—but there are many ways.
- Mark
/**
* Separate selected text frame into column frames.
* @author m1b
* @discussion https://community.adobe.com/t5/indesign-discussions/undo-a-script-in-one-control-z-a-routine-problem/m-p/14021929
*/
function main() {
separateTextColumns(app.activeDocument.selection[0]);
}
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Split Into Columns');
/**
* Splits a multi-column text frame
* into separate text frames.
* @author m1b
* @version 2023-08-21
* @param {TextFrame} textFrame - the text frame to split.
*/
function separateTextColumns(textFrame) {
if (
textFrame == undefined
|| textFrame.constructor.name != 'TextFrame'
|| textFrame.textFramePreferences.textColumnCount < 2
)
return;
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
var columnCount = textFrame.textFramePreferences.textColumnCount,
columnGutter = textFrame.textFramePreferences.textColumnGutter,
b = textFrame.geometricBounds,
frameWidth = b[3] - b[1],
inset = textFrame.textFramePreferences.insetSpacing,
frames = [textFrame];
// calculate the column width
var columnWidth = (frameWidth - inset[1] - inset[3] - (columnGutter * (columnCount - 1))) / columnCount;
// adjust the textFrame to the width of one column
// also remove inset spacing, if any
textFrame.textFramePreferences.textColumnCount = 1;
textFrame.textFramePreferences.insetSpacing = [inset[0], 0, inset[2], 0];
textFrame.geometricBounds = [b[0], b[1] + inset[1], b[2], b[1] + inset[1] + columnWidth];
// now add the other column frames and thread them
for (var i = 1; i < columnCount; i++) {
var frame = frames[i - 1].duplicate(undefined, [(columnWidth + columnGutter), 0]);
frame.parentStory.contents = '';
frames[i - 1].nextTextFrame = frame;
frames.push(frame);
}
// done!
};
Copy link to clipboard
Copied
Hello,
Thank you very much for this sample, Ill dig into to it and try and see if I can understand
Many thanks
Smyth
Find more inspiration, events, and resources on the new Adobe Community
Explore Now