Copy link to clipboard
Copied
Hello InDesign-ers!
Its a long shot, but checking to see if someone can maybe help. We have somewhat of an old jsx script for InDesign someone found awhile back (2016) called ExportStoriesToRTF.jsx. Works on the Macs, but in Windows its been hit or miss. We can't for the life of us figure out why it works on some workstations and not others. And all versions of ID are the same. Settings too. Not sure if we actually need Java installed, but version of Java is the same as well. We get a crazy pop when we execute the script from the Scripts panel which I've attached. Anyone ever use this script? Any experience you can share?
Thankyou, that's what we need.
The problem is probably that the script has been wrecked at some point or someone copy/pasted from another script. Line 122 where the error occurs uses the (undeclared variable "i") and compares it to the number of stories in the document. This serves no purpose (even it it worked—which it doesn't). Try removing it (and the balancing brace on line 126, so you have this:
//If the imported text did not end with a return, enter a return
if (myNewStory.characters.ite
...
Copy link to clipboard
Copied
Hi @MacPhobic, we would have to see the rest of the script to understand why i is undefined. Are you able to share? Or at least the flow up to that point?
- Mark
Copy link to clipboard
Copied
@m1b You bet! Sorry, i wasn't sure if i could post it or not. Here it is:
main();
function main(){
//Make certain that user interaction (display of dialogs, etc.) is turned on.
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if(app.documents.length != 0){
if (app.activeDocument.stories.length != 0){
myGetFileName(app.documents.item(0).name);
}
else{
alert("The document does not contain any text. Please open a document containing text and try again.");
}
}
else{
alert("No documents are open. Please open a document and try again.");
}
}
function myGetFileName(myDocumentName){
var myFilePath = File.saveDialog("Save Exported File As:");
if(myFilePath != null){
myExportAllText(myDocumentName, myFilePath);
}
}
function myExportAllText(myDocumentName, myFilePath){
app.scriptPreferences.userInteractionLevel=UserInteractionLevels.NEVER_INTERACT; // this line will detect all the interaction like missing fonts missing links.
var myPage, myStory;
var myExportedStories = [];
var myTempFolder = Folder.temp;
var myTempFile = File(myTempFolder + "/tempTextFile.rtf");
var myNewDocument = app.documents.add();
var myDocument = app.documents.item(myDocumentName);
var myTextFrame = myNewDocument.pages.item(0).textFrames.add({geometricBounds:myGetBounds(myNewDocument, myNewDocument.pages.item(0))});
var myNewStory = myTextFrame.parentStory;
var minLength = 0;
var fullLength;
var PBNY = false;
var iDial = new Window('dialog', 'Options');
var panel1 = iDial.add('panel', undefined, 'Ignore stories with fewer than this number of characters:');
var IgnoreChars= panel1.add('edittext', undefined, '30');
IgnoreChars.minimumSize.height = 25;
IgnoreChars.minimumSize.width = 200;
var IncludePasteboard = panel1.add('checkbox', undefined, "Include text boxes from paste board.", {name:'paste'});
var group = iDial.add('group', undefined, 'Group title');
var OKBtn = panel1.add('button', undefined, 'OK', {name:'close'});
OKBtn.onClick = function(){
minLength = IgnoreChars.text;
PBYN = IncludePasteboard.value;
iDial.hide();
}
iDial.show();
if (PBYN) {
var myTextFrames = myDocument.pageItems.everyItem().getElements();
for (var i = 0; i < myTextFrames.length; i++ ) {
if ( myTextFrames[i] == "[object TextFrame]" ) {
myStory = myTextFrames[i].parentStory;
exportStory(myStory, myExportedStories, minLength, myTempFile, myNewStory, myDocument);
}
}
}
else {
for (var i = 0; i < myDocument.pages.length; i++) {
myPage = myDocument.pages.item(i);
for (var t = 0; t < myPage.textFrames.length; t++){
myStory = myPage.textFrames[t].parentStory;
exportStory(myStory, myExportedStories, minLength, myTempFile, myNewStory, myDocument);
}
}
}
myExtension = ".rtf"
myNewStory.exportFile(ExportFormat.RTF, File(myFilePath + myExtension));
myNewDocument.close(SaveOptions.no);
myTempFile.remove();
app.scriptPreferences.userInteractionLevel=UserInteractionLevels.INTERACT_WITH_ALL;
alert("RTF file has been created.");
}
function myGetBounds(myDocument, myPage){
var myPageWidth = myDocument.documentPreferences.pageWidth;
var myPageHeight = myDocument.documentPreferences.pageHeight
if(myPage.side == PageSideOptions.leftHand){
var myX2 = myPage.marginPreferences.left;
var myX1 = myPage.marginPreferences.right;
}
else{
var myX1 = myPage.marginPreferences.left;
var myX2 = myPage.marginPreferences.right;
}
var myY1 = myPage.marginPreferences.top;
var myX2 = myPageWidth - myX2;
var myY2 = myPageHeight - myPage.marginPreferences.bottom;
return [myY1, myX1, myY2, myX2];
}
function IsInArray(myString, myArray) {
for (x in myArray) {
if (myString == myArray[x]) {
return true;
}
}
return false;
}
function exportStory(myStory, myExportedStories, minLength, myTempFile, myNewStory, myDocument){
fullLength = myStory.length;
if (!IsInArray(myStory.id, myExportedStories) && fullLength > minLength ) {
//Export the story as rff.
myStory.exportFile(ExportFormat.RTF, myTempFile);
myExportedStories.push(myStory.id);
//Import (place) the file at the end of the temporary story.
myNewStory.insertionPoints.item(-1).place(myTempFile);
//If the imported text did not end with a return, enter a return
if(i != myDocument.stories.length -1){
if(myNewStory.characters.item(-1).contents != "\r"){
myNewStory.insertionPoints.item(-1).contents = "\r";
}
}
}
}
Copy link to clipboard
Copied
Thankyou, that's what we need.
The problem is probably that the script has been wrecked at some point or someone copy/pasted from another script. Line 122 where the error occurs uses the (undeclared variable "i") and compares it to the number of stories in the document. This serves no purpose (even it it worked—which it doesn't). Try removing it (and the balancing brace on line 126, so you have this:
//If the imported text did not end with a return, enter a return
if (myNewStory.characters.item(-1).contents != "\r") {
myNewStory.insertionPoints.item(-1).contents = "\r";
}
Also the declaration line 38 should be:
var PBYN = false;
See how that goes.
- Mark
Copy link to clipboard
Copied
@m1b WOW, that worked! Thanks for this, MUCH appreciated!!!!
Copy link to clipboard
Copied
@m1b Now we're cookin'! Totally worked, thanks for the help with this!
Copy link to clipboard
Copied
@m1b already fixed your problem.
Can you explain the purpose of this script? I'm trying to understand what it is doing - but for me - it doesn't make much sense?
It iterates through TextFrames collection - instead of Stories - then exports and re-imports into a new document?
Copy link to clipboard
Copied
@Robert at ID-Tasker Its a script that was pulled from the internet to export to RTF. We've used it for the longest time. And whats nice about it is it exports to a single file. Unless you have something better we can utilize?
Copy link to clipboard
Copied
Yes, I have, something truly amazing - unfortunately, it would work directly only on a PC.
But @m1b already gave you a better version of what you had.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
@Robert at ID-Tasker, yes it's quite an odd script, but often that's how scripting goes... just keep scripting away until it works, without a care to the final architecture or strange or unnecessary steps. Oh well, it seems to work. 🙂
Copy link to clipboard
Copied
@MacPhobic, just for fun, and for general learning, here's the way I would script this. (Just did it now, so might need some testing!)
- Mark
/*
* Export Stories As RTF or TXT
* @author m1b
* @discussion https://community.adobe.com/t5/indesign-discussions/adobe-indesign-export-to-rtf-script/m-p/14219040
*/
var MyExportFormats = {
RTF: {
display: 'Rich Text',
fileExtension: 'rtf',
exportFormat: ExportFormat.RTF,
},
TXT: {
display: 'Plain Text',
fileExtension: 'txt',
exportFormat: ExportFormat.TEXT_TYPE,
},
};
function main() {
if (app.documents.length == 0)
return alert("No documents are open. Please open a document and try again.");
exportStoriesAsRTF({
doc: app.activeDocument,
outputFile: undefined, /* can define here or later */
includeStoriesThatStartOnPasteboard: false,
minLengthStory: 30,
showUI: true,
showResult: true,
exportFormat: MyExportFormats.RTF,
});
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Export Document As RTF');
/**
* Export all stories to an RTF file.
* @author m1b
* @version 2023-11-08
* @param {Object} [settings.doc] - an Indesign Document (default: the active document).
* @param {File} [settings.outputFile] - file reference to the .rtf file (default: ask user).
* @param {Boolean} [settings.includeStoriesThatStartOnPasteboard] - whether to export stories that start on the pasteboard (default: false).
* @param {Number} [settings.minLengthStory] - will ignore stories with character counts less than this number (default: 30).
* @param {Boolean} [settings.showUI] - whether to show UI (default: true).
* @param {Boolean} [settings.showResult] - whether to show results (default: true).
* @returns {File} - the exported .rtf file.
*/
function exportStoriesAsRTF(settings) {
// some defaults
settings = settings || {};
settings.minLengthStory = settings.minLengthStory || 30;
settings.includeStoriesThatStartOnPasteboard = settings.includeStoriesThatStartOnPasteboard === true;
var doc = settings.doc = settings.doc || app.activeDocument;
if (
doc == undefined
|| !doc.isValid
)
return alert("Document is invalid.");
if (doc.stories.length == 0)
return alert("The document does not contain any text. Please open a document containing text and try again.");
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
// show UI
if (
settings.showUI
&& ui(settings) == 2
)
// user cancelled UI
return;
// confirm the output file
var exportFile = settings.outputFile || File.saveDialog("Save Exported File As:");
if (exportFile == null)
return;
// make the temporary document
var tempDoc = app.documents.add({
documentPreferences: {
intent: DocumentIntentOptions.PRINT_INTENT,
facingPages: false,
createPrimaryTextFrame: true,
pagesPerDocument: 1,
startPageNumber: 1,
pageHeight: 3000,
pageWidth: 3000,
},
textPreferences: {
limitToMasterTextFrames: true,
smartTextReflow: false,
},
});
// copy filtered stories to the temp document
var stories = doc.stories.everyItem().getElements();
for (var cr, i = stories.length - 1; i >= 0; i--) {
if (stories[i].length < settings.minLengthStory)
// story too short
continue;
if (
settings.includeStoriesThatStartOnPasteboard == false
&& stories[i].textContainers[0].parentPage == null
)
// story starts on pasteboard
continue;
// add carriage returns between stories
cr = stories[i].characters.item(-1).contents == "\r" ? '\r' : cr = '\r\r';
stories[i]
.duplicate(LocationOptions.AT_END, tempDoc.textFrames[0].parentStory.insertionPoints[0])
.insertionPoints.item(-1).contents = cr;
}
var success = false,
f = File(exportFile.fsName.replace(/(\.[^\.]+)?$/, '.' + settings.exportFormat.fileExtension));
try {
// do the export
tempDoc.textFrames[0].parentStory
.exportFile(settings.exportFormat.exportFormat, f);
success = true;
}
catch (error) { alert(error) }
finally {
// clean up
tempDoc.close(SaveOptions.no);
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;
}
if (success && settings.showResult) {
alert(settings.exportFormat.display + ' file has been created.');
if (f.parent.exists)
f.parent.execute();
}
return f;
};
/**
* The UI for this script.
* @param {Object} settings - the settings object for the UI.
* @returns {Number} - ScriptUI result code.
*/
function ui(settings) {
var formats = [],
formatsDisplay = [];
for (var key in MyExportFormats) {
if (MyExportFormats.hasOwnProperty(key)) {
formats.push(MyExportFormats[key]);
formatsDisplay.push(MyExportFormats[key].display);
}
}
var w = new Window('dialog', 'Options'),
panel = w.add('panel', undefined, 'Ignore stories with fewer than this number of characters:'),
minLengthStoryEditText = panel.add('edittext', undefined, settings.minLengthStory),
formatGroup = w.add('group {orientation:"row", alignment:["left","center"], alignChildren:["left","center"], spacing:12, preferredSize: [120,undefined], margins:[10,10,10,10] }'),
formatMenu = formatGroup.add('statictext', undefined, 'Export Format:'),
formatMenu = formatGroup.add('dropdownlist', [20, 20, 130, 29], formatsDisplay),
checkGroup = w.add('group {orientation:"row", alignment:["left","center"], alignChildren:["left","center"], spacing:12, preferredSize: [120,undefined], margins:[10,10,10,10] }'),
includePasteboardCheckBox = checkGroup.add('checkbox { text:"Include stories on pasteboard.", alignment: ["left","center"], value:' + settings.includeStoriesThatStartOnPasteboard + '}'),
okayButton = w.add('button', undefined, 'OK', { name: 'close' });
minLengthStoryEditText.minimumSize.height = 25;
minLengthStoryEditText.minimumSize.width = 100;
includePasteboardCheckBox.value = settings.includeStoriesThatStartOnPasteboard;
formatMenu.selection = 0;
formatMenu.addEventListener('change', function (ev) {
settings.exportFormat = formats[formatMenu.selection.index];
});
okayButton.onClick = function () {
settings.minLengthStory = Number(minLengthStoryEditText.text);
settings.includeStoriesThatStartOnPasteboard = includePasteboardCheckBox.value;
w.close(1);
};
return w.show();
};
EDIT 2023-11-09: added support for Plain Text format.
Copy link to clipboard
Copied
@m1b WORKED! Nice one! Just curious, if we wanted to export to .txt, is that possible? Or would that require a entirely new script?
Copy link to clipboard
Copied
@m1b WORKED! Nice one! Just curious, if we wanted to export to .txt, is that possible? Or would that require a entirely new script?
By @MacPhobic
No, just a simple change to one line.
Copy link to clipboard
Copied
@Robert at ID-Tasker We like simple! Thank you!
Copy link to clipboard
Copied
@MacPhobic I've updated the script above to handle Plain Text.
- Mark
Copy link to clipboard
Copied
@m1b Works like a charm! Thanks for this!
Copy link to clipboard
Copied
Hello! I am a total newbie when it comes to using scripts, but I was hoping to try this one since it seems to do what I need. I tried copying this to a text edit document and then adding it to my Indesign scripts folder as an idjs file. When I tried running it, I got a message that the ExportFormat is not defined. Are there steps that I'm missing? Thanks!
Copy link to clipboard
Copied
Hi @elizabethm1655023, this is ExtendScript code, not UXP, so save it as plain text (rtf won't work) and give it ".js" extension.