Generate or convert text, programs, documents, or reports of any format or language
What can you do with the universal text generator? What is UniT?
What are the advantages of using UniT? Advantages
Frequently asked questions FAQ
How to install and start UniT Installation
How to program templates with the universal text generator How to use it
How to use the UniT interpreter with Java API
Things that might come in near future To Do
I appreciate comments Guest book
Nice stuff Credits & Links
Read license & download here License
Disclaimer
Imprint

How to use UniT

Now we dive into the technical details, but since UniT is so easy, after reading this text you should know nearly everything about using UniT if you are already familiar with similar technologies.

The remaining part introduces the main features of UniT by giving a short description, a code example, and example output. Some of these examples do not make much sense, they just demonstrate the features. (Of course, all features, e.g., loops, can be nested like in Java.)

Special UniT tags
name and description of the UniT feature example syntax and example output
of the UniT feature
start tag
Each UniT text template or program can be recognized by the start tag in the first line and column. By the way, UniT source code is case sensitive, of course! Every UniT source code starts with the UniT start tag:
[UniT]
unit bracket escapes
A UniT is a text template, i.e., a mixture of text and UniT tags. Tags allow the insertion of dynamic data. Brackets ("[" and "]") are used to limit all the UniT tags. Nevertheless, it should be possible to generate/output the usual brackets, like those above. Therefore, bracket escapes are defined. Double opening bracket ("[[") to output a single opening bracket: [; double closing bracket ("]]") to output a single closing bracket: ]. They can be combined in any order and number:
]][[]][[]]
][][]
output expressions
As in other technologies, it is very easy to convert any expression to a String object and direct it to output:
[= 1+1]
2
nestable comments
Of course, it is possible to include comments that should not be part of the output. Those comments are enclosed in brackets, too, but with a (following/leading) star within them. They can span a single or multiple lines and they can be nested:
short comment:
start-[*short comment*]-end 
short comment:
start--end 

multiple line comment:
start-[*
	comment over
	multiple lines
*]-end 
multiple line comment:
start--end 

nested comment:
start-[*
	This is a [* nested *] comment 
	with some source code:
	[= "hi, this will not be executed"]
*]-end 
nested comment:
start--end
Expressions of the UniT programming language (only the easy parts of Java)
name and description of the UniT feature example-syntax and example-result
of the UniT feature
variable declarations
As in Java methods, you are allowed to declare any valid Java identifiers as references to objects. Because UniT is realized with dynamic type checking, type declarations and type casting are not needed. The type is always Object.
[Object reference]
[= reference]

null
single declaration with immediate initialization
A reference can be initialized immediately at declaration with any expression.
[Object int1 = 1]
[= int1]

1
multiple declarations
Several references can be declared at once, separated by comma.
[Object oneDimIntArray, 
	twoDimIntArray, 
	initialized, 
	counter]
[=oneDimIntArray]
[=twoDimIntArray]
[=initialized]
[=counter]
[Object int2 = 1+1, 
	int3 = int2 +1, 
	test = new unit.Test(out)]
[=int2]
[=int3]
[=test]

null
null
null
null
called overloaded constructor Test()

2
3
unit.Test@a8e2e35c
strings
Strings are supported, of course.
[= "hello world"]
hello world
multiple line strings
Even this is possible:
[= "hello 
world"]
hello 
world
string concatenation
[= "hello" + " " + "world"]
[= 2 + " times"]
hello world
2 times
decimals/int, multiplication, division, modulo, addition, subtraction, unay minus, parenthesis:
Calculation is supported, as is usual in Java.
[= 123]
[= 2*3]
[= 6/2]
[= 5%3]
[= 2+3]
[= 5-2]
[= -1]
[= (2 + 3) * 4]
123
6
3
2
5
3
-1
20
preferences
All operators have the usual preferences:
[= 2 + 3 * 4] = [= 2 + ( 3 * 4 )] 
14 = 14
boolean literals, logic and, logic or, (unary) not:
Conditions are possible.
[= true]
[= false]
[= true && false]
[= false || true]
[= !false]
true
false
false
true
true
lower operator, lower equal, greater equal, greater, equality of two operands, no equality:
Comparison:
[= 2 < 2]
[= 2 <= 2]
[= 2 >= 2]
[= 2 > 2]
[= 2 == 2]
[= 2 != 2]
false
true
true
false
true
false
any kind of references
Any locally declared identifier within the current scope, any named argument as described below, and even the null literal can be used in expressions:
[= int3]
[= int3 = 2]
[= int3]
[= null]
3
2
2
null
field access
Read and write any public static or non-static field of any class.
[= test.intField]
[= test.intField = 1]
[= test.intField]
[= unit.Test.staticIntField]
[= unit.Test.staticIntField = 2]
[= unit.Test.staticIntField]
0
1
1
0
2
2
object constructor with arguments and array constructor
[= new Integer(1)]
[= oneDimIntArray = new int[2]]
[= twoDimIntArray = new int[2][]]
1
[I@ce52e35c
[[I@c5c6e35c
array read and write access
[= oneDimIntArray[0]]
[= oneDimIntArray[0] = 1]
[= oneDimIntArray[0]]
0
1
1
call any public static or non-static method with any arguments,
Pass argument(s) that do not exactly match with the method signature/parameter declaration(s) (a dynamic method resolution will be applied).
All values/objects of the classes
  • java.lang.Boolean,
  • java.lang.Character,
  • java.lang.Byte,
  • java.lang.Short,
  • java.lang.Integer,
  • java.lang.Long,
  • java.lang.Float,
  • java.lang.Double
can be created and usually will be treated as/converted to values of primitive types, automatically:
[System.out.println("hello world")]
[System.out.println(System.out)]
[unit.Test.staticMethod(1, out)]
[unit.Test.staticMethod(new Float("1.5"), out)]
[unit.Test.staticMethod("a".charAt(0), out)]
hello world
java.io.PrintStream@391b4be2
called static method with primitive int argument

called static method with primitive float argument

called static method with primitive char argument
operator instanceof
Runtime type information about objects and arrays:
[= "hello" instanceof String]
[= oneDimIntArray instanceof int[]]
true
true
type checking
Of course, UniT always checks the type of Boolean conditions and expression operands and UniT throws appropriate RuntimeExceptions.
Control flow (only the easy parts of Java)
name and description of the UniT feature example syntax and example result
of the UniT feature
while loop with continue and break
The most important feature for a dynamic text generator language like UniT is a loop. UniT allows all the kinds of loops that are allowed in Java, too.
[counter = 1]
[while (counter < 5){]
	[= counter]. iteration
	[counter = counter +1]
	[if (counter == 3) {]
		continuing iteration
		[continue]
	[} else {]
		[if (counter == 4) {]
			breaking iteration
			[break]
			blabla
		[}]
	[}]
[}]


	1. iteration
	
	
		
	

	2. iteration
	
	
		continuing iteration
		
	3. iteration
	
	
		
			breaking iteration
			
do loop
[do {]
	within do
	[break]
	blabla
[} while(false)]

	within do
	
for loop with declaration initialization
A for loop with declaration list in initialization that does NOT iterate.
[for (	Object a = 1, b = 2, c = 3; 
	false; 
	a = 1, b = 2) {]
	within for
	[break]
	blabla
[}]
for loop with break
A for loop without condition usually never ends. But we use a break statement:
[for (;;) {]
	within for
	[break]
[}]

	within for
	
conditionals
Often special conditions must be checked and handled differently.
[if (true) {]
	within then
[}]

[if (false) {]
	within then
[} else {]
	within else
[}]

	within then


	within else
error handling
It is possible to generate and handle exceptions in UniT like in Java. Of course, the finally block can be omitted. Or any catch block.
[try {]
	within try with throw 1
	[Object withinEHandling]
	[withinEHandling = null]
	
[throw new RuntimeException("This is a stupidly provocated RuntimeException.")]
[} catch (RuntimeException exception) {]
	caught RuntimeException: [=exception]
	[Object withinEHandling]
	[withinEHandling = null]
	
[} finally {] within finally, e.g., for closing files [Object withinEHandling] [withinEHandling = null] [}] [Object withinEHandling] [withinEHandling = null] within try with throw 1 caught RuntimeException:
java.lang.RuntimeException: This is a stupidly provocated RuntimeException.
	
	
	
within finally, e.g., for closing files
exit unit
A UniT program can be left at any location (further text won't be generated anymore!):
[return]

Special features of UniT

The predefined identifier/reference "out":

All generated output is directed to an object called/referenced by the identifier "out", which is always predefined (with the System.out object wrapped in a Writer instance) and can be reassigned at any time. It can even be passed to a unit as a named argument (see below). It must be an instance of the class java.io.Writer. And because the identifier out always references a Writer object, any file and anything else can be output to it.

First we save the current out object:

[Object savedOut = out]

The out object can be used to redirect output to a file or to multiple targets or to install special filters, like the following example illustrates. We create and set a special output Writer that replaces all white space sequences by one space and that has special methods for reinserting white space explicitly. This is a way having a nicely formatted UniT source code and getting pretty output at the same time, because you can indent and format the UniT source code and the output as you like, completely independently/orthogonally.

After using such a WhiteSpaceStripper, your indentation in the UniT source code, e.g., in loops, has no effect on the output because all white space is stripped and one space is inserted instead. But if the output needs to look nice, too, or special white space is needed, it can be created explicitly with some special methods.

[out = new unit.WhiteSpaceStripper(out)]
1. line 2. line 3. line 

Now a method calls to create white space explicitly: 
3 spaces([out.space()]):   end of spaces 
3 tabulators([out.tab()]):			end of tabs 
3 newlines([out.newline()]):


end of newlines 

Now we restore the original out object: [out = savedOut] 

Of course, a Java programmer can write his own filter that does anything he wants, e.g.,

  • buffer all output text until a flush occurs, to be able to stop output if an error occurs.
  • an HTML filter that replaces special characters with other special characters, e.g., & by &amp;,
  • or a filter that translates from one tag format to another tag format, e.g., from HTML tags to a proprietary tag format or vice versa,
  • or a filter that passes the output to another transformation tool, e.g., XML to an XSLT processor,
  • or a filter that replaces special tags with example text (from the designer) by dynamically created text/tags (from the programming expert),
  • or a filter that carries out even more complex actions.

Passing arguments to a UniT by name and the predefined identifier/reference "identifiers"

A Hashtable containing named objects can be passed to a UniT. Those named objects can be accessed like local references/variables. This is a way of passing any argument by name to a UniT. The Hashtable is an element of itself named "identifiers". This way it can be passed to methods. It can be passed to other UniTs that need to have access to all current identifiers.

Include/reuse

Of course, it is possible to include other text files, e.g., via file i/o and redirection to the out object or to include/execute another UniT, e.g., as a header or footer. This is analogous to Server Side Includes. Even parameters can be passed to another UniT by the identifiers that can be passed to a UniT as described above.

You can also parse a UniT file once and execute it multiple times without parsing it again. It could even be executed in parallel threads. Of course, this is a tricky topic. Did you find a bug? Contact me.

Of course, you can experiment with UniT and write your own programs to get to know the functionality and use-cases of UniT. Enjoy and have fun!

Download the unrestricted, non-commercial version of UniT now!
It's about 220 KB including this whole site and examples.
With the download you accept the license agreement.


Generated with UniT - the Universal Text Generator Version 1.0
Copyright © 2000 Thorsten van Ellen. All Rights Reserved.

mailto:thorsten@textgenerator.com

Home