Tuesday, December 1, 2009: JScript Hypertext Preprocessor « from the old blog archive »

I and my team are in a HTML website making competition. We can use only text editors and other tools unrelated to building websites. Here's what they have

  • Windows XP
  • Adobe Photoshop
  • Macromedia Flash (Yes, Macromedia.)

I asked the staff to let my team install some more applications:

  • Notepad2
  • GIMP

With these 2 applications, I can write HTML codes more comfortable.

But I still need a way to quickly generate templates (e.g. the header, menu, footer) so when I change something I don't have to edit all the files. Something like a templating system. It makes me think of Windows Scripting Host. What about making a .bat file that runs a JScript script that processes text file?

So I wrote this something that I call it "JScript Hypertext Preprocessor." I will start by creating a working directory for the web. In this post I will refer as "C:\Web". Create the directory structure as follows:

  • C:\Web - The working directory.
  • C:\Web\Dev - All the website files will stay in here.
  • C:\Web\Dev\include - The .jshp files that you don't want to make it publicly available.

And these 2 little file.

C:\Web\Build.bat

cd %0\..

cd Dev
for /r %%i in (*.jshp) do wscript ..\Eval.js %%i
cd ..

del /s /q Publish
xcopy /s /i Dev Publish
cd Publish
del /s *.jshp
rmdir /s /q include
cd ..

C:\Web\Eval.js

var _sh = WScript.createObject('WScript.Shell');
var _fs = WScript.createObject('Scripting.FileSystemObject');
var _sn = WScript.arguments(0);
var _ob = '';

function alert(x) {
    _sh.popup (x + '');
}

function include(x) {
    var file = _fs.openTextFile(x, 1);
    var content = file.readAll();
    file.close ();
    return content.replace(/[^<]+|\<\?jshp([\s\S]*?)\?\>\s*|\<\?=([\s\S]*?)\?\>\s*|[\s\S]/g, function(a, b, c) {
        if (b) {
            return b + '\n';
        }
        if (c) {
            return 'output(\'\' + eval(unescape(\'' + escape(c) + '\')));\n';
        }
        return 'output(unescape(\'' + escape(a) + '\'));\n';
    });
}

function output(x) {
    _ob += (x);
}

echo = output;
print = output;

function output_file() {
    if (_ob.match(/^\s*$/)) return;
    var file = _fs.createTextFile(_sn.substr(0, _sn.length - 4) + 'html', true);
    file.write (_ob);
    file.close ();
}

eval (include(_sn));
output_file ();

Very tiny, isn't it?

Now, to use it, I will show you some bit of code.

C:\Web\Dev\index.jshp

<?jshp eval(include('include/config.jshp')) ?>
<!DOCTYPE html>
<title>Homepage - <?= siteTitle; ?></title>
<body>
<h1>PI = <?=Math.PI?>!!</h1>
<p><?jshp
     showGenerated ();
?></p>
</body>

C:\Web\Dev\include\config.jshp

<?jshp

var siteTitle = 'My Web Site Title';

function showGenerated() {
 print ('Generated: ' + new Date().toString());
}

?>

Then double click on "Build.bat".

If you go and look into the "Dev" directory, you will see that "index.html" file is generated. It is generated from .jshp file.

.html file is generated from .jshp file.

You will note that there is also a directory called "Publish."

That directory is, in fact, a copy of the "Dev" directory, with .jshp files and the include directory removed.

Here are the list of functions you can use:

  • Functions from JScript.
  • alert(text) - Displays an alert.
  • output(blah), print(blah), echo(blah) - Prints the text into the .html file.
  • eval(include('filename')) - Like include in PHP.
  • print(include('filename')) - Like readfile in PHP.

The open and close tags are <?jshp and ?>. I use the PHP styles because text editors with syntax highlighting will treat it as PHP code.

Oh and about the competition, here is the list of scoring points:

  • Use frames (10 points)
  • Beautifulness of design (10 points)
  • Use of animations (10 points)
  • Content layouts (10 points)
  • And something I didn't remember (10 points)

I didn't use frames because I can't remember how to write it. However I used an iframe on one page. I hope that it counts as frames!

For animations, I just use a subtle animation in the header part so that it does not distract the whole page.

When the result is out I will tell you.