CODE GENERATORS
- HFL has special scopes that generate output code for their blocks, instead of executing them. Currently, only two languages are supported: CSS and javascript.
- These 'code generator' blocks allow all of the sources to be written in HFL, instead of a mixture of files written in the three main languages: HTML, CSS and javascript.
- When these blocks are used, the HFL code is translated into the target language syntax. The generated code can be used for any purpose, including being output to a run-time source file.
Generating javascript code using an 'at_runtime' block
- The 'at_runtime' block defines HFL code that is to be translated to javascript.
-
It has the following syntax:
-
For example:
-
at_runtime {
div:..1 {
id = 'div1' color:red;
}
}
-
- The translation action removes the code block from the cell tree, and places the generated code into the current page's clip pool inside a <javascript> HTML tag.
-
This code can be accessed as clip{ javascript:last{} } if the
application wishes to manipulate it.
-
For example:
-
clip {
writeFile('myscripts.js', scope(javascript:last), 'append', 'cut#discard');
}
-
-
For example:
- For the generated code to work at run-time, the application must include a javascript run-time library. A standard version of this library is provided with the distribution. However the HFL language will work with any library that provides the similar functionality and uses the same function and data names.
-
The translations that will be made are:
-
HFL scope references are translated into calls to run-time javascript function 'scope()'.
There are two forms of the run-time 'scope()' javascript function:
-
scope(<scope-strings>, el, function(el) {<js-code>})scope(<scope-strings>, el)where:<scope-strings>:='<scope-string>' [, '<scope-string>']*<scope-string>:=an HFL scope specification string<js-code>:=javascript code to run if scope spec matches
The first form defines an enclosing scope, and calls the function containing the <js-code> block once for each match of a <scope-string> pattern. The el argument passed to the function is the node element that matched the pattern.
The shorter second form is used within expressions, and returns the node element that matched as a value, or as an array of values if more than one <scope-string> matched. If there was no match, it returns 0.
For example:
-
div:..1 {
if (!scope(p:1)) { print("MISSING THE 'P' ELEMENT"); }
}
would be translated into:
-
scope('div:.. 1', el, function(el) {
if (!scope('p:1')) {
printConsole("MISSING THE 'P' ELEMENT");
}
});
-
-
Cell properties are translated into javascript 'style' properties.
For example:
-
color:red;
would be translated into:
-
el.style.color = "red";
-
-
Cell class and id values are translated into javascript node properties.
For example:
-
id = 'div1'
class = 'topic'
would be translated into:
-
el.id = "div1";
el.className = "topic";
-
-
'$' Variable references that are embedded within double-quoted strings are translated into javascript string concatenations.
For example:
-
var $szHere = 'div:1';
print("IN $szHere!");
would be translated into:
-
var $szHere = 'div:1';
printConsole("IN "+$szHere+"!");
-
-
Certain function names are mapped to avoid colisions with javascript functions having the same name.
For example, because 'print' is defined differently in javascript:
-
print("Hello World!");
would be translated into:
-
printConsole("Hello World!");
-
-