# JQHTML Parser
The JQHTML parser converts template files into JavaScript functions that use the component system.
## Quick Start - Common Patterns
### Basic Component with innerHTML (Most Common)
```jqhtml
<%= content() %>
Card Title
This is the card content.
```
This `content()` pattern is the **primary way** to compose components in JQHTML. It works like regular HTML - the innerHTML you pass gets rendered where `content()` is called.
### Container Component Example
```jqhtml
<%= content() %>
Any content here
```
**Note:** Slots (`<#slotname>`) are an advanced feature only needed when you have multiple distinct content areas. For 95% of use cases, the simple `content()` pattern shown above is recommended.
### Define Tag Attributes (Component Configuration)
Define tags support three types of attributes for configuring components:
```jqhtml
Content here
```
**1. `extends=""` - Template Inheritance**
Explicitly declare parent template for inheritance (without requiring a JavaScript class).
**2. `$property=value` - Default Args**
Set default values for `this.args` that component invocations can override:
- **Quoted**: `$user_id="123"` → String literal `"123"`
- **Unquoted**: `$handler=MyController.fetch` → Raw JavaScript expression
- These become defaults; invocations can override them
**3. Regular Attributes**
Standard HTML attributes like `class=""`, `tag=""` applied to root element.
**Generated Output:**
```javascript
{
name: 'Contacts_DataGrid',
tag: 'div',
defaultAttributes: {"class": "card DataGrid"},
defineArgs: {"ajax_endpoint": Frontend_Contacts_Controller.datagrid_fetch, "per_page": "25"},
extends: 'DataGrid_Abstract',
render: function() { ... }
}
```
### Slot-Based Template Inheritance
When a template contains **ONLY slots** (no HTML), it automatically inherits the parent class template:
```jqhtml
<%= content('header') %>
<% for (let record of this.data.records) { %>
<%= content('row', record) %>
<% } %>
<#header>
ID
Name
Email
#header>
<#row>
<%= row.id %>
<%= row.name %>
<%= row.email %>
#row>
```
The parser detects slot-only templates and generates `{_slots: {...}}` format. Runtime walks prototype chain to find parent templates. **Data passing**: `content('row', record)` passes data to slot parameter `function(row) { ... }`. **Reserved words**: Slot names cannot be JavaScript keywords (`function`, `if`, etc.) - parser rejects with fatal error.
## Lexer (Task 1 - COMPLETE)
The lexer is the first stage of the parser. It converts raw JQHTML template text into a stream of tokens.
### Features
- **No regex** - Uses simple character scanning for maintainability
- **Position tracking** - Every token includes line, column, and absolute positions for source maps
- **Simple token types** - Clear, unambiguous token categories
- **Efficient scanning** - Single pass through the input
### Token Types
- `TEXT` - Plain HTML/text content
- `EXPRESSION_START` - `<%=` opening tag
- `CODE_START` - `<%` opening tag
- `TAG_END` - `%>` closing tag
- `DEFINE_START`, `DEFINE_END` - Component definition tags
- `COMPONENT_NAME` - Component identifier
- `JAVASCRIPT` - JavaScript code within tags
### Usage
```typescript
import { Lexer } from '@jqhtml/parser';
const template = `
<%= this.data.title %>
<% if (this.data.show) { %>
Content here
<% } %>
`;
const lexer = new Lexer(template);
const tokens = lexer.tokenize();
// tokens is an array of Token objects with:
// - type: TokenType
// - value: string
// - line: number
// - column: number
// - start: number (absolute position)
// - end: number
```
### Testing
```bash
# Build the parser
npm run build
# Run the test suite
node test-lexer.js
# Run the demo
node demo-lexer.js
```
### Implementation Notes
The lexer uses a simple state machine approach:
1. **Text scanning** - Default mode, captures plain text
2. **Tag detection** - Looks for `<%`, `<%=`, `%>` sequences
3. **Keyword matching** - After `<%`, checks for control flow keywords
4. **JavaScript capture** - Captures code between tags
5. **Position tracking** - Updates line/column for every character
No regex patterns are used. All scanning is done with:
- `match_sequence()` - Check for exact string match
- `match_keyword()` - Check for keyword with word boundary
- Character-by-character advancement
## Parser/AST Builder (Task 2 - COMPLETE)
The parser takes the token stream from the lexer and builds an Abstract Syntax Tree (AST) representing the template structure.
### Features
- **Recursive descent parsing** - Simple, predictable parsing algorithm
- **Clear node types** - Each AST node represents a specific construct
- **Position preservation** - All nodes include source positions
- **Error reporting** - Clear messages with line/column information
### AST Node Types
- `Program` - Root node containing all top-level definitions
- `ComponentDefinition` - Component template definition
- `Text` - Plain text/HTML content
- `Expression` - JavaScript expressions (`<%= ... %>`)
- `IfStatement` - Conditional rendering with optional else
- `ForStatement` - Loop constructs
- `CodeBlock` - Generic JavaScript code blocks
### Usage
```typescript
import { Lexer, Parser } from '@jqhtml/parser';
const template = `
<%= title %>
<% if (showContent) { %>
<%= content %>
<% } %>
`;
// Tokenize
const lexer = new Lexer(template);
const tokens = lexer.tokenize();
// Parse to AST
const parser = new Parser(tokens);
const ast = parser.parse();
// AST structure:
// {
// type: 'Program',
// body: [{
// type: 'ComponentDefinition',
// name: 'Card',
// body: [...]
// }]
// }
```
### Testing
```bash
# Run the parser test suite
node test-parser.js
# Run the interactive demo
node demo-parser.js
```
### Implementation Notes
The parser uses straightforward techniques:
1. **Token consumption** - Advances through tokens one at a time
2. **Lookahead** - Peeks at upcoming tokens to decide parsing path
3. **Context tracking** - Knows when inside components, loops, etc.
4. **Error recovery** - Provides helpful error messages
No parser generators or complex algorithms - just simple recursive functions that build nodes.
## Code Generator (Task 3 - COMPLETE)
The code generator takes the AST and produces executable JavaScript functions that work with the JQHTML component system.
### Features
- **jQuery-based DOM manipulation** - Generates efficient jQuery code
- **Component render functions** - Each template becomes a render function
- **Control flow handling** - Properly handles if/else and for loops
- **Expression evaluation** - Safely evaluates and renders expressions
- **Colon syntax support** - Strips trailing colons from control statements
### Generated Code Structure
```javascript
// Each component gets a render function
jqhtml_components.set('ComponentName', {
name: 'ComponentName',
render: function render() {
const $root = $('