IRScript: The Image Rodeo Scripting Language

Overview

IRML is HTML with IRScript statements contained within SGML processing tags (<? ?>). Anything outside the tags is considered HTML and passed along to the resulting HTML file. Anything inside the SGML processing tags is considered IRScript.

You can include anything that’s legal in a HTML file, and even stuff that’s not legal, with the exception of anything that also uses the <? ?> tags (such as PHP). Image Rodeo doesn’t interpret the HTML, it just passes it along.

Unlike JavaScript, IRScript statements consist of all the text inside the SGML processing tags, no matter where they appear in the HTML. This means that IRScript can appear (and often does appear) inside HTML tags. For example:

<img src="thumb/<?echo uid;?>.jpg" width="<?echo tw;?>" height="<?echo th;?>">

The echo statement is used to write a string into the HTML stream at the point where it was found. When the web site is built, and the IRScript statements are executed, the fragment above could generate:

<img src="thumb/1.jpg" width="100" height="75">

Of course, the exact HTML generated depends on the values of the uid, tw and th variables.

Syntax

IRScript syntax is loosely based on JavaScript syntax, which itself is loosely based on “C” syntax. This is strictly to avoid defining a new syntax – you’ll find that many key features of JavaScript (such as objects) are missing.

<? /* This is a comment. Note that // is not supported! */ ?>
<? echo "hello, world"; ?>

Normally it makes sense to look at an IRML file as HTML with embedded IRScript tags, but it’s possible to turn that inside-out: you can consider an IRML file as IRScript with embedded HTML. Consider this fragment:

<?for (i = 0; i < pages; i = i + 1) {?><a href="<?echo pages[i].uid;?>.html"><?echo pages[i].title;?></a> <?}?>

This rather complicated fragment can be indented to highlight the nested characteristics of both IRScript and HTML:

<?for (i = 0; i < pages; i = i + 1) {?>
    <a href="<?echo pages[i].uid;?>.html">
        <?echo pages[i].title;?>
    </a>
<?}?>

This is fairly readable, but it has the side effect of generating more white space – which the browser will remove, but which wastes a little space and bandwidth. As a further refinement we could substitute echo statements for the inside-out tags:

<?
for (i = 0; i < pages; i = i + 1) {
    echo '<a href="';
    echo pages[i].uid;
    echo '.html">';
    echo pages[i].title;
    echo '</a> ';
}
?>

Which style you use depends on your personal preferences.

Statements

IRScript consists of a sequence of statements separated by semicolons. You can combine statements in blocks using braces ({}). The braces don’t affect variable scoping – it’s always global.

In this and subsequent sections the <? ?> tags are omitted for clarity.

Assignment

Like many languages, IRScript assignment is a hybrid between a statement and an expression. In the simple form it looks like this:

foo = 1;
bar = foo + 1;

However, it also evaluates to an expression, so you can use forms such as:

foo = bar = 2;

Echo

The echo statement is the workhorse of IRScript. It writes strings into the HTML stream being generated. Two examples:

echo "Hello, world.";    /* Writes a string into the HTML stream. */
echo foo;                /* Writes the contents of a variable into the HTML stream. */

If-Else

If-else statements work just like “C” and JavaScript. The expression inside the ( ) is coerced to an integer if necessary. 0 means false; any other integer means true.

if (foo == 1)
    echo "Foo is 1";

if (foo == 1) {
    echo "Foo is 1";
} else if (foo == 2) {
    echo "Foo is 2";
} else {
    echo "Foo is something else";
}

For-Loop

For loops are similar to “C” or JavaScript. There’s an initializer expression, a test expression, and an increment expression. The test expression is coerced to an integer if necessary. 0 means false, any other value means true.

for (i = 0; i < count; i = i + 1) {
    echo "Iteration #";
    echo i;
    echo "<p>";
}

Types

IRScript supports two simple types with fairly typical semantics: integer and string. The real power, though, lies in the access to Image Rodeo’s internal objects, which can be considered types.

Integers

There’s no boolean type, but IRScript applies boolean semantics to integers. Boolean expressions (if statements, etc.) consider 0 to be false, and any other integer to be true. Boolean expressions always return an integer (0 or 1).

Integer literals have the usual forms: 0, -1, 12334, etc. You can use the standard math operators on integers. See Operators.

Strings

Strings consist of sequences of Latin-1 characters (ISO 8859-1).

String literals may be surrounded by foot (') or inch (") marks, depending on the situation. There are only two operators that work with strings: == (equality) and != (inequality).

Arrays

Arrays are ordered collections of objects. IRScript does not allow you to create new arrays, so the only way to get an array is to reference an object property that returns an array. Once you have an array you can get at any element using the subscript ([]) operator. Arrays start at 0, not 1.

echo myArray[0];    /* Note that arrays start with 0 - like "C" and JavaScript. */

There are no array literals.

Objects

An object is a bundle of properties. IRScript does not allow you to define new object types, but you do have access to four built-in Image Rodeo internal object types:

firstPage = pages[0];
titleOfFirstPage = firstPage.title;
titleOfSecondPage = pages[1].title;
titleOfTheTopLevelPage = document.indexPage.title;

The four built-in object types are: page, photo page, index page, and document. In addition, there’s one abstract object type: the page. A page may be either an index page or a photo page. (O-O programmers will note that photo page and index page subclass from page.)

There are no object literals. A property that returns an object may return nothing at all – it’s as if you referenced an unassigned variable. You can test for this by taking advantage of a quirk in type conversion:

if (previous) {
    echo '<a href="';
    echo previous.uid;
    echo '.html">Previous</a>';
}

Type Conversion

All of the types may be converted to an integer or a string, although the conversion isn’t always meaningful. Conversion is based on context; there’s no explicit conversion operator.

Objects and Properties

Page Object

The page object is an abstract type, so you’ll never actually see a page object. Instead, you’ll see a photo page object or index page object. If you have a page object and you want to find out what sort of object it is (photo or index), test the isIndex property:

if (page.isindex) {
    echo "This is an index page.";
} else {
    echo "This is a photo page.";
}

As a convenience, the current page object is referred to as this. All page objects have properties such as uid, title, previous, and next.

Photo Page Object

All photo page objects have these properties in addition to the page properties outlined above, including source (the path to the source JPEG), caption, and image dimensions.

Index Page Object

All index page objects have these properties in addition to the page properties outlined above, including pages (the array of child pages/photos) and columns.

Document Object

The document object represents the entire web site. It has properties such as indexPage (the top-level index page), columns, thumbnailSize, photoSize, showPhotoTitles, and showThumbnailTitles.

Application Object

The application object has properties such as name and version.

Operators

IRScript supports the usual collection of integer operators, and a few odd ones for good measure. The usual collection of boolean operators is also supported, but note that there is no boolean type, so boolean operators work on and return integers.

  • Math: + - * / %
  • Comparison: == != < > <= >=
  • Boolean: && || !
  • String: == !=
  • Subscript: []
  • Member: .

Variables

Variables in IRScript are typeless, and do not have to be declared before being used. To create a variable simply assign something to it. It will hold that value until all the IRScript statements in a single IRML file have finished executing. All variables have global scope.

Access to the built-in objects is provided by adding all the properties for the active page to the global scope. IRScript runs in the context of an IRML file, and each file corresponds to a page object, so all the page’s properties are available directly.

When searching for variables, any user-defined variables are searched first. Watch out! It’s possible to lose access to the built-in objects by assigning values to user-defined variables of the same name.

if (isIndex) {
    /* Must be an index page; dump the pages array. */
    echo pages;
} else {
    /* Must be a photo page; dump the source path. */
    echo source;
}

It’s OK to reference a variable before it’s been assigned anything – it will simply return nothing. This ‘nothing’ value will be converted to 0 (integer) or the empty string ("") if necessary.