Language Reference
by Helmut Emmelmann, PhD

General Design Considerations

heitml has the following design goals:

  • heitml is a monolithic language, providing a seemless integration between itself and HTML. The fact that part of the application runs on the server and part on the client's Web Browser is transparent to the User and of no concern.
  • heitml is an integrated Document Description Language, Template Generation Language, Scripting Language and Full-featured Programming language.
  • heitml was created especially for Database Applications, but due to its modular, re-usable approach to Web Page design and maintenance, it should prove beneficial to anyone working in the field of Web Publishing.
  • heitml applications are portable among Operating Systems, Browsers, (SQL) Database Systems, and Webservers.
  • heitml is designed to be a secure language, freeing Web Administrators from many of the usual concerns they encounter when various applications and scripting languages interact with one another.
Because heitml is a monolithic language, Users are shielded from extraneous technical details normally encountered when working with Scripting Languages. All functions related to an application are called using the same Syntax and Parameter passing mechanism, regardless of whether it is a Browser-, Server-, Programming Language, or User-defined function.

Document Description and Template Languages are easy and straight forward for simple applications. However, there usually comes a point when an application grows so complex that a Programming Language provides a better solution. heitml is designed to integrate these types of languages, and not just glue them together as we have seen in previous approaches to Web Publishing.


heitml as a Monolithic Language

heitml was designed as an extension of HTML. The idea is to deliver a single integrated tool which enables Users to get their Applications up and running quickly and with minimum effort..

Currently, most Web Application Developers use a development model which involves Scripting Languages to produce HTML, which is then sent to the Browser for interpretation.

heitml offers a new approach, illustrated by the following example:

 <if 0 <amount >
   Please send us the amount of $ <? amount>. 
   <br> 
 <else>
   We will send you 
   <font color="red"> $<? -amount> </font>.
   <br> 
 </if>

We assume the value amount was obtained from a database. If amount is positive, the above code fragment prints "Please send us the amount of...", and if it is negative "We will send you ..." appears on the User's screen. (In the latter case amount should be displayed in red.)

Previously, (using a hypothetical Scripting Language) the same process would look something like this:


 if 0<amount; 
    echo "Please send us the amount of "; 
    echo  amount;
    echo "<br> \\n";
 else
    echo "We will send you; 
    echo <font color=\"red\"> $";
    echo -amount;
    echo "</font><br>\\n";
 /if

Although both approaches use a control statement in the form of
if - else - endif, there are a number of artifacts of the Scripting Language which serve only to add complexity to what really should be a quite simple task.

First, the Scripting Language requires a special command (in this case the echo statement) to send output to the Browser. Also, text has to be enclosed in quotation marks in order to distinguish it from variables (in this case amount).

Because the Scripting Language requires quotation marks to handle text, it runs into difficulties when passing values to HTML Tags that also require them. Hence, yet another artifact is introduced, namely the backslash or escape character "\" as seen in the <FONT> Tag above.

However the biggest drawback is that the <FONT> Tag is called in a completely different syntax (inside the echo) than the if. This constantly reminds a programmer of the fact that he is actually writing a program that is generating some other program (in this case, an HTML page) which is then interpreted and displayed. The programmer must forever distinguish between Scripting Lanugage and HTML functionality.

This unneccessay complexity is always present during development, distracting the User from the real problem and so slowing down the development process and increasing the error rate.

heitml avoids all of these problems by offering a syntactically similar environment to HTML. Note that in the heitml example text and variables can be handled on the same line. The <? > Tag asks the question "What is?" and passes information to HTML in text format, exactly as required. The Tag also begins and ends with less-than / greater-than symbols, giving it the familiar appearance of an HTML Tag. Finally, the HTML <br> Tag signals the end of a line, bringing things to a logical conclusion.

Besides Scripting Languages, Template Tools are used for Web-applications. Template Tools avoid writing the echo statements of the Scripting Language, but most of them still use a very different syntax for their commands than HTML uses, and these differences create difficulties that often leads to confusion in the mind of the programmer.

With the design of heitml there is no principle difference between the <if> Tag and the <font> Tag. Both are functions of the heitml "Programming Language". You don't have to know what runs on the Browser and what happens on the Server.

All heitml Tags are used in the same manner as HTML Tags, with the same syntax, parameter passing convention etc.

Furthermore, heitml allows you to define your own Tags in the HTML style, which means you can extened HTML in your own manner, to suit your own purposes, and not have to worry about compatibility with any current or future HTML standards.

Consider what a typical Template Generator requires of you:
  • Put !--% (or some other special syntax) in front of every non-HTML Tag

    Try doing that and see if you can avoid thinking of which Tag is processed by the Browser and which by the Server. By their very nature, such a Template Language constantly throws their differences in your face, forcing you to keep track of where you are - i.e. which environment you're working in at the time.

    It's like typing a letter while having to insert !--% in front of every noun, and at the same time avoid thinking of whether a word is a noun or not. It's really quite impossible.

And here's a situation we've encountered more times than we care to remember:
  • Explain to an HTML User (who is not a professional programmer) the difference between inserting <databaseform> and <!--%databaseform> into his HTML document.

    (Now try doing the same thing over the phone.)


heitml as an integrated Template
and Programming Language

Template or Macro languages usually work well in simple cases, but as soon as an application gets complicated you run into problems. This often happens simply because Template Languages are not powerful enough, or they do not take advantage of well-known Programming Language concepts. Unfortunately, even when they do embrace high-level Language features, all too often we wind up using cumbersome Syntactical constructs that make Source Code listings difficult to read.

We often see Template Languages and Programming Languages used in concert with one another. This approach is at least workable, since you can solve all your application problems with it. But it has the drawback that you have to use two languages instead of one, which doubles your learning effort. (In some cases it can be successfully argued that problems related to the interface of these languages actually quadruples the total complexity associated with getting an application up and running.)

The solutions heitml provides to address these problems are many.

First, heitml is a full featured, professional Programming Language. Everything you expect to find in a modern-day Programming Language is contained within heitml: Procedures, Functions, Local Variables, Recursion, Parameter Passing, etc.

heitml is, however, a Template Language and a Programming Language at the same time, and the following examples show how the heitml Syntax manages to bring these two diverse models into harmony with each other:

First, we look at a code fragment:

<if a==5> Hello World </if>

Are we looking at an if Tag followed by some text and an end-if Tag? This is certainly a traditional HTML-centric view, as can be seen by an illustration following the same format, but with different Tags:

<font size=5> Hello World </font>

While HTML has trained us to look at things this way, the following code fragment shows that we could just as easily view things from a different perspective:


 if a==5
  > Hello World < 
 /if

We now see that the if statement contains the text Hello World wrapped in > ... < brackets. In other words, we could think of heitml as a Programming Language that contains a > Text < construct, the function of which is to display text.

For example:


 i=1;
 while i<10;
  > The square of <  ?i  > is <  ?i*i  > <br> < 
  let i=i+1;
 /while;

The > Text < construct appears three times in the above example. Everything else is what we would normally view as high-level Language contructs such as control statements and expression evaluation routines.

While newcomers to the heitml Language may feel more comfortable staying with the traditional HTML Tag-oriented view of things, we feel certain that as time goes on, the heitml Programming Language view will become dominant. It will likely be a gradual, almost invisible process, but as one begins to develop applications with thoughts in mind such as, "What if User A has an old Browser and User B has the latest, supporting FRAMES, JavaScripts, etc.? How can I design a single Template to handle both cases?"

Another thought might be, "How can I tailor my Applications to respond to Users with different interests?"

As time goes on, you'll find yourself thinking more and more in terms of if THIS then I'll do THAT, and while This condition remains true, I'll present This specific view of a database. After awhile, you'll realize that you've made the transition from a Tag-oriented to a process oriented mindset, and you'll wonder how you ever got along without it.

User-defined Tags in heitml work just like Procedure Calls of a Programming Language, and that's where the true power lies in developing next-generation Web Applications.


heitml as a Database Language

heitml contains special features to integrate with SQL, so writing database programs becomes a straight-forward process.

Additionally, heitml has a built in tuple data type, which is very convenient when programming database applications. It can be used like a struct in C. It can directly be passed to the database, and it can even be used anonymously without knowing the individual field names.

The tuple data type is dynamic. That means fields can dynamically be added. Tuples can be compared and assigned as a whole, in which case pointer semantics apply as in modern Object Oriented Languages.


heitml is Designed to be Safe and Portable

heitml Pages can be ported to many different kinds of systems. This means that applications are independent of the underlying Operating System, the Web Server, and the Database System.

heitml is designed to be safe - i.e. heitml programs can not produce core dumps and they can access only certain system resources. The latter feature makes it possible to upload heitml Pages to an Internet Provider's Website without the usual security risks associated with programs that contain CGI scripts.

Actually, this has been achieved by leaving out features, rather than including them. heitml pages do not have access to files, they can not access operating system functions, and they can not access special (non-standard) features of a particular Database System. Interfaces to system components have their own definition in heitml. They are not realized by making available the functional interfaces of specific components.

It should be noted, however, that Web Server Administrators can link User written C libraries to heitml, and adaptations can be made to the database interface. Although system specific needs can be met in this manner, portability comes to an end here, as well as when a non-standard SQL implementation is used.


Lexical Structure

Input text can be processed in

Different lexical rules apply for each mode, but heitml comments are allowed within all modes. A comment starts with two forward-slash marks "//" followed by a whitespace character such as a Space or Tab, and extends until the end of the line. Also, text enclosed in "/*" and "*/" is interpreted as a comment.

Text processed in HTML mode is left unchanged (except for comments). Based on the context, the text is either sent to the browser, assigned to a variable, send by email, written to a file, or interpreted as a SQL command. heitml starts to process a document in HTML mode and to send it to the browser. HTML mode ends as soon as a heitml-tag or a user defined tag is encounterd. All the text inside the < > brackets of a heitml or user defined tag is processed in expression mode.

In expression mode the following lexical tokens can occur:
  1. Identifiers - created from any combination of case insensitive letters, digits, the underscore character '_', and the dollar sign '$', but must always begin with a letter.
  2. Integer constants - a sequence of numbers
  3. Real constants - composed of numbers plus a decimal point ".", followed by more number(s) and, optionally, an exponent in the following format: [E [+\-] number(s)]
  4. String constants - enclosed in double-quote marks. However, to include double-quotes within the constant, they must be preceded by the backslash symbol "\". To include a backslash as part of the string, you must enter the backslash character twice "\\".
  5. Operator Symbols
  6. Reserved Words - currently true, false, null, emptytuple, html, furl, quoted, dbhtml, input, cdfn, and hstv are reserved words.

White space (including new lines) is ignored in expression mode, unless needed to seperate two tokens.


Processing

General

heitml is written in pages, just like HTML. A heitml page is processed as a procedural program producing an HTML page which is sent through the internet to the browser on the fly.

Although this is how heitml works on a technical level, it is probably not the way you should think while writing heitml pages.

When creating heitml applications you can view heitml and HTML as a single integrated language that produces nicely formatted output on your screen. The fact that there are two languages (heitml and HTML) and two programs (heitml on the Web Server and a Browser on the Client computer) is completely transparaent to both programmers and end users alike and should have no effect on their thinking.

Execution Order

A heitml page is normally executed top down, left to right. Normal text and HTML Tags are executed by just copying them to the output. As soon as a heitml tag or a user defined tag is encountered it is executed. Execution means to evaluate the parameters and to perform a certain action, as described below for every heitml tag.

Kinds of Tags

heitml distinguishes between heitml, HTML, and User-defined Tags. A Tag generally has the form:

< [/] Identifier Parameters >

The type of Tag is implicitely known by the identifier. heitml has several built-in heitml Tags that are specified in this document. All Tags defined by the user using the <def and <defenv Tags are user defined Tags. All other Tags are HTML Tags and remain undisturbed by heitml. User defined Tags can override HTML Tags, but not heitml Tags.

Several heitml and User-defined Tags can be combined and written within one pair of brackets < > seperated by semicolons:

< [/] Identifier Parameters ; [/] Identifier Parameters ; ... >

After some heitml Tags without parameters the semicolon can be omitted. For example:

< if !isempty(a); ? a; /if >


Expressions

Expressions can occur as parameters for heitml and user defined tags. They are evaluated before execution of a specific tag.

Datatypes

heitml knows the following data types:

Integer and boolean are different types (and not the same as in C). The special value null is the only value which has the type unknown.

A tuple is (as a struct in C) a sequence of fields with an associated value. However the number of fields, their names and types can change dynamically.

Values

Each value processed by heitml has one of the 6 above-described datatypes associated with it. Note that there is a difference between 6 as an integer value and "6" as a string. Also, true as boolean value and "true" as a string are different.

Variables

Each heitml variable has an identifier, which must be declared when a value is first assigned to it. heitml is a Dynamically Typed Language, which means that variable types are assigned according to the type of data associated with it. Later, the variable type can change simply by assigning it a new type of data.

Variables are local to the current heitml-page or to the current invocation of a procedure.

There are two global tuple variables called gl and ff. Global means that all procedures can access these variables.

Assignments

Assignments occur when explicitely written down with the = operator and implicitely during parameter passing.

Assignments of all types except tuple have the usual value semantics, the whole value is copied. For tuples pointer semantics applies. This means a tuple is an object on the heap and a tuple variable always contains a reference to a tuple on the heap. Assignment assigns this reference. Unused tuples are automatically cleand up (currently reference counting is used).

Operations

heitml knows the operators + (add), - (subtract), * (multiply), / (divide), % (modulo) which work as usual on integer and real variables. The plus symbol "+" can also be used to concatenate strings.

Binary boolean expressions use the operators ==, !=, <, <=, >=, ||, && with ascending precedence. Unary boolean expressions consist of the not operator "!" followed by a boolean expression.

The assignment operator "=" assigns the right operand to the left operand. Therefore, the left operand must denote a variable or a field of a tuple.

The operator "," evaluates both operands and returns the result of the second.

The operator "." selects a field of a tuple. The right operand of "." must be an identifier and the left operand a tuple. The result is the field of the tuple designated by the identifier. The "." operator can be used on the left hand side or the right hand side of an assignment statement. If used on the right hand side, the named field must be existent. If used on the left hand side a new field is added to the tuple, if neccessary.

The operator "[]" can be used to index a tuple or a string. If t is a tuple and i an integer t[i] denotes the i-th field of the tuple, counting starts with 0. If s is a string and i an integer s[i] denotes the i-th character of the string, counting starts with 0. If t is a tuple and s is a string t[s] denotes the field of t with name s.


heitml Tags

heitml contains a number of special purpose Tags that bring full-featured programming language capability to your Web Page Development Projects. These Tags will help you dynamically format and control the flow of Data to the User's Browser window.

A basic explanation of each Tag, as well as a short Source Code example, can be found in the individual sub-pages in this section.

Note: These Tags are Case Sensitive, which means that heitml will only recognize them in lower-case format.


? Tag Format: < ? Expression [Format] >

Purpose: Evaluates Expression and outputs the result.

The Expression part can take various forms. Here are just a few examples:

Quoted Data <? "H(e)i 2 all of U">
A Local Variable <? VariableName>
A Global Variable <? gl.VariableName>
A Tuple Variable <? TupleName.TupleField>
A Server Variable <? SrvUserAgent>
A Numerical Formula <? sqr(4)*5>
A String Formula <? FirstName+" "+LastName>
A Mixed-Data Formula <? Item+" costs $"+(Price*.80)>

Special attention need the HTML special characters "<", ">", and "&". replaces them by the neccessary control characters to display these characters unchanges on the screnn on the browser screen:

heitml source code: heitml sends to Client Browser: Browser displays:
<let x="Text1<p>Text2">

<? x>

Text1&lt;p&gt;Text2 Text1<p>Text2

You can also specify one of the four below-listed Format options if you need to exercise a finer degree of control over the outputed result. The format can be either one of the words HTML, quoted, heitml, or furl; or it can be a string expression.

HTML - The content of Expression is interpreted as HTML. The less-than and greater-than symbols "<" and ">" are not replaced, so the field may contain HTML tags, which are interpreted by the browser.

heitml source code: heitml sends to Client Browser: Browser displays:
<let x="Text1<p>Text2">
<? x html>

Text1<p>Text2

Text1

Text2

quoted - The field content is printed in double quotes.

heitml source code: heitml output:
<let x = "message">
<?  x>
<?  x   quoted>

message
"message"

heitml - The field content itself is interpreted as heitml code and executed. This way layouts or even complete heitml pages can be maintained in the database.

heitml source code: heitml output:
<let x = "<Pic>" + "<p>" + "<Slogan>"

<?  x   heitml>



heitml takes the
World Wide Web
to a higher level!

furl - The field content is encoded as a url parameter.

String Expression - The string expression must evaluate to an option string. Each character of the option string has its own meaning and special effect on the formatting done. A precise description is found below.

Formatting works differently when the ? tag is used in text mode. Replacement of characters for the browser do not take place. The quoted format uses the escaping mechanism of the underlying database system instead. Only quoted and furl format are allowed in text mode.

String Format Parameters

Using the ? tag with a string format parameter makes lots of formatting options available. For example < ? 55.666 ".2" > prints a real constant with two digits after the decimal point 55.57

However s formatting options go far beyond for example the "T" format formats a value for use in an HTML table so

   < let x="Numbers are right aligned"; y=700; >
   < table >
   <tr> <? y "Tn" > </tr > 
   <tr> <? x "Tn" > </tr > 
   < /table >
prints
y700
xNumbers are right aligned
The n format charater in the example causes heitml to include the variable name.

In general the formatting option string has the following format:

[Separator%] [Context] [Options] [Format]
We first give an introduction and afterwards a detailed description.

Separator a string of arbitrary characters excluding %. Context is one of the following characters (sequences): 'H','A','T','F','FT','Q','U','P'. Options are documented below. The Format is one of the following characters 'x','i','s','f','e','E','g','t' .

Context specifies for what context the output should be formatted. Per default the Context is 'H' for HTML. This means the value is formatted in a way to be shown on a HTML page. In contrast 'A' stands for ASCII-File. For example formatting the string "x<p" prints the characters 'x','<','p' in the ASCII Context, but 'x','&','l','t',';','p' in HTML. The < character is substituted so that the browser shows 'x<p' rather than interpreting the < character as an HTML tag.

Other Contexts are T for inside an HTML table, F for inside an HTML form, FT for inside a form and inside a table, 'P' for an HTML tag parameter, 'Q' for inside an SQL query, and 'U' for inside an URL.

The Format character specifies different ways to format a value. These are dependent on the type of the value to be formatted. For strings there is 's' Format only and 's' is the default. For integers 'i' is the default and other possibilities are 'x','X','o','c' for hexadecimal, octal or character representation. For reals 'f' is the default and other possibilies are 'e','E', and 'g' requesting different forms of scientific notation. For tuples there is the special 't' Format described later. If the data type does not match the Format character given, then the default Format is taken.

Also complete tuples can be formatted. Without Options the tuple is shown nicely as in debugging mode: if it is small enough in one line otherwise inside a table. With the Format character 't' all fields of the tuple are formatted with the format specified. The fields are separated by the Separator string.

There are various Options possible. Most important are : the 'n' option that will include the field name and a number specifying the field size.

Formatting Contexts

'H' - format for use inside an HTML document: The field is formatted to be shown by the browser. Special characters that the browser interprets as formatting control are replaced ( '<' is replaced by &lt, '>' by &gt, &' by &amp, '&circ' by &circ and '"' by &quot). 'H' is default and should usually be used when embedding data in an HTML page.

'T' - format for use inside an HTML table: Formatting is very similar as with 'H'. However the field is enclosed in <td> and </td> tags. This is convenient especially when a tuple is formatted, because the <td> and </td> tags are put around each field. Field alignment is handled by specifying the align parameter in the <td> tag, normally strings are left aligned and numbers are right aligned.

'F' - format for use inside an HTML form: An HTML form-textfield is created using the HTML-input tag. The value to be formatted is put into the textfield. As a name the field receives the name of the variable or tuple field being formatted. The field size is taken from the field size option specified in the format string. Using the 'h' option also hidden fields can be created.

'TF' - format for use inside an HTML form and a table: This combines table and form Context ('T' and 'F'). Form fields are produced, embedded in <td> and </td> tags.

'P' - format for use inside an HTML tag: This format applies when creating an HTML tag definition. For example if you want to create an image tag where the filename is stored in a variable named src

< img src=< ? src "P"; > >
The field content will automatically be put in double quotes and special characters are replaced. Using the n option the field name followed by an equal sign is written before the field content. It is possible to format a tuple in order to pass multiple parameters.

'U' - format for use inside an URL: The value is formatted to be used inside an URL. Characters are encoded in the way required for URLs. It is possible to format tuples. In this case the Separator defaults to & as required for URLs.

'A' - format for use inside an ASCII text: The value is formatted to be used in an ASCII text. No character replacement is performed. The 'A' format is useful inside the mail tag or inside the assign tag. 'A' format can also be used to insert a string into an HTML document without doing any character translation.

The default Separator is a tabulator character. So formatting of a tuple results in a field list, separated by tabs.

'Q' - format for use inside a query: The value is formatted to be used inside an SQL query as a field content. It is enclosed in quotes and special characters are encoded as required for the database system at hand.

Using the 'n' option the fieldname followed by a '=' sign is written before the value. This is useful inside an SQL-update statement or in a search condition. Tuples can also be formatted, the default for the Separator is ','. So the value list for a SQL update statement can be direcly produced.

Format Characters

For String Values only 's' is allowed, and 's' is the default.

For Integer Values 'i' is the default. It will print the integer value as a decimal number. 'x' will print it as a hexadecimal number using lowercase letters. 'X' will print a hexadecimal number using uppercase letters. 'o' will print the number in octal. If a precision option is given, it gives the minimal number of digits to be displayed. If neccessary leading zeros are inserted.

For Real Values 'f' is the default. It will print the real number in the form dd.dd where dd is a sequence of digits. As precision option the number of digits after the decimal point can be specified, the default is 6. The 'e' Format will display the real number in exponential representation. 'E' does the same, but uses a capital E to show the exponent. 'g' (or 'G') will use either 'f' or 'e' (or 'E') Format. 'e' is used if the precision is smaller than the exponent or if the exponent is less than -4. The precision here give the number of significant digits.

The number formatting Options are very similar to those of the C printf library. If you are interested in a more detailed discussion please refer to these.

For Tuple Values there are two fundamental different formatting mechanisms. In HTML Context a tuple is formatted by an intelligent formatting routine, that tries to show the tuple in the most readable way. If the tuple is small, it is printed within one line, if it is bigger it is printed in form of a table. Nested tuples are also shown, up to a sensible limit. This formatting option is very good for debug and test output, as well as applications that do not require a customized format.

The other way of tuple formatting applies in all other Contexts and when using the 't' Format in HTML Context. All fields of the tuple are formatted with the same given format. The fields are separated by the Separator string given. The default Separator is ' ' in HTML and 'P' Contexts, tab in 'A' Context, newline in 'T' and 'F' Contexts, and ',' in the 'Q' Context. Using the 'n' option the field name can be printed for each field. If the 't' Format character is used in any Context other than 'H', field names have the form tuplename.fieldname. Tuplename is the name of the tuple variable that is formatted, fieldname the name of the current tuple field. Nested tuples are not displayed. Fields containing null are displayed according to the N option, including the Separator. If 'Nv' is specified, fields containing null are completely left out (including the Separator and the field name).

Options

'n' - Include the field Name The field name is included into the formatting. If the expression to be formatted is a variable then the variable name is taken. If a tuple field is displayed then the field name is taken. Otherwise the field name is empty and the 'n' option has no effect.

In 'H', 'A', 'F', 'P', 'Q', and 'U' Contexts the field name followed by a '=' sign is printed before the formatted value. In 'T' and 'TF' Context a table column containing the name is shown before the table column containing the value.

If a tuple is formatted in field list format, (option 'Ht' or any other Context) then the 'n' option will include the field names for each field of the tuple. The name of the tuple itself is printed in 'H' format only.

dd - Field Size dd must be a sequence of digits. They specify the minimal field size. If the field content is smaller then the field is filled up with spaces (or zeros, see option '0'). Numbers are shown right justified, strings left justified. In 'F' and 'TF' Context the field size is also taken as the size of the form field.

.dd - Precision dd must be a sequence of digits. If field size and precision are give, then precision must be given immediatly after the field size. The precision can have very different meanings, depending on the Format character. Please read the documentation of the Format character you are using.

'-' - Alternative Alignment With this Options numbers are left aligned and strings are right aligned.

'D' - Use Default Function The default function is used on the argument before it is formatted: If the variable or the tuple field that should be displayed is not declared then null is assumed. Normally an undefined variable error message is shown.

'N'x - Handling of Null Values The capital N must be followed by another character that specifies how null values are formatted. Possibilities are '0' to display an integer 0, 'r' to display a real 0.0, 'e' to display an empty string, 'b' to display false, 's' to display a string consisting of one space. Other possibilities are 'n' to display 'null', 'N' to display 'NULL', 'S' to display &nbsp, and 'v' to display nothing.

'v' is special, it does not even display the field name and the Separator. It is useful in 'P', 'U', and 'Q' Contexts to completely leave out the fields containing null. The 'S' is useful to display a normal but empty table cell in HTML. HTML normally displays empty table cells in a different layout.

In 'H', 'P', 'U', and 'A' Context 'v' is the default. In the 'Q' Context 'N' is the default. In 'T', 'F', and 'TF' Contexts 'e' is the default.

'NV' - does not show a value This is useful to display the field name only. So "NV" prints all field names of a tuple separated by commas, "\t%NV" prints them separated by tabs.

'h' - create hidden fields This Options is valid in 'F' and 'FT' Contexts only. Then it creates hidden fields instead of normal text form fields.

'0' - Zero Padding Fields are padded with zeros instead of blanks.

'+' - Show Sign For non negative numbers a '+' sign is printed. Normally a sign is printed for negative numbers only.

' ' - Show a space for the + sign Leaves a space as sign for positive numbers.

'#' - Alternative Format In real formatting always a decimal point is shown, even if not followed by a digit. Octal conversions start with a leading 0. Hexadecimal conversions start with 0x or 0X for x and X Formats respectively.


assign Tag Format: <assign Variable> heitml </assign>

Purpose: Useful when a lengthly text is to be produced using some of the formatting features of heitml.

Variable must be a valid variable name or tuple data field.

Anything you type between the opening and closing assign tags is processed in text mode, which means that the resulting string output is not sent to the browser, as usual, but stored in the Variable.

Here's a Source Code example that uses the <assign> Tag to store a nice little heitml demo routine in a variable s. (We won't go into detail about the inner workings of the routine itself other than to explain that you can easily adapt it to many purposes, including to convert a string of text to a furl argument that could be passed to another page on the URL line of your Browser.)

<assign s>
  <\let x="Convert this string to a furl.">
  <\? x> 
  x is <\? len(x)> characters long.
  <br>
  <\let i=0; z="";
   while i<len(x);
     if x[i]==" "; 
        z=z+"+"; 
     else 
        z=z+x[i]; 
     /if;
     i=i+1;
   /while;
  ? z> <br> z is also < \? len(z)> characters. 
</assign>

Now that we've stored the routine into the variable s, here's what happens when you use the <? s> Tag to display the contents of the variable.

<pre> <? s> </pre>

 <let x="Convert this string to a furl.">
 <? x> 
 x is <? len(x)> characters long.
 <br>
 <let i=0; z="";
  while i<len(x);
    if x[i]==" "; 
       z=z+"+"; 
    else 
       z=z+x[i]; 
    /if;
    i=i+1;
  /while;
 ? z> <br> z is also <? len(z)> characters. 

Notice that heitml automatically knew it should omit the escape characters "\" to show the Code in its pure form (i.e. the normal form you would use if you were executing the code directly, without having assigned it to a variable.

And here's what happens when we tell heitml to interpret the contents of the s variable as heitml Source Code to be executed:

<? s heitml>

 
 Convert this string to a furl. 
 x is 30 characters long.
 
Convert+this+string+to+a+furl.
z is also 30 characters.

Note: Currently the maximum text size that can be assigned to a variable is 32767 characters. Also, the assign Tag is Case Sensitive, which means that heitml will not recognize it if you use capital letters (e.g. <ASSIGN Variable>)


break Tag Format: <break name>

Purpose: The <break> Tag leaves a <while> loop or a User-defined Environment Tag. Program execution continues with the next statement after encountering the </while> or </UsrDefEnvTag>. If there is no while loop or environment to leave, then <break> leaves the current procedure.

To leave a while loop
HTML SyntaxAlternate Syntax
<let i = 1>
<while i < len(a)>
 <if a[i]=="x"> <break> 
 <let i = i + 1>
</while>
<let i = 1;
 while i < len(a);
  if a[i]=="x"; break; 
  i = i + 1; 
 /while
>

To leave a User Defined Environment Tag
HTML SyntaxAlternate Syntax
<defenv for i f t>
 <let i = f>
 <while i <= t>
   <defbody>
   <let i = i + 1>
 </while>
</defenv>

<for i,0,len(a)-1>
  <if (a[i]=="Test")>
    <break>
</for>
<defenv for i f t;
  i=f;
  while i <= t;
    defbody;
    i = i + 1;
  /while
/defenv;

for i,0,len(a)-1;
  if (a[i]=="Test"); 
     break;
/for
>

Note: The break Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <BREAK name>)


dbdatabase Tag Format: <dbdatabase name>

Purpose: The <dbdatabase> Tag allows you to switch to another database. This is used when you want to access an SQL Table in a database other than the one that is currently open.

Note: This Tag is not implemented on the Windows NT version. Also, the dbdatabase Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <DBDATABASE>)


def Tag Format: <def IDname> heitml code </def>

Purpose: Defines a User-defined tag or a User-defined Function called IDname. A User-defined Tag is also called a heitml procedure and the heitml source code within the Tag is referred to as the body. If the body contains a return Tag returning a value then the defined Tag can be used as (and is called) a User-defined Function.

When a heitml Web Page contains a Tag <IDname>, the User-defined Tag is called and the statements contained within it are executed. This means that any resulting text is inserted into the HTML Page generated by heitml. When an expression contains IDname(expression) then the User-defined Function is called and executed. A Function can also be called by <IDname>, but in that case the function result would be discarded.

Every function or procedure has its own set of Local Variables. The variables of the calling procedure can not be accessed. However the variables ff and gl are Global Variables and can be accesssed everywhere. These are tuples and can therefore contain as many global fields as desired. (For example: ff.name ff.address and gl.name gl.address etc.)

Note: It is possible to pass parameters to the Procedure or Function. The format of the procedure call is

< Identifier (Identifier = Expression)* >

Before the procedure is called, all the expressions in the call are evaluated. For each Identifier = Expression in the call, the called procedure gets a Local Variable named Identifier with the value of Expression.

A def-ined Tag might have a formal parameter list like

<def Identifier ([*] Identifier [= Expression])* >
        heitml source code
</def>

All parameters marked with an asterisk * are Output Parameters. All other parameters are Input Parameters. The optional Expression associated with a parameter is called Default Value. In this case the format of the procedure call is

< Identifier ([Identifier =] Expression)* >

All parameters with the optional "Identifier =" in front are called Keyword Parameters. The parameters without the "Identifier =" are called Positional Parameters. The parameters occuring in the call are named Actual parameters.

During the call every Actual Parameter is associated with a Formal Parameter: The parameter in the n-th position is associated with the n-th formal parameter. A Keyword Parameter is associated with the Formal Parameter having the same name.

It is a bug if there are two Actual Keyword parameters with the same name or if a Keyword Parameter and a Positional Parameter are associated with the same Formal Parameter. If a Formal Parameter has no Actual Parameter associated with it, then the Default Value is used instead. If no Default Value was specified at the time the Tag was defined, it will result in a bug.

The called procedure or function gets a Local Variable for each Formal Input Parameter containing the value of the associated Actual parameter. For Output Parameters the Actual Parameter has to be a variable or a tuple component. When the called procedure returns, the Formal Parameter is assigned to the Actual one. (i.e. a Local Variable of the procedure with the name of the Formal Parameter)

A procedure can be called only after it has been defined. In this case, the word "after" refers to the sequence of text in the input file.

Procedures can be redefined; however, the type of procedure (def or devenv) must stay the same.

Procedures can also be called recursively. If two procedures call each other recursively, it is neccessay to define one first as empty, and afterwards redefine it.

Note: The def Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <DEF IDname>)


defenv Tag Format: <defenv IdName> heitml code </defenv>

Purpose: The defenv tag (re)defines an evironment tag, i.e. a tag with an end tag. The defenv tag can contain any mixture of HTML and heitml Tags incuding the special < defbody > tag.

When a tag named IdName (where IdName is the identifier after defenv) occurs the body of the defenv tag is called and executed. As soon as the defbody tag is reached the body of the IdName tag is called. defbody can be called zero, one, or many times.

The body of the call has the same local variables as the procedure containing the environment call. Using the <defbody> Tag inside the source code of the environment calls the content of the defenv Tag. Therefore, <defbody> can so be used several times at any place inside of the environment.

Parameter passing and redefinitions work as with the <def> Tag. Output parameters are copied to the caller, each time the defbody is called and when the environment finally returns.

For example, environments are useful for defining Web Page layouts, etc. that control the "look and feel" of an application or module. A sample environment definition is as follows:


<defenv MyWebPageLayout> 
  <ShowLogo>
  <ShowSlogan>
  <defbody>
  <ShowEmailAddress>
  <ShowCopyrightMessage> 
</defenv>

Now that the environment has been defined, it can be called as follows:


<MyWebPageLayout> 
  <Procedure1>
  <Procedure2>
  <ProcedureN>
</MyWebPageLayout>

When the environment is called as in the above example, it begins by issuing calls to the <ShowLogo> and <ShowSlogan> procedures, then continues by executing Procedures1,2,N which are called automatically by the <defbody> Tag contained withing the environment definition. After the last Procedure has been executed, the environment issues calls to the <ShowEmailAddress> and <ShowCopyrightMessage> procedures before exiting.

Note: The defenv Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <DEFENV IdName>)


if Tag Format: <if Expression> heitml <else> heitml </if>

Purpose: Evaluates the expression. Its result must be of type boolean. The "then" part is performed if the expression evaluates to true, otherwise the else part.

Sample heitml source code:
<if x == y>
   <DoThisProcedure>
   <DoThisOneToo>
<else>
   <ShowErrorMessage>
</if>

Note: The if Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <IF Expression>)


include Tag Format: <include Filename>

Purpose: Includes the content of the given filename. The above form of the include is performed statically, when reading the hei file. The file may contain defines needed for the current page. The include tag may not be combined with other tags in a pair of <> brackets.

Format: <include > heitml < /include >

This alternate form includes a file whose name is given by the heitml text. The name can be calculated dynamically. The file is read in only at execution time.

The filename must not be an absolute path and it must not contain "..". It has to have the ".hei" extension. The inlcude path is searched from left to right for a directory containing the filename given.

Note: The include Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <INCLUDE Filename>)


let Tag Format: <let Expression>

Purpose: In the above form the Expression parameter is evaluated and the result is discarded. Normally, the Expression parameter uses the assignment operator = to perform an assignment that saves the result (e.g. <let a = a + 1>).

When used after a semicolon the keyword let can be omitted.
(e.g. <while x <10; x = x + 1; /while>)

Note: The let Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <LET Expression>)


mail Tag Format: <mail to> text </mail>

Purpose: Sends a message to the email address specified in the to parameter.

The email address can take either of the following forms:

name@domain
or
Display_name <name@domain>

Here are a few practical examples:

Email Address enclosed by Quotes
<mail to="cecile@aol.com">
    Message goes here.
</mail>

In Quotes together with a Name
<mail to="Cecile Provot <cecile@aol.com>">
    Message goes here.
</mail>

Email assigned from a Tuple Data Field
<mail to=r.Email>
    Message goes here.
</mail>

The <mail> Tag can also accept the following optional parameters:

Parameter Purpose
subject A short description that indicates what the message is about.
from The email address of the person sending the message.
cc List of email addresses that received copies of the message.
bcc Hidden list of email addresses that received copies of the message. (i.e. The primary recipient of the email does not see who else may have received the message.

The from, cc, and bcc parameters all accept email addresses in either of the two form previous illustrated. However, the cc and bcc parameters can accept multiple emaill addresses separated by commas.

Note: Currently the maximum text size is 32767 characters. Also, the mail Tag is Case Sensitive, which means that heitml will not recognize it if you use capital letters (e.g. <MAIL to>). The parameters (to, from, subject, etc.) are not Case Sensitive.


return Tag Format: <return>

Purpose: The above format is used to leave the current User-defined Tag or heitml page.

Format: <return> expr

This alternate format leaves the current User-defined Tag or heitml page and returns the value calculated by the expression. This form may occur only in a user defined tag. This tag can then be used as a function inside of expressions.

Note: The return Tag is Case Sensitive, which means that heitml will not recognize it if you use capital letters (e.g. <RETURN to>).


shell Tag Format: <shell> OpSysCommand </shell>

Purpose: The <shell> Tag allows you send a command to the Operating System, the results of which are displayed in the Browser page.

Here's an example that would produce a directory listing within the Web Page. (Remember to use the HTML <pre> and </pre> Tags around the outside for proper formatting.)

On Unix Systems On Windows 95On Windows NT
<shell>
ls -l
</shell>
<shell>
command.com /C dir
</shell>
<shell>
cmd /C dir
</shell>

Note: The shell Tag is Case Sensitive, which means heitml will not recognize it if you use capital letters (e.g. <SHELL>)


while Tag Format: <while Expression> heitml <while>

Purpose: Evaluates the expression. Its result must be of type boolean. While the expression evaluates to true, the actions defined in the body of the loop is executed.

HTML SyntaxAlternate Syntax
<let i = f>
 <while i <= t>
   <let i = i + 1> 
 </while>
<let i=f;
  while i <= t; 
    i = i + 1;
  /while
>

Note: The while Tag is Case Sensitive, which means that heitml will not recognize it if you use capital letters (e.g. <WHILE to>).


\ Tag Format: <\ Anytext>

Purpose: The backslash (known as an escape Tag) is removed and <anytext is copied to the output. This feature can be used to escape a redefined HTML Tag.

For example, let's first redefine an HTML Tag to change what happens when heitml sees the Tag in a ".hei" page:

<def p> <br> &nbsp; &nbsp; &nbsp; </def>

And now we'll show a sample of text using the redefined parapgraph Tag, followed by the way it looks when heitml interprets it:

HTML formatted text:
<p>This is a sample of text that has been created using a re-defined paragraph Tag. <p> Note that new paragraphs do not skip a line, but the first line of the new paragraph is indented several spaces.
As interpreted by heitml:

      This is a sample of text that has been created using a re-defined paragraph Tag.
      Note that new paragraphs do not skip a line, but the first line of the new paragraph is indented several spaces.
And now using the escape Tag <\p> to restore the original HTML functionality:

This is a sample of text that has been created using a re-defined paragraph Tag.

Note that new paragraphs do not skip a line, but the first line of the new paragraph is indented several spaces.






heitml Functions


heitml Functions are divided into three categories: Built-in Functions, Library Functions, and User-defined Functions.
Built-in Functions


Buit-in Functions are part of the heitml core language, which means they are available to you at all times. You can make calls to these functions anywhere in your code without having to do anything special. heitml will recognize them and know what action to perform.

A basic explanation of each Function, as well as a short example, can be found in the individual sub-pages in this section.

Built-in Functions can be further sub-divided into three categories:

Datatype Handling Functions test for certain Data Types and convert between types. Those that test for certain Data Types return "true" or "false". Conversion functions change from string to numeric, numeric to string, and sometimes from one numeric type to another (such as integer to real, or decimal to hex).

Tuple Handling Functions provide special support for the heitml tuple data type.

String Handling Functions manipulate alpha-numeric data or report results based on tests performed on such alpha-numeric data.
Library Functions


Library Functions are external to the language. They reside in separate Source Code files and must be linked to your application via the <include> Tag.



Library functions are included in several source code files in the lib sub-directory, which is part of the download package you receive when you select the appropriate version of heitml that runs on your system.

We've organized these libraries by category and placed documentation describing each of them in The heitml Libraries section of our Web Site.

These Source Code Libraries are intended to be used "as is", and we do not recommend that you make any changes to them. If you find a Library Tag or Function that doesn't quite suit your needs, feel free to use it as a "template" or starting point to design your own, but first copy it to another file and change the name somewhat in order to distinguish it from the original. Then you can customize it as little or as much as you want, and add it to a Library file of your own.
User-defined Functions
User-defined Functions are those that you create yourself. You can define them as needed and insert them directly into your application, or you can organize and store them in separate files, linking them via the <include> Tag, thus creating your own Library of re-usable tools. Refer to User-defined Libraries in the Language Guide for a Tutorial discussion on this topic.

Format: array (size, reserve)


Purpose: Creates a tuple with size fields. Such a tuple can be used as an array, using the [] operator with integer arguments.

The reserve parameter can usually be left out. It can be used to increase the efficiency of memory handling. If specified, it must be bigger than size and tells how much memory should be reserved for the array. In cases where an array is enlarged using the resize( ) function, the reserved space is used if possible.

Here's a Source Code example that shows how you could use the array( ) funtionc to create a multidimensional array and assign values to each element:


<let x=array(3);           / / Declare an array
 i=0; j=0;                 / / Initialize counters
 while j<=2;               / / Begin outer loop 
   i=0; x[j]=array(3);     / / Declare a sub-array
   while i<=;              / / Begin inner loop  
     x[j][i]=chr(j+i+65);  / / Assign data value

     ? "x[";?j;?"][";?i;?"] = ";  
     ? x[j][i]             / / Show the array value 
     > <br> <              / / New line
     let i=i+1;            / / Increment i counter 
   /while                  / / End inner loop
   > <p> <                 / / Blank line 
   let j=j+1;              / / Increment j counter 
 /while;                   / / End outer loop.
>


The above code produces the following result:

x[0][0] = A
x[0][1] = B
x[0][2] = C


x[1][0] = B
x[1][1] = C
x[1][2] = D


x[2][0] = C
x[2][1] = D
x[2][2] = E




An array such as the one above can be used to display rows and columns of data in a Table. A more complex 3-dimensional array could be declared as x[year][month][sales] for Accounting purposes to track sales by period. And, of course, anyone engaged in the analysis of mathematical or statistical data can declare an n-dimensional matrix to suit their individual needs.



Format: asc (character)


Purpose: Returns the numerical ASCII value of character.

heitml input resulting output
<? asc(" ")> 32
<? asc("0")> 48
<? asc("1")> 49
<? asc("2")> 50
<? asc("A")> 65
<? asc("a")> 97


Format: chr (integer)


Purpose: Returns the ASCII character of an integer value between 0 and 255.

heitml input resulting output
<? chr(48)> 0
<? chr(49)> 1
<? chr(65)> A
<? chr(97)> a


Programmers should pay particular attention to the fact that Browsers treat ASCII characters from 0 through 32 as "white space" (i.e. non-printable characters) and will not display the normally expected results. For instance, in the examples below you will see that Browsers treat the ASCII space character chr(32) the same as the ASCII null value chr(0).

heitml input resulting output
<? chr(0)>
<? chr(32)>


Also, the "carriage return" and "newline" values will not seem to have any effect on your outputted text.

heitml input resulting output
Hello<? chr(13)><? chr(10)>World Hello World


Format: contains ( string, substring )
Format: ContainsCase ( string, substring )


Purpose: Returns true, if and only if string contains the substring. The ContainsCase() function works very similar but is not case sensitive.
heitml input resulting output
<? contains("Hello World","ello")> true
<? contains("Hello World","xello")> false

heitml input:
<if contains("Helmut is a Wizard","Wiz")
    > Helmut is a Wiz. <
 else
    > Helmut should use heitml. <br><br>
    Then he'd be a programming Wiz like Keith. < 
 /if>
resulting output:
Helmut is a Wiz.


Tip: Once you have determined that substring is contained within the string, you can then use the index( ) function to determine the starting location of substring within the string being searched.

Format: copy ( tuple )


Purpose: Performs a deep copy of a tuple. That means a new tuple is created and all fields are copied into it. If a field contains itself a tuple this one is recursively copied.

Format: crypt ( string [, salt])


Purpose: Calls the unix function for password encryption. It is not available on Windows.

Operating Systems: Unix sytems only.

heitml input resulting output
<?crypt("Hello")> xxAva79L2eoCI


You should use this function before storing sensitive data such as a password into an SQL Database.

Format: default ( value, value, ... )


Purpose: Evaluates the operands from left to right and returns the first one which is declared and not null. Null is returned if all operands are null or not declared.

heitml input resulting output
<? default (null,5,7)> 5


Format: fname (tuplefield)


Purpose: Returns the name of a tuplefield in the form of a string.

heitml input resulting output
<let x=emptytuple; x.hallo="test"; ? fname(x[0])> hallo


The fname( ) function is useful in desciphering the structure of an unknown tuple, or when you want to print the data field names along with their associated values (as in the following example).

heitml input resulting output
<let x=emptytuple; x.hallo="test"><b> <? fname(x[0])>:</b> <? x[0]> hallo: test


Format: index ( string, substring)
Format: IndexCase ( string, substring)


Purpose: Looks for substring in string and returns the position where it starts. null is returned if the substring is not contained within the string.

The IndexCase() function works very similar but is not case sensitive.

heitml input resulting output
<? index("Hello World","ello")> 1
<? index("Hello World","xello")>


Tip: You can use the index( ) function in combination with the substring( ) function to update portions of a database field without disturbing the rest of its contents. Here's an example:

heitml input:
<let a="Take the ball and run with it!";
 b="e ball and run with"; 
 x=index(a,b);
 c="is job and shove";
 d=substring(a,0,x)+c+substring(a,x+len(b),len(a));
 ? d
>
resulting output:
Take this job and shove it!


Format: integer ( value [,base] )


Purpose: Converts value to integer. If the value is of type string, then base is taken as the base (10 for decimal, 16 for hex numbers).

If the argument string is not a legal number, then the null Value is returned.

heitml input resulting output
<? integer(3.14159)> 3
<? integer("3.14159",10)>
<? integer("3",10)> 3
<? integer("ff",16)> 255
<? integer("ffff",16)> 65535


Format: isbool ( v )


Purpose: Returns true if and only if v is of type boolean.

Format: isdecl ( variable )


Purpose: Checks to see if the variable given has previously been declared.

heitml input resulting output
<? isdecl(ff.notdef)> false


If heitml ever generates a "variable not declared" error message, you'll know you forgot to assign or declare a value before attempting to use that variable in an expression.

Format: isempty ( variable )


Purpose: Checks to see if the variable being tested is empty.

A variable is empty if:

heitml input resulting output
<? isempty("")> true
<?isempty(5)> false
<? isempty(null)> true


The isempty function should prove useful when you need to process User inputed data from an HTML <FORM>. In most FORMs, there are some fields that can be left blank, and others that are required. Here is a practical example:

heitml input:
<if isempty(ZipCode)
  >  You <b>must</b> specify a Zip Code before
    we can process your order. <
 else
  if len(ZipCode)!=5
     > A Zip Code <b>must</b> be 5 digits long! < 
   else
    if real(ZipCode)==null;
        ? ZipCode
        > is <b>not</b> a legal Zip Code. <
   /if;
  /if;
 /if> 
resulting output:
You must specify a Zip Code before we can process your order.


Notice in the above example that we first made sure the ZipCode variable had a value assigned to it before doing any further validation checks. Had we omitted this test, heitml would have generated an error message when it tried to determine the length of a variable that had not previously been declared. Also note that our validation checks assume that we are using a five digit Zip Code instead of the newer Zip+4 format, which is why we tested for a length of 5 with the len function. And, of course, U.S. Zip Codes contain only numbers, so if a User had entered something like "x0321", our real function would not have been able to convert the string of characters contained within ZipCode to a numeric value. In both cases our program would have recognized that an invalid Zip Code had been entered and printed the appropriate message.

Here's another programming tip:

If you've been paying attention to the way our Web Site operates, you've probably noticed that no matter what item you select from the "Contents" menu at the left, we always chain to the same Web Page: index.hei

Most of the time you see a parameter attached to index.hei in the form ?rmenu=Web+Page+Selected, except for when you first entered out Web Site. Here is the actual code we use to determine whether our Web Site Template should call a particular Web Page from its inventory, or begin with the default "Introduction" Page:

<if isempty(ff.rmenu);
  gl.menu="Introduction";
 else
  gl.menu=ff.rmenu;
 /if>


Format: isinteger ( v )


Purpose: Returns true if and only if v is of type integer.

heitml input resulting output
<? isinteger(128)> true
<? isinteger(128.39)> false
<? isinteger("256")> false
<? isinteger("256.42")> false
<? isinteger(0)> true


Format: isnull ( field )


Purpose: Checks to see if the variable or data field given is null or not declared.

heitml input resulting output
<? isnull(null)> true
<? isnull(undeclared)> true
<let S=""; ? isnull(S)> false
<? isnull(" ")> false


If it's not obvious how to use this function, imagine that you have a variable named S that has been declared, but assigned an "empty" value. You might want to do this at times to clear old data from variables before re-using them.

Also, as seen in the last example, a variable may contain invisible or unprintable characters like the space character. (For more information on non-printable characters, see the chr( ) function.)

Format: isstring ( v )


Purpose: Returns true if and only if v is of type string.

heitml input resulting output
<? isstring(128)> false
<? isstring(128.39)> false
<? isstring("256")> true
<? isstring("256.42")> true
<? isstring("0")> true


Format: istuple ( v )


Purpose: Returns true if and only if v is of type tuple.



Format: isreal ( v )


Purpose: Returns true if and only if v is a real number.

heitml input resulting output
<? isreal(128)> false
<? isreal(128.39)> true
<? isreal("256")> false
<? isreal("256.42")> false
<? isreal(0)> false


Format: len ( string )


Purpose: Returns the length of a string. (The len function can also be used for tuples).

heitml input resulting output
<? len("text")> 4
<let x="Hello World"; ? len(x)> 11


Format: real ( value )


Purpose: Converts value to a real number. If the argument string is not a legal number, then the null Value is returned.

heitml input resulting output
<? real("text")>
<? real("42")> 42.000000
<? real("6+4")>
<? real(integer("ff",16))> 255.000000
<? real(len("text"))> 4.000000


Format: substring ( string, from, to )


Purpose: Returns a substring from string starting at position from and ending at position to -1. Positions are counted from left to right starting with 0.

heitml input resulting output
<? substring ("Hello World",4,8)> o Wo


Format: tolower ( string )


Purpose: Converts a string to lower case.

heitml input resulting output
<? tolower(" Hello World ")> hello world
<? tolower("GREAT SCOTT!")> great scott!


Format: toupper ( string )


Purpose: Converts a string to upper case.

heitml input resulting output
<? toupper(" Hello World ")> HELLO WORLD



Format: trim ( string )


Purpose: Removes leading and trailing whitespace (spaces and tabs) from a string of characters.

heitml input resulting output
<? trim(" Hello ")> Hello



The function returns null if the argument is null.

Format: trimleft ( string )


Purpose: Removes leading whitespace (spaces and tabs) from a string.

heitml input resulting output
<? trimleft(" Hello ")> Hello



The function returns null if the argument is null.

Format: trimright ( string )


Purpose: Removes trailing whitespace (spaces and tabs) from a string.

heitml input resulting output
&nbsp;<? trimright(" Hello ")>   Hello



The function returns null if the argument is null.


heitml Tags to access the database


Accessing the database is done by the <dbquery> tag. It has the following syntax:

<dbquery queryname>    SQL-Querystatement 
   <dbrow>               text for every row
   <dbtop>               top of table
   <dbfoot>              foot of table
   <dbempty>             in case of empty result
</dbquery>


The SQL-Querystatement must be a valid SQL-SELECT statement. The SQL-Querystatement is processed in HTML mode . All heitml tags can be used to generate the desired SQL-Query.

The SQL statement is executed and the row section is processed repeatedly for every row selected. The row section is processed in HTML mode. It may contain the ? tag to include the content of a database field within the page. However, the row part may contain any other HTML or heitml tags, including nested queries or update statements.

An arbitrary queryname can be choosen distinct from the names of local variables. The fields of the selected rows are accessed by writing queryname.fieldname (e.g. if the query was named q, then <? q.firstname> prints the firstname field in the database). In fact queryname denotes a heitml tuple that contains the current row. The tuple can be read as any other tuple but it can not be written.

The empty section is processed (in HTML mode) if the result of the select statement is empty. Otherwise top and foot sections are processed once, in the beginning and at the end of the table respectively. The advantage of the top and foot section over writing the table head and table foot before and after the query tag is that in case of an empty result table only the text in the empty section is displayed.

Modifying the Database


<dbupdate> SQL-Statement </dbupdate>


The update tag can contain SQL update, delete or insert statements. With appropiate database systems also many other SQL statements are allowed, including create table etc.

The SQL statement is passed unaltered to the database system and is executed immediately.
Format: <dbdatabase > heitml </dbdatabase>


Select a database. This is neccessay only if you want to change the database during processing. (See also configuartion files.)

Accessing Anonymous Relations



<dbquery queryname> SQL-Querystatement 
   <dbhead>         headline for a column  
   <dbbody>         sperator between head & body 
   <dbrow>          text for every row
   <dbcolumn>       text for column 
   <dbrowend>       end of text for every row
</dbquery>


This form of the <dbquery> Tag can be used to display a table whose field names are not known a priori. It first shows a headline with one entry for every field. This entry is specified after dbhead. It can use the special variable SrvFname to access the name of the current field. Afterwards a seperator, dbbody, is printed. Note that you can leave out the headline by leaving out both the dbhead and dbbody parts.

All records in the table are then shown. For each record, first the text in dbrow is shown; then for every field the text in dbcolum and finally the text in dbrowend. Inside dbcolumn, the special variable SrvField can be used to access the field content and SrvFname can be used to access the field name.

dbtop and dbfoot can be used as in the usual dbquery Tag. It is also possible to give a name to the current tuple and access specific fields, all as documented with the normal database access.


Modifying the Database


<dbupdate> SQL-Statement </dbupdate>


A .hei file may contain several update Tags. These can contain SQL update, delete or insert statements. All update tags whose fields are present in the input form are executed in the order as they occur in the .hei file. In other words: an update is not executed for those form fields that are left blank. This feature can be used (as with altqueries) to handle several forms with one heitml page.
Format: <dbdatabase > heitml </dbdatabase>


Select a database. This is neccessay only if you want to change the database during processing. (See also configuartion files.)


Accessing Anonymous Relations



<dbquery queryname> SQL-Querystatement 
   <dbhead>         headline for a column  
   <dbbody>         sperator between head & body 
   <dbrow>          text for every row
   <dbcolumn>       text for column 
   <dbrowend>       end of text for every row
</dbquery>


This form of the <dbquery> Tag can be used to display a table whose field names are not known a priori. It first shows a headline with one entry for every field. This entry is specified after dbhead. It can use the special variable SrvFname to access the name of the current field. Afterwards a seperator, dbbody, is printed. Note that you can leave out the headline by leaving out both the dbhead and dbbody parts.

All records in the table are then shown. For each record, first the text in dbrow is shown; then for every field the text in dbcolum and finally the text in dbrowend. Inside dbcolumn, the special variable SrvField can be used to access the field content and SrvFname can be used to access the field name.

dbtop and dbfoot can be used as in the usual dbquery Tag. It is also possible to give a name to the current tuple and access specific fields, all as documented with the normal database access.


Accessing FORM fields


There is a global tuple variable named ff. It contains all the input fields from the calling FORM. Therefore, if the FORM contains a field named "firstname", <? ff.firstname> prints it. FORM fields can have a name of the form x.y, where x and y are strings. Then ff has a component named x, which itself is a tuple with a component y containing the field value. This way FORM fields can be structured into different tuples.

Server Variables


The following variables are heitml Reserved Words that can be used to access data from the Server and obtain information about the current connection, i.e. User, IP address, etc.

Version 1.0
Server Variables
Result
SrvHost  
SrvUser Note: This variable returns a result only on password protected pages.
SrvUserAgent MSIE
SrvIP 192.168.1.4
SrvDate 19970820
SrvTime 160016825
SrvServer CGI
SrvDbsys YARD
SrvOs LINUX
New Version 1.2
Server Variables
Result
Srv_Http_Accept  
Srv_Http_User_Agent MSIE
Srv_Remote_Addr 192.168.1.4
Srv_Remote_Host  
Srv_Remote_User Note: This variable returns a result only on password protected pages.
Srv_Server_Admin  
Srv_Server_Name  
Srv_Server_Port  
Srv_Server_Protocol  
Srv_Server_Software  
SrvFileName /home/emmel/website/docroot/heitml1.2/lref_all.htm
SrvLocalUrl  
SrvHeitmlVersion 1.200000

Session Mode
 

Example
Session mode keeps all the variables named se.name, where name specifies a particular variable on any page of your Session Mode Application. Session variables can use any data type you like, including tuples and arrays.

To use session mode you need to include the ses.hei Library, and put all of the Source Code from a Seesion Mode Web Page into the <session> environment Tag. Instead of the normal anchor tag <a ... > you need to use the <sa ... > tag.

So the simplest example for session mode is

<include ses.hei>
<session mode="create">
   <let se.i=default(se.i,0)+1>
   The number is <?se.i>.
   <sa href="sessimp.hei"> Increment </sa>
</session>

This will show a counter, and whenever the user clicks on increment it will increment the counter by one.  

How does it work ?


Once a user enters a session mode page, (s)he gets a session card number assigned (currently made up by the date, time, and ip-number). After processing of this page the session variables are written to a file (named as the card number).

Now when the user requests the next page session variables are read again. To know which session it is the session card number is passed from the first page to the second one, by adding it to the url. This is why you need to use the <sa ... &> tag. It automatically adds the card number to the requested url.

For forms there is another way to add something to the url. It is called hidden fields. All you need to do is to call the < sessionhidden > tag somewhere within your form, and session mode will work fine.

 

Starting Pages and Inner Pages


When using session mode many of you pages will require that certain session variable have been set already. Such a page must always be called from another session mode page. So we call it an inner page . In contrast pages where a session can start are called starting pages . By carfully setting your links, you can make sure inner pages are always called from another session mode page ..., except when a user types in an url of such a page directly.

heitml allows you to specify which pages are starting pages and which are inner pages using the mode parameter of the < session > tag. When a user tries to direcly access an inner page, he gets an error message, referring him to a starting page.

However still the user could by manually modifying urls confuse session files for several applications. This is why you can specify and application name in the session tag. Then heitml automatically checks that a session file and a page both belong to the same application.  

Handling the Back Key


Please remember, when writing an application, that the user can always use the back key in the browser. heitml session mode assists you in finding out, whether this has happened:

Dialog steps are numbered, starting from 1. The variable se.step contains the number of the current dialog step and se.laststep the number of the previous one. Usually there is se.step=se.laststep+1. However if the user has pressed back several times the step number is decremented accordingly. So se.laststep+1-se.step gives how often the back key has been pressed.

The number of the upcoming dialog step is passed as a second parameter within the url (just as the card number).  

Session Mode Tags


To use the following tags the file ses.hei needs to be included.
< session mode="std" start="/" appkey="" > ... </session >
This is the basic session mode environment, you have to enclose the whole page into it. The mode parameter can be "std" for an inner page and "create" for a starting page. In case an innerpage is called directly an error message is displayed. It tells the user to start at the url given as the start parameter of session. The appkey parameter gives an application name. When given, heitml makes sure that the session variables belong to the same application.
< sa href par=null urlpar""  > ... </sa >
The < sa > environment acts as a replacement for the < a > tag. It adds the card number to url called. par can be a tuple. The content of this tuple is added in the appropiate format to the url called. The urlpar parameter is a string, that is also added to the url.

If for some reason the sa tag is to restrictive, please use the sessionurl tag.
< sessionUrl >
creates url parameters to be added to a url for session mode. Normally you can just use sa, however, in some special cases sessionurl is more flexible. An example how to use sessionurl is <a href="mypage.hei?<sessionurl>">.
< sessionHidden > 
adds the neccessay parameters as hidden fields to a from. In session mode, you just add inside each form you are using.
< sessionCreate > ... </sessionCreate > 
The body of the sessioncreate environment is executed only if the user just entered session mode. This is a convenient way of initializing variables for session mode.


Syntax of heitml


	
heitmlpage = heitml * .

hei<