Full-width to half-width script. Performance improvement
The following indesign script searches full-width alphabets and numerals and converts them to half-width, but is way too low. Any suggestions for performance improvement?
(function () {
if (!app.documents.length) {
alert("No document is open.");
return;
}
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Convert Full-width Alphanumeric Characters");
function main() {
// Settings dialog
var dialog = app.dialogs.add({ name: "Convert Full-width Alphanumerics to Half-width" });
with (dialog.dialogColumns.add()) {
staticTexts.add({ staticLabel: "Please select the type of characters to convert:" });
var typeGroup = radiobuttonGroups.add();
with (typeGroup) {
radiobuttonControls.add({ staticLabel: "Alphabet only"});
radiobuttonControls.add({ staticLabel: "Numbers only" });
radiobuttonControls.add({ staticLabel: "Both alphabets and numbers", checkedState: true });
}
with(dialogRows.add()) staticTexts.add({ staticLabel: "" });
with(dialogRows.add()) staticTexts.add({ staticLabel: "Scope of conversion:" });
var scopeCheckbox = checkboxControls.add({ staticLabel: "Convert only selected text", checkedState: false });
with(dialogRows.add()) staticTexts.add({ staticLabel: "" });
with(dialogRows.add()) staticTexts.add({ staticLabel: "Show preview?" });
var previewCheckbox = checkboxControls.add({ staticLabel: "Review changes before converting", checkedState: false });
with(dialogRows.add()) staticTexts.add({ staticLabel: "" });
with(dialogRows.add()) staticTexts.add({ staticLabel: "Save log?" });
var logCheckbox = checkboxControls.add({ staticLabel: "Save conversion details to log file", checkedState: true });
}
var userChoice, selectionOnly, logging, doPreview;
if (dialog.show() === true) {
userChoice = typeGroup.selectedButton;
selectionOnly = scopeCheckbox.checkedState;
logging = logCheckbox.checkedState;
doPreview = previewCheckbox.checkedState;
dialog.destroy();
} else {
dialog.destroy();
return;
}
var targets = [];
if (selectionOnly) {
if (app.selection.length === 0) {
alert("No text is selected.");
return;
}
for (var i = 0; i < app.selection.length; i++) {
if (app.selection[i].hasOwnProperty("characters")) {
targets.push(app.selection[i]);
}
}
if (targets.length === 0) {
alert("Selected object does not contain text.");
return;
}
} else {
targets = app.activeDocument.stories.everyItem().getElements();
}
function convertChar(ch) {
var code = ch.charCodeAt(0);
if ((userChoice === 1 || userChoice === 2) && code >= 0xFF10 && code <= 0xFF19) {
return String.fromCharCode(code - 0xFEE0);
}
if ((userChoice === 0 || userChoice === 2) &&
((code >= 0xFF21 && code <= 0xFF3A) || (code >= 0xFF41 && code <= 0xFF5A))) {
return String.fromCharCode(code - 0xFEE0);
}
return null;
}
var changeLog = [];
var previewChanges = [];
// Prepare preview
for (var i = 0; i < targets.length; i++) {
var chars = targets[i].characters;
for (var j = 0; j < chars.length; j++) {
var original = String(chars[j].contents);
var replacement = convertChar(original);
if (replacement !== null) {
previewChanges.push("Story " + i + " / Character " + j + ": " + original + " → " + replacement);
}
}
}
if (previewChanges.length === 0) {
alert("No full-width alphanumerics found to convert.");
return;
}
if (doPreview) {
var previewDialog = new Window("dialog", "Conversion Preview");
previewDialog.orientation = "column";
previewDialog.alignChildren = "fill";
previewDialog.add("statictext", undefined, "The following changes will be made:");
var listBox = previewDialog.add("edittext", undefined, previewChanges.join("\r"), {
multiline: true,
scrolling: true
});
listBox.minimumSize.height = 300;
listBox.minimumSize.width = 500;
var buttonGroup = previewDialog.add("group");
buttonGroup.alignment = "center";
buttonGroup.add("button", undefined, "Execute Conversion", { name: "ok" });
buttonGroup.add("button", undefined, "Cancel", { name: "cancel" });
if (!previewDialog.show()) {
return;
}
}
// Execution
var applied = 0;
for (var i = 0; i < targets.length; i++) {
var chars = targets[i].characters;
for (var j = 0; j < chars.length; j++) {
var original = String(chars[j].contents);
var replacement = convertChar(original);
if (replacement !== null) {
chars[j].contents = replacement;
if (logging) {
changeLog.push("Story " + i + " / Character " + j + ": " + original + " → " + replacement);
}
applied++;
}
}
}
// Write log
if (logging && changeLog.length > 0) {
try {
var logFile = File.saveDialog("Please select location to save the log file", "Text File:*.txt");
if (logFile) {
logFile.encoding = "UTF-8";
logFile.open("w");
logFile.write(changeLog.join("\n"));
logFile.close();
}
} catch (e) {
alert("Failed to save the log file: " + e.message);
}
}
alert(applied + " conversions completed. Use 'Edit > Undo' to revert changes.");
}
})();
