947 lines
15 KiB
Markdown
947 lines
15 KiB
Markdown
# Receipt Template Language (RTL) Syntax Documentation
|
|
|
|
This document describes the syntax for creating receipt templates used by the Epson thermal printer template engine.
|
|
|
|
## Table of Contents
|
|
|
|
1. [Overview](#overview)
|
|
2. [Basic Text](#basic-text)
|
|
3. [Data Bindings](#data-bindings)
|
|
4. [Styled Text](#styled-text)
|
|
5. [Separators](#separators)
|
|
6. [Comments](#comments)
|
|
7. [Conditionals](#conditionals)
|
|
8. [Loops](#loops)
|
|
9. [Rows and Columns](#rows-and-columns)
|
|
10. [Complete Example](#complete-example)
|
|
11. [Printer Profiles](#printer-profiles)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
RTL is a line-based template language designed for thermal receipt printers. Templates are plain text files with embedded directives, bindings, and style markers that get transformed into printer commands.
|
|
|
|
**File Extension:** `.template`
|
|
|
|
**Key Concepts:**
|
|
- Templates are processed line by line
|
|
- Data is provided as JSON and accessed via bindings `{path}`
|
|
- Styles are applied using `#style# text #` syntax
|
|
- Control flow uses `@directive` syntax
|
|
|
|
---
|
|
|
|
## Basic Text
|
|
|
|
Plain text is output directly to the printer.
|
|
|
|
```
|
|
Hello World
|
|
This is plain text
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Hello World
|
|
This is plain text
|
|
```
|
|
|
|
### Empty Lines
|
|
|
|
Empty lines in templates produce empty lines on the receipt.
|
|
|
|
```
|
|
Line 1
|
|
|
|
Line 3
|
|
```
|
|
|
|
---
|
|
|
|
## Data Bindings
|
|
|
|
Bindings insert values from the JSON data into the output.
|
|
|
|
### Simple Binding
|
|
|
|
```
|
|
{PropertyName}
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{"PropertyName": "Hello"}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Hello
|
|
```
|
|
|
|
### Nested Properties
|
|
|
|
Use dot notation to access nested objects.
|
|
|
|
```
|
|
{Customer.Name}
|
|
{Order.Items.0.Name}
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{
|
|
"Customer": {"Name": "John Doe"},
|
|
"Order": {"Items": [{"Name": "Coffee"}]}
|
|
}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
John Doe
|
|
Coffee
|
|
```
|
|
|
|
### Format Specifiers
|
|
|
|
Add a format string after a colon to format numbers and dates.
|
|
|
|
#### Numeric Formats
|
|
|
|
```
|
|
Total: {Amount:F2}
|
|
Order #: {OrderNumber:D4}
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{"Amount": 19.5, "OrderNumber": 42}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Total: 19.50
|
|
Order #: 0042
|
|
```
|
|
|
|
| Format | Description | Example Input | Output |
|
|
|--------|-------------|---------------|--------|
|
|
| `F2` | Fixed-point, 2 decimals | 19.5 | 19.50 |
|
|
| `F0` | Fixed-point, no decimals | 19.5 | 20 |
|
|
| `D4` | Decimal, padded to 4 digits | 42 | 0042 |
|
|
| `N2` | Number with grouping | 1234.5 | 1,234.50 |
|
|
|
|
#### Date/Time Formats
|
|
|
|
```
|
|
Date: {TransactionDateTime:dd-MMM-yy}
|
|
Time: {TransactionDateTime:HH:mm}
|
|
Full: {TransactionDateTime:yyyy-MM-dd HH:mm:ss}
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{"TransactionDateTime": "2024-03-15T14:30:00"}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Date: 15-Mar-24
|
|
Time: 14:30
|
|
Full: 2024-03-15 14:30:00
|
|
```
|
|
|
|
| Format | Description | Example Output |
|
|
|--------|-------------|----------------|
|
|
| `dd-MMM-yy` | Day-Month-Year | 15-Mar-24 |
|
|
| `dd/MM/yyyy` | European date | 15/03/2024 |
|
|
| `MM/dd/yyyy` | US date | 03/15/2024 |
|
|
| `HH:mm` | 24-hour time | 14:30 |
|
|
| `hh:mm tt` | 12-hour time | 02:30 PM |
|
|
|
|
### Array Count
|
|
|
|
Access the count/length of an array.
|
|
|
|
```
|
|
Items: {Items.count}
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{"Items": ["A", "B", "C"]}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Items: 3
|
|
```
|
|
|
|
### Missing Values
|
|
|
|
If a binding path doesn't exist or is null, an empty string is output.
|
|
|
|
```
|
|
Name: {MissingProperty}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Name:
|
|
```
|
|
|
|
---
|
|
|
|
## Styled Text
|
|
|
|
Apply formatting styles to text using the `#styles# content #` syntax.
|
|
|
|
### Basic Syntax
|
|
|
|
```
|
|
#style1,style2# text content #
|
|
```
|
|
|
|
The styles are comma-separated and applied to all content between the markers.
|
|
|
|
### Available Styles
|
|
|
|
| Style | Description | PrintCommand Property |
|
|
|-------|-------------|----------------------|
|
|
| `bold` | Bold text | `IsBold = true` |
|
|
| `big` | Double-width and double-height | `IsBig = true` |
|
|
| `tall` | Double-height only | `IsTall = true` |
|
|
| `red` | Red color (if printer supports) | `IsRed = true` |
|
|
| `center` | Center-align text | Text padded with spaces |
|
|
| `right` | Right-align text | Text padded with spaces |
|
|
| `left` | Left-align text (default) | No padding |
|
|
| `spacing:N` | Set line spacing to N | `SetLineSpacing = N` |
|
|
|
|
### Examples
|
|
|
|
#### Bold Text
|
|
```
|
|
#bold# Important Notice #
|
|
```
|
|
|
|
#### Centered Title
|
|
```
|
|
#center# RECEIPT #
|
|
```
|
|
|
|
#### Combined Styles
|
|
```
|
|
#bold,big,center# RESTAURANT NAME #
|
|
```
|
|
|
|
#### Red Text (Impact Printers)
|
|
```
|
|
#red,bold# WARNING #
|
|
```
|
|
|
|
#### With Bindings
|
|
```
|
|
#bold,center# {Title} #
|
|
#big# Table: {TableNumber} #
|
|
```
|
|
|
|
#### Line Spacing
|
|
```
|
|
#spacing:50# Spaced text #
|
|
```
|
|
|
|
### Style Scope
|
|
|
|
Styles apply only to content within the markers on the same line.
|
|
|
|
```
|
|
#bold# This is bold # but this is not
|
|
```
|
|
|
|
---
|
|
|
|
## Separators
|
|
|
|
Create horizontal lines using repeated characters.
|
|
|
|
### Dash Separator
|
|
```
|
|
---
|
|
```
|
|
Output: `------------------------------------------------` (full line width)
|
|
|
|
### Equals Separator
|
|
```
|
|
===
|
|
```
|
|
Output: `================================================`
|
|
|
|
### Star Separator
|
|
```
|
|
***
|
|
```
|
|
Output: `************************************************`
|
|
|
|
### Tilde Separator
|
|
```
|
|
~~~
|
|
```
|
|
Output: `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
|
|
|
|
**Note:** Separator width automatically matches the printer's line width (48 chars for TM-T30III, 33 chars for TM-U220II).
|
|
|
|
---
|
|
|
|
## Comments
|
|
|
|
Add comments to templates for documentation purposes. Comments are stripped during parsing and do not appear in the output.
|
|
|
|
### Single-Line Comment
|
|
|
|
Use `@*` at the start of a line to comment out the entire line.
|
|
|
|
```
|
|
@* This is a single-line comment
|
|
Regular text here
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Regular text here
|
|
```
|
|
|
|
### Inline Comment
|
|
|
|
Use `@* ... *@` to create a comment that can have content after it on the same line.
|
|
|
|
```
|
|
@* This is a comment *@
|
|
@* Header section *@
|
|
#bold,center# Title #
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
|
|
Title
|
|
```
|
|
|
|
### Multi-Line Comment
|
|
|
|
Use `@*` on its own line to start a multi-line comment block, and `*@` to close it.
|
|
|
|
```
|
|
@*
|
|
This is a multi-line comment.
|
|
All these lines are ignored.
|
|
Directives like @if are also ignored here.
|
|
*@
|
|
This text appears in output
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
This text appears in output
|
|
```
|
|
|
|
### Use Cases
|
|
|
|
#### Document Template Sections
|
|
```
|
|
@* === HEADER SECTION === *@
|
|
#bold,center# {Title} #
|
|
---
|
|
|
|
@* === ITEMS SECTION === *@
|
|
@foreach item in Items
|
|
{item.Name}
|
|
@end
|
|
```
|
|
|
|
#### Temporarily Disable Code
|
|
```
|
|
@*
|
|
@if DebugMode
|
|
Debug info: {DebugData}
|
|
@end
|
|
*@
|
|
```
|
|
|
|
#### Add Notes for Maintainers
|
|
```
|
|
@* Note: This section only shows for orders over $100 *@
|
|
@if Total > 100
|
|
#bold# Large Order #
|
|
@end
|
|
```
|
|
|
|
### Important Notes
|
|
|
|
- Comments must start at the beginning of a line (after optional whitespace)
|
|
- `@*` mid-line in content is treated as regular text, not a comment
|
|
- Star separators (`***`) are not confused with comments
|
|
- Unclosed multi-line comments produce a lexer error
|
|
|
|
---
|
|
|
|
## Conditionals
|
|
|
|
Control which content is rendered based on data values.
|
|
|
|
### Basic If
|
|
|
|
```
|
|
@if Condition
|
|
Content shown when true
|
|
@end
|
|
```
|
|
|
|
### If-Else
|
|
|
|
```
|
|
@if HasDiscount
|
|
Discount Applied!
|
|
@else
|
|
No Discount
|
|
@end
|
|
```
|
|
|
|
### If-ElseIf-Else
|
|
|
|
```
|
|
@if Status == "pending"
|
|
Order Pending
|
|
@elseif Status == "complete"
|
|
Order Complete
|
|
@else
|
|
Unknown Status
|
|
@end
|
|
```
|
|
|
|
### Truthy/Falsy Values
|
|
|
|
The following are considered **falsy**:
|
|
- `null` or missing property
|
|
- `false`
|
|
- Empty string `""`
|
|
- Number `0`
|
|
- Empty array `[]`
|
|
|
|
Everything else is **truthy**.
|
|
|
|
### Comparison Operators
|
|
|
|
| Operator | Description | Example |
|
|
|----------|-------------|---------|
|
|
| `==` | Equal | `Status == "active"` |
|
|
| `!=` | Not equal | `Type != "void"` |
|
|
| `>` | Greater than | `Amount > 100` |
|
|
| `<` | Less than | `Count < 5` |
|
|
| `>=` | Greater or equal | `Total >= 50` |
|
|
| `<=` | Less or equal | `Qty <= 10` |
|
|
|
|
### Negation
|
|
|
|
```
|
|
@if !IsVoided
|
|
Valid Order
|
|
@end
|
|
```
|
|
|
|
### String Literals
|
|
|
|
Use quotes for string comparisons.
|
|
|
|
```
|
|
@if Status == "active"
|
|
Active
|
|
@end
|
|
```
|
|
|
|
### Numeric Comparisons
|
|
|
|
```
|
|
@if Amount > 100
|
|
Large Order
|
|
@end
|
|
|
|
@if Items.count > 0
|
|
Has Items
|
|
@end
|
|
```
|
|
|
|
### Examples
|
|
|
|
#### Check for Optional Field
|
|
```
|
|
@if SpecialInstruction
|
|
#bold# Note: {SpecialInstruction} #
|
|
@end
|
|
```
|
|
|
|
#### Check Array Has Items
|
|
```
|
|
@if Modifications.count > 0
|
|
Modifications:
|
|
@foreach mod in Modifications
|
|
- {mod}
|
|
@end
|
|
@end
|
|
```
|
|
|
|
#### Conditional Separator
|
|
```
|
|
@if Items.count > 0
|
|
---
|
|
@end
|
|
```
|
|
|
|
---
|
|
|
|
## Loops
|
|
|
|
Iterate over arrays in the data.
|
|
|
|
### Basic Foreach
|
|
|
|
```
|
|
@foreach item in Items
|
|
{item}
|
|
@end
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{"Items": ["Apple", "Banana", "Cherry"]}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Apple
|
|
Banana
|
|
Cherry
|
|
```
|
|
|
|
### Object Properties
|
|
|
|
```
|
|
@foreach product in Products
|
|
{product.Name} - {product.Price:F2}
|
|
@end
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{
|
|
"Products": [
|
|
{"Name": "Coffee", "Price": 3.50},
|
|
{"Name": "Tea", "Price": 2.50}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Coffee - 3.50
|
|
Tea - 2.50
|
|
```
|
|
|
|
### Nested Loops
|
|
|
|
```
|
|
@foreach category in Categories
|
|
#bold# {category.Name} #
|
|
@foreach item in category.Items
|
|
{item.Name}
|
|
@end
|
|
@end
|
|
```
|
|
|
|
### Loop Metadata Variables
|
|
|
|
Inside a loop, these special variables are available:
|
|
|
|
| Variable | Description | Example Value |
|
|
|----------|-------------|---------------|
|
|
| `_index` | Zero-based index | 0, 1, 2, ... |
|
|
| `_number` | One-based number | 1, 2, 3, ... |
|
|
| `_first` | True if first item | true/false |
|
|
| `_last` | True if last item | true/false |
|
|
| `_count` | Total items in collection | 5 |
|
|
|
|
#### Examples
|
|
|
|
```
|
|
@foreach item in Items
|
|
{_number}. {item.Name}
|
|
@end
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
1. Apple
|
|
2. Banana
|
|
3. Cherry
|
|
```
|
|
|
|
```
|
|
@foreach item in Items
|
|
{item}
|
|
@if !_last
|
|
---
|
|
@end
|
|
@end
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Apple
|
|
---
|
|
Banana
|
|
---
|
|
Cherry
|
|
```
|
|
|
|
### Nested Path Collections
|
|
|
|
```
|
|
@foreach dish in Order.Kitchen.Dishes
|
|
{dish.Name}
|
|
@end
|
|
```
|
|
|
|
---
|
|
|
|
## Rows and Columns
|
|
|
|
Create tabular layouts with fixed-width columns.
|
|
|
|
### Basic Row
|
|
|
|
```
|
|
@row
|
|
|width|content|width|content
|
|
@endrow
|
|
```
|
|
|
|
### Row Styles
|
|
|
|
Apply styles to an entire row by adding style names after `@row`:
|
|
|
|
```
|
|
@row bold
|
|
|width|content|width|content
|
|
@endrow
|
|
```
|
|
|
|
Multiple styles can be combined with commas:
|
|
|
|
```
|
|
@row bold, big
|
|
|width|content|width|content
|
|
@endrow
|
|
```
|
|
|
|
#### Available Row Styles
|
|
|
|
| Style | Description |
|
|
|-------|-------------|
|
|
| `bold` | Bold text for entire row |
|
|
| `big` | Double-width and double-height |
|
|
| `tall` | Double-height only |
|
|
| `red` | Red color (if printer supports) |
|
|
| `spacing:N` | Set line spacing to N |
|
|
|
|
#### Row Style Examples
|
|
|
|
```
|
|
@row bold
|
|
|30|{Name}|10,right|{Price:F2}
|
|
@endrow
|
|
```
|
|
|
|
```
|
|
@row bold, big
|
|
|15|TOTAL|9,right|{Total:F2}
|
|
@endrow
|
|
```
|
|
|
|
```
|
|
@row red, bold
|
|
|40|*** WARNING ***
|
|
@endrow
|
|
```
|
|
|
|
### Column Syntax
|
|
|
|
```
|
|
|width|content
|
|
|width,alignment|content
|
|
```
|
|
|
|
- **width**: Number of characters for the column
|
|
- **alignment**: `left` (default), `right`, or `center`
|
|
|
|
### Examples
|
|
|
|
#### Two Columns
|
|
```
|
|
@row
|
|
|30|{Name}|10,right|{Price:F2}
|
|
@endrow
|
|
```
|
|
|
|
**JSON:**
|
|
```json
|
|
{"Name": "Coffee", "Price": 3.50}
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
Coffee 3.50
|
|
```
|
|
|
|
#### Three Columns
|
|
```
|
|
@row
|
|
|5,right|{Qty}|25|{Name}|10,right|{Total:F2}
|
|
@endrow
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
2 Espresso 7.00
|
|
```
|
|
|
|
#### Header Row
|
|
```
|
|
@row
|
|
|5|Qty|25|Item|10,right|Price
|
|
@endrow
|
|
===
|
|
```
|
|
|
|
### Columns in Loops
|
|
|
|
```
|
|
@foreach item in Items
|
|
@row
|
|
|5,right|{item.Quantity}|25|{item.Name}|10,right|{item.Price:F2}
|
|
@endrow
|
|
@end
|
|
```
|
|
|
|
### Text Truncation
|
|
|
|
If content exceeds the column width, it is truncated.
|
|
|
|
```
|
|
@row
|
|
|10|VeryLongProductNameHere
|
|
@endrow
|
|
```
|
|
|
|
**Output:**
|
|
```
|
|
VeryLongPr
|
|
```
|
|
|
|
---
|
|
|
|
## Complete Example
|
|
|
|
Here's a complete kitchen receipt template:
|
|
|
|
```
|
|
#red,big,tall,center# {Title} #
|
|
---
|
|
|
|
#center# {TransactionDateTime:dd-MMM-yy HH:mm} Nr.:{ReceiptNumber} #
|
|
#center# {WaiterName} #
|
|
#center# {WaiterId} #
|
|
#big,bold,center# Tisch: {TableNumber} #
|
|
|
|
@if SpecialInstruction
|
|
|
|
#big,bold,center# {SpecialInstruction} #
|
|
|
|
@end
|
|
---
|
|
@foreach gang in Gangs
|
|
#red,big,tall,center# {gang.Id}. {gang.Name} #
|
|
@foreach dish in gang.Dishes
|
|
#tall# {dish.Number}x {dish.Name} #
|
|
@if dish.Modifications.Removed.count > 0
|
|
@foreach removed in dish.Modifications.Removed
|
|
#bold,tall# - {removed} #
|
|
@end
|
|
@end
|
|
@if dish.Modifications.Added.count > 0
|
|
@foreach added in dish.Modifications.Added
|
|
#bold,tall# + {added} #
|
|
@end
|
|
@end
|
|
@if dish.Comment
|
|
#bold,tall# Comment: {dish.Comment} #
|
|
@end
|
|
@end
|
|
@end
|
|
@if Gangs.count > 0
|
|
---
|
|
@end
|
|
@foreach dish in Dishes
|
|
#tall# {dish.Number}x {dish.Name} #
|
|
@if dish.Modifications.Removed.count > 0
|
|
@foreach removed in dish.Modifications.Removed
|
|
#bold,tall# - {removed} #
|
|
@end
|
|
@end
|
|
@if dish.Modifications.Added.count > 0
|
|
@foreach added in dish.Modifications.Added
|
|
#bold,tall# + {added} #
|
|
@end
|
|
@end
|
|
@if dish.Comment
|
|
#bold,tall# Comment: {dish.Comment} #
|
|
@end
|
|
@end
|
|
@if Dishes.count > 0
|
|
|
|
---
|
|
|
|
@end
|
|
```
|
|
|
|
**Sample JSON:**
|
|
```json
|
|
{
|
|
"Title": "Restaurant Kitchen",
|
|
"TransactionDateTime": "2024-03-15T14:30:00",
|
|
"ReceiptNumber": "12345",
|
|
"WaiterName": "John Doe",
|
|
"WaiterId": "W001",
|
|
"TableNumber": "5",
|
|
"SpecialInstruction": "Rush Order",
|
|
"Gangs": [
|
|
{
|
|
"Id": 1,
|
|
"Name": "Starters",
|
|
"Dishes": [
|
|
{
|
|
"Number": 2,
|
|
"Name": "Caesar Salad",
|
|
"Modifications": {
|
|
"Removed": ["Croutons"],
|
|
"Added": ["Extra Dressing"]
|
|
},
|
|
"Comment": "No anchovies"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"Dishes": []
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Printer Profiles
|
|
|
|
Templates adapt to different printer capabilities using profiles.
|
|
|
|
### Built-in Profiles
|
|
|
|
| Printer | Profile ID | Line Width | Big Width | Red Support |
|
|
|---------|------------|------------|-----------|-------------|
|
|
| TM-T30III | `tm-t30iii` | 48 | 24 | No |
|
|
| TM-U220II | `tm-u220ii` | 33 | 20 | Yes |
|
|
|
|
### How Profiles Affect Output
|
|
|
|
1. **Line Width**: Separators and centered text use the profile's line width
|
|
2. **Big Width**: When `big` style is applied, centering uses the reduced width
|
|
3. **Red Support**: The `red` style only produces red output on supported printers
|
|
|
|
### Template Assignment
|
|
|
|
Templates are assigned to receipt types and printer profiles in `assignments.json`:
|
|
|
|
```json
|
|
{
|
|
"assignments": [
|
|
{
|
|
"receiptType": 1,
|
|
"profileId": "tm-t30iii",
|
|
"template": "kitchen-default.template"
|
|
},
|
|
{
|
|
"receiptType": 1,
|
|
"profileId": "tm-u220ii",
|
|
"template": "kitchen-u220.template"
|
|
},
|
|
{
|
|
"receiptType": 1,
|
|
"profileId": null,
|
|
"template": "kitchen-default.template"
|
|
}
|
|
],
|
|
"fallbackTemplate": "fallback.template"
|
|
}
|
|
```
|
|
|
|
**Resolution Priority:**
|
|
1. Exact match (receiptType + profileId)
|
|
2. Type-only match (receiptType, no profileId)
|
|
3. Fallback template
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
### Syntax Summary
|
|
|
|
| Syntax | Description |
|
|
|--------|-------------|
|
|
| `{path}` | Data binding |
|
|
| `{path:format}` | Formatted binding |
|
|
| `#style# text #` | Styled text |
|
|
| `---` | Dash separator |
|
|
| `===` | Equals separator |
|
|
| `***` | Star separator |
|
|
| `~~~` | Tilde separator |
|
|
| `@* comment` | Single-line comment |
|
|
| `@* comment *@` | Inline comment |
|
|
| `@*` ... `*@` | Multi-line comment block |
|
|
| `@if condition` | Start conditional |
|
|
| `@elseif condition` | Else-if branch |
|
|
| `@else` | Else branch |
|
|
| `@end` | End block |
|
|
| `@foreach var in collection` | Start loop |
|
|
| `@row` | Start row |
|
|
| `@row style1, style2` | Start row with styles |
|
|
| `@endrow` | End row |
|
|
| `\|width\|content` | Column definition |
|
|
| `\|width,align\|content` | Column with alignment |
|
|
|
|
### Style Reference
|
|
|
|
| Style | Effect |
|
|
|-------|--------|
|
|
| `bold` | Bold text |
|
|
| `big` | Double size |
|
|
| `tall` | Double height |
|
|
| `red` | Red color |
|
|
| `center` | Center align |
|
|
| `right` | Right align |
|
|
| `spacing:N` | Line spacing |
|
|
|
|
### Loop Variables
|
|
|
|
| Variable | Value |
|
|
|----------|-------|
|
|
| `_index` | 0, 1, 2, ... |
|
|
| `_number` | 1, 2, 3, ... |
|
|
| `_first` | true/false |
|
|
| `_last` | true/false |
|
|
| `_count` | total count |
|