Here is one of my favorite bits of code from xtools/xlib/stdlib.js: File.strf(). It's a handy routine for getting the file extension, base file name, etc... and doing interesting things with them usually to create new file names.
Here's the docs:
File.strf(fmt [, fs])
Folder.strf(fmt [, fs])
This is based of the file name formatting facility in exiftool. Part of
the description is copied directly from there. You can find exiftool at:
http://www.sno.phy.queensu.ca/~phil/exiftool/
Description:
Format a file string using a printf-like format string
fmt is a string where the following substitutions occur
%d - the directory name (no trailing /)
%f - the file name without the extension
%e - the file extension without the leading '.'
%p - the name of the parent folder
%% - the '%' character
If fs is true the folder is in local file system format (Windows only)
(e.g. C:\images instead of /c/images)
Examples:
Reformat the file name:
var f = new File("/c/work/test.jpg");
f.strf("%d/%f_%e.txt") == "/c/work/test_jpg.txt"
Change the file extension
f.strf("%d/%f.psd") == "/c/work/test.psd"
Convert to a file name in a subdirectory named after the extension
f.strf("%d/%e/%f.%e") == "/c/work/jpg/test.jpg"
Change the file extension and convert to a file name in a subdirectory named
after the new extension
f.strf("%d/psd/%f.psd") == "/c/work/psd/test.psd"
Handle '.xxx' files
var f = new File("~/.bashrc");
f.strf("%f") == ".bashrc"
f.strf("%e") == ""
Advanced Substitution
A substring of the original file name, directory or extension may be
taken by specifying a string length immediately following the % character.
If the length is negative, the substring is taken from the end. The
substring position (characters to ignore at the start or end of the
string) may be given by a second optional value after a decimal point.
For example:
var f = new File("Picture-123.jpg");
f.strf("%7f.psd") == "Picture.psd"
f.strf("%-.4f.psd") == "Picture.psd"
f.strf("%7f.%-3f") == "Picture.123"
f.strf("Meta%-3.1f.xmp") == "Meta12.xmp"
Note that other format specifiers (like %d and %s) are silently passed through in case you need to process the string with another sprintf-like function.
And here's the code. Careful use of RegExp makes this relatively easy.
Code: Select allFile.prototype.strf = function(fmt, fs) {
var self = this;
var name = decodeURI(self.name);
//var name = (self.name);
// get the portions of the full path name
// extension
var m = name.match(/.+\.([^\.\/]+)$/);
var e = m ? m[1] : '';
// basename
m = name.match(/(.+)\.[^\.\/]+$/);
var f = m ? m[1] : name;
fs |= !($.os.match(/windows/i)); // fs only matters on Windows
// fs |= isMac();
// full path...
var d = decodeURI((fs ? self.parent.fsName : self.parent.absoluteURI));
// parent directory...
var p = decodeURI(self.parent.name);
//var d = ((fs ? self.parent.fsName : self.parent.toString()));
var str = fmt;
// a regexp for the format specifiers
var rex = /([^%]*)%(-)?(\d+)?(\.\d+)?(%|d|e|f|p)(.*)/;
var result = '';
while (m = rex.exec(str)) {
var pre = m[1];
var sig = m[2];
var len = m[3];
var ign = m[4];
var typ = m[5];
var post = m[6];
var subst = '';
if (typ == '%') {
subst = '%';
} else {
var s = '';
switch (typ) {
case 'd': s = d; break;
case 'e': s = e; break;
case 'f': s = f; break;
case 'p': s = p; break;
// default: s = "%" + typ; break; // let others pass through
}
var strlen = s.length;
if (strlen && (len || ign)) {
ign = (ign ? Number(ign.slice(1)) : 0);
if (len) {
len = Number(len);
if (sig) {
var _idx = strlen - len - ign;
subst = s.slice(_idx, _idx+len);
} else {
subst = s.slice(ign, ign+len);
}
} else {
if (sig) {
subst = s.slice(0, strlen-ign);
} else {
subst = s.slice(ign);
}
}
} else {
subst = s;
}
}
result += pre + subst;
str = post;
}
result += str;
return result;
};
Folder.prototype.strf = File.prototype.strf;
-X