Introduction

SmartText is a tool of generating text.
It can help you rapidly generating lots of text (Like code, report, configuration files, etc.).This help file is also generated by SmartText.
SmartText has a built-in text template engine (similar to Velocity), also provides a fancy and friendly GUI for better user experience.



Features :


Getting Started

SmartText needs to be run on Windows XP/Vista/7 and above OS.
Also needs .Net Framework 4.0 and above installed.
Double click SmartText.exe to run.


Nice GUI huh? OK, let’s see what SmartText can do for you.

So, smart as you can figure out SmartText's capability?




Template

SmartText's template is a skeleton of the text to be generated.
There are some marks in template, to distinguish normal text and special text.
SmartText mainly uses Lua syntax as template syntax,
So if you’re familiar with Lua, you will easily grasp SmartText's template.
if not, it's ok, you just need to learn a couple of simple structures.

Variable

By passing through the example in Getting Started, you should probably know the syntax of variable in SmartText's template:

${expression}

Any valid expression of Lua, SmartText will evaluate it, and replace its representation with evaluating result.
Due to Lua, we can easily set a default value to a variable, like :

${person.name or 'somebody'}

If person.name is nil (means nothing in Lua), use the value after "or"(here is a string "somebody").
Note that string can be surrounded by either double quote (") or single quote (') in Lua.

All the examples before demonstrate a very important thing, using dot (.) to express hierarchical data structure.
We look into that in more detail later in Parameter

Flow Controlling

In template, condition statement (if) and repeat statement (for) can be used to control the flow of text generating.
Because SmartText uses Lua inside (The template will be parsed into Lua code), so all the flow controlling statements use standard Lua syntax.
Only need to use #{} form.

#{Lua statement}

if

See the following example:

#{if person.age < 18 then}
${person.name} is a child.
#{else}
${person.name} is an adult.
#{end}

In this example, if statement is used to make decision between "child" and "adult".
By using the previous xml parameter, the output text will be:

WAKU is an adult.

Here is the complete syntax of if in Lua:

stat ::= if exp then block {elseif exp then block} [else block] end

Lua operator can also be used in condition statement. Following is a brief table of operators.

Operator Meaning
== Equal
~= Not Equal
< Less than
> Great than
<= Less than or Equal to
>= Great than or Equal to
and And
or Or
not Not

for

For statement is very useful, it can repeatedly generate a part of text.
For statement has two forms: one numeric and one generic. Let’s see the first.

#{for i = 1, 5 do}
i = ${i}
#{end}

This template is so simple even need no parameter to generate result:

i = 1
i = 2
i = 3
i = 4
i = 5

Following is the syntax of numeric form:

stat ::= for Name `=´ exp1 `,´ exp2 [`,´ exp3] do block end
exp1 is the initial value,
exp2 is the termination value,
exp3 is the step value, when omitted, 1 as default.

However, in practice, we often use another form: generic for
Before demonstration, we need to expand our parameter file:

<list>
    <person>
        <name>WAKU</name>
        <age>29</age>
    </person>
    <person>
        <name>Joey</name>
        <age>2</age>
    </person>
</list>

Then use generic for like this:

#{for p in enum(list.person) do}
NAME: ${p.name} AGE: ${p.age}
#{end}

The result:

NAME: WAKU AGE: 29
NAME: Joey AGE: 2

SmartText parses XML parameter into Lua code (detail in Parameter),
"person" is a Lua Table(used as an array here), can be accessed by "list.person".
SmartText provides a very handy function "enum" to enumerate element of a Table,
So "enum(list.peronson)" is enumerating every person, which is assigned to "p".


The syntax of generic for:

stat ::= for namelist in explist do block end

Above is all the explanations about flow controlling, mainly if and for, but SmartText and Lua have a very flexible combination,
In fact, you can insert any valid Lua statements into #{...}, they will be parsed into Lua code and executed.
You can define global variables in #{...}, and use it somewhere else.
You can even define functions, in order to implement macros like Velocity does.




Parameter

SmartText supports three types of parameter files (CSV XML LUA), even though they have similar usage (provide data to template),
but each type has its own advantages and disadvantages, you should use appropriate type on different occasions.
SmartText parses CSV and XML parameter files to Lua code. You needn't to grasp the details of parsing, only need to know how to use data correctly.

CSV Parameter File

CSV parameter file is the easiest type, it has a straightforward data relationship. You can use EXCEL to edit CSV files.
The row-column form is also correspond to database table, so if you want to use a database table as a parameter, then, the CSV parameter file is most appropriate.
However, CSV parameter file cannot represent hierarchical relationships of data structure, then you need to consider the use of XML or LUA parameter files.

Example:

Template file:

${parameter[1].name} is ${parameter[1].age} years old.
${parameter[2].name} is ${parameter[2].age} years old.

Parameter file "parameter.csv":

name,age
WAKU,29
Joey,2

Generated result:

WAKU is 29 years old.
Joey is 2 years old.

Since CSV file has no root element like XML file, so SmartText uses CSV file name as a prefix of each variable.
In above example, the CSV parameter file's name is "parameter", so the prefix of each variable is "parameter".
Use subscript form "parameter[1]" to access the the line "WAKU,29" (the subscripts of Lua array starts from 1),
Access the content of column "name" is also straightforward: "parameter[1].name".

The above example works well, though; the template was slightly awkward,
Using generic for, you can use the following template form to get exactly the same result:

#{for p in enum(parameter) do}
${p.name} is ${p.age} years old.
#{end}

It is worth mentioning that, SmartText uses LumenWorks parsing CSV files, LumenWorks is the best .Net CSV parser in my opinion.


XML Parameter File

XML is a very popular file format, and has good compatibility. The tree-form is very suitable to represent the data structure with a hierarchical relationship.
.Net also have an excellent support for XML, you can serialize an object to XML file, a Dataset object can be directly written to XML file and so on.
The disadvantage of XML file maybe somewhat lengthy, editing is a little inconvenient without a handy tool.
Same with CSV, SmartText parses XML parameter file into Lua code.

Example:

Template file:

#{for p in enum(list.person) do}
${p.name} is ${p.age} years old.
${p.name} likes ${join(p.favourite_food.food)}.
#{end}

Parameter file "parameter.xml":

<list>
    <person name="WAKU" age="29">
        <favourite_food>
            <food>rice</food>
            <food>chicken</food>
        </favourite_food>
    </person>
    <person name="Joey" age="2">
        <favourite_food>
            <food>milk</food>
            <food>juice</food>
            <food>candy</food>
        </favourite_food>
    </person>
</list>

Generated result:

WAKU is 29 years old.
WAKU likes rice,chicken.
Joey is 2 years old.
Joey likes milk,juice,candy.

This example demonstrates how to access the content of XML parameter correctly.
Just remember a few simple rules:
1. Variables start from the root node ("list" in the example)
2. Use DOT (.) to access attribute (like "name" and "age" in the example)
3. Also use DOT (.) to access child node
4. If a node appears more than once, it is an array, you can use the "enum" function for enumeration (like "person" and "food" in the example)

There is a new function "join", it's also provided by SmartText.
It is used to concatenate string elements of an array, the first argument is same with "enum"(.Net array, collection or Lua Table); the second argument separator is optional, default is a comma(,).

LUA Parameter File

Lua parameter file is the most efficient of the three types (as both CSV and XML are required to parse into Lua code first), and also the most flexible one.
Its disadvantage is not very popular, and using it needs a certain knowledge of Lua.
Lua parameter file can get exactly same result of previous examples, just use the Lua code in the technical details as a Lua parameter file.
But there are something that CSV and XML cannot do.

Example:

Template file:

a = ${a}
b = ${b}
c = ${c}
a + b + c = ${a + b + c}

Parameter file "parameter.lua":

a = 1
b = 2
c = 3

Generated result:

a = 1
b = 2
c = 3
a + b + c = 6

If you use CSV or XML, you have to quote the CSV template file name or the name of the XML root node,
The parameter also needs to be split by comma or placed into XML-TAG, while Lua parameter is very straightforward.
Note, however, that all these variables are defined as global, so you need to pay attention to naming conflicts.
Of course, if there are pretty much variables, you should get them organized by using Lua Table.



Error Handling

If an error was raised when generating text, SmartText will display the error message in the textbox with red color.

Lua Error

As mentioned before, SmartText parses the content of the template into Lua code, so the template should meet Lua syntax requirement, otherwise Lua compiler will complain.
Another case is that there's no syntax error in template, but the Lua code raises a runtime-error,
Anyway, SmartText will get the error message and display into the text box.
Look at the following example:

#{for i = 1, 5}
i = ${i}
#{end}

The template does not require a parameter file to run, but an error occurs:

The first line of the text box is the Lua compiler error messages, a compilation error is in the format [string "chunk"]: line :
Here line is the line number of the wrong Lua code. Following is a detailed description of the error ("do" was missing)
After second line is the parsed Lua code based on the template, for ease of viewing, SmartText added the line number before each line.

From the parsed Lua code, we can see some details of processing template in SmartText:
1. The content in flow controlling #{...} is parsed directly into Lua code (like "for" and "end" in the example);
2. "RenderText" is a SmartText's internal function, which returns the generated text;
3. Use [=[ and ]=] to surround normal string, prevent string from being escaped;
4. "return 0" at last is a fixed statement added by SmartText

Undefined Variable Error

When variable used does not exist in parameter, this error occurs, such as the following template:

${a} + ${b} + ${c}

If you do not use any parameter file, the template will raise the following error:

[string "chunk"]:1: attempt to concatenate global 'c' (a nil value)
Lua Source:
  1 : RenderText(1, [=[]=] .. (a) .. [=[ + ]=] .. (b) .. [=[ + ]=] .. (c) .. [=[]=], '\r\n'); 
  2 : return 0

Error message clearly indicates which variable does not exist, and the location where variable appears.

In addition, if you specify a parameter file, SmartText will also append the parsed Lua code of the parameter file to the end of the text box in order to analyze the error.



Command Line

SmartText can use the command-line parameters in the following format:

SmartText.exe template [parameter [output [template encoding [parameter encoding [output encoding]]]]]

Respectively, template file, parameter file, output file, encoding of template file, encoding of parameter file, encoding of output file.
Where the template file must be specified, the others can be omitted.
The 4th to 6th parameter is required to be the Code Page of the encoding (an integer), you can get it in the setting window of SmartText.
Here is an example of using the command-line parameters:

SmartText.exe "d:\template.txt" "" "d:\output.txt" 936 0 65001

Use "d:\template.txt" as template file, no parameter file, uses "d:\output.txt" as output file, the template file encoding is GB2312, and the output file encoding is UTF-8.

When successes, the output file will be generated and a zero value will be returned, in addition to this, no any other prompt.
If failed, the GUI of SmartText will be displayed, the methods described in Error Handling will help you figure out what went wrong.