Saturday, August 27, 2005
Script of the Day -- Smart Title Case
I posted a version of this script on the Adobe U2U forum just the other day. This is an improved version that will use text files for the two lists (words that stay lowercase and words with internal capitals) rather than requiring you to edit the script itself. But I get ahead of myself. Let me start by explaining what I mean by "Smart" Title Case.
In the InDesign user interface, you can select some text and then choose Title Case from the Change Case submenu of the Type menu. If you do this, InDesign simply gives each selected word an initial cap, forcing the rest of the word to lowercase. So, if you type:
And, as is so often the case, I no sooner publish a script and I realize there's a problem with it. What if the first word in a title is a word like "iTunes"? You surely don't want it to be represented by "ITunes" and yet that's what this script will do. I need to come up with a mechanism for for dealing with this (although you could just choose to not select the first character and the script will then work in this situation).
It is also worth pointing out that the technique employed here will cause any internal character styling to be lost, unless the character styling is applied by a nested style. In all my use of this script over the past two or more years, this has never mattered.
In the InDesign user interface, you can select some text and then choose Title Case from the Change Case submenu of the Type menu. If you do this, InDesign simply gives each selected word an initial cap, forcing the rest of the word to lowercase. So, if you type:
- this is an indesign test
- This Is An Indesign Test
- This is an InDesign Test
//DESCRIPTION: Converts selected text to title case smartly
// Customize this script by either editing these arrays:
var ignoreWords = ["a","an","and","the","to","with","in","on",
"as","of","or","at","is","into","by","from","for"];
var intCaps = ["PineRidge","InDesign","NJ","UMC"];
// or by creating text files named ignoreWords.txt
// and intCaps.txt in the script's folder
ignoreWords = getIgnoreFile(ignoreWords);
intCaps = getIntCaps(intCaps);
try {
myText = app.selection[0].texts[0].contents;
} catch(e) {
exit();
}
theWords = myText.toLowerCase().split(" ");
//First word must have a cap, but might have an internal cap
myNewText = "";
for (var j = 0; theWords.length > j; j++) {
k = isIn(intCaps,theWords[j])
if (k > -1) {
myNewText = myNewText + intCaps[k] + " ";
continue;
} else {
if ((isIn(ignoreWords,theWords[j]) > -1) && (j != 0)) {
myNewText = myNewText + theWords[j] + " ";
} else {
myNewText = myNewText + InitCap(theWords[j]) + " ";
}
}
}
app.selection[0].texts[0].contents = myNewText.substring(0,myNewText.length - 1);
// +++++++ Functions Start Here +++++++++++++++++++++++
function getIgnoreFile(theWords) {
var myFile = File(File(getScriptPath()).parent.fsName + "/ignoreWords.txt");
if (!myFile.exists) { return theWords }
// File exists, so use it instead
myFile.open("r");
var importedWords = myFile.read();
myFile.close();
return importedWords.split("\n"); // Could filter these, but what's the point?
}
function getIntCaps(theWords) {
var myFile = File(File(getScriptPath()).parent.fsName + "/intCaps.txt");
if (!myFile.exists) { return theWords }
// File exists, so use it instead
myFile.open("r");
var importedWords = myFile.read();
myFile.close();
return importedWords.split("\n"); // Could filter these, but what's the point?
}
function getScriptPath() {
// This function returns the path to the active script, even when running ESTK
try {
return app.activeScript;
} catch(e) {
return e.fileName;
}
}
function isIn(aList,aWord) {
for (var i = 0; aList.length > i; i++) {
if (aList[i].toLowerCase() == aWord) {
return i;
}
}
return -1;
}
function InitCap(aWord) {
if (aWord.length == 1) {
return (aWord.toUpperCase());
}
return (aWord.substr(0,1).toUpperCase() + aWord.substring(1,aWord.length))
}
And, as is so often the case, I no sooner publish a script and I realize there's a problem with it. What if the first word in a title is a word like "iTunes"? You surely don't want it to be represented by "ITunes" and yet that's what this script will do. I need to come up with a mechanism for for dealing with this (although you could just choose to not select the first character and the script will then work in this situation).
It is also worth pointing out that the technique employed here will cause any internal character styling to be lost, unless the character styling is applied by a nested style. In all my use of this script over the past two or more years, this has never mattered.
Comments:
<< Home
I'm wondering how much value there is in just listing the scripts here. Why not just let them be available for download and leave it at that?
Perhaps what's needed is a place where the scripts are decomposed and described in detail. Perhaps a second Blog aimed at providing such detail to those who are interested.
Dave
Perhaps what's needed is a place where the scripts are decomposed and described in detail. Perhaps a second Blog aimed at providing such detail to those who are interested.
Dave
Keep the (smaller) scripts visible, as here.
I can see what you are doing, and can copy/paste or adapt from this.
If it was a d/l, I'd have ignored it and *maybe* re-invent.
Larger scripts would be a different matter.
I can see what you are doing, and can copy/paste or adapt from this.
If it was a d/l, I'd have ignored it and *maybe* re-invent.
Larger scripts would be a different matter.
This was a godsend!!
Once I changed the file name to .jsx and dropped it in "\\Adobe InDesign CS3\Scripts\Scripts Panel\Version 4.0 Scripts\" it worked like a charm.
I'm glad I spent the hour tracking it down as it will save me many many hours in the future!
Thanks!
Post a Comment
Once I changed the file name to .jsx and dropped it in "\\Adobe InDesign CS3\Scripts\Scripts Panel\Version 4.0 Scripts\" it worked like a charm.
I'm glad I spent the hour tracking it down as it will save me many many hours in the future!
Thanks!
<< Home