Saturday 31 October 2009

JavaScript / VBScript string interpolation

JavaScript (JScript) and VBScript are two pretty nifty programming / automation tools on the windows platform. You can run JS / VBS programs on a plain vanilla Windows XP (or above) PC without installing anything. They can be used for a variety of purposes from automating MS-WORD, EXCEL, Internet explorer etc to doing basic everyday tasks like copying files and folders programmatically. But if you have used them for any length of time then I think you will agree that these languages are not feature complete by any means. But this does not mean that you cannot improvise! Here is my own take on providing formatted string output support for JavaScript and VBScript. Enjoy!


JScript
String.prototype.Trim = function() {
    return this.replace(/^\s\s*/, "").replace(/\s\s*$/, "");;
}


function sprint(str)
{
    var re = /\$(?:\{(.*?)\}|(\w[\w\d]*))/g; //The ? makes the * non-greedy

    var arr;
    var retVal = "";
    var lastIndex = 0;
    
    while ((arr = re.exec(str)) != null)
    {
       retVal += str.substring(lastIndex, arr.index);
       var expr = "";
       for(j=1; j<arr.length; j++)
       {
            if(arr[j].Trim() != "")
            {
                expr = arr[j].Trim();
                break;
            }
       }
       retVal += eval(expr);
       lastIndex = arr.lastIndex;
    }
    
    //Note using substr below and not substring
    retVal += str.substr(lastIndex);
    return retVal;
}


function print(str)
{
    WScript.Echo(sprint(str))
}

/////////////////  USAGE  ///////////////
var greeting  = "Hello"
var firstName = "SDX"
var lastName  = "2000"

var i=1

print("$greeting $firstName ${lastName}!")
print("3+5=${3+5}")
print("Square root of 81 is ${   Math.sqrt(81)   }")
print("${i = i+1}") //increaments i
print("${i == i+1}") //does a comparison
//NOTE: WScript.Echo does not return anything hence you can see an "undefined"
//in the output
print("${WScript.Echo(greeting +\" \" + firstName +\" \" + lastName)}")

Output

Hello SDX 2000!
3+5=8
Square root of 81 is 9
2
false
Hello SDX 2000
undefined


VBScript
option explicit

dim firstName, lastName, greeting


function sprint(str)
    Dim regEx, matches, match, subMatch, smatches, i, expr
    set regEx = new RegExp
    regEx.IgnoreCase = true ' This is VBScript after all
    regEx.Global = true
    regEx.Pattern = "\$(?:\{(.*?)\}|(\w[\w\d]*))" 'The ? makes the * non-greedy
    
    set matches = regEx.Execute(str)
    
    for each match in matches
        for i=0 to match.SubMatches.Count-1 'Unable to 'for each' over SubMatches for some reason
            if trim(match.SubMatches(i)) <> "" then
                expr = trim(match.SubMatches(i))
            end if
        next
        
        str = replace(str, Match.Value, eval(expr)) 'Note this will replace all instances of the expression
    next
    sprint = str
end function

sub print(str)
    WScript.Echo sprint(str)
end sub

' *************  USAGE  ************
greeting  = "Hello"
firstName = "SDX"
lastName  = "2000"

dim i
i=1

print "$greeting $firstName ${LastName}!"
print "3+5=${3+5}"
print "Square root of 81 is ${sqr(81)}"
print "${i = i+1}" 'Prints false; does not increment i
print "${msgbox(firstName & lastName,0,greeting)}"

Output

Hello SDX 2000!
3+5=8
Square root of 81 is 9
False
1

No comments:

Post a Comment