# Progressive Complexity Roadmap

A systematic plan for creating wasot example files that introduce syntax features one concept at a time, validated through S-expression output.

## Purpose

The `progressive_complexity/` directory will contain numbered wasot files that progressively introduce syntax features. Each file should differ from the previous by introducing **exactly one new concept** visible in the S-expression output.

## S-Expression Node Types

Based on the parser output, these are the S-expression constructs we need to introduce:

| Node Type | Attributes | Example |
|-----------|------------|---------|
| `block` | `type`, `level`, `id`, `line_index` | `(block type: "div" level: 1 id: "1" line_index: 0 ...)` |
| `inline-text` | `content`, `quoted` | `(inline-text content: "Hello" quoted: false)` |
| `text` | Contains `line` children | `(text (line ...) ...)` |
| `line` | `index`, `content` | `(line index: 0 content: "Hello")` |
| `kwarg` | Contains `key` and `value` | `(kwarg (key ...) (value ...))` |
| `key` | `content`, `quoted` | `(key content: "class" quoted: false)` |
| `value` | `content`, `quoted` | `(value content: "container" quoted: true)` |
| `void` | `type`, `level`, `id`, `line_index` | `(void type: "hr" level: 1 ...)` |
| `context-line` | `type`, `level`, `id`, `line_index`, contains `inline-text` | `(context-line type: "meta" level: 1 line_index: 1 ...)` |
| `link` | `target_type`, `start`, `length`, contains `name` | `(link target_type: uri start: 10 length: 23 ...)` |
| `name` (in link) | `content`, `quoted` | `(name content: "https://..." quoted: false)` |

**Note**: A truly empty file (0 bytes) produces no output. A file with only whitespace/newlines produces standalone `(text ...)` nodes.

## File Sequence Plan

### Phase 1: Foundation (000-009)

These files establish the basic building blocks.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `000_empty.wasot` | *(0 bytes)* | Truly empty file produces no output | No output |
| `001_single_block.wasot` | `.block` | Minimal block declaration | Introduces `(block type: level: id: line_index:)` |
| `002_block_with_text.wasot` | `.block`<br>`Hello` | Text content in block | Introduces `(text (line ...))` |
| `003_multiline_text.wasot` | `.block`<br>`Line 1`<br>`Line 2` | Multiple text lines | Multiple `(line ...)` nodes |
| `004_inline_text.wasot` | `.div Hello World` | Inline text on meta-line | Introduces `(inline-text content: quoted: false)` |
| `005_inline_text_quoted.wasot` | `.div "Hello World"` | Quoted inline text | Shows `(inline-text ... quoted: true)` |
| `006_block_id.wasot` | `.div :my-id` | Block with explicit ID | Shows explicit `id:` value in block |
| `007_nested_block.wasot` | `.outer`<br>`..inner` | Block nesting | Shows `level: 2` in nested block |
| `008_deeply_nested.wasot` | `.a`<br>`..b`<br>`...c` | Three-level nesting | Shows `level: 3` |
| `009_sibling_blocks.wasot` | `.first`<br>`.second` | Multiple root-level blocks | Multiple top-level `(block ...)` nodes |

### Phase 2: Parameters (010-019)

Introducing the parameter system (`..` separator).

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `010_param_separator.wasot` | `.div text ..` | Empty parameter section | Shows inline-text before `..` |
| `011_positional_arg.wasot` | `.div .. primary` | Single positional argument | Arg appears in inline-text after `..` |
| `012_multiple_args.wasot` | `.div .. arg1 arg2 arg3` | Multiple positional args | Multiple args in sequence |
| `013_keyword_arg.wasot` | `.div .. key=value` | Keyword argument | Introduces `(kwarg (key ...) (value ...))` |
| `014_quoted_value.wasot` | `.div .. key="my value"` | Quoted kwarg value | Shows `(value ... quoted: true)` |
| `015_quoted_key.wasot` | `.div .. "my key"=value` | Quoted kwarg key | Shows `(key ... quoted: true)` |
| `016_multiple_kwargs.wasot` | `.div .. a=1 b=2` | Multiple kwargs | Multiple `(kwarg ...)` nodes |
| `017_mixed_args.wasot` | `.div .. arg1 key=val arg2` | Positional and keyword mixed | Args + kwargs together |
| `018_inline_and_params.wasot` | `.div text .. key=val` | Inline text + parameters | Both `inline-text` and `kwarg` |
| `019_id_with_params.wasot` | `.div .. key=val :my-id` | ID with parameters | ID at end with kwargs |

### Phase 3: Block Type Variations (020-029)

Exploring different block type syntaxes.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `020_type_with_number.wasot` | `.h1`<br>`text` | Type containing numbers | Shows `type: "h1"` |
| `021_type_with_dash.wasot` | `.my-type`<br>`text` | Type with dashes | Shows `type: "my-type"` |
| `022_type_with_underscore.wasot` | `.my_type`<br>`text` | Type with underscores | Shows `type: "my_type"` |
| `023_type_starting_number.wasot` | `.123class`<br>`text` | Type starting with number | Shows `type: "123class"` |
| `024_quoted_type.wasot` | `."my type"`<br>`text` | Quoted type (spaces) | Shows `type: "my type"` |
| `025_unicode_type.wasot` | `.日本語`<br>`text` | Unicode type | Shows `type: "日本語"` |
| `026_emoji_type.wasot` | `.emoji🎉`<br>`text` | Emoji in type | Shows emoji in type |
| `027_empty_type.wasot` | `.`<br>`text` | Empty type (just dot) | Shows `type: ""` |
| `028_empty_nested_type.wasot` | `.a`<br>`..` | Empty nested type | Shows `type: ""` at level 2 |
| `029_escaped_quotes_type.wasot` | `."type \"x\""` | Escaped quotes in type | Shows escaped quotes |

### Phase 4: Headings (030-034)

The special `#` heading syntax.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `030_heading_empty.wasot` | `.#` | Self-closing heading | Shows `type: "#"` |
| `031_heading_with_text.wasot` | `.# Title` | Heading with inline text | `type: "#"` + `inline-text` |
| `032_heading_level_2.wasot` | `.##` | Double-hash heading | Shows `type: "##"` |
| `033_heading_level_3.wasot` | `.###` | Triple-hash heading | Shows `type: "###"` |
| `034_nested_heading.wasot` | `.outer`<br>`..# Section` | Nested heading | Heading at level 2 |

### Phase 5: ID Variations (035-039)

Different ID syntaxes and placements.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `035_id_with_numbers.wasot` | `.div :id123` | ID containing numbers | Shows `id: "id123"` |
| `036_id_with_dashes.wasot` | `.div :my-id` | ID with dashes | Shows `id: "my-id"` |
| `037_id_with_colons.wasot` | `.div :ns:id` | Namespaced ID | Shows `id: "ns:id"` |
| `038_unicode_id.wasot` | `.div :日本語` | Unicode ID | Shows unicode in id |
| `039_id_with_inline.wasot` | `.div Hello :my-id` | ID after inline text | ID at end of inline |

### Phase 6: Text Content Variations (040-044)

Different text content scenarios.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `040_text_empty_lines.wasot` | `.p`<br>`Line 1`<br>` `<br>`Line 3` | Empty lines in text | Shows `content: ""` for blank |
| `041_text_leading_whitespace.wasot` | `.p`<br>`   indented` | Leading whitespace | Whitespace preserved |
| `042_text_trailing_whitespace.wasot` | `.p`<br>`text   ` | Trailing whitespace | Whitespace preserved |
| `043_text_very_long.wasot` | `.p`<br>`(100+ chars)` | Very long line | Shows long content |
| `044_text_mixed_content.wasot` | `.a`<br>`text`<br>`..b`<br>`more` | Text before and around child | Multiple text nodes |

### Phase 7: Void Elements (045-054)

Self-closing void elements with trailing colon.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `045_void_basic.wasot` | `.hr:` | Basic void element | Introduces `(void type: level:)` |
| `046_void_with_inline.wasot` | `.img: alt text` | Void with inline text | `void` + `inline-text` |
| `047_void_with_kwarg.wasot` | `.img: .. src="x"` | Void with kwargs | `void` + `kwarg` |
| `048_void_with_id.wasot` | `.br: :br1` | Void with ID | `void` with `id:` |
| `049_void_nested.wasot` | `.a`<br>`..hr:` | Nested void | `void` at `level: 2` |
| `050_void_quoted_type.wasot` | `."page break":` | Quoted void type | Shows `type: "page break"` |
| `051_void_between_blocks.wasot` | `.a`<br>`.hr:`<br>`.b` | Void between blocks | Sequence of block/void/block |
| `052_void_in_nested.wasot` | `.a`<br>`..b`<br>`..hr:`<br>`..c` | Void among nested siblings | Void at same level as blocks |
| `053_void_with_all.wasot` | `.img: alt .. src="x" :id` | Void with everything | inline-text + kwarg + id |
| `054_multiple_voids.wasot` | `.br:`<br>`.hr:`<br>`.br:` | Sequential voids | Multiple void nodes |

### Phase 8: Context Lines (055-059)

The `./` context line syntax (metadata within blocks).

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `055_context_basic.wasot` | `.doc`<br>`./meta` | Basic context line | Introduces context-line node |
| `056_context_with_text.wasot` | `.doc`<br>`./author Alice` | Context with inline text | context-line + inline-text |
| `057_context_nested.wasot` | `.a`<br>`..b`<br>`../ver 1.0` | Nested context line | context-line at level 2 |
| `058_context_with_id.wasot` | `.doc`<br>`./meta :m1` | Context with ID | context-line + id |
| `059_context_multiple.wasot` | `.doc`<br>`./a 1`<br>`./b 2` | Multiple context lines | Multiple context-line nodes |

### Phase 9: Special Characters and Edge Cases (060-069)

Handling special characters and edge cases.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `060_arg_special_chars.wasot` | `.div .. @notify` | Special chars in args | Shows `@notify` |
| `061_arg_empty_quoted.wasot` | `.div .. ""` | Empty quoted arg | Shows empty string arg |
| `062_kwarg_empty_value.wasot` | `.div .. key=""` | Empty kwarg value | Shows `value: ""` |
| `063_kwarg_equals_in_value.wasot` | `.div .. k="a=b"` | Equals in quoted value | Shows `a=b` in value |
| `064_unicode_kwargs.wasot` | `.div .. キー=値` | Unicode in kwargs | Unicode key and value |
| `065_whitespace_type.wasot` | `." "` | Whitespace-only type | Shows `type: " "` |
| `066_multiple_separators.wasot` | `.div .. .. ..` | Multiple `..` separators | Shows `..` as args |
| `067_unclosed_quote.wasot` | `."unclosed` | Unclosed quote fallback | Parser recovery behavior |
| `068_escaped_quotes_arg.wasot` | `.div .. "a \"b\" c"` | Escaped quotes in arg | Quotes in string |
| `069_deep_nesting_10.wasot` | `.1`..`..........10` | 10 levels deep | Shows `level: 10` |

### Phase 10: Links in Text (070-076)

Links using `(( ))` syntax in text content.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `070_link_url.wasot` | `.p`<br>`See ((https://x.com))` | Simple URL link | Introduces `(link target_type: uri ...)` |
| `071_link_named.wasot` | `.p`<br>`See ((Name\|url))` | Named link | Shows display name in link |
| `072_link_id_ref.wasot` | `.p`<br>`See ((:section-id))` | ID reference link | Shows `target_type: id` |
| `073_link_multiple.wasot` | `.p`<br>`((a)) and ((b))` | Multiple links | Multiple `(link ...)` nodes |
| `074_link_with_args.wasot` | `.p`<br>`((text .. class=x))` | Link with parameters | Link with kwargs |
| `075_link_positions.wasot` | `.p`<br>`((start)) mid ((end))` | Link positions | Different `start:` values |
| `076_link_multiline.wasot` | `.p`<br>`Line 1 ((a))`<br>`Line 2 ((b))` | Links on multiple lines | Links in different lines |

### Phase 11: Complex Combinations (077-085)

Files combining multiple features.

| File | Wasot | New Concept | S-expr Change |
|------|-------|-------------|---------------|
| `077_everything_block.wasot` | `."type" text .. a key=v :id` | All block features | All attributes populated |
| `078_everything_void.wasot` | `."type": text .. k=v :id` | All void features | All void attributes |
| `079_mixed_hierarchy.wasot` | Complex nesting with all types | Mixed blocks/voids/context | Full structure |
| `080_realistic_document.wasot` | Simple doc structure | Realistic usage | Clean example |
| `081_realistic_config.wasot` | Configuration-like structure | Config-style | Nested kwargs |
| `082_realistic_form.wasot` | Form-like structure | Form elements | Nested blocks with args |
| `083_text_heavy.wasot` | Lots of text content | Multiple text blocks | Many text nodes |
| `084_meta_heavy.wasot` | Many kwargs and args | Parameter-heavy | Many kwarg nodes |
| `085_nesting_heavy.wasot` | Deep and wide nesting | Complex tree | Deep/wide structure |
| `086_everything.wasot` | Ultimate test | All features | Full coverage |

## Validation Command

For each file, run:
```bash
wasot -t sexp progressive_complexity/NNN_name.wasot
```

Compare with previous file to verify exactly one new concept is introduced.

## Implementation Notes

1. **One concept per file**: Each file should change exactly one thing in the S-expression output compared to the previous file.

2. **Cumulative learning**: Later files can use concepts from earlier files, but should only introduce one new thing.

3. **Clear naming**: File names should describe the new concept being introduced.

4. **Minimal examples**: Use the shortest possible example that demonstrates the concept.

5. **Comments in files**: Consider adding a comment header explaining what the file demonstrates (if wasot supports comments).

## Testing Notes

You can test any wasot content interactively using stdin:
```bash
echo '.div text' | wasot -t sexp /dev/stdin
# or
wasot -t sexp /dev/stdin <<< '.div text'
```

For files:
```bash
wasot -t sexp progressive_complexity/NNN_name.wasot
```

## Summary Statistics

- **Total files**: ~87
- **Phases**: 11
- **Coverage**: All syntax features from `tests/wasot_syntax_tests.md`

## Next Steps

1. Create `progressive_complexity/` directory
2. Start with Phase 1 files (000-009)
3. Validate each with `wasot -t sexp`
4. Document any unexpected behaviors
5. Continue through all phases
